Skip to content

Commit

Permalink
proxy: Add optional flags to OpenImage
Browse files Browse the repository at this point in the history
See containers#1829 (comment)

This is prep for adding another option like `require-signatures`.

Signed-off-by: Colin Walters <[email protected]>
  • Loading branch information
cgwalters committed Jan 10, 2023
1 parent 4517ea0 commit 0eaaa97
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 5 deletions.
46 changes: 41 additions & 5 deletions cmd/skopeo/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ import (
// 0.2.3: Added GetFullConfig
// 0.2.4: Added OpenImageOptional
// 0.2.5: Added LayerInfoJSON
const protocolVersion = "0.2.5"
// 0.2.6: OpenImage now accepts a second argument with an array of options
const protocolVersion = "0.2.6"

// maxMsgSize is the current limit on a packet size.
// Note that all non-metadata (i.e. payload data) is sent over a pipe.
Expand Down Expand Up @@ -214,8 +215,18 @@ func (h *proxyHandler) Initialize(args []interface{}) (replyBuf, error) {

// OpenImage accepts a string image reference i.e. TRANSPORT:REF - like `skopeo copy`.
// The return value is an opaque integer handle.
//
// A second argument may be present; if so, it is an array of string-valued flags.
//
// - optional: Do not error if the image is not present; instead return a zero imageid. Since: 0.2.6
func (h *proxyHandler) OpenImage(args []interface{}) (replyBuf, error) {
return h.openImageImpl(args, false)
opts := openOptions{}
if len(args) > 1 {
if err := opts.parse(args[1]); err != nil {
return replyBuf{}, err
}
}
return h.openImageImpl(args, opts)
}

// isDockerManifestUnknownError is a copy of code from containers/image,
Expand All @@ -237,7 +248,32 @@ func isNotFoundImageError(err error) bool {
errors.Is(err, ocilayout.ImageNotFoundError{})
}

func (h *proxyHandler) openImageImpl(args []interface{}, allowNotFound bool) (replyBuf, error) {
type openOptions struct {
optional bool
}

func (o *openOptions) parse(argsval interface{}) error {
args, ok := argsval.([]interface{})
if !ok {
return fmt.Errorf("expecting array for options, not %T", argsval)
}
for _, argv := range args {
arg, ok := argv.(string)
if !ok {
return fmt.Errorf("expecting string option, not %T", arg)
}
switch arg {
case "optional":
o.optional = true
default:
return fmt.Errorf("unknown option %s", arg)
}
}

return nil
}

func (h *proxyHandler) openImageImpl(args []interface{}, opts openOptions) (replyBuf, error) {
h.lock.Lock()
defer h.lock.Unlock()
var ret replyBuf
Expand All @@ -259,7 +295,7 @@ func (h *proxyHandler) openImageImpl(args []interface{}, allowNotFound bool) (re
}
imgsrc, err := imgRef.NewImageSource(context.Background(), h.sysctx)
if err != nil {
if allowNotFound && isNotFoundImageError(err) {
if opts.optional && isNotFoundImageError(err) {
ret.value = sentinelImageID
return ret, nil
}
Expand All @@ -283,7 +319,7 @@ func (h *proxyHandler) openImageImpl(args []interface{}, allowNotFound bool) (re
// The return value is an opaque integer handle. If the image does not exist, zero
// is returned.
func (h *proxyHandler) OpenImageOptional(args []interface{}) (replyBuf, error) {
return h.openImageImpl(args, true)
return h.openImageImpl(args, openOptions{})
}

func (h *proxyHandler) CloseImage(args []interface{}) (replyBuf, error) {
Expand Down
22 changes: 22 additions & 0 deletions integration/proxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,28 @@ func runTestOpenImageOptionalNotFound(p *proxy, img string) error {
if imgid != 0 {
return fmt.Errorf("Unexpected optional image id %v", imgid)
}

// Also verify the optional options
opts := []string{"optional"}
v, err = p.callNoFd("OpenImage", []interface{}{img, opts})
if err != nil {
return err
}

imgidv, ok = v.(float64)
if !ok {
return fmt.Errorf("OpenImage return value is %T", v)
}
imgid = uint32(imgidv)
if imgid != 0 {
return fmt.Errorf("Unexpected optional image id %v", imgid)
}

_, err = p.callNoFd("CloseImage", []interface{}{imgid})
if err != nil {
return err
}

return nil
}

Expand Down

0 comments on commit 0eaaa97

Please sign in to comment.