Skip to content

Commit be3ec80

Browse files
committed
docker: use umoci library and podman image library
* fixes issues with extracting to wrong directory * allows pulling from other oci registries (will still pull from docker if unspecified) * allows to specify digest (can't specify both digest and tag at the same time) Signed-off-by: Allen Davis <hoplin44@proton.me>
1 parent d342e98 commit be3ec80

File tree

1 file changed

+70
-18
lines changed

1 file changed

+70
-18
lines changed

sources/docker.go

Lines changed: 70 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,23 @@ package sources
22

33
import (
44
"context"
5+
"encoding/json"
56
"fmt"
67
"os"
78
"path/filepath"
89

9-
"github.com/opencontainers/umoci"
1010
"github.com/opencontainers/umoci/oci/cas/dir"
1111
"github.com/opencontainers/umoci/oci/casext"
1212
"github.com/opencontainers/umoci/oci/layer"
1313

14-
"github.com/lxc/distrobuilder/shared"
14+
"go.podman.io/image/v5/copy"
15+
"go.podman.io/image/v5/docker/reference"
16+
"go.podman.io/image/v5/oci/layout"
17+
"go.podman.io/image/v5/signature"
18+
"go.podman.io/image/v5/transports/alltransports"
19+
"go.podman.io/image/v5/types"
20+
21+
imgspec "github.com/opencontainers/image-spec/specs-go/v1"
1522
)
1623

1724
type docker struct {
@@ -33,33 +40,78 @@ func (s *docker) Run() error {
3340

3441
defer func() { _ = os.RemoveAll(ociPath) }()
3542

36-
// Download from Docker Hub.
37-
imageTag := "latest"
38-
err = shared.RunCommand(
39-
context.TODO(),
40-
nil,
41-
nil,
42-
"skopeo",
43-
"--insecure-policy",
44-
"copy",
45-
"--remove-signatures",
46-
fmt.Sprintf("%s/%s", "docker://docker.io", s.definition.Source.URL),
47-
fmt.Sprintf("oci:%s:%s", ociPath, imageTag))
43+
// Parse the image reference
44+
imageRef, err := reference.ParseNormalizedNamed(s.definition.Source.URL)
45+
if err != nil {
46+
return fmt.Errorf("Failed to parse image reference: %w", err)
47+
}
48+
49+
// Docker references with both a tag and digest are currently not supported
50+
var imageTag string
51+
if digested, ok := imageRef.(reference.Digested); ok {
52+
imageTag = digested.Digest().String()
53+
} else {
54+
imageTag = "latest"
55+
if tagged, ok := imageRef.(reference.NamedTagged); ok {
56+
imageTag = tagged.Tag()
57+
}
58+
}
59+
60+
srcRef, err := alltransports.ParseImageName(fmt.Sprintf("docker://%s", s.definition.Source.URL))
61+
if err != nil {
62+
return fmt.Errorf("Failed to parse image name: %w", err)
63+
}
64+
65+
dstRef, err := layout.ParseReference(fmt.Sprintf("%s:%s", ociPath, imageTag))
66+
if err != nil {
67+
return fmt.Errorf("Failed to parse destination reference: %w", err)
68+
}
69+
70+
// Create policy context
71+
systemCtx := &types.SystemContext{
72+
DockerInsecureSkipTLSVerify: types.OptionalBoolFalse,
73+
}
74+
policy, err := signature.DefaultPolicy(systemCtx)
75+
if err != nil {
76+
return fmt.Errorf("Failed to create policy: %w", err)
77+
}
78+
policyCtx, err := signature.NewPolicyContext(policy)
79+
if err != nil {
80+
return fmt.Errorf("Failed to create policy context: %w", err)
81+
}
82+
83+
defer policyCtx.Destroy()
84+
85+
copyOptions := &copy.Options{
86+
RemoveSignatures: true,
87+
SourceCtx: systemCtx,
88+
DestinationCtx: systemCtx,
89+
}
90+
91+
ctx := context.TODO()
92+
93+
// Pull image from OCI registry
94+
copiedManifest, err := copy.Image(ctx, policyCtx, dstRef, srcRef, copyOptions)
4895
if err != nil {
4996
return err
5097
}
5198

52-
// Unpack.
53-
var unpackOptions layer.UnpackOptions
54-
unpackOptions.KeepDirlinks = true
99+
// Unpack OCI image
100+
unpackOptions := &layer.UnpackOptions{KeepDirlinks: true}
55101

56102
engine, err := dir.Open(ociPath)
57103
if err != nil {
58104
return err
59105
}
60106

61107
engineExt := casext.NewEngine(engine)
108+
62109
defer func() { _ = engine.Close() }()
63110

64-
return umoci.Unpack(engineExt, imageTag, absRootfsDir, unpackOptions)
111+
var manifest imgspec.Manifest
112+
if err := json.Unmarshal(copiedManifest, &manifest); err != nil {
113+
return fmt.Errorf("Failed to parse manifest: %w", err)
114+
}
115+
116+
return layer.UnpackRootfs(ctx, engineExt, absRootfsDir, manifest, unpackOptions)
65117
}

0 commit comments

Comments
 (0)