@@ -26,17 +26,18 @@ import (
2626 "strings"
2727
2828 "github.com/adrg/xdg"
29+ "github.com/compose-spec/compose-go/loader"
2930 "github.com/distribution/reference"
3031 "github.com/docker/buildx/store/storeutil"
3132 "github.com/docker/buildx/util/imagetools"
3233 "github.com/docker/cli/cli/command"
3334 v1 "github.com/opencontainers/image-spec/specs-go/v1"
34-
35- "github.com/compose-spec/compose-go/loader"
3635)
3736
38- func OCIRemoteLoaderEnabled () (bool , error ) {
39- if v := os .Getenv ("COMPOSE_EXPERIMENTAL_OCI_REMOTE" ); v != "" {
37+ const OCI_REMOTE_ENABLED = "COMPOSE_EXPERIMENTAL_OCI_REMOTE"
38+
39+ func ociRemoteLoaderEnabled () (bool , error ) {
40+ if v := os .Getenv (OCI_REMOTE_ENABLED ); v != "" {
4041 enabled , err := strconv .ParseBool (v )
4142 if err != nil {
4243 return false , fmt .Errorf ("COMPOSE_EXPERIMENTAL_OCI_REMOTE environment variable expects boolean value: %w" , err )
@@ -76,6 +77,14 @@ func (g ociRemoteLoader) Accept(path string) bool {
7677}
7778
7879func (g ociRemoteLoader ) Load (ctx context.Context , path string ) (string , error ) {
80+ enabled , err := ociRemoteLoaderEnabled ()
81+ if err != nil {
82+ return "" , err
83+ }
84+ if ! enabled {
85+ return "" , fmt .Errorf ("experimental OCI remote resource is disabled. %q must be set" , OCI_REMOTE_ENABLED )
86+ }
87+
7988 if g .offline {
8089 return "" , nil
8190 }
@@ -99,50 +108,57 @@ func (g ociRemoteLoader) Load(ctx context.Context, path string) (string, error)
99108 local := filepath .Join (g .cache , descriptor .Digest .Hex ())
100109 composeFile := filepath .Join (local , "compose.yaml" )
101110 if _ , err = os .Stat (local ); os .IsNotExist (err ) {
102-
103- err = os . MkdirAll ( local , 0o700 )
111+ var manifest v1. Manifest
112+ err = json . Unmarshal ( content , & manifest )
104113 if err != nil {
105114 return "" , err
106115 }
107116
108- f , err := os . Create ( composeFile )
109- if err != nil {
110- return "" , err
117+ err2 := g . pullComposeFiles ( ctx , local , composeFile , manifest , ref , resolver )
118+ if err2 != nil {
119+ return "" , err2
111120 }
112- defer f .Close () //nolint:errcheck
121+ }
122+ return composeFile , nil
123+ }
113124
114- var manifest v1.Manifest
115- err = json .Unmarshal (content , & manifest )
125+ func (g ociRemoteLoader ) pullComposeFiles (ctx context.Context , local string , composeFile string , manifest v1.Manifest , ref reference.Named , resolver * imagetools.Resolver ) error {
126+ err := os .MkdirAll (local , 0o700 )
127+ if err != nil {
128+ return err
129+ }
130+
131+ f , err := os .Create (composeFile )
132+ if err != nil {
133+ return err
134+ }
135+ defer f .Close () //nolint:errcheck
136+
137+ if manifest .ArtifactType != "application/vnd.docker.compose.project" {
138+ return fmt .Errorf ("%s is not a compose project OCI artifact, but %s" , ref .String (), manifest .ArtifactType )
139+ }
140+
141+ for i , layer := range manifest .Layers {
142+ digested , err := reference .WithDigest (ref , layer .Digest )
116143 if err != nil {
117- return "" , err
144+ return err
118145 }
119-
120- if manifest . ArtifactType != "application/vnd.docker.compose.project" {
121- return "" , fmt . Errorf ( "%s is not a compose project OCI artifact, but %s" , ref . String (), manifest . ArtifactType )
146+ content , _ , err := resolver . Get ( ctx , digested . String ())
147+ if err != nil {
148+ return err
122149 }
123-
124- for i , layer := range manifest .Layers {
125- digested , err := reference .WithDigest (ref , layer .Digest )
126- if err != nil {
127- return "" , err
128- }
129- content , _ , err := resolver .Get (ctx , digested .String ())
150+ if i > 0 {
151+ _ , err = f .Write ([]byte ("\n ---\n " ))
130152 if err != nil {
131- return "" , err
132- }
133- if i > 0 {
134- _ , err = f .Write ([]byte ("\n ---\n " ))
135- if err != nil {
136- return "" , err
137- }
138- }
139- _ , err = f .Write (content )
140- if err != nil {
141- return "" , err
153+ return err
142154 }
143155 }
156+ _ , err = f .Write (content )
157+ if err != nil {
158+ return err
159+ }
144160 }
145- return composeFile , nil
161+ return nil
146162}
147163
148164var _ loader.ResourceLoader = ociRemoteLoader {}
0 commit comments