Skip to content
This repository has been archived by the owner on Dec 7, 2023. It is now read-only.

Commit

Permalink
Tiny image import fix
Browse files Browse the repository at this point in the history
When an image is very small, filesystem creation using mkfs fails due to
not enough space. This adds a minimum base image size that's used when
the image is too small.

Also, fixes the /etc/resolv.conf symlink error when there's no /etc
directory in the image filesystem. /etc dir is created as part of the
import step if it doesn't exists.

Adds an e2e test for this fix using hello-world docker container image
which is tiny and lacks /etc dir.
  • Loading branch information
darkowlzz committed Mar 5, 2020
1 parent 2f6b054 commit 7666fe7
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 2 deletions.
33 changes: 33 additions & 0 deletions e2e/image_test.go
Original file line number Diff line number Diff line change
@@ -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,
)
// Igore 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))
}
24 changes: 22 additions & 2 deletions pkg/dmlegacy/image_format.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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())
}

Expand Down Expand Up @@ -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)
}

Expand Down

0 comments on commit 7666fe7

Please sign in to comment.