mirror of
https://github.com/containers/skopeo.git
synced 2025-09-20 01:20:09 +00:00
proxy: Add an API to fetch the config upconverted to OCI
While the caller could fetch this today as a blob, it'd be in either docker or oci schema. In keeping with the model of having this proxy only expose OCI, add an API which uses the c/image logic to do the conversion. This is necessary for callers to get the diffIDs, and in general to implement something like an external `skopeo copy`. Signed-off-by: Colin Walters <walters@verbum.org>
This commit is contained in:
@@ -83,9 +83,11 @@ import (
|
|||||||
|
|
||||||
// protocolVersion is semantic version of the protocol used by this proxy.
|
// protocolVersion is semantic version of the protocol used by this proxy.
|
||||||
// The first version of the protocol has major version 0.2 to signify a
|
// The first version of the protocol has major version 0.2 to signify a
|
||||||
// departure from the original code which used HTTP. The minor version is 1
|
// departure from the original code which used HTTP.
|
||||||
// instead of 0 to help exercise semver parsers.
|
//
|
||||||
const protocolVersion = "0.2.1"
|
// 0.2.1: Initial version
|
||||||
|
// 0.2.2: Added support for fetching image configuration as OCI
|
||||||
|
const protocolVersion = "0.2.2"
|
||||||
|
|
||||||
// maxMsgSize is the current limit on a packet size.
|
// maxMsgSize is the current limit on a packet size.
|
||||||
// Note that all non-metadata (i.e. payload data) is sent over a pipe.
|
// Note that all non-metadata (i.e. payload data) is sent over a pipe.
|
||||||
@@ -380,6 +382,53 @@ func (h *proxyHandler) GetManifest(args []interface{}) (replyBuf, error) {
|
|||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetConfig returns a copy of the image configuration, converted to OCI format.
|
||||||
|
func (h *proxyHandler) GetConfig(args []interface{}) (replyBuf, error) {
|
||||||
|
h.lock.Lock()
|
||||||
|
defer h.lock.Unlock()
|
||||||
|
|
||||||
|
var ret replyBuf
|
||||||
|
|
||||||
|
if h.sysctx == nil {
|
||||||
|
return ret, fmt.Errorf("Must invoke Initialize")
|
||||||
|
}
|
||||||
|
if len(args) != 1 {
|
||||||
|
return ret, fmt.Errorf("invalid request, expecting: [imgid]")
|
||||||
|
}
|
||||||
|
imgref, err := h.parseImageFromID(args[0])
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.TODO()
|
||||||
|
config, err := imgref.img.OCIConfig(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
serialized, err := json.Marshal(&config.Config)
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
piper, f, err := h.allocPipe()
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
// Signal completion when we return
|
||||||
|
defer f.wg.Done()
|
||||||
|
_, err = io.Copy(f.w, bytes.NewReader(serialized))
|
||||||
|
if err != nil {
|
||||||
|
f.err = err
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
ret.fd = piper
|
||||||
|
ret.pipeid = uint32(f.w.Fd())
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetBlob fetches a blob, performing digest verification.
|
// GetBlob fetches a blob, performing digest verification.
|
||||||
func (h *proxyHandler) GetBlob(args []interface{}) (replyBuf, error) {
|
func (h *proxyHandler) GetBlob(args []interface{}) (replyBuf, error) {
|
||||||
h.lock.Lock()
|
h.lock.Lock()
|
||||||
@@ -551,6 +600,8 @@ func (h *proxyHandler) processRequest(req request) (rb replyBuf, terminate bool,
|
|||||||
rb, err = h.CloseImage(req.Args)
|
rb, err = h.CloseImage(req.Args)
|
||||||
case "GetManifest":
|
case "GetManifest":
|
||||||
rb, err = h.GetManifest(req.Args)
|
rb, err = h.GetManifest(req.Args)
|
||||||
|
case "GetConfig":
|
||||||
|
rb, err = h.GetConfig(req.Args)
|
||||||
case "GetBlob":
|
case "GetBlob":
|
||||||
rb, err = h.GetBlob(req.Args)
|
rb, err = h.GetBlob(req.Args)
|
||||||
case "FinishPipe":
|
case "FinishPipe":
|
||||||
|
Reference in New Issue
Block a user