@@ -2,10 +2,8 @@ package manifests
2
2
3
3
import (
4
4
"context"
5
- "errors"
6
- "fmt"
5
+ "io/ioutil"
7
6
"net/http"
8
- "net/url"
9
7
"strconv"
10
8
"strings"
11
9
@@ -14,8 +12,10 @@ import (
14
12
"github.com/containers/podman/v4/pkg/api/handlers"
15
13
"github.com/containers/podman/v4/pkg/bindings"
16
14
"github.com/containers/podman/v4/pkg/bindings/images"
17
- "github.com/containers/podman/v4/version"
15
+ "github.com/containers/podman/v4/pkg/domain/entities"
16
+ "github.com/containers/podman/v4/pkg/errorhandling"
18
17
jsoniter "github.com/json-iterator/go"
18
+ "github.com/pkg/errors"
19
19
)
20
20
21
21
// Create creates a manifest for the given name. Optional images to be associated with
@@ -91,74 +91,27 @@ func Add(ctx context.Context, name string, options *AddOptions) (string, error)
91
91
options = new (AddOptions )
92
92
}
93
93
94
- if bindings .ServiceVersion (ctx ).GTE (semver .MustParse ("4.0.0" )) {
95
- optionsv4 := ModifyOptions {
96
- All : options .All ,
97
- Annotations : options .Annotation ,
98
- Arch : options .Arch ,
99
- Features : options .Features ,
100
- Images : options .Images ,
101
- OS : options .OS ,
102
- OSFeatures : nil ,
103
- OSVersion : options .OSVersion ,
104
- Variant : options .Variant ,
105
- }
106
- optionsv4 .WithOperation ("update" )
107
- return Modify (ctx , name , options .Images , & optionsv4 )
108
- }
109
-
110
- // API Version < 4.0.0
111
- conn , err := bindings .GetClient (ctx )
112
- if err != nil {
113
- return "" , err
114
- }
115
- opts , err := jsoniter .MarshalToString (options )
116
- if err != nil {
117
- return "" , err
118
- }
119
- reader := strings .NewReader (opts )
120
-
121
- headers := make (http.Header )
122
- v := version.APIVersion [version.Libpod ][version.MinimalAPI ]
123
- headers .Add ("API-Version" ,
124
- fmt .Sprintf ("%d.%d.%d" , v .Major , v .Minor , v .Patch ))
125
- response , err := conn .DoRequest (ctx , reader , http .MethodPost , "/manifests/%s/add" , nil , headers , name )
126
- if err != nil {
127
- return "" , err
94
+ optionsv4 := ModifyOptions {
95
+ All : options .All ,
96
+ Annotations : options .Annotation ,
97
+ Arch : options .Arch ,
98
+ Features : options .Features ,
99
+ Images : options .Images ,
100
+ OS : options .OS ,
101
+ OSFeatures : nil ,
102
+ OSVersion : options .OSVersion ,
103
+ Variant : options .Variant ,
128
104
}
129
- defer response .Body .Close ()
130
-
131
- var idr handlers.IDResponse
132
- return idr .ID , response .Process (& idr )
105
+ optionsv4 .WithOperation ("update" )
106
+ return Modify (ctx , name , options .Images , & optionsv4 )
133
107
}
134
108
135
109
// Remove deletes a manifest entry from a manifest list. Both name and the digest to be
136
110
// removed are mandatory inputs. The ID of the new manifest list is returned as a string.
137
111
func Remove (ctx context.Context , name , digest string , _ * RemoveOptions ) (string , error ) {
138
- if bindings .ServiceVersion (ctx ).GTE (semver .MustParse ("4.0.0" )) {
139
- optionsv4 := new (ModifyOptions ).WithOperation ("remove" )
140
- return Modify (ctx , name , []string {digest }, optionsv4 )
141
- }
112
+ optionsv4 := new (ModifyOptions ).WithOperation ("remove" )
113
+ return Modify (ctx , name , []string {digest }, optionsv4 )
142
114
143
- // API Version < 4.0.0
144
- conn , err := bindings .GetClient (ctx )
145
- if err != nil {
146
- return "" , err
147
- }
148
-
149
- headers := http.Header {}
150
- headers .Add ("API-Version" , "3.4.0" )
151
-
152
- params := url.Values {}
153
- params .Set ("digest" , digest )
154
- response , err := conn .DoRequest (ctx , nil , http .MethodDelete , "/manifests/%s" , params , headers , name )
155
- if err != nil {
156
- return "" , err
157
- }
158
- defer response .Body .Close ()
159
-
160
- var idr handlers.IDResponse
161
- return idr .ID , response .Process (& idr )
162
115
}
163
116
164
117
// Push takes a manifest list and pushes to a destination. If the destination is not specified,
@@ -229,8 +182,36 @@ func Modify(ctx context.Context, name string, images []string, options *ModifyOp
229
182
}
230
183
defer response .Body .Close ()
231
184
232
- var idr handlers.IDResponse
233
- return idr .ID , response .Process (& idr )
185
+ data , err := ioutil .ReadAll (response .Body )
186
+ if err != nil {
187
+ return "" , errors .Wrap (err , "unable to process API response" )
188
+ }
189
+
190
+ if response .IsSuccess () || response .IsRedirection () {
191
+ var report entities.ManifestModifyReport
192
+ if err = jsoniter .Unmarshal (data , & report ); err != nil {
193
+ return "" , errors .Wrap (err , "unable to decode API response" )
194
+ }
195
+
196
+ err = errorhandling .JoinErrors (report .Errors )
197
+ if err != nil {
198
+ errModel := errorhandling.ErrorModel {
199
+ Because : (errors .Cause (err )).Error (),
200
+ Message : err .Error (),
201
+ ResponseCode : response .StatusCode ,
202
+ }
203
+ return report .ID , & errModel
204
+ }
205
+ return report .ID , nil
206
+ } else {
207
+ errModel := errorhandling.ErrorModel {
208
+ ResponseCode : response .StatusCode ,
209
+ }
210
+ if err = jsoniter .Unmarshal (data , & errModel ); err != nil {
211
+ return "" , errors .Wrap (err , "unable to decode API response" )
212
+ }
213
+ return "" , & errModel
214
+ }
234
215
}
235
216
236
217
// Annotate modifies the given manifest list using options and the optional list of images
0 commit comments