@@ -26,17 +26,18 @@ import (
26
26
"strings"
27
27
28
28
"github.com/adrg/xdg"
29
+ "github.com/compose-spec/compose-go/loader"
29
30
"github.com/distribution/reference"
30
31
"github.com/docker/buildx/store/storeutil"
31
32
"github.com/docker/buildx/util/imagetools"
32
33
"github.com/docker/cli/cli/command"
33
34
v1 "github.com/opencontainers/image-spec/specs-go/v1"
34
-
35
- "github.com/compose-spec/compose-go/loader"
36
35
)
37
36
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 != "" {
40
41
enabled , err := strconv .ParseBool (v )
41
42
if err != nil {
42
43
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 {
76
77
}
77
78
78
79
func (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
+
79
88
if g .offline {
80
89
return "" , nil
81
90
}
@@ -99,50 +108,57 @@ func (g ociRemoteLoader) Load(ctx context.Context, path string) (string, error)
99
108
local := filepath .Join (g .cache , descriptor .Digest .Hex ())
100
109
composeFile := filepath .Join (local , "compose.yaml" )
101
110
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 )
104
113
if err != nil {
105
114
return "" , err
106
115
}
107
116
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
111
120
}
112
- defer f .Close () //nolint:errcheck
121
+ }
122
+ return composeFile , nil
123
+ }
113
124
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 )
116
143
if err != nil {
117
- return "" , err
144
+ return err
118
145
}
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
122
149
}
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 " ))
130
152
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
142
154
}
143
155
}
156
+ _ , err = f .Write (content )
157
+ if err != nil {
158
+ return err
159
+ }
144
160
}
145
- return composeFile , nil
161
+ return nil
146
162
}
147
163
148
164
var _ loader.ResourceLoader = ociRemoteLoader {}
0 commit comments