-
Notifications
You must be signed in to change notification settings - Fork 253
Add index build commands #106
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 index build commands #106
Conversation
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.
It would be nice to have at least one sanity e2e test that builds an image - can we check if podman is available in CI? Jeff recently added some ginkgo e2e tests for this repo.
go.mod
Outdated
@@ -3,6 +3,7 @@ module github.com/operator-framework/operator-registry | |||
require ( | |||
github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6 | |||
github.com/ghodss/yaml v1.0.0 | |||
github.com/go-bindata/go-bindata v3.1.2+incompatible // indirect |
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 don't think this should be here?
pkg/containertools/labelreader.go
Outdated
|
||
// GetLabelsFromContainer takes a container image path as input, pulls that image | ||
// to the local environment and then inspects it for labels | ||
func (r LabelReaderImpl) GetLabelsFromContainer(image string) (map[string]string, error) { |
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: Container generally refers to a running container, not an image. GetLabelsFromImage
?
require.Equal(t, dockerfile, expectedDockerfileWithPreviousIndex) | ||
} | ||
|
||
func TestGenerateDockerfileWithPreviousIndexDeleteOperators(t *testing.T) { |
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.
These should probably be table tests that at least test 0,1,n cases; ideally error cases as well
docs/contributors/mocking.md
Outdated
@@ -0,0 +1,15 @@ | |||
# Mocking code in operator-registry |
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.
We migrated away from gomock to https://github.com/maxbrunsfeld/counterfeiter in OLM; it's been significantly lower maintenance than gomock.
This doesn't need to block, but if you check it out I think you'll find it easier 😄
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, I was going off this:
https://github.com/operator-framework/operator-registry/tree/master/pkg/apprclient/mock
but now I realize that that's probably there because we never cleaned it up? I can look into this and see if I can do it quickly. We probably want to have all of the mocks in the project on the same framework at some point
pkg/lib/index/indexer.go
Outdated
@@ -0,0 +1,129 @@ | |||
package index |
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.
why lib/index
?
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.
IMO the right way to do all of these is to stop putting functional logic into the cmd
package and instead define that as just the steps to collect parameters from the terminal. Then have the first order function that actually implements those in the lib
package. If we do this, it allows any arbitrary project to import our calls without actually having to import the Cobra stuff. Also, it makes testing the higher order library functions significantly easier.This is a first pass attempt to do that.
|
||
// GenerateIndexDockerfile builds a string representation of a dockerfile to use when building | ||
// an operator-registry index image | ||
func (g *DockerfileGeneratorImpl) GenerateIndexDockerfile(binarySourceImage, previousIndexImage string, bundlesToAdd, operatorsToDelete []string) (string, error) { |
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.
super-nit: my brain keeps reading "binary source image" as "source code written in binary" and not "the source image containing the binaries"
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.
Yeah I had a lot of trouble coming up with these names (there are actually 3 different images involved). I was hoping someone could tell me this is bad and have a better idea. Any suggestions?
// Generate the registry database | ||
if len(bundlesToAdd) > 0 { | ||
add := strings.Join(bundlesToAdd, ",") | ||
dockerfile += fmt.Sprintf("RUN /build/bin/opm registry add \"%s\" -o \"index.db\"\n", add) |
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: seems weird to intentionally place our binaries in /build
?
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.
Yeah this is an artifact of the fact that the builder image (https://github.com/operator-framework/operator-registry/blob/master/upstream-builder.Dockerfile) just runs make
on the source. If we wanted to change that we may have to create a new dockerfile for that build since I assume other things depend on that one.
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, I see that in the final image it's in a better location. Thanks!
pkg/lib/index/indexer.go
Outdated
|
||
// Indexer allows the creation of index container images from scratch or | ||
// based on previous index images | ||
type Indexer 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.
This feels like it should be two interfaces, one for adding and one for removing?
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.
good point
pkg/lib/index/indexer.go
Outdated
} | ||
|
||
// IndexerImpl is a struct implementation of the Indexer interface | ||
type IndexerImpl 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.
This is mostly a style thing, but I don't love <interface> interface
and <interface>Impl struct
, if you can think if something more descriptive.
For this one, I could imagine a a non-image-based implementation of this that operates on database files only. Then I would have IndexerImpl
and DatabaseFileIndexerImpl
, at which point why not have ImageIndexer
and DatabaseFileIndexer
so I can tell their intent apart?
cmd/opm/index/add.go
Outdated
|
||
indexer := index.NewIndexer(containerTool, logger) | ||
|
||
request := index.AddToIndexRequest{ |
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.
This is fine for now, for some other commands I started doing something similar to what oc
does for building cobra commands:
https://github.com/operator-framework/operator-registry/blob/master/pkg/mirror/options.go#L7
It's not a huge problem the way it's written now, but it makes it difficult to use the defaulting/validation that's here if I wanted to use an indexer as a library (because that is done solely though the cobra flag setting).
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.
interesting, i'll take a look
0e8cacd
to
24a083c
Compare
@ecordell Updated based on your feedback, ptal |
24a083c
to
52c3383
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.
some minor nits + the need to rebase but looks great!
|
||
// AddToIndex is an aggregate API used to generate a registry index image with additional bundles | ||
func (i ImageIndexer) AddToIndex(request AddToIndexRequest) error { | ||
databaseFile := defaultDatabaseFile |
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: spacing looks off in this function
|
||
// DeleteFromIndex is an aggregate API used to generate a registry index image | ||
// without specific operators | ||
func (i ImageIndexer) DeleteFromIndex(request DeleteFromIndexRequest) error { |
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: spacing looks off in this function too
Motivation: In order to generate operator registry images, we need to create a high level command that allows CI and users to update the database based on previous images - Added `opm index add` which generates indexes (either as a dockerfile or shelling out to container tools) with additional bundles - Added `opm index delete` which generates an index based on a previous index minus a specified operator - Introduce counterfeiter as an interface mocker
9fa3022
to
1be113b
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.
Looks great!
} | ||
|
||
func TestGenerateDockerfile_EmptyBaseImage(t *testing.T) { | ||
controller := gomock.NewController(t) |
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/nonblocking: I don't think this is used anymore?
if err != nil { | ||
return nil, err | ||
} | ||
return data[0].Config.Labels, nil |
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/followup: should check length of data to be safe, right?
package containertools_test | ||
|
||
import ( | ||
"fmt" |
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: gofmt
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
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: ecordell, gallettilance, kevinrizza 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 |
opm index add
which generates indexes (either as adockerfile or shelling out to container tools) with additional bundles
opm index rm
which generates an index based on a previousindex minus a specified operator
In order to write tests for these, added mock files for the new
containertools
package viagomocks
. Added a readme in thedoc/contributors/
folder that defines the process of updating thesemocks.
Note: this needs to be rebased on top of #89 once that merges. For now, marking this pr as WIP
Description of the change:
Motivation for the change:
Reviewer Checklist
/docs