d2vm/docker_image_test.go

169 lines
3.5 KiB
Go

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.SetDebug(true)
tmp := filepath.Join(os.TempDir(), "d2vm-tests", "image-flatten")
require.NoError(t, os.MkdirAll(tmp, os.ModePerm))
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.Build(ctx, false, img, "", tmp, "linux/amd64"))
defer docker.Remove(ctx, img)
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)
}