@@ -28,7 +28,6 @@ import (
2828
2929 "github.com/containerd/containerd/v2/core/remotes"
3030 pusherrors "github.com/containerd/containerd/v2/core/remotes/errors"
31- "github.com/containerd/errdefs"
3231 "github.com/distribution/reference"
3332 "github.com/docker/compose/v2/pkg/api"
3433 "github.com/opencontainers/go-digest"
@@ -94,20 +93,20 @@ func DescriptorForEnvFile(path string, content []byte) v1.Descriptor {
9493 }
9594}
9695
97- func PushManifest (ctx context.Context , resolver remotes.Resolver , named reference.Named , layers []v1.Descriptor , ociVersion api.OCIVersion ) error {
96+ func PushManifest (ctx context.Context , resolver remotes.Resolver , named reference.Named , layers []v1.Descriptor , ociVersion api.OCIVersion ) (v1. Descriptor , error ) {
9897 // Check if we need an extra empty layer for the manifest config
9998 if ociVersion == api .OCIVersion1_1 || ociVersion == "" {
10099 err := push (ctx , resolver , named , v1 .DescriptorEmptyJSON )
101100 if err != nil {
102- return err
101+ return v1. Descriptor {}, err
103102 }
104103 }
105104 // prepare to push the manifest by pushing the layers
106105 layerDescriptors := make ([]v1.Descriptor , len (layers ))
107106 for i := range layers {
108107 layerDescriptors [i ] = layers [i ]
109108 if err := push (ctx , resolver , named , layers [i ]); err != nil {
110- return err
109+ return v1. Descriptor {}, err
111110 }
112111 }
113112
@@ -119,13 +118,13 @@ func PushManifest(ctx context.Context, resolver remotes.Resolver, named referenc
119118 // try to push in the OCI 1.1 format but fallback to OCI 1.0 on 4xx errors
120119 // (other than auth) since it's most likely the result of the registry not
121120 // having support
122- err := createAndPushManifest (ctx , resolver , named , layerDescriptors , api .OCIVersion1_1 )
121+ descriptor , err := createAndPushManifest (ctx , resolver , named , layerDescriptors , api .OCIVersion1_1 )
123122 var pushErr pusherrors.ErrUnexpectedStatus
124123 if errors .As (err , & pushErr ) && isNonAuthClientError (pushErr .StatusCode ) {
125124 // TODO(milas): show a warning here (won't work with logrus)
126125 return createAndPushManifest (ctx , resolver , named , layerDescriptors , api .OCIVersion1_0 )
127126 }
128- return err
127+ return descriptor , err
129128}
130129
131130func push (ctx context.Context , resolver remotes.Resolver , ref reference.Named , descriptor v1.Descriptor ) error {
@@ -134,37 +133,21 @@ func push(ctx context.Context, resolver remotes.Resolver, ref reference.Named, d
134133 return err
135134 }
136135
137- pusher , err := resolver .Pusher (ctx , fullRef .String ())
138- if err != nil {
139- return err
140- }
141- push , err := pusher .Push (ctx , descriptor )
142- if errdefs .IsAlreadyExists (err ) {
143- return nil
144- }
145- if err != nil {
146- return err
147- }
148- defer func () {
149- _ = push .Close ()
150- }()
151-
152- _ , err = push .Write (descriptor .Data )
153- return err
136+ return Push (ctx , resolver , fullRef , descriptor )
154137}
155138
156- func createAndPushManifest (ctx context.Context , resolver remotes.Resolver , named reference.Named , layers []v1.Descriptor , ociVersion api.OCIVersion ) error {
157- toPush , err := generateManifest (layers , ociVersion )
139+ func createAndPushManifest (ctx context.Context , resolver remotes.Resolver , named reference.Named , layers []v1.Descriptor , ociVersion api.OCIVersion ) (v1. Descriptor , error ) {
140+ descriptor , toPush , err := generateManifest (layers , ociVersion )
158141 if err != nil {
159- return err
142+ return v1. Descriptor {}, err
160143 }
161144 for _ , p := range toPush {
162145 err = push (ctx , resolver , named , p )
163146 if err != nil {
164- return err
147+ return v1. Descriptor {}, err
165148 }
166149 }
167- return nil
150+ return descriptor , nil
168151}
169152
170153func isNonAuthClientError (statusCode int ) bool {
@@ -175,7 +158,7 @@ func isNonAuthClientError(statusCode int) bool {
175158 return ! slices .Contains (clientAuthStatusCodes , statusCode )
176159}
177160
178- func generateManifest (layers []v1.Descriptor , ociCompat api.OCIVersion ) ([]v1.Descriptor , error ) {
161+ func generateManifest (layers []v1.Descriptor , ociCompat api.OCIVersion ) (v1. Descriptor , []v1.Descriptor , error ) {
179162 var toPush []v1.Descriptor
180163 var config v1.Descriptor
181164 var artifactType string
@@ -205,10 +188,9 @@ func generateManifest(layers []v1.Descriptor, ociCompat api.OCIVersion) ([]v1.De
205188 case api .OCIVersion1_1 :
206189 config = v1 .DescriptorEmptyJSON
207190 artifactType = ComposeProjectArtifactType
208- // N.B. the descriptor has the data embedded in it
209191 toPush = append (toPush , config )
210192 default :
211- return nil , fmt .Errorf ("unsupported OCI version: %s" , ociCompat )
193+ return v1. Descriptor {}, nil , fmt .Errorf ("unsupported OCI version: %s" , ociCompat )
212194 }
213195
214196 manifest , err := json .Marshal (v1.Manifest {
@@ -222,7 +204,7 @@ func generateManifest(layers []v1.Descriptor, ociCompat api.OCIVersion) ([]v1.De
222204 },
223205 })
224206 if err != nil {
225- return nil , err
207+ return v1. Descriptor {}, nil , err
226208 }
227209
228210 manifestDescriptor := v1.Descriptor {
@@ -236,5 +218,5 @@ func generateManifest(layers []v1.Descriptor, ociCompat api.OCIVersion) ([]v1.De
236218 Data : manifest ,
237219 }
238220 toPush = append (toPush , manifestDescriptor )
239- return toPush , nil
221+ return manifestDescriptor , toPush , nil
240222}
0 commit comments