Skip to content

Commit ae9ad41

Browse files
jwhoncemheon
authored andcommitted
Fix manifest 4.0 Endpoints
Branch forced 4.0 only endpoints Signed-off-by: Jhon Honce <[email protected]>
1 parent 1a8c715 commit ae9ad41

File tree

4 files changed

+57
-72
lines changed

4 files changed

+57
-72
lines changed

pkg/api/handlers/libpod/manifests.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ func ManifestModify(w http.ResponseWriter, r *http.Request) {
401401
case len(report.Errors) > 0 && len(report.Images) > 0:
402402
statusCode = http.StatusConflict
403403
case len(report.Errors) > 0:
404-
statusCode = http.StatusInternalServerError
404+
statusCode = http.StatusBadRequest
405405
}
406406
utils.WriteResponse(w, statusCode, report)
407407
}

pkg/bindings/manifests/manifests.go

+48-67
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@ package manifests
22

33
import (
44
"context"
5-
"errors"
6-
"fmt"
5+
"io/ioutil"
76
"net/http"
8-
"net/url"
97
"strconv"
108
"strings"
119

@@ -14,8 +12,10 @@ import (
1412
"github.com/containers/podman/v4/pkg/api/handlers"
1513
"github.com/containers/podman/v4/pkg/bindings"
1614
"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"
1817
jsoniter "github.com/json-iterator/go"
18+
"github.com/pkg/errors"
1919
)
2020

2121
// 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)
9191
options = new(AddOptions)
9292
}
9393

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,
128104
}
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)
133107
}
134108

135109
// Remove deletes a manifest entry from a manifest list. Both name and the digest to be
136110
// removed are mandatory inputs. The ID of the new manifest list is returned as a string.
137111
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)
142114

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)
162115
}
163116

164117
// 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
229182
}
230183
defer response.Body.Close()
231184

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+
}
234215
}
235216

236217
// Annotate modifies the given manifest list using options and the optional list of images

pkg/bindings/test/common_test.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"os/exec"
99
"path/filepath"
1010
"strings"
11+
"testing"
1112
"time"
1213

1314
"github.com/containers/podman/v4/libpod/define"
@@ -151,7 +152,12 @@ func createTempDirInTempDir() (string, error) {
151152
}
152153

153154
func (b *bindingTest) startAPIService() *gexec.Session {
154-
cmd := []string{"--log-level=debug", "system", "service", "--timeout=0", b.sock}
155+
logLevel := "debug"
156+
if testing.Verbose() {
157+
logLevel = "trace"
158+
}
159+
160+
cmd := []string{"--log-level=" + logLevel, "system", "service", "--timeout=0", b.sock}
155161
session := b.runPodman(cmd)
156162

157163
sock := strings.TrimPrefix(b.sock, "unix://")

pkg/bindings/test/manifests_test.go

+1-3
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ var _ = Describe("podman manifest", func() {
8787

8888
list, err := manifests.Inspect(bt.conn, id, nil)
8989
Expect(err).ToNot(HaveOccurred())
90-
9190
Expect(len(list.Manifests)).To(BeNumerically("==", 1))
9291

9392
// add bogus name to existing list should fail
@@ -96,7 +95,7 @@ var _ = Describe("podman manifest", func() {
9695
Expect(err).To(HaveOccurred())
9796

9897
code, _ = bindings.CheckResponseCode(err)
99-
Expect(code).To(BeNumerically("==", http.StatusInternalServerError))
98+
Expect(code).To(BeNumerically("==", http.StatusBadRequest))
10099
})
101100

102101
It("remove digest", func() {
@@ -129,7 +128,6 @@ var _ = Describe("podman manifest", func() {
129128
// removal on good manifest with good digest should work
130129
data, err = manifests.Inspect(bt.conn, id, nil)
131130
Expect(err).ToNot(HaveOccurred())
132-
133131
Expect(data.Manifests).Should(BeEmpty())
134132
})
135133

0 commit comments

Comments
 (0)