diff --git a/lxcconfig/BUILD b/lxcconfig/BUILD index 2aca87a..16dda50 100644 --- a/lxcconfig/BUILD +++ b/lxcconfig/BUILD @@ -12,6 +12,7 @@ go_test( srcs = ["lxcconfig_test.go"], embed = [":go_default_library"], deps = [ + "//src/undocker/internal/tartest:go_default_library", "@com_github_stretchr_testify//assert:go_default_library", "@com_github_stretchr_testify//require:go_default_library", ], diff --git a/lxcconfig/lxcconfig.go b/lxcconfig/lxcconfig.go index 6f70c81..22a63ee 100644 --- a/lxcconfig/lxcconfig.go +++ b/lxcconfig/lxcconfig.go @@ -57,8 +57,8 @@ type ( ) // LXCConfig accepts a Docker container image and returns lxc configuration. -func LXCConfig(in io.ReadSeeker, wr io.Writer) error { - dockerCfg, err := getDockerConfig(in) +func LXCConfig(rd io.ReadSeeker, wr io.Writer) error { + dockerCfg, err := getDockerConfig(rd) if err != nil { return err } @@ -90,9 +90,9 @@ func (l lxcConfig) WriteTo(wr io.Writer) error { return _lxcTemplate.Execute(wr, l) } -func getDockerConfig(in io.ReadSeeker) (dockerConfig, error) { - tr := tar.NewReader(in) - // get offsets to all json files in the archive +func getDockerConfig(rd io.ReadSeeker) (dockerConfig, error) { + tr := tar.NewReader(rd) + // get offsets to all json files rd the archive jsonOffsets := map[string]int64{} for { hdr, err := tr.Next() @@ -102,19 +102,19 @@ func getDockerConfig(in io.ReadSeeker) (dockerConfig, error) { if hdr.Typeflag != tar.TypeReg { continue } - if !strings.HasSuffix(_json, hdr.Name) { + if !strings.HasSuffix(hdr.Name, _json) { continue } - here, err := in.Seek(0, io.SeekCurrent) + here, err := rd.Seek(0, io.SeekCurrent) if err != nil { return dockerConfig{}, err } jsonOffsets[hdr.Name] = here } - // manifest is the docker manifest in the image + // manifest is the docker manifest rd the image var manifest dockerManifest - if err := parseJSON(in, jsonOffsets, _manifestJSON, &manifest); err != nil { + if err := parseJSON(rd, jsonOffsets, _manifestJSON, &manifest); err != nil { return dockerConfig{}, err } if len(manifest) == 0 { @@ -122,22 +122,24 @@ func getDockerConfig(in io.ReadSeeker) (dockerConfig, error) { } var config dockerConfig - if err := parseJSON(in, jsonOffsets, manifest[0].Config, &config); err != nil { + if err := parseJSON(rd, jsonOffsets, manifest[0].Config, &config); err != nil { return dockerConfig{}, err } return config, nil } -func parseJSON(in io.ReadSeeker, offsets map[string]int64, fname string, c interface{}) error { +//TODO: don't seek to files, read them. +func parseJSON(rd io.ReadSeeker, offsets map[string]int64, fname string, c interface{}) error { configOffset, ok := offsets[fname] + fmt.Printf("jumping to %s in %x\n", fname, configOffset) if !ok { return fmt.Errorf("file %s not found", fname) } - if _, err := in.Seek(configOffset, io.SeekStart); err != nil { + if _, err := rd.Seek(configOffset, io.SeekStart); err != nil { return fmt.Errorf("seek to %s: %w", fname, err) } - tr := tar.NewReader(in) + tr := tar.NewReader(rd) if _, err := tr.Next(); err != nil { return err } diff --git a/lxcconfig/lxcconfig_test.go b/lxcconfig/lxcconfig_test.go index b523371..9d6b209 100644 --- a/lxcconfig/lxcconfig_test.go +++ b/lxcconfig/lxcconfig_test.go @@ -1,14 +1,18 @@ package lxcconfig import ( + "archive/tar" "bytes" + "encoding/json" "testing" + "github.com/motiejus/code/undocker/internal/tartest" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestLXCConfig(t *testing.T) { + tests := []struct { name string docker dockerConfig @@ -24,35 +28,59 @@ lxc.architecture = amd64 lxc.execute.cmd = '/bin/sh' `, }, - { - name: "all fields", - docker: dockerConfig{ - Architecture: "amd64", - Config: dockerConfigConfig{ - Entrypoint: []string{"/entrypoint.sh"}, - Cmd: []string{"/bin/sh", "-c", "echo foo"}, - WorkingDir: "/x", - Env: []string{ - `LONGNAME="Foo Bar"`, - "SHELL=/bin/tcsh", + /* + { + name: "all fields", + docker: dockerConfig{ + Architecture: "amd64", + Config: dockerConfigConfig{ + Entrypoint: []string{"/entrypoint.sh"}, + Cmd: []string{"/bin/sh", "-c", "echo foo"}, + WorkingDir: "/x", + Env: []string{ + `LONGNAME="Foo Bar"`, + "SHELL=/bin/tcsh", + }, + }, + }, + want: `lxc.include = LXC_TEMPLATE_CONFIG/common.conf + lxc.architecture = amd64 + lxc.execute.cmd = '/entrypoint.sh /bin/sh -c echo foo' + lxc.init.cwd = /x + lxc.environment = LONGNAME="Foo Bar" + lxc.environment = SHELL=/bin/tcsh + `, }, - }, - }, - want: `lxc.include = LXC_TEMPLATE_CONFIG/common.conf -lxc.architecture = amd64 -lxc.execute.cmd = '/entrypoint.sh /bin/sh -c echo foo' -lxc.init.cwd = /x -lxc.environment = LONGNAME="Foo Bar" -lxc.environment = SHELL=/bin/tcsh -`, - }, + */ } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + manifest := tartest.File{ + Name: "manifest.json", + Contents: bytes.NewBufferString(`[{"Config":"config.json"}]`), + } + _ = manifest + archive := tartest.Tarball{ + manifest, + //tt.docker, + } + in := bytes.NewReader(archive.Buffer().Bytes()) var buf bytes.Buffer - require.NoError(t, docker2lxc(tt.docker).WriteTo(&buf)) + require.NoError(t, LXCConfig(in, &buf)) assert.Equal(t, tt.want, string(buf.Bytes())) }) } } + +// Helpers +func (c dockerConfig) Tar(tw *tar.Writer) error { + configJSON, err := json.MarshalIndent(c, "", " ") + if err != nil { + return err + } + return tartest.File{ + Name: "config.json", + Contents: bytes.NewBuffer(configJSON), + }.Tar(tw) +} diff --git a/rootfs/rootfs_test.go b/rootfs/rootfs_test.go index bc9acd1..b596e63 100644 --- a/rootfs/rootfs_test.go +++ b/rootfs/rootfs_test.go @@ -187,9 +187,7 @@ func TestRootFS(t *testing.T) { } // Helpers -type ( - manifest []string -) +type manifest []string func (m manifest) Tar(tw *tar.Writer) error { b, err := json.Marshal(dockerManifestJSON{{Layers: m}})