-
Notifications
You must be signed in to change notification settings - Fork 295
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
Add Copy packages command for registry to registry image and chart copy #4420
Conversation
Codecov Report
@@ Coverage Diff @@
## main #4420 +/- ##
==========================================
+ Coverage 70.95% 71.05% +0.09%
==========================================
Files 405 412 +7
Lines 32926 33069 +143
==========================================
+ Hits 23364 23498 +134
- Misses 8081 8089 +8
- Partials 1481 1482 +1
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. |
/test eks-anywhere-release-tooling-test-presubmit |
0985076
to
319de31
Compare
/test eks-anywhere-release-tooling-test-presubmit |
319de31
to
a8a9a13
Compare
Closes: #4109 |
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" |
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.
Could we use gomega? That's the preferred test library in this repo
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.
I thought we had a discussion that everyone hated gomega
pkg/registry/orasinterface.go
Outdated
) | ||
|
||
// OrasInterface thin layer for oras. | ||
type OrasInterface interface { |
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.
type OrasInterface interface { | |
type Oras interface { |
since the type already says it's an interface and this what we expose to the outside caller
pkg/registry/orasinterface.go
Outdated
return result, err | ||
} | ||
|
||
// Resolve call oras Resolve. |
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.
could we explain a bit what this does?
pkg/registry/orasinterface.go
Outdated
} | ||
|
||
// OrasImplementation thin wrapper on oras. | ||
type OrasImplementation struct{} |
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.
curious why you decided to create this layer on top of oras.
I was thinking instead we could just define the interface with same same signature as the oras original methods
And then compose those original oras objects into one to satisfy that interface
like
type OrasInterface interface {
Repository(ctx context.Context, name string) (orasregistry.Repository, error)
Resolve(ctx context.Context, reference string) (ocispec.Descriptor, error)
CopyGraph(ctx context.Context, src content.ReadOnlyStorage, dst content.Storage, root ocispec.Descriptor, opts oras.CopyGraphOptions) error
}
Although it's still coupled to the oras module, since it uses its structs as input and output, it still can be implemented in different ways since it's not dependent on the "service" objects (remote.Registry
, rasregistry.Repository
, etc.).
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.
I only did this to get enough test coverage.
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.
Ah got you. Then if it doesn't require too much work, I would to change this to something similar to what I suggested. I believe it should allow us to reach the same amount of coverage.
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.
Yeh, compose isn't going to work, but I was going to rearrange the code a bit to get the coverage back up AND get rid of this OrasImplementation
99751f9
to
728b6e1
Compare
if err := copyPackagesCmd.MarkFlagRequired("bundle"); err != nil { | ||
log.Fatalf("Cannot mark 'bundle' flag as required: %s", err) | ||
} | ||
copyPackagesCmd.Flags().StringVarP(©PackagesCommand.dstCert, "dst-cert", "", "", "Package bundles file to read artifact dependencies from") |
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.
Looks like some sort of cut and paste errors? Both here on line 39 and on line 40?
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.
Thanks, fixed.
} | ||
|
||
// NewCache creates an OCI registry client. | ||
func NewCache() *Cache { |
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.
How useful is this cache, given that this is used via the CLI and won't be long-lived?
I imagine we don't care, but this too isn't thread-safe... But unless we decide to parallelize the for loop that's reading from this cache, I suppose it's not important.
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.
There is no intention of parallelizing this for now, this is for convenience so we we can mindless loop over the images to copy and reuse a client. The normal case, there are two sources and one destination.
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.
oras paralielizes blob (aka image layer) copy under the covers
pkg/registry/client.go
Outdated
project string | ||
certFile string | ||
insecure bool | ||
dryRun bool |
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.
Maybe an idea for the future, but if there were a separate implementation, DryRunRegistryClient
or the like, then the code doesn't need to branch on the dry run flag (i.e. it's simpler), and is therefore easier to read, and less prone to someone adding a method implementation and forgetting to check the value of the dry run flag and abort before making changes.
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.
That was my original intention, but it ended up having a lot of repeated code. It was a complete copy of the client minus the actual call to CopyGraph
pkg/registry/client.go
Outdated
|
||
// Init registry configuration. | ||
func (or *OCIRegistryClient) Init() error { | ||
if or.initialized { |
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.
I guess there's not much to worry about, but this is a race condition... Consider a sync.Mutex
or a sync.Once
if it's really important that this code only be run once per instantiation. I don't see anything here that isn't safe to run more than once?
pkg/registry/client.go
Outdated
return nil | ||
} | ||
|
||
credentialStore := NewCredentialStore() |
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.
For the future, it's typically a better pattern to build these in your main, and pass them to a constructor. That makes your code more testable (you can easily pass in a test implementation), and it corrals the possible Init() errors to the main method where they can more easily be dealt with.
c114e62
to
3ca097d
Compare
pkg/registry/client.go
Outdated
) | ||
|
||
// Context describes aspects of a registry. | ||
type Context struct { |
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.
I personally find a bit confusing to name this context given how common context.Context
is in Go and that this one doesn't implement context.Context
.
What do you think about about RegistryConfig
?
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.
sounds good to me.
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.
lint doesn't like RegistryContext, so I'll go with something else like maybe StorageContext
pkg/registry/orasinterface.go
Outdated
} | ||
|
||
// OrasImplementation thin wrapper on oras. | ||
type OrasImplementation struct{} |
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.
Ah got you. Then if it doesn't require too much work, I would to change this to something similar to what I suggested. I believe it should allow us to reach the same amount of coverage.
/approve |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: TerryHowe The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
30d33d6
to
e8451c9
Compare
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.
/lgtm
/unapprove
Not sure if you were gonna change the tests to use gomega, so un-approving jic. Feel free to approve it again if not.
/test eks-anywhere-release-tooling-test-presubmit |
e8451c9
to
9cadc20
Compare
I am copy/pasta some of these files to packages and it doesn't use gomega 🤷 which is part of the reasoning. |
/lgtm Good luck with those tests |
/test eks-anywhere-presubmit |
/test eks-anywhere-release-tooling-test-presubmit |
/override eks-anywhere-release-tooling-test-presubmit this is failing because of the golden file being out of date again. I just merged a new one this morning and already it is out of date. |
@TerryHowe: Overrode contexts on behalf of TerryHowe: eks-anywhere-release-tooling-test-presubmit In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
/override eks-anywhere-release-tooling-test-presubmit |
@TerryHowe: Overrode contexts on behalf of TerryHowe: eks-anywhere-release-tooling-test-presubmit In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
/cherry-pick release-0.14 |
@TerryHowe: #4420 failed to apply on top of branch "release-0.14":
In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
New command that takes advantage of oras copy command to copy images from one registry to another. The primary use case for this would be to copy images from ECR to Harbor or other private registry.