diff --git a/lxcconfig/lxcconfig.go b/lxcconfig/lxcconfig.go index 22a63ee..4d55de6 100644 --- a/lxcconfig/lxcconfig.go +++ b/lxcconfig/lxcconfig.go @@ -35,6 +35,12 @@ type ( Env []string } + // offsetSize is a tuple which stores file offset and size + offsetSize struct { + offset int64 + size int64 + } + // dockerManifest is manifest.json dockerManifest []struct { Config string `json:"Config"` @@ -93,7 +99,7 @@ func (l lxcConfig) WriteTo(wr io.Writer) error { func getDockerConfig(rd io.ReadSeeker) (dockerConfig, error) { tr := tar.NewReader(rd) // get offsets to all json files rd the archive - jsonOffsets := map[string]int64{} + jsonOffsets := map[string]offsetSize{} for { hdr, err := tr.Next() if err == io.EOF { @@ -109,7 +115,10 @@ func getDockerConfig(rd io.ReadSeeker) (dockerConfig, error) { if err != nil { return dockerConfig{}, err } - jsonOffsets[hdr.Name] = here + jsonOffsets[hdr.Name] = offsetSize{ + offset: here, + size: hdr.Size, + } } // manifest is the docker manifest rd the image @@ -129,21 +138,17 @@ func getDockerConfig(rd io.ReadSeeker) (dockerConfig, error) { return config, nil } -//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) +func parseJSON(rd io.ReadSeeker, offsets map[string]offsetSize, fname string, c interface{}) error { + osize, ok := offsets[fname] if !ok { return fmt.Errorf("file %s not found", fname) } - if _, err := rd.Seek(configOffset, io.SeekStart); err != nil { + if _, err := rd.Seek(osize.offset, io.SeekStart); err != nil { return fmt.Errorf("seek to %s: %w", fname, err) } - tr := tar.NewReader(rd) - if _, err := tr.Next(); err != nil { - return err - } - dec := json.NewDecoder(tr) + + lrd := io.LimitReader(rd, osize.size) + dec := json.NewDecoder(lrd) if err := dec.Decode(c); err != nil { return fmt.Errorf("decode %s: %w", fname, err) } diff --git a/lxcconfig/lxcconfig_test.go b/lxcconfig/lxcconfig_test.go index 9d6b209..54fc197 100644 --- a/lxcconfig/lxcconfig_test.go +++ b/lxcconfig/lxcconfig_test.go @@ -4,6 +4,7 @@ import ( "archive/tar" "bytes" "encoding/json" + "strings" "testing" "github.com/motiejus/code/undocker/internal/tartest" @@ -23,35 +24,37 @@ func TestLXCConfig(t *testing.T) { docker: dockerConfig{ Architecture: "amd64", }, - want: `lxc.include = LXC_TEMPLATE_CONFIG/common.conf -lxc.architecture = amd64 -lxc.execute.cmd = '/bin/sh' -`, + want: strings.Join([]string{ + `lxc.include = LXC_TEMPLATE_CONFIG/common.conf`, + `lxc.architecture = amd64`, + `lxc.execute.cmd = '/bin/sh'`, + ``, + }, "\n"), }, - /* - { - 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 - `, + { + 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: strings.Join([]string{ + `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`, + ``, + }, "\n"), + }, } for _, tt := range tests { @@ -60,10 +63,9 @@ lxc.execute.cmd = '/bin/sh' Name: "manifest.json", Contents: bytes.NewBufferString(`[{"Config":"config.json"}]`), } - _ = manifest archive := tartest.Tarball{ manifest, - //tt.docker, + tt.docker, } in := bytes.NewReader(archive.Buffer().Bytes()) var buf bytes.Buffer