summaryrefslogtreecommitdiffstats
path: root/pkg/v1/remote/mount.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/v1/remote/mount.go')
-rw-r--r--pkg/v1/remote/mount.go108
1 files changed, 108 insertions, 0 deletions
diff --git a/pkg/v1/remote/mount.go b/pkg/v1/remote/mount.go
new file mode 100644
index 0000000..36d0885
--- /dev/null
+++ b/pkg/v1/remote/mount.go
@@ -0,0 +1,108 @@
+// Copyright 2018 Google LLC All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package remote
+
+import (
+ "github.com/google/go-containerregistry/pkg/name"
+ v1 "github.com/google/go-containerregistry/pkg/v1"
+ "github.com/google/go-containerregistry/pkg/v1/partial"
+)
+
+// MountableLayer wraps a v1.Layer in a shim that enables the layer to be
+// "mounted" when published to another registry.
+type MountableLayer struct {
+ v1.Layer
+
+ Reference name.Reference
+}
+
+// Descriptor retains the original descriptor from an image manifest.
+// See partial.Descriptor.
+func (ml *MountableLayer) Descriptor() (*v1.Descriptor, error) {
+ return partial.Descriptor(ml.Layer)
+}
+
+// Exists is a hack. See partial.Exists.
+func (ml *MountableLayer) Exists() (bool, error) {
+ return partial.Exists(ml.Layer)
+}
+
+// mountableImage wraps the v1.Layer references returned by the embedded v1.Image
+// in MountableLayer's so that remote.Write might attempt to mount them from their
+// source repository.
+type mountableImage struct {
+ v1.Image
+
+ Reference name.Reference
+}
+
+// Layers implements v1.Image
+func (mi *mountableImage) Layers() ([]v1.Layer, error) {
+ ls, err := mi.Image.Layers()
+ if err != nil {
+ return nil, err
+ }
+ mls := make([]v1.Layer, 0, len(ls))
+ for _, l := range ls {
+ mls = append(mls, &MountableLayer{
+ Layer: l,
+ Reference: mi.Reference,
+ })
+ }
+ return mls, nil
+}
+
+// LayerByDigest implements v1.Image
+func (mi *mountableImage) LayerByDigest(d v1.Hash) (v1.Layer, error) {
+ l, err := mi.Image.LayerByDigest(d)
+ if err != nil {
+ return nil, err
+ }
+ return &MountableLayer{
+ Layer: l,
+ Reference: mi.Reference,
+ }, nil
+}
+
+// LayerByDiffID implements v1.Image
+func (mi *mountableImage) LayerByDiffID(d v1.Hash) (v1.Layer, error) {
+ l, err := mi.Image.LayerByDiffID(d)
+ if err != nil {
+ return nil, err
+ }
+ return &MountableLayer{
+ Layer: l,
+ Reference: mi.Reference,
+ }, nil
+}
+
+// Descriptor retains the original descriptor from an index manifest.
+// See partial.Descriptor.
+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
+}