-
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
Manifest List Interface #191
Merged
natalieparellano
merged 189 commits into
buildpacks:main
from
husni-faiz:dev-image-index
May 7, 2024
Merged
Changes from 4 commits
Commits
Show all changes
189 commits
Select commit
Hold shift + click to select a range
9eb407f
index: add Image Index interface
husni-faiz 816341c
remote: index: function to create new index
husni-faiz fefd9bc
bugfix: index: Remove mutating media type to DockerManifestList
husni-faiz 05456ff
index: optimize: get image from descriptor
husni-faiz 13989a3
index: check for image architecture
husni-faiz dc5c024
index: add default path to Save()
husni-faiz 02d354b
index: add keychain to new index
husni-faiz db82b69
index: add image index types
husni-faiz cdb04c9
indexOptions for creating image index
husni-faiz d87b7d1
index: path and mediatype options for creating index
husni-faiz 7842116
index: add remove index method
husni-faiz 390546a
remote: index: remove path option
husni-faiz aa43a59
remote: index: user docker mediatype by default
husni-faiz 21a4790
remote: index: remove saving to layout
husni-faiz 74f8e44
remote: index: save index to registry
husni-faiz d91432c
index: local: annotate and add functionality
husni-faiz bccd2af
remote/index: return error instead of calling panic
husni-faiz e24cebc
remote/index: return a wrapped error if fetcing an image fails
husni-faiz c17b6d9
local/index: return error instead of calling panic
husni-faiz add9675
remote/new_index: validate index name
husni-faiz db2e406
local/index: refactor interface functions to use the index path
husni-faiz 3464e40
local/index_options: create new index with IndexManifest
husni-faiz 08653dd
remote/index_options: create new index with IndexManifest
husni-faiz c941979
remote/new_index: rename file
husni-faiz 9d284ea
get IndexManifest from ggcr index
husni-faiz 2752977
remote/index/save: return error if platform information is missing
husni-faiz a4589d4
remote/index: ImageIndexTest to be used in unit tests
husni-faiz 8c5d049
remote/index_test: setup a registry for test
husni-faiz 4f9c64b
remote/index_test: basic tests for remote index
husni-faiz 85b8899
remote/new_index: NewIndexTest function to create a test index
husni-faiz 6a0c434
remote/new_index: use index in registry if already exists
husni-faiz 8653514
remote/index: remove ManifestSize unused function
husni-faiz 93861df
index: add brief comments to all index functions
husni-faiz afaa657
index: remove returning error when platform information is missing
husni-faiz 2f6f5c9
local/index: remove AppendManifet wrapper function
husni-faiz d558685
local/index: save indent formatted json output
husni-faiz adae788
local/index save: use os module instead of layout package
husni-faiz 7e6c885
local/index: delete method to remove index from local storage
husni-faiz 54343a5
local/index: wrap GetIndexManifest errors
husni-faiz 191f664
new_index: check for local index first
husni-faiz fcb5ade
local/index: copy referenced images to same registry as index
husni-faiz 51609ae
index: fix github action tests failing
husni-faiz 818f3a2
fix linter error: io/ioutil deprecated
husni-faiz 8fdc89d
Merge branch 'main' into dev-image-index
husni-faiz b31a1ee
WIP added image-index methods
WYGIN 186495b
fWIP fix lint and run format
WYGIN 0c5a954
removed ,gitpod.yml file
WYGIN bd7af69
WIP removed ImageIndexHandler
WYGIN 85fd5dc
WIP fix some missing logic
WYGIN f6f80f1
WIP added registry and insecure fields to IndexAddOptions
WYGIN 20568f7
WIP added empty test cases
WYGIN 51446eb
WIP added tests but failing
WYGIN 334b72a
WIP removed oci layout test files
WYGIN 4e79960
WIP removed cnb dir from local
WYGIN 3b842ab
WIP refactor code to improve readability
WYGIN bd05301
WIP added fake index with empty test cases
WYGIN 39a6fa3
WIP added few tests for fake index
WYGIN 45d6b75
WIP fixed fake index tests
WYGIN e8c303a
WIP defined errors at one place
WYGIN 00a8a80
WIP trying to fix error when saving index
WYGIN 01db00c
WIP fix: imgutil#Save() and annotations bugs
WYGIN 592a65c
WIP fix: all bugs fixed except image hash change when adding image to…
WYGIN 9ec2c8c
WIP added tests for all indexes
WYGIN 324a62a
WIP made index.NewIndex to return imgutil.ImageIndex instead of imgut…
WYGIN 95b0df4
WIP improved test coverage
WYGIN 3ca7018
WIP improved test coverage by adding #Save
WYGIN fe02008
WIP fix failing tests for #Add
WYGIN ab15c33
WIP fix all bugs except mutated configFile and Manifest of image when…
WYGIN fd3d91c
WIP fix bug except #Save urls
WYGIN 13c3f65
WIP fix all bugs except #Save URLs
WYGIN d01eaf4
WIP fix: SetURLs for #Save
WYGIN e158f8d
WIP bug fixes
WYGIN 8d76f28
WIP added goroutines to improve performance
WYGIN cdd16f8
WIP minor bug fixes
WYGIN 921a22f
WIP added manifestOnly handler
WYGIN 9edc6be
WIP minor changes to ImageIndex#Push
WYGIN e7cfa9c
WIP fix: use latest index when pushing index
WYGIN c98cea9
WIP added TaggableIndex to push IndexManifest only
WYGIN fad6445
WIP fix: added decribable methods to TaggableIndex
WYGIN 0b018df
WIP added documentation, fix: IndexHandler#Push iissue
WYGIN 1d563fd
WIP added tests for index.NewIndex
WYGIN 8656617
Merge branch 'main' into dev-image-index
jjbustamante da80ffb
Merge branch 'dev-image-index' into image-index
WYGIN d071ec2
WIP formatted code after Merge upstream branch
WYGIN 2f20186
WIP: fix bugs
WYGIN d57cc75
fix: tests making 'pack manifest' fail
WYGIN 5f5ff95
fix: return error when setters called on unknown digest of fake index
WYGIN 658b7ff
refactor: improved error messages
WYGIN 363020d
fix: bug causing local images to fail annotate
WYGIN 2b39c6a
fix: manifest handler not saved annotated images
WYGIN 052db76
refactor: removed IndexHandler
WYGIN 96558aa
refactor: remove dead code
WYGIN 38da26f
refactor: improve ManifestHandler#Save readability
WYGIN 2dad2cc
refactor: nit all methods except #Add
WYGIN 0bf93b7
refactor: nit nil pointer handling
WYGIN 3a656df
refactor: ManifestHandler tests
WYGIN 1c3b05e
feat: added #Features #OSFeatures #URLs #Annotations methods to imgut…
WYGIN abfcabf
refactor: remove IndexHandler
WYGIN 439fac9
fix: removed duplicate stringSlices for features, osFeatures, urls
WYGIN 6e77fba
refactor: change imgutil.Platform to v1.Platform
WYGIN 49941ee
refactor: local imaages added to index should implement EdditableImage
WYGIN 3acfd71
fix: add local images return index not found error
WYGIN b5aab10
WIP: added tests for imgutil#MutateManifest
WYGIN 5a8a519
WIP: added tests
SaikiranIndia 3eb4bc6
fix: test
SaikiranIndia c709d08
WIP: refactor: improve code readability
SaikiranIndia ce6569d
Merge pull request #2 from WYGIN/image-index
jjbustamante 9e2d51b
fixing some linting errors that are preventing the tests to be executed
jjbustamante 9153420
Fixing failing unit tests
jjbustamante 6550208
Fixing unit test
jjbustamante 6745c1c
Running Manifest Handler tests in Parallel
jjbustamante d7596e5
Running the rest of the tests in Parallel
jjbustamante 59056e1
fix: layout image concurrency issue while saving
SaikiranIndia 9533f44
chore: revert changes from v1.Platform to imgutil.Platform
WYGIN 75b7c54
Merge pull request #3 from WYGIN/husni-image-index
jjbustamante 103e126
running layout and sparse tests in parallel
jjbustamante b85e83c
merging latest changes from main
jjbustamante ba1701d
restoring imgutil.MakeFileSafeName method to convert the image name t…
jjbustamante 1db264b
skipping some test for windows because we don't have Indexes availabl…
jjbustamante b437d70
fixing windows error message and skipping one more test
jjbustamante eac7a17
Skipping test with alpine on windows
jjbustamante ae178ae
Updating doc comments and removing some logic that I think we don't n…
jjbustamante 96301fa
Merge branch 'main' into dev-image-index
jjbustamante fc5c913
Fixing lint errors
jjbustamante 897ad17
Fixing lint error
jjbustamante 1d0faab
Fixing unit test after cleaning a little bit
jjbustamante 5ff17bd
Refactoring packages, removing fake implemenatation because it is not…
jjbustamante 6fd707e
Merging latest changes from main 04/11
jjbustamante b7d201c
Merge branch 'main' into dev-image-index
jjbustamante d8861b6
removing unused files
jjbustamante 53dd3a9
Removing fake implementation, we don't need it right now, if we do ne…
jjbustamante 1c7c3ec
Removing fake implementation, we don't need it right now, if we do ne…
jjbustamante a0a34ed
Removing more fake implementations
jjbustamante cedf3ad
restoring from main branch
jjbustamante 50d54c8
refactoring layout image index implementation to be similar to our im…
jjbustamante ebde93a
Merge branch 'main' into dev-image-index
jjbustamante 5cd3d3e
refactoring the image index options to follow the same pattern we use…
jjbustamante d038320
Merge branch 'main' into dev-image-index
jjbustamante 0f3054e
adding assertions for checking an ImageIndex that was saved on disk
jjbustamante c87bd7a
adding #Save, #Add, #Push test scenarios
jjbustamante fd63c31
adding #Save, #Add, #Push test scenarios
jjbustamante 530a05d
adding #Inspect and #Remove test cases
jjbustamante d0e9f35
Removing URL() method from index interface, it is not clear to me if …
jjbustamante 1dfd895
removing index package all the implementation is under cnb_index.go, …
jjbustamante 6eb1a70
Removing URLs method in other places
jjbustamante 2c63503
Merge branch 'main' into dev-image-index
jjbustamante 02e8bfa
Remove unneeded setters
natalieparellano 718dd15
Remove unneeded things from local package
natalieparellano 974fe62
Remove features, we don't care about it for now
natalieparellano 0898f25
Remove annotations as a field on the image struct,
natalieparellano c98f11b
Merge pull request #5 from buildpacks/image-index
jjbustamante 8426835
Remove mutate manifest functions, these should not be needed
natalieparellano ff8f39f
Remove focus
natalieparellano d8821bf
Fix failing test
natalieparellano 531abe9
Merge pull request #6 from buildpacks/image-index
jjbustamante ffa9fbc
Cleanup imgutil.Image interface to organize methods by manifest, conf…
natalieparellano ad4eec6
Merge pull request #7 from buildpacks/image-index
jjbustamante 9b2f042
Remove the option to add an index to another index,
natalieparellano bae2d77
Merge pull request #8 from buildpacks/image-index
jjbustamante 88cde47
Prune more stuff from cnb_index.go, but add back setters!
natalieparellano ba33b6b
Merge pull request #9 from buildpacks/image-index
jjbustamante 289f30c
Fix format
natalieparellano ea2a3cb
Revert "Fix format"
natalieparellano 55ed46a
Remove CNBIndex.Format as it's not used
natalieparellano b25226d
Fix a few tests by updating the fixtures
natalieparellano 811ca75
WIP: try to fix tests by overriding path.AppendIndex, but now there's…
natalieparellano 31615f7
Revert "WIP: try to fix tests by overriding path.AppendIndex, but now…
natalieparellano 0d6d63a
WIP: fix all but RemoveManifest test
natalieparellano c46fcc1
Merge pull request #10 from buildpacks/image-index
jjbustamante 614338e
Fix in-memory part
natalieparellano e767856
Merge remote-tracking branch 'buildpacks/image-index' into dev-image-…
jjbustamante e9716db
fixing the remove manifest test, we need to create an empty index on …
jjbustamante 725d3c9
Override Image method instead of renaming us
natalieparellano d382bdb
Remove insecure as it is not used
natalieparellano 3255562
Try to simplify index options by putting them all on one struct
natalieparellano ddc5be8
Merge pull request #11 from buildpacks/image-index
jjbustamante 697ac4c
Merge branch 'buildpacks:main' into dev-image-index
jjbustamante a6fda53
Move some stuff around
natalieparellano d508728
Move stuff around
natalieparellano 4aedd4c
Merge pull request #12 from buildpacks/image-index
jjbustamante c2871d0
Fixing - these tests should push and pull from a local registry to av…
jjbustamante 8412584
removing focus
jjbustamante cbecaa8
adding one more test case for adding multiple manifests, updating Pus…
jjbustamante f00946b
removing blobs from test data, after testing on pack we don't want to…
jjbustamante f79d933
when using a fake.Image for unit testing purpose, the Platform is und…
jjbustamante 7a7ff3e
moving layout index tests to index_test.go and adding test coverage t…
jjbustamante d4a3c74
adding more test coverage for error cases in image index
jjbustamante 2e42a19
fixing an issue when a docker media-type is updated and the value is …
jjbustamante 73a2d7c
change a FIXME into a Note
jjbustamante File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,8 +20,8 @@ | |
|
||
var ( | ||
ErrManifestUndefined = errors.New("encountered unexpected error while parsing image: manifest or index manifest is nil") | ||
ErrUnknownMediaType = func(format types.MediaType) error { | ||
return fmt.Errorf("unsupported media type encountered in image: '%s'", format) | ||
} | ||
) | ||
|
||
|
@@ -35,346 +35,347 @@ | |
RepoName string | ||
} | ||
|
||
func (h *CNBIndex) getConfigFileFrom(digest name.Digest) (v1.ConfigFile, error) { | ||
hash, err := v1.NewHash(digest.Identifier()) | ||
if err != nil { | ||
return v1.ConfigFile{}, err | ||
} | ||
image, err := h.Image(hash) | ||
if err != nil { | ||
return v1.ConfigFile{}, err | ||
} | ||
configFile, err := GetConfigFile(image) | ||
if err != nil { | ||
return v1.ConfigFile{}, err | ||
} | ||
return *configFile, nil | ||
} | ||
|
||
func (h *CNBIndex) getManifestFileFrom(digest name.Digest) (v1.Manifest, error) { | ||
hash, err := v1.NewHash(digest.Identifier()) | ||
if err != nil { | ||
return v1.Manifest{}, err | ||
} | ||
image, err := h.Image(hash) | ||
func (h *CNBIndex) getDescriptorFrom(digest name.Digest) (v1.Descriptor, error) { | ||
indexManifest, err := getIndexManifest(h.ImageIndex) | ||
if err != nil { | ||
return v1.Manifest{}, err | ||
return v1.Descriptor{}, err | ||
} | ||
manifestFile, err := GetManifest(image) | ||
if err != nil { | ||
return v1.Manifest{}, err | ||
for _, current := range indexManifest.Manifests { | ||
if current.Digest.String() == digest.Identifier() { | ||
return current, nil | ||
} | ||
} | ||
return *manifestFile, nil | ||
return v1.Descriptor{}, fmt.Errorf("failed to find image with digest %s in index", digest.Identifier()) | ||
} | ||
|
||
// OS returns `OS` of an existing Image. | ||
func (h *CNBIndex) OS(digest name.Digest) (os string, err error) { | ||
configFile, err := h.getConfigFileFrom(digest) | ||
desc, err := h.getDescriptorFrom(digest) | ||
if err != nil { | ||
return "", err | ||
} | ||
return configFile.OS, nil | ||
if desc.Platform != nil { | ||
return desc.Platform.OS, nil | ||
} | ||
return "", nil | ||
} | ||
|
||
// Architecture return the Architecture of an Image/Index based on given Digest. | ||
// Returns an error if no Image/Index found with given Digest. | ||
func (h *CNBIndex) Architecture(digest name.Digest) (arch string, err error) { | ||
configFile, err := h.getConfigFileFrom(digest) | ||
desc, err := h.getDescriptorFrom(digest) | ||
if err != nil { | ||
return "", err | ||
} | ||
return configFile.Architecture, nil | ||
if desc.Platform != nil { | ||
return desc.Platform.Architecture, nil | ||
} | ||
return "", nil | ||
} | ||
|
||
// Variant return the `Variant` of an Image. | ||
// Returns an error if no Image/Index found with given Digest. | ||
func (h *CNBIndex) Variant(digest name.Digest) (osVariant string, err error) { | ||
configFile, err := h.getConfigFileFrom(digest) | ||
desc, err := h.getDescriptorFrom(digest) | ||
if err != nil { | ||
return "", err | ||
} | ||
return configFile.Variant, nil | ||
if desc.Platform != nil { | ||
return desc.Platform.Variant, nil | ||
} | ||
return "", nil | ||
} | ||
|
||
// OSVersion returns the `OSVersion` of an Image with given Digest. | ||
// Returns an error if no Image/Index found with given Digest. | ||
func (h *CNBIndex) OSVersion(digest name.Digest) (osVersion string, err error) { | ||
configFile, err := h.getConfigFileFrom(digest) | ||
desc, err := h.getDescriptorFrom(digest) | ||
if err != nil { | ||
return "", err | ||
} | ||
return configFile.OSVersion, nil | ||
if desc.Platform != nil { | ||
return desc.Platform.OSVersion, nil | ||
} | ||
return "", nil | ||
} | ||
|
||
// OSFeatures returns the `OSFeatures` of an Image with given Digest. | ||
// Returns an error if no Image/Index found with given Digest. | ||
func (h *CNBIndex) OSFeatures(digest name.Digest) (osFeatures []string, err error) { | ||
configFile, err := h.getConfigFileFrom(digest) | ||
desc, err := h.getDescriptorFrom(digest) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return configFile.OSFeatures, nil | ||
if desc.Platform != nil { | ||
return desc.Platform.OSFeatures, nil | ||
} | ||
return []string{}, nil | ||
} | ||
|
||
// Annotations return the `Annotations` of an Image with given Digest. | ||
// Returns an error if no Image/Index found with given Digest. | ||
// For Docker images and Indexes it returns an error. | ||
func (h *CNBIndex) Annotations(digest name.Digest) (annotations map[string]string, err error) { | ||
manifestFile, err := h.getManifestFileFrom(digest) | ||
desc, err := h.getDescriptorFrom(digest) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return manifestFile.Annotations, nil | ||
return desc.Annotations, nil | ||
} | ||
|
||
// setters | ||
|
||
func (h *CNBIndex) SetAnnotations(digest name.Digest, annotations map[string]string) (err error) { | ||
return h.mutateExistingImage(digest, func(image v1.Image) (v1.Image, error) { | ||
partial := mutate.Annotations(image, annotations) | ||
annotatedImage, ok := partial.(v1.Image) | ||
if !ok { | ||
return nil, fmt.Errorf("failed to annotate image") | ||
return h.replaceDescriptor(digest, func(descriptor v1.Descriptor) (v1.Descriptor, error) { | ||
if len(descriptor.Annotations) == 0 { | ||
descriptor.Annotations = make(map[string]string) | ||
} | ||
return annotatedImage, nil | ||
|
||
for k, v := range annotations { | ||
descriptor.Annotations[k] = v | ||
} | ||
return descriptor, nil | ||
}) | ||
} | ||
|
||
func (h *CNBIndex) SetArchitecture(digest name.Digest, arch string) (err error) { | ||
return h.mutateExistingImage(digest, func(image v1.Image) (v1.Image, error) { | ||
configFile, err := image.ConfigFile() | ||
if err != nil { | ||
return nil, err | ||
} | ||
configFile.Architecture = arch | ||
return mutate.ConfigFile(image, configFile) | ||
return h.replaceDescriptor(digest, func(descriptor v1.Descriptor) (v1.Descriptor, error) { | ||
descriptor.Platform.Architecture = arch | ||
return descriptor, nil | ||
}) | ||
} | ||
|
||
func (h *CNBIndex) SetOS(digest name.Digest, os string) (err error) { | ||
return h.mutateExistingImage(digest, func(image v1.Image) (v1.Image, error) { | ||
configFile, err := image.ConfigFile() | ||
if err != nil { | ||
return nil, err | ||
} | ||
configFile.OS = os | ||
return mutate.ConfigFile(image, configFile) | ||
return h.replaceDescriptor(digest, func(descriptor v1.Descriptor) (v1.Descriptor, error) { | ||
descriptor.Platform.OS = os | ||
return descriptor, nil | ||
}) | ||
} | ||
|
||
func (h *CNBIndex) SetVariant(digest name.Digest, osVariant string) (err error) { | ||
return h.mutateExistingImage(digest, func(image v1.Image) (v1.Image, error) { | ||
configFile, err := image.ConfigFile() | ||
if err != nil { | ||
return nil, err | ||
} | ||
configFile.Variant = osVariant | ||
return mutate.ConfigFile(image, configFile) | ||
return h.replaceDescriptor(digest, func(descriptor v1.Descriptor) (v1.Descriptor, error) { | ||
descriptor.Platform.Variant = osVariant | ||
return descriptor, nil | ||
}) | ||
} | ||
|
||
func (h *CNBIndex) mutateExistingImage(digest name.Digest, withFunc func(image v1.Image) (v1.Image, error)) (err error) { | ||
hash, err := v1.NewHash(digest.Identifier()) | ||
func (h *CNBIndex) replaceDescriptor(digest name.Digest, withFun func(descriptor v1.Descriptor) (v1.Descriptor, error)) (err error) { | ||
desc, err := h.getDescriptorFrom(digest) | ||
if err != nil { | ||
return err | ||
} | ||
image, err := h.Image(hash) | ||
desc, err = withFun(desc) | ||
if err != nil { | ||
return err | ||
} | ||
if err = h.RemoveManifest(digest); err != nil { | ||
return err | ||
} | ||
newImage, err := withFunc(image) | ||
if err != nil { | ||
return err | ||
add := mutate.IndexAddendum{ | ||
Add: h.ImageIndex, | ||
Descriptor: desc, | ||
} | ||
h.AddManifest(newImage) | ||
h.ImageIndex = mutate.AppendManifests(mutate.RemoveManifests(h.ImageIndex, match.Digests(desc.Digest)), add) | ||
return nil | ||
} | ||
|
||
func (h *CNBIndex) Image(hash v1.Hash) (v1.Image, error) { | ||
index, err := h.IndexManifest() | ||
if err != nil { | ||
return nil, err | ||
} | ||
if !indexContains(index.Manifests, hash) { | ||
return nil, fmt.Errorf("failed to find image with digest %s in index", hash.String()) | ||
} | ||
return h.ImageIndex.Image(hash) | ||
} | ||
|
||
func indexContains(manifests []v1.Descriptor, hash v1.Hash) bool { | ||
for _, m := range manifests { | ||
if m.Digest.String() == hash.String() { | ||
return true | ||
} | ||
} | ||
return false | ||
} | ||
|
||
// AddManifest adds an image to the index. | ||
func (h *CNBIndex) AddManifest(image v1.Image) { | ||
desc, _ := descriptor(image) | ||
h.ImageIndex = mutate.AppendManifests(h.ImageIndex, mutate.IndexAddendum{ | ||
Add: image, | ||
Add: image, | ||
Descriptor: desc, | ||
}) | ||
} | ||
|
||
// SaveDir will locally save the index. | ||
func (h *CNBIndex) SaveDir() error { | ||
layoutPath := filepath.Join(h.XdgPath, MakeFileSafeName(h.RepoName)) // FIXME: do we create an OCI-layout compatible directory structure? | ||
natalieparellano marked this conversation as resolved.
Show resolved
Hide resolved
|
||
var ( | ||
path layout.Path | ||
err error | ||
) | ||
|
||
if _, err = os.Stat(layoutPath); !os.IsNotExist(err) { | ||
// We need to always init an empty index when saving | ||
if err = os.RemoveAll(layoutPath); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
indexType, err := h.ImageIndex.MediaType() | ||
if err != nil { | ||
return err | ||
} | ||
if path, err = newEmptyLayoutPath(indexType, layoutPath); err != nil { | ||
return err | ||
} | ||
|
||
var errs SaveError | ||
index, err := h.ImageIndex.IndexManifest() | ||
if err != nil { | ||
return err | ||
} | ||
for _, desc := range index.Manifests { | ||
appendManifest(desc, path, &errs) | ||
} | ||
if len(errs.Errors) != 0 { | ||
return errs | ||
} | ||
return nil | ||
} | ||
|
||
func appendManifest(desc v1.Descriptor, path layout.Path, errs *SaveError) { | ||
if err := path.RemoveDescriptors(match.Digests(desc.Digest)); err != nil { | ||
errs.Errors = append(errs.Errors, SaveDiagnostic{ | ||
Cause: err, | ||
}) | ||
} | ||
if err := path.AppendDescriptor(desc); err != nil { | ||
errs.Errors = append(errs.Errors, SaveDiagnostic{ | ||
Cause: err, | ||
}) | ||
} | ||
} | ||
|
||
func newEmptyLayoutPath(indexType types.MediaType, path string) (layout.Path, error) { | ||
if indexType == types.OCIImageIndex { | ||
return layout.Write(path, empty.Index) | ||
} | ||
return layout.Write(path, NewEmptyDockerIndex()) | ||
} | ||
|
||
// Push Publishes ImageIndex to the registry assuming every image it referes exists in registry. | ||
// | ||
// It will only push the IndexManifest to registry. | ||
func (h *CNBIndex) Push(ops ...func(*IndexOptions) error) error { | ||
func (h *CNBIndex) Push(ops ...IndexOption) error { | ||
var pushOps = &IndexOptions{} | ||
for _, op := range ops { | ||
if err := op(pushOps); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
if pushOps.MediaType != "" { | ||
if !pushOps.MediaType.IsIndex() { | ||
return ErrUnknownMediaType(pushOps.MediaType) | ||
} | ||
existingType, err := h.ImageIndex.MediaType() | ||
if err != nil { | ||
return err | ||
} | ||
if pushOps.MediaType != existingType { | ||
h.ImageIndex = mutate.IndexMediaType(h.ImageIndex, pushOps.MediaType) | ||
} | ||
} | ||
|
||
ref, err := name.ParseReference( | ||
h.RepoName, | ||
name.WeakValidation, | ||
name.Insecure, | ||
) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
indexManifest, err := getIndexManifest(h.ImageIndex) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
var taggableIndex = NewTaggableIndex(indexManifest) | ||
multiWriteTagables := map[name.Reference]remote.Taggable{ | ||
ref: taggableIndex, | ||
} | ||
for _, tag := range pushOps.DestinationTags { | ||
multiWriteTagables[ref.Context().Tag(tag)] = taggableIndex | ||
} | ||
|
||
// FIXME: this will only push the index manifest, assuming that all the images it refers to exist in the registry | ||
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. I think this is not a FIXME, I tried to remove it and use the
jjbustamante marked this conversation as resolved.
Show resolved
Hide resolved
|
||
err = remote.MultiWrite( | ||
multiWriteTagables, | ||
remote.WithAuthFromKeychain(h.KeyChain), | ||
remote.WithTransport(GetTransport(pushOps.Insecure)), | ||
) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if pushOps.Purge { | ||
return h.DeleteDir() | ||
} | ||
return h.SaveDir() | ||
natalieparellano marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
// Inspect Displays IndexManifest. | ||
func (h *CNBIndex) Inspect() (string, error) { | ||
rawManifest, err := h.RawManifest() | ||
if err != nil { | ||
return "", err | ||
} | ||
return string(rawManifest), nil | ||
} | ||
|
||
// RemoveManifest removes an image with a given digest from the index. | ||
func (h *CNBIndex) RemoveManifest(digest name.Digest) (err error) { | ||
hash, err := v1.NewHash(digest.Identifier()) | ||
if err != nil { | ||
return err | ||
} | ||
h.ImageIndex = mutate.RemoveManifests(h.ImageIndex, match.Digests(hash)) | ||
_, err = h.ImageIndex.Digest() // force compute | ||
return err | ||
} | ||
|
||
// DeleteDir removes the index from the local filesystem if it exists. | ||
func (h *CNBIndex) DeleteDir() error { | ||
layoutPath := filepath.Join(h.XdgPath, MakeFileSafeName(h.RepoName)) | ||
if _, err := os.Stat(layoutPath); err != nil { | ||
if os.IsNotExist(err) { | ||
return nil | ||
} | ||
return err | ||
} | ||
return os.RemoveAll(layoutPath) | ||
} | ||
|
||
func getIndexManifest(ii v1.ImageIndex) (mfest *v1.IndexManifest, err error) { | ||
mfest, err = ii.IndexManifest() | ||
if mfest == nil { | ||
return mfest, ErrManifestUndefined | ||
} | ||
return mfest, err | ||
} | ||
|
||
// descriptor returns a v1.Descriptor filled with a v1.Platform created from reading | ||
// the image config file. | ||
func descriptor(image v1.Image) (v1.Descriptor, error) { | ||
// Get the image configuration file | ||
cfg, _ := GetConfigFile(image) | ||
platform := v1.Platform{} | ||
platform.Architecture = cfg.Architecture | ||
platform.OS = cfg.OS | ||
platform.OSVersion = cfg.OSVersion | ||
platform.Variant = cfg.Variant | ||
platform.OSFeatures = cfg.OSFeatures | ||
return v1.Descriptor{ | ||
Platform: &platform, | ||
}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
nit:
getDescriptorFrom
never returns nil in its first argument, so I think you can remove this checkThere 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.
I think I added it because on unit testing when using
random
packages inggcr
some nil in these attributes but let me check if everything is file after removing it