-
Notifications
You must be signed in to change notification settings - Fork 42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Layout wraps v1 image #243
Changes from 2 commits
efd1f09
c3794cc
37c0fdc
8ca3b4a
b8563b8
5a1af60
a65b1a9
9cef4d4
244aa16
f737e8d
59770c9
78930ee
33de307
7ed58a5
a59c8b4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ package imgutil | |
import ( | ||
"errors" | ||
"fmt" | ||
"io" | ||
"strings" | ||
"time" | ||
|
||
|
@@ -18,26 +19,15 @@ import ( | |
// The working image could be any v1.Image, | ||
// but in practice will start off as a pointer to a locallayout.v1ImageFacade (or similar). | ||
type CNBImageCore struct { | ||
v1.Image // the working image | ||
Store ImageStore | ||
// required | ||
repoName string | ||
v1.Image // the working image | ||
// optional | ||
createdAt time.Time | ||
preferredMediaTypes MediaTypes | ||
preserveHistory bool | ||
previousImage v1.Image | ||
} | ||
|
||
type ImageStore interface { | ||
Contains(identifier string) bool | ||
Delete(identifier string) error | ||
Save(image IdentifiableV1Image, withName string, withAdditionalNames ...string) (string, error) | ||
SaveFile(image IdentifiableV1Image, withName string) (string, error) | ||
|
||
DownloadLayersFor(identifier string) error | ||
Layers() []v1.Layer | ||
} | ||
|
||
type IdentifiableV1Image interface { | ||
v1.Image | ||
Identifier() (Identifier, error) | ||
|
@@ -47,7 +37,7 @@ var _ v1.Image = &CNBImageCore{} | |
|
||
// FIXME: mark deprecated methods as deprecated on the interface when other packages (remote, layout) expose a v1.Image | ||
|
||
// Deprecated: Architecture | ||
// TBD Deprecated: Architecture | ||
func (i *CNBImageCore) Architecture() (string, error) { | ||
configFile, err := getConfigFile(i.Image) | ||
if err != nil { | ||
|
@@ -56,7 +46,7 @@ func (i *CNBImageCore) Architecture() (string, error) { | |
return configFile.Architecture, nil | ||
} | ||
|
||
// Deprecated: CreatedAt | ||
// TBD Deprecated: CreatedAt | ||
func (i *CNBImageCore) CreatedAt() (time.Time, error) { | ||
configFile, err := getConfigFile(i.Image) | ||
if err != nil { | ||
|
@@ -65,7 +55,7 @@ func (i *CNBImageCore) CreatedAt() (time.Time, error) { | |
return configFile.Created.Time, nil | ||
} | ||
|
||
// Deprecated: Entrypoint | ||
// TBD Deprecated: Entrypoint | ||
func (i *CNBImageCore) Entrypoint() ([]string, error) { | ||
configFile, err := getConfigFile(i.Image) | ||
if err != nil { | ||
|
@@ -96,25 +86,28 @@ func (i *CNBImageCore) GetAnnotateRefName() (string, error) { | |
return manifest.Annotations["org.opencontainers.image.ref.name"], nil | ||
} | ||
|
||
// Deprecated: History | ||
func (i *CNBImageCore) History() ([]v1.History, error) { | ||
configFile, err := getConfigFile(i.Image) | ||
func (i *CNBImageCore) GetLayer(diffID string) (io.ReadCloser, error) { | ||
hash, err := v1.NewHash(diffID) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return configFile.History, nil | ||
layer, err := i.LayerByDiffID(hash) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return layer.Uncompressed() | ||
} | ||
|
||
func (i *CNBImageCore) Kind() string { | ||
storeType := fmt.Sprintf("%T", i.Store) | ||
parts := strings.Split(storeType, ".") | ||
if len(parts) < 2 { | ||
return storeType | ||
// TBD Deprecated: History | ||
func (i *CNBImageCore) History() ([]v1.History, error) { | ||
configFile, err := getConfigFile(i.Image) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return strings.TrimPrefix(parts[0], "*") | ||
return configFile.History, nil | ||
} | ||
|
||
// Deprecated: Label | ||
// TBD Deprecated: Label | ||
func (i *CNBImageCore) Label(key string) (string, error) { | ||
configFile, err := getConfigFile(i.Image) | ||
if err != nil { | ||
|
@@ -123,7 +116,7 @@ func (i *CNBImageCore) Label(key string) (string, error) { | |
return configFile.Config.Labels[key], nil | ||
} | ||
|
||
// Deprecated: Labels | ||
// TBD Deprecated: Labels | ||
func (i *CNBImageCore) Labels() (map[string]string, error) { | ||
configFile, err := getConfigFile(i.Image) | ||
if err != nil { | ||
|
@@ -132,16 +125,12 @@ func (i *CNBImageCore) Labels() (map[string]string, error) { | |
return configFile.Config.Labels, nil | ||
} | ||
|
||
// Deprecated: ManifestSize | ||
// TBD Deprecated: ManifestSize | ||
func (i *CNBImageCore) ManifestSize() (int64, error) { | ||
return i.Image.Size() | ||
} | ||
|
||
func (i *CNBImageCore) Name() string { | ||
return i.repoName | ||
} | ||
|
||
// Deprecated: OS | ||
// TBD Deprecated: OS | ||
func (i *CNBImageCore) OS() (string, error) { | ||
configFile, err := getConfigFile(i.Image) | ||
if err != nil { | ||
|
@@ -150,7 +139,7 @@ func (i *CNBImageCore) OS() (string, error) { | |
return configFile.OS, nil | ||
} | ||
|
||
// Deprecated: OSVersion | ||
// TBD Deprecated: OSVersion | ||
func (i *CNBImageCore) OSVersion() (string, error) { | ||
configFile, err := getConfigFile(i.Image) | ||
if err != nil { | ||
|
@@ -165,7 +154,7 @@ func (i *CNBImageCore) TopLayer() (string, error) { | |
return "", err | ||
} | ||
if len(layers) == 0 { | ||
return "", fmt.Errorf("image %q has no layers", i.Name()) | ||
return "", errors.New("image has no layers") | ||
} | ||
topLayer := layers[len(layers)-1] | ||
hex, err := topLayer.DiffID() | ||
|
@@ -185,7 +174,7 @@ func (i *CNBImageCore) Valid() bool { | |
return err == nil | ||
} | ||
|
||
// Deprecated: Variant | ||
// TBD Deprecated: Variant | ||
func (i *CNBImageCore) Variant() (string, error) { | ||
configFile, err := getConfigFile(i.Image) | ||
if err != nil { | ||
|
@@ -194,7 +183,7 @@ func (i *CNBImageCore) Variant() (string, error) { | |
return configFile.Variant, nil | ||
} | ||
|
||
// Deprecated: WorkingDir | ||
// TBD Deprecated: WorkingDir | ||
func (i *CNBImageCore) WorkingDir() (string, error) { | ||
configFile, err := getConfigFile(i.Image) | ||
if err != nil { | ||
|
@@ -208,6 +197,9 @@ func (i *CNBImageCore) AnnotateRefName(refName string) error { | |
if err != nil { | ||
return err | ||
} | ||
if manifest.Annotations == nil { | ||
manifest.Annotations = make(map[string]string) | ||
} | ||
manifest.Annotations["org.opencontainers.image.ref.name"] = refName | ||
mutated := mutate.Annotations(i.Image, manifest.Annotations) | ||
image, ok := mutated.(v1.Image) | ||
|
@@ -218,25 +210,21 @@ func (i *CNBImageCore) AnnotateRefName(refName string) error { | |
return nil | ||
} | ||
|
||
func (i *CNBImageCore) Rename(name string) { | ||
i.repoName = name | ||
} | ||
|
||
// Deprecated: SetArchitecture | ||
// TBD Deprecated: SetArchitecture | ||
func (i *CNBImageCore) SetArchitecture(architecture string) error { | ||
return i.MutateConfigFile(func(c *v1.ConfigFile) { | ||
c.Architecture = architecture | ||
}) | ||
} | ||
|
||
// Deprecated: SetCmd | ||
// TBD Deprecated: SetCmd | ||
func (i *CNBImageCore) SetCmd(cmd ...string) error { | ||
return i.MutateConfigFile(func(c *v1.ConfigFile) { | ||
c.Config.Cmd = cmd | ||
}) | ||
} | ||
|
||
// Deprecated: SetEntrypoint | ||
// TBD Deprecated: SetEntrypoint | ||
func (i *CNBImageCore) SetEntrypoint(ep ...string) error { | ||
return i.MutateConfigFile(func(c *v1.ConfigFile) { | ||
c.Config.Entrypoint = ep | ||
|
@@ -266,7 +254,7 @@ func (i *CNBImageCore) SetEnv(key, val string) error { | |
}) | ||
} | ||
|
||
// Deprecated: SetHistory | ||
// TBD Deprecated: SetHistory | ||
func (i *CNBImageCore) SetHistory(histories []v1.History) error { | ||
return i.MutateConfigFile(func(c *v1.ConfigFile) { | ||
c.History = histories | ||
|
@@ -288,21 +276,21 @@ func (i *CNBImageCore) SetOS(osVal string) error { | |
}) | ||
} | ||
|
||
// Deprecated: SetOSVersion | ||
// TBD Deprecated: SetOSVersion | ||
func (i *CNBImageCore) SetOSVersion(osVersion string) error { | ||
return i.MutateConfigFile(func(c *v1.ConfigFile) { | ||
c.OSVersion = osVersion | ||
}) | ||
} | ||
|
||
// Deprecated: SetVariant | ||
// TBD Deprecated: SetVariant | ||
func (i *CNBImageCore) SetVariant(variant string) error { | ||
return i.MutateConfigFile(func(c *v1.ConfigFile) { | ||
c.Variant = variant | ||
}) | ||
} | ||
|
||
// Deprecated: SetWorkingDir | ||
// TBD Deprecated: SetWorkingDir | ||
func (i *CNBImageCore) SetWorkingDir(dir string) error { | ||
return i.MutateConfigFile(func(c *v1.ConfigFile) { | ||
c.Config.WorkingDir = dir | ||
|
@@ -329,11 +317,8 @@ func (i *CNBImageCore) AddLayerWithDiffIDAndHistory(path, _ string, history v1.H | |
if !i.preserveHistory { | ||
history = emptyHistory | ||
} | ||
configFile, err := getConfigFile(i) | ||
if err != nil { | ||
return err | ||
} | ||
history.Created = configFile.Created | ||
history.Created = v1.Time{Time: i.createdAt} | ||
|
||
i.Image, err = mutate.Append( | ||
i.Image, | ||
mutate.Addendum{ | ||
|
@@ -346,9 +331,6 @@ func (i *CNBImageCore) AddLayerWithDiffIDAndHistory(path, _ string, history v1.H | |
} | ||
|
||
func (i *CNBImageCore) Rebase(baseTopLayerDiffID string, withNewBase Image) error { | ||
if i.Kind() != withNewBase.Kind() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If my underlying image i is a remote image, does it mean I can rebase it with a local or layout image? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, in theory - I haven't tested it, but probably you can |
||
return fmt.Errorf("expected new base to be a %s image; got %s", i.Kind(), withNewBase.Kind()) | ||
} | ||
newBase := withNewBase.UnderlyingImage() // FIXME: when all imgutil.Images are v1.Images, we can remove this part | ||
var err error | ||
i.Image, err = mutate.Rebase(i.Image, i.newV1ImageFacade(baseTopLayerDiffID), newBase) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Originally I thought this could be an interface that all packages could implement, but since most packages would override the methods that call this interface it's not so useful