Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9e6aba330e | |||
| d810f1cd33 | |||
| f8172015a8 | |||
| 04a61d2fc9 | |||
|
|
555983fc2e |
8
Makefile
8
Makefile
@@ -5,7 +5,7 @@ VSN ?= $(shell git describe --dirty)
|
|||||||
VSNHASH ?= $(shell git rev-parse --verify HEAD)
|
VSNHASH ?= $(shell git rev-parse --verify HEAD)
|
||||||
LDFLAGS ?= -ldflags "-X main.Version=$(VSN) -X main.VersionHash=$(VSNHASH)"
|
LDFLAGS ?= -ldflags "-X main.Version=$(VSN) -X main.VersionHash=$(VSNHASH)"
|
||||||
|
|
||||||
undocker: ## builds binary for the current architecture
|
undocker: $(GODEPS) ## builds binary for the current architecture
|
||||||
go build $(LDFLAGS) -o $@
|
go build $(LDFLAGS) -o $@
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
@@ -16,7 +16,7 @@ lint:
|
|||||||
go vet ./...
|
go vet ./...
|
||||||
staticcheck -f stylish ./...
|
staticcheck -f stylish ./...
|
||||||
shellcheck $(SCRIPTS)
|
shellcheck $(SCRIPTS)
|
||||||
shfmt $(SCRIPTS)
|
shfmt -w -i 4 $(SCRIPTS)
|
||||||
git diff --exit-code
|
git diff --exit-code
|
||||||
|
|
||||||
.INTERMEDIATE: coverage.out
|
.INTERMEDIATE: coverage.out
|
||||||
@@ -30,7 +30,9 @@ coverage.html: coverage.out
|
|||||||
clean:
|
clean:
|
||||||
rm -f undocker coverage.html
|
rm -f undocker coverage.html
|
||||||
|
|
||||||
TEST_IMAGES = busybox-glibc_65ad0d468eb1
|
TEST_IMAGES = \
|
||||||
|
busybox-glibc_65ad0d468eb1 \
|
||||||
|
docker_v27.1.2_save
|
||||||
|
|
||||||
.PHONY: test-integration
|
.PHONY: test-integration
|
||||||
test-integration: $(foreach IMG,$(TEST_IMAGES),test-integration-$(IMG))
|
test-integration: $(foreach IMG,$(TEST_IMAGES),test-integration-$(IMG))
|
||||||
|
|||||||
@@ -108,12 +108,7 @@ rejected.
|
|||||||
Communication
|
Communication
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
Feel free to ping me [directly][motiejus-comms].
|
Ping me [directly][motiejus-comms].
|
||||||
|
|
||||||
LICENSE
|
|
||||||
-------
|
|
||||||
|
|
||||||
MIT
|
|
||||||
|
|
||||||
[1]: https://www.freedesktop.org/software/systemd/man/systemd.exec.html
|
[1]: https://www.freedesktop.org/software/systemd/man/systemd.exec.html
|
||||||
[2]: https://fly.io/blog/docker-without-docker/
|
[2]: https://fly.io/blog/docker-without-docker/
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ func Flatten(rd io.ReadSeeker, w io.Writer) (_err error) {
|
|||||||
var closer func() error
|
var closer func() error
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
// layerOffsets maps a layer name (a9b123c0daa/layer.tar) to it's offset
|
// fileOffsets maps a file name (a9b123c0daa/layer.tar) to it's offset
|
||||||
layerOffsets := map[string]int64{}
|
fileOffsets := map[string]int64{}
|
||||||
|
|
||||||
// manifest is the docker manifest in the image
|
// manifest is the docker manifest in the image
|
||||||
var manifest dockerManifestJSON
|
var manifest dockerManifestJSON
|
||||||
@@ -58,31 +58,29 @@ func Flatten(rd io.ReadSeeker, w io.Writer) (_err error) {
|
|||||||
if hdr.Typeflag != tar.TypeReg {
|
if hdr.Typeflag != tar.TypeReg {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
switch {
|
|
||||||
case filepath.Clean(hdr.Name) == _manifestJSON:
|
|
||||||
dec := json.NewDecoder(tr)
|
|
||||||
if err := dec.Decode(&manifest); err != nil {
|
|
||||||
return fmt.Errorf("decode %s: %w", _manifestJSON, err)
|
|
||||||
}
|
|
||||||
case strings.HasSuffix(hdr.Name, _tarSuffix):
|
|
||||||
here, err := rd.Seek(0, io.SeekCurrent)
|
here, err := rd.Seek(0, io.SeekCurrent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
layerOffsets[strings.TrimPrefix(hdr.Name, "./")] = here
|
fileOffsets[strings.TrimPrefix(hdr.Name, "./")] = here
|
||||||
|
if filepath.Clean(hdr.Name) == _manifestJSON {
|
||||||
|
dec := json.NewDecoder(tr)
|
||||||
|
if err := dec.Decode(&manifest); err != nil {
|
||||||
|
return fmt.Errorf("decode %s: %w", _manifestJSON, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := validateManifest(layerOffsets, manifest); err != nil {
|
if err := validateManifest(fileOffsets, manifest); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// enumerate layers the way they would be laid down in the image
|
// enumerate layers the way they would be laid down in the image
|
||||||
layers := make([]nameOffset, len(layerOffsets))
|
layers := make([]nameOffset, len(manifest[0].Layers))
|
||||||
for i, name := range manifest[0].Layers {
|
for i, name := range manifest[0].Layers {
|
||||||
layers[i] = nameOffset{
|
layers[i] = nameOffset{
|
||||||
name: name,
|
name: name,
|
||||||
offset: layerOffsets[strings.TrimPrefix(name, "./")],
|
offset: fileOffsets[strings.TrimPrefix(name, "./")],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,7 +230,7 @@ func whiteoutDirs(whreaddir map[string]int, nlayers int) []*tree {
|
|||||||
|
|
||||||
// validateManifest
|
// validateManifest
|
||||||
func validateManifest(
|
func validateManifest(
|
||||||
layerOffsets map[string]int64,
|
fileOffsets map[string]int64,
|
||||||
manifest dockerManifestJSON,
|
manifest dockerManifestJSON,
|
||||||
) error {
|
) error {
|
||||||
if len(manifest) == 0 {
|
if len(manifest) == 0 {
|
||||||
@@ -240,7 +238,7 @@ func validateManifest(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, layer := range manifest[0].Layers {
|
for _, layer := range manifest[0].Layers {
|
||||||
if _, ok := layerOffsets[layer]; !ok {
|
if _, ok := fileOffsets[layer]; !ok {
|
||||||
return fmt.Errorf("%s defined in manifest, missing in tarball", layer)
|
return fmt.Errorf("%s defined in manifest, missing in tarball", layer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
t/docker_v27.1.2_save.txt
Normal file
1
t/docker_v27.1.2_save.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
-rw-r--r-- 0/0 39 2024-09-10 10:49 Dockerfile
|
||||||
Reference in New Issue
Block a user