mirror of
https://github.com/linka-cloud/d2vm.git
synced 2025-12-14 15:03:12 +00:00
d2vm: flatten docker image using github.com/google/go-containerregistry
This allows to preserve files like /etc/hostname or /etc/resolv.conf that will otherwise be overriden by running the container to extract rootfs wip img entrypoint script Signed-off-by: Adphi <philippe.adrien.nousse@gmail.com>
This commit is contained in:
171
docker_image_test.go
Normal file
171
docker_image_test.go
Normal file
@@ -0,0 +1,171 @@
|
||||
package d2vm
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"go.linka.cloud/d2vm/pkg/docker"
|
||||
"go.linka.cloud/d2vm/pkg/exec"
|
||||
)
|
||||
|
||||
func TestDockerImageAsRunSript(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
image DockerImage
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "nothing",
|
||||
image: DockerImage{
|
||||
DockerImageConfig: DockerImageConfig{
|
||||
User: "",
|
||||
WorkingDir: "",
|
||||
Env: nil,
|
||||
Entrypoint: nil,
|
||||
Cmd: nil,
|
||||
},
|
||||
},
|
||||
want: `
|
||||
#!/bin/sh
|
||||
|
||||
|
||||
|
||||
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "tail -f /dev/null",
|
||||
image: DockerImage{
|
||||
DockerImageConfig: DockerImageConfig{
|
||||
User: "root",
|
||||
Cmd: []string{"tail", "-f", "/dev/null"},
|
||||
},
|
||||
},
|
||||
want: `
|
||||
#!/bin/sh
|
||||
|
||||
|
||||
|
||||
su root -p -s /bin/sh -c '"tail" "-f" "/dev/null"'
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "tail -f /dev/null inside home",
|
||||
image: DockerImage{
|
||||
DockerImageConfig: DockerImageConfig{
|
||||
User: "root",
|
||||
WorkingDir: "/root",
|
||||
Cmd: []string{"tail", "-f", "/dev/null"},
|
||||
},
|
||||
},
|
||||
want: `
|
||||
#!/bin/sh
|
||||
|
||||
cd /root
|
||||
|
||||
su root -p -s /bin/sh -c '"tail" "-f" "/dev/null"'
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "subshell tail -f /dev/null",
|
||||
image: DockerImage{
|
||||
DockerImageConfig: DockerImageConfig{
|
||||
User: "root",
|
||||
Entrypoint: []string{"/bin/sh", "-c"},
|
||||
Cmd: []string{"tail -f /dev/null"},
|
||||
},
|
||||
},
|
||||
want: `
|
||||
#!/bin/sh
|
||||
|
||||
|
||||
|
||||
su root -p -s /bin/sh -c '"/bin/sh" "-c" "tail -f /dev/null"'
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "www-data with env",
|
||||
image: DockerImage{
|
||||
DockerImageConfig: DockerImageConfig{
|
||||
User: "www-data",
|
||||
Cmd: []string{"tail", "-f", "/dev/null"},
|
||||
Env: []string{"ENV=PROD", "DB=mysql://user:password@localhost"},
|
||||
},
|
||||
},
|
||||
want: `
|
||||
#!/bin/sh
|
||||
export ENV=PROD
|
||||
export DB=mysql://user:password@localhost
|
||||
|
||||
|
||||
|
||||
su www-data -p -s /bin/sh -c '"tail" "-f" "/dev/null"'
|
||||
`,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var w bytes.Buffer
|
||||
require.NoError(t, tt.image.AsRunScript(&w))
|
||||
assert.Equal(t, tt.want, w.String())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestImageFlatten(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
const (
|
||||
img = "d2vm-flatten-test"
|
||||
dockerfile = `FROM alpine
|
||||
|
||||
COPY resolv.conf /etc/
|
||||
COPY hostname /etc/
|
||||
|
||||
RUN rm -rf /etc/apk
|
||||
`
|
||||
)
|
||||
exec.Run = exec.RunStdout
|
||||
tmp := filepath.Join(os.TempDir(), "d2vm-tests", "image-flatten")
|
||||
require.NoError(t, os.MkdirAll(tmp, perm))
|
||||
defer os.RemoveAll(tmp)
|
||||
|
||||
require.NoError(t, os.WriteFile(filepath.Join(tmp, "hostname"), []byte("d2vm-flatten-test"), perm))
|
||||
require.NoError(t, os.WriteFile(filepath.Join(tmp, "resolv.conf"), []byte("nameserver 8.8.8.8"), perm))
|
||||
require.NoError(t, os.WriteFile(filepath.Join(tmp, "Dockerfile"), []byte(dockerfile), perm))
|
||||
require.NoError(t, docker.Cmd(ctx, "image", "build", "-t", img, tmp))
|
||||
defer docker.Cmd(ctx, "image", "rm", img)
|
||||
|
||||
// imgTar := filepath.Join(tmp, img+".tar")
|
||||
// require.NoError(t, docker.Cmd(ctx, "image", "save", img, "-o", imgTar))
|
||||
//
|
||||
imgTmp := filepath.Join(tmp, "image")
|
||||
|
||||
i, err := NewImage(ctx, img, imgTmp)
|
||||
require.NoError(t, err)
|
||||
|
||||
rootfs := filepath.Join(tmp, "rootfs")
|
||||
require.NoError(t, i.Flatten(ctx, rootfs))
|
||||
|
||||
b, err := os.ReadFile(filepath.Join(rootfs, "etc", "resolv.conf"))
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "nameserver 8.8.8.8", string(b))
|
||||
|
||||
b, err = os.ReadFile(filepath.Join(rootfs, "etc", "hostname"))
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "d2vm-flatten-test", string(b))
|
||||
|
||||
_, err = os.Stat(filepath.Join(rootfs, "etc", "apk"))
|
||||
assert.Error(t, err)
|
||||
|
||||
require.NoError(t, i.Close())
|
||||
_, err = os.Stat(imgTmp)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
Reference in New Issue
Block a user