@@ -2,16 +2,23 @@ package sources
22
33import (
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
1724type 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