diff --git a/e2e/image_test.go b/e2e/image_test.go new file mode 100644 index 000000000..16283405a --- /dev/null +++ b/e2e/image_test.go @@ -0,0 +1,33 @@ +package e2e + +import ( + "fmt" + "os/exec" + "testing" + + "gotest.tools/assert" +) + +func TestImportTinyImage(t *testing.T) { + assert.Assert(t, e2eHome != "", "IGNITE_E2E_HOME should be set") + + // NOTE: Along with tiny image, this also tests the image import failure + // when there's no /etc directory in the image filesystem. + + testImage := "hello-world:latest" + // Remove if the image already exists. + rmvImgCmd := exec.Command( + igniteBin, + "image", "rm", testImage, + ) + // Ignore error if the image doesn't exists. + _, _ = rmvImgCmd.CombinedOutput() + + // Import the image. + importImgCmd := exec.Command( + igniteBin, + "image", "import", testImage, + ) + importImgOut, importImgErr := importImgCmd.CombinedOutput() + assert.Check(t, importImgErr, fmt.Sprintf("image import: \n%q\n%s", importImgCmd.Args, importImgOut)) +} diff --git a/pkg/dmlegacy/image_format.go b/pkg/dmlegacy/image_format.go index 9d8866730..2cb05a59d 100644 --- a/pkg/dmlegacy/image_format.go +++ b/pkg/dmlegacy/image_format.go @@ -19,7 +19,10 @@ import ( "github.com/weaveworks/ignite/pkg/util" ) -const blockSize = 4096 // Block size to use for the ext4 filesystems, this is the default +const ( + blockSize = 4096 // Block size to use for the ext4 filesystems, this is the default + minimumBaseSize = 500000 // Mimimum size of the base image, ~ half a megabyte. +) // CreateImageFilesystem creates an ext4 filesystem in a file, containing the files from the source func CreateImageFilesystem(img *api.Image, src source.Source) error { @@ -34,7 +37,18 @@ func CreateImageFilesystem(img *api.Image, src source.Source) error { // To accommodate space for the tar file contents and the ext4 journal + other metadata, // make the base image a sparse file three times the size of the source contents. This // will be shrunk to fit by resizeToMinimum later. - if err := imageFile.Truncate(int64(img.Status.OCISource.Size.Bytes()) * 3); err != nil { + var baseImageSize int64 + threeTimesImageSize := img.Status.OCISource.Size.Bytes() * 3 + // If the base image is too small, filesystem creation using mkfs fails with + // not enough space error. Ensure the base image size is at least the + // minimum base size. + if threeTimesImageSize < minimumBaseSize { + baseImageSize = int64(minimumBaseSize) + } else { + baseImageSize = int64(threeTimesImageSize) + } + + if err := imageFile.Truncate(baseImageSize); err != nil { return errors.Wrapf(err, "failed to allocate space for image %s", img.GetUID()) } @@ -106,6 +120,12 @@ func setupResolvConf(tempDir string) error { return nil } + // Ensure /etc directory exists. Some images don't contain /etc directory + // which results in symlink creation failure. + if err := os.MkdirAll(filepath.Dir(resolvConf), constants.DATA_DIR_PERM); err != nil { + return err + } + return os.Symlink("../proc/net/pnp", resolvConf) }