Skip to content

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

Merged

Conversation

kevinrizza
Copy link
Member

@kevinrizza kevinrizza commented Oct 28, 2019

  • Added opm index add which generates indexes (either as a
    dockerfile or shelling out to container tools) with additional bundles
  • Added opm index rm which generates an index based on a previous
    index minus a specified operator

In order to write tests for these, added mock files for the new
containertools package via gomocks. Added a readme in the
doc/contributors/ folder that defines the process of updating these
mocks.

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

  • Implementation matches the proposed design, or proposal is updated to match implementation
  • Sufficient unit test coverage
  • Sufficient end-to-end test coverage
  • Docs updated or added to /docs
  • Commit messages sensible and descriptive

@openshift-ci-robot openshift-ci-robot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Oct 28, 2019
@openshift-ci-robot openshift-ci-robot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label Oct 28, 2019
Copy link
Member

@ecordell ecordell left a 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
Copy link
Member

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?


// 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) {
Copy link
Member

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) {
Copy link
Member

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

@@ -0,0 +1,15 @@
# Mocking code in operator-registry
Copy link
Member

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 😄

Copy link
Member Author

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

@@ -0,0 +1,129 @@
package index
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why lib/index?

Copy link
Member Author

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) {
Copy link
Member

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"

Copy link
Member Author

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)
Copy link
Member

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?

Copy link
Member Author

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.

Copy link
Member

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!


// Indexer allows the creation of index container images from scratch or
// based on previous index images
type Indexer interface {
Copy link
Member

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?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point

}

// IndexerImpl is a struct implementation of the Indexer interface
type IndexerImpl struct {
Copy link
Member

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?


indexer := index.NewIndexer(containerTool, logger)

request := index.AddToIndexRequest{
Copy link
Member

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).

Copy link
Member Author

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

@openshift-ci-robot openshift-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Oct 30, 2019
@kevinrizza
Copy link
Member Author

@ecordell Updated based on your feedback, ptal

@openshift-ci-robot openshift-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Nov 1, 2019
Copy link
Member

@gallettilance gallettilance left a 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
Copy link
Member

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 {
Copy link
Member

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
@kevinrizza kevinrizza changed the title WIP: Add index build commands Add index build commands Nov 2, 2019
@openshift-ci-robot openshift-ci-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Nov 2, 2019
Copy link
Member

@gallettilance gallettilance left a 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)
Copy link
Member

@ecordell ecordell Nov 2, 2019

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
Copy link
Member

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"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: gofmt

Copy link
Member

@ecordell ecordell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm

@openshift-ci-robot openshift-ci-robot added the lgtm Indicates that a PR is ready to be merged. label Nov 2, 2019
@openshift-ci-robot
Copy link

[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 /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci-robot openshift-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Nov 2, 2019
@openshift-merge-robot openshift-merge-robot merged commit f30cfde into operator-framework:master Nov 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants