diff --git a/pkg/v1/partial/compressed_test.go b/pkg/v1/partial/compressed_test.go index 789158505..ed6a3f3d3 100644 --- a/pkg/v1/partial/compressed_test.go +++ b/pkg/v1/partial/compressed_test.go @@ -87,6 +87,14 @@ func TestRemote(t *testing.T) { if got, want := ok, true; got != want { t.Errorf("Exists() = %t != %t", got, want) } + + cl, err := partial.ConfigLayer(img) + if err != nil { + t.Fatal(err) + } + if _, ok := cl.(*remote.MountableLayer); !ok { + t.Errorf("ConfigLayer() expected to be MountableLayer, got %T", cl) + } } type noDiffID struct { diff --git a/pkg/v1/partial/with.go b/pkg/v1/partial/with.go index 3a5c61572..b64e9881e 100644 --- a/pkg/v1/partial/with.go +++ b/pkg/v1/partial/with.go @@ -88,9 +88,22 @@ func (cl *configLayer) MediaType() (types.MediaType, error) { var _ v1.Layer = (*configLayer)(nil) +// withConfigLayer allows partial image implementations to provide a layer +// for their config file. +type withConfigLayer interface { + ConfigLayer() (v1.Layer, error) +} + // ConfigLayer implements v1.Layer from the raw config bytes. // This is so that clients (e.g. remote) can access the config as a blob. +// +// Images that want to return a specific layer implementation can implement +// withConfigLayer. func ConfigLayer(i WithRawConfigFile) (v1.Layer, error) { + if wcl, ok := unwrap(i).(withConfigLayer); ok { + return wcl.ConfigLayer() + } + h, err := ConfigName(i) if err != nil { return nil, err diff --git a/pkg/v1/remote/mount.go b/pkg/v1/remote/mount.go index 728997044..36d088567 100644 --- a/pkg/v1/remote/mount.go +++ b/pkg/v1/remote/mount.go @@ -93,3 +93,16 @@ func (mi *mountableImage) LayerByDiffID(d v1.Hash) (v1.Layer, error) { func (mi *mountableImage) Descriptor() (*v1.Descriptor, error) { return partial.Descriptor(mi.Image) } + +// ConfigLayer retains the original reference so that it can be mounted. +// See partial.ConfigLayer. +func (mi *mountableImage) ConfigLayer() (v1.Layer, error) { + l, err := partial.ConfigLayer(mi.Image) + if err != nil { + return nil, err + } + return &MountableLayer{ + Layer: l, + Reference: mi.Reference, + }, nil +}