mirror of
https://github.com/containers/skopeo.git
synced 2025-09-09 10:39:30 +00:00
proxy: Add a GetFullConfig method
Sadly...I swear I had tested this at one point, but it was *definitely* not the intention that we just return the container runtime configuration. I need a method to return the full image configuration. At some point I must have accidentally added a redundant `.Config`. This whole new method `GetFullConfig` is like `GetConfig` but returns the whole image configuration. A specific motivation here is that it's only in the image configuration that we can stick arbitrary metadata (labels) that will survive a round trip through docker schema v2.
This commit is contained in:
@@ -430,7 +430,45 @@ func (h *proxyHandler) GetManifest(args []interface{}) (replyBuf, error) {
|
|||||||
return h.returnBytes(digest, serialized)
|
return h.returnBytes(digest, serialized)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetConfig returns a copy of the image configuration, converted to OCI format.
|
// GetFullConfig returns a copy of the image configuration, converted to OCI format.
|
||||||
|
// https://github.com/opencontainers/image-spec/blob/main/config.md
|
||||||
|
func (h *proxyHandler) GetFullConfig(args []interface{}) (replyBuf, error) {
|
||||||
|
h.lock.Lock()
|
||||||
|
defer h.lock.Unlock()
|
||||||
|
|
||||||
|
var ret replyBuf
|
||||||
|
|
||||||
|
if h.sysctx == nil {
|
||||||
|
return ret, fmt.Errorf("client error: 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
|
||||||
|
}
|
||||||
|
err = h.cacheTargetManifest(imgref)
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
img := imgref.cachedimg
|
||||||
|
|
||||||
|
ctx := context.TODO()
|
||||||
|
config, err := img.OCIConfig(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
serialized, err := json.Marshal(&config)
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
return h.returnBytes(nil, serialized)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetConfig returns a copy of the container runtime configuration, converted to OCI format.
|
||||||
|
// Note that due to a historical mistake, this returns not the full image configuration,
|
||||||
|
// but just the container runtime configuration. You should use GetFullConfig instead.
|
||||||
func (h *proxyHandler) GetConfig(args []interface{}) (replyBuf, error) {
|
func (h *proxyHandler) GetConfig(args []interface{}) (replyBuf, error) {
|
||||||
h.lock.Lock()
|
h.lock.Lock()
|
||||||
defer h.lock.Unlock()
|
defer h.lock.Unlock()
|
||||||
@@ -463,7 +501,6 @@ func (h *proxyHandler) GetConfig(args []interface{}) (replyBuf, error) {
|
|||||||
return ret, err
|
return ret, err
|
||||||
}
|
}
|
||||||
return h.returnBytes(nil, serialized)
|
return h.returnBytes(nil, serialized)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBlob fetches a blob, performing digest verification.
|
// GetBlob fetches a blob, performing digest verification.
|
||||||
@@ -639,6 +676,8 @@ func (h *proxyHandler) processRequest(req request) (rb replyBuf, terminate bool,
|
|||||||
rb, err = h.GetManifest(req.Args)
|
rb, err = h.GetManifest(req.Args)
|
||||||
case "GetConfig":
|
case "GetConfig":
|
||||||
rb, err = h.GetConfig(req.Args)
|
rb, err = h.GetConfig(req.Args)
|
||||||
|
case "GetFullConfig":
|
||||||
|
rb, err = h.GetFullConfig(req.Args)
|
||||||
case "GetBlob":
|
case "GetBlob":
|
||||||
rb, err = h.GetBlob(req.Args)
|
rb, err = h.GetBlob(req.Args)
|
||||||
case "FinishPipe":
|
case "FinishPipe":
|
||||||
|
@@ -250,18 +250,37 @@ func runTestGetManifestAndConfig(p *proxy, img string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
v, configBytes, err := p.callReadAllBytes("GetConfig", []interface{}{imgid})
|
v, configBytes, err := p.callReadAllBytes("GetFullConfig", []interface{}{imgid})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var config imgspecv1.ImageConfig
|
var config imgspecv1.Image
|
||||||
err = json.Unmarshal(configBytes, &config)
|
err = json.Unmarshal(configBytes, &config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate that the image config seems sane
|
||||||
|
if config.Architecture == "" {
|
||||||
|
return fmt.Errorf("No architecture found")
|
||||||
|
}
|
||||||
|
if len(config.Config.Cmd) == 0 && len(config.Config.Entrypoint) == 0 {
|
||||||
|
return fmt.Errorf("No CMD or ENTRYPOINT set")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also test this legacy interface
|
||||||
|
v, ctrconfigBytes, err := p.callReadAllBytes("GetConfig", []interface{}{imgid})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var ctrconfig imgspecv1.ImageConfig
|
||||||
|
err = json.Unmarshal(ctrconfigBytes, &ctrconfig)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Validate that the config seems sane
|
// Validate that the config seems sane
|
||||||
if len(config.Cmd) == 0 && len(config.Entrypoint) == 0 {
|
if len(ctrconfig.Cmd) == 0 && len(ctrconfig.Entrypoint) == 0 {
|
||||||
return fmt.Errorf("No CMD or ENTRYPOINT set")
|
return fmt.Errorf("No CMD or ENTRYPOINT set")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user