From 554e2756d9021a36d1dffb559db8f83775789567 Mon Sep 17 00:00:00 2001 From: Anik Bhattacharjee Date: Wed, 13 Jan 2021 11:28:44 -0500 Subject: [PATCH] Add declarative index config enhancement --- enhancements/assets/community-operators.png | Bin 0 -> 39301 bytes .../assets/new-community-operators.png | Bin 0 -> 72041 bytes enhancements/declarative-index-config.md | 947 ++++++++++++++++++ 3 files changed, 947 insertions(+) create mode 100644 enhancements/assets/community-operators.png create mode 100644 enhancements/assets/new-community-operators.png create mode 100644 enhancements/declarative-index-config.md diff --git a/enhancements/assets/community-operators.png b/enhancements/assets/community-operators.png new file mode 100644 index 0000000000000000000000000000000000000000..713eb4464f972912556258a2f6f0fc6c621e2b91 GIT binary patch literal 39301 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 z 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 TT&12QCusawEAs?X=k@;|N+^@A literal 0 HcmV?d00001 diff --git a/enhancements/declarative-index-config.md b/enhancements/declarative-index-config.md new file mode 100644 index 00000000..4ebef2cb --- /dev/null +++ b/enhancements/declarative-index-config.md @@ -0,0 +1,947 @@ +--- +title: declarative-index-config +authors: + - "@anik120" +reviewers: + - @njhale + - @benluddy + - @dmesser + - @exdx + - @Jamstah + - @bparees + - @ecordell +approvers: + - @dmesser + - @bparees + - @ecordell + - @krizza +creation-date: 2021-02-05 +last-updated: 2021-02-05 +status: implementable +--- + +# Package representation and management in an index + +## Release Signoff Checklist + +- [ ] Enhancement is `implementable` +- [ ] Design details are appropriately documented from clear requirements +- [ ] Test plan is defined +- [ ] Graduation criteria for dev preview, tech preview, GA + +## Summary + +This enhancement proposes the representation of packages in an index in a standard declarative way(using json/yaml), so that index authors and operator authors can communicate with each other about the content of an index using json/yaml files, without needing to communicate with each other using containers(index images, operator bundle images etc). Using the declarative representation of the packages in the index, it also proposes allowing index authors and individual package owners to alter the properties of the packages(package name, channel information etc) as well as the structure of the packages (upgrade graphs of channels etc) of the index without having to rebuild bundles+republish the index. Finally, it discusses using the representations as source of truth for serving data from the index over a gRPC api, instead of the sqllite database that is used currently, along with migration strategy for existing indexes from the sqllite databases to the package representations. + +## Motivation + +In the current state of the world, operators are introduced to operator-lifecycle-manager(OLM) by representing them as [Operator Bundles](https://github.com/operator-framework/operator-registry/blob/master/docs/design/operator-bundle.md#operator-bundle). These operator bundles are then loaded onto a container using the [opm](https://github.com/operator-framework/operator-registry/blob/master/docs/design/opm-tooling.md) tool (`opm index add --bundles`) to build an index of operators. Operator bundles conceptually belong to a channel in a package, with each bundle having the ability to upgrade to a different bundle in the channel. + +![Alt text](assets/community-operators.png?raw=true "community-operators") + +The way we describe the intent of a bundle to be on a particular channel in a package is by hard-coding that information in the [bundle annotations](https://github.com/operator-framework/operator-registry/blob/release-4.6/docs/design/operator-bundle.md#bundle-annotations) inside the bundle metadata itself. However, the channel that the bundle wants to be in is more of a package level information. Hard-coded channel information inside a bundle restricts a bundle in a particular channel once the bundle is built and loaded into an index. This makes it difficult to change channel info retroactively. When a bundle is added to an index using `opm`, the `mode` (one of `replaces`|`semver`|`semver-skippatch`) in which the bundle is added (`opm index add --bundles --mode `) determines the upgrade graph of bundles in the channel (which bundle can be upgrade to which). This upgrade graph for bundles in a channel can also not be changed retroactively. The only way to change the channel info, the upgrade graph or any package level information currently is to rebuild the bundles with the modified package information and then republish the index. This is done by making additive changes to the index using the`opm` tool. + +Furthermore, a lot of the rules about the structure of an index are implicitly documented in various sources that are scattered. A best effort is being made to keep the rules updated in the form of a library in the [api repo](https://github.com/operator-framework/api/tree/master/pkg/validation) that is imported by tools like `opm`, `operator-courier` etc that perform index validation. However, like all tools that aspire to provide data validation, these tools, or api libraries that these tools import the rules from, have to be constantly maintained to keep up with the latest rule changes, while also maintaining older rules in previous releases. This introduces a lot of overhead in ensuring that olm is easy to use by users, while also leaving windows for lapses due to mis-coordination between different tools across different versions. + +Since indexes are manipulated by making additive changes to it, the way an index can be reproduced today is by managing a knowledge base of the series of changes made to the index (i.e storing the `opm` commands chronologically) along with a set of intermediary container images of the index with their corresponding digest etc. This introduces a lot of overhead in maintaining indexes, and as a by product has significantly burdened the `opm` tool with feature requests to add an increasing number of sub-commands to allow index authors to manipulate their indexes in various ways. + +## Goals + +A human consumable representation of packages in an index in the form of json/yaml will: + +1. Allow for editing of package level information without rebuilding and republishing artifacts(remove bundle/s from a channel, switch bundle/s to a different channel, edit the upgrade graph in a channel etc). +2. Allow modification of upgrade graph for a package without needing to rebuild and republish the index the package belongs to(i.e combine packages from two indexes, create multiple indexes with packages from a single index, remove bundles from the index, switch channels bundles belong to etc). +3. Allow for validation of the structure of an index against a standard definition of an index. +4. Provide a way for index authors to reason about their indexes via a visual representation of the index, without having to curl a grpc api that in turn queries a sqllite database underneath, etc. +5. Provide a way for tools like `opm`, `operator-registry` etc to consume the content of an index without needing a sqlite database as an input whenever they need information about the index to perform a task. +6. Allow for reproducibility of an index using just the yaml/json representation of the index. + +## Non-goals + +1. Enumerate/implement tooling to allow different operations to be performed on the package representations. Numerous tooling(eg those that allow operation on files) that already exists can be leveraged to perform various operations on package representations. +2. Advanced tooling to verify dependency satisfiability for individual bundles, channel upgrade graph validity for each channel in a package etc. This will be considered in a separate enhancement. + +## User Stories + +### Story 1 + +As a user with pull permission from the namespace an index is hosted in/as a component of OLM, I can query an index for a json/yaml representation of the packages of an index. +The representation of individual packages will allow individual package owners to reason about/make changes to their individual packages in isolation. + +`opm index inspect --image=docker.io/my-namespace/community-operators --output=json` + +pulls the index image from the registry, creates a new folder `community-operators` and copies the package representations for the packages that are in the image to the local folder. + +```bash +$ cd community-operators +$ tree +. +├── etcd.json +├── amqstreams.json + +$ cat etcd.json +{ + "schema": "olm.package", + "name": "etcd", + "defaultChannel": "singlenamespace-alpha", + "icon": { + "base64data":"iVBORw0KGgoAAAANSUhEUgAAA.....", + "mediatype":"image/png" + }, + "channels": ["alpha", "singlenamespace-alpha", "clusterwide-alpha"], + "description": "A message about etcd operator, a description of channels" +}, +{ + "schema": "olm.bundle", + "name": "etcdoperator-community.v0.6.1", + "package": "etcd", + "image": "quay.io/operatorhubio/etcd:v0.6.1", + "version": "0.6.1", + "properties":[ + { + "name": "olm.package", + "values": { + "packageName": "etcd", + "version": "0.6.1" + } + }, + { + "name":"olm.gvk", + "type": "provided", + "values":{ + "group": "etcd.database.coreos.com", + "kind": "EtcdCluster", + "version": "v1beta2" + } + }, + { + "name": "olm.channel", + "value": "alpha" + } + ], + "relatedImages": [ + { + "name": "etcdv0.6.1", + "image": "quay.io/coreos/etcd-operator@sha256:bd944a211eaf8f31da5e6d69e8541e7cada8f16a9f7a5a570b22478997819943" + } + ] +}, +{ + "schema": "olm.bundle", + "name": "etcdoperator.v0.9.0", + "package": "etcd", + "image": "quay.io/operatorhubio/etcd:v0.9.0", + "version": "0.9.0", + "properties":[ + { + "name": "olm.package", + "values": { + "packageName": "etcd", + "version": "0.9.0" + } + }, + { + "name":"olm.gvk", + "type": "provided", + "values":{ + "group": "etcd.database.coreos.com", + "kind": "EtcdBackup", + "version": "v1beta2" + } + }, + { + "name": "olm.channel", + "value": "singlenamespace-alpha" + } + { + "name": "olm.channel", + "value": "clusterwide-alpha" + } + ], + "relatedImages" : [ + { + "name": "etcdv0.9.0", + "image": "quay.io/coreos/etcd-operator@sha256:db563baa8194fcfe39d1df744ed70024b0f1f9e9b55b5923c2f3a413c44dc6b8" + } + ] +}, +{ + "schema": "olm.bundle", + "name": "etcdoperator.v0.9.2", + "package": "etcd", + "image": "quay.io/operatorhubio/etcd:v0.9.2", + "version": "0.9.2", + "properties":[ + { + "name": "olm.package", + "values": { + "packageName": "etcd", + "version": "0.9.2" + } + }, + { + "name":"olm.gvk", + "type": "provided", + "values":{ + "group": "etcd.database.coreos.com", + "kind": "EtcdRestore", + "version": "v1beta2" + } + }, + { + "name": "olm.channel", + "value": "singlenamespace-alpha", + "replaces": "etcdoperator.v0.9.0" + } + ], + "relatedImages":[ + { + "name":"etcdv0.9.2", + "image": "quay.io/coreos/etcd-operator@sha256:c0301e4686c3ed4206e370b42de5a3bd2229b9fb4906cf85f3f30650424abec2" + } + ] +}, +{ + "schema": "olm.bundle", + "name": "etcdoperator.v0.9.2-clusterwide", + "package": "etcd", + "image": "quay.io/operatorhubio/etcd:v0.9.2-clusterwide", + "version": "0.9.2-clusterwide", + "properties":[ + { + "name": "olm.package", + "values": { + "packageName": "etcd", + "version": "0.9.2-clusterwide" + } + }, + { + "name":"olm.gvk", + "type": "provided", + "values":{ + "group": "etcd.database.coreos.com", + "kind": "EtcdBackup", + "version": "v1beta2" + } + }, + { + "name": "skipRange", + "value": ">=0.9.0 <0.9.2" + }, + { + "name": "skips", + "value" : "v0.12.2, v0.14.1" + }, + { + "name": "olm.channel", + "value": "clusterwide-alpha", + "replaces": "etcdoperator.v0.9.0" + } + ], + "relatedImages":[ + { + "name":"etcdv0.9.2", + "image":"quay.io/coreos/etcd-operator@sha256:c0301e4686c3ed4206e370b42de5a3bd2229b9fb4906cf85f3f30650424abec2" + } + ] +}, +{ + "schema": "olm.bundle", + "name" : "etcdoperator.v0.9.4", + "package": "etcd", + "image": "quay.io/operatorhubio/etcd:v0.9.4", + "version": "0.9.4", + "properties":[ + { + "name": "olm.package", + "values": { + "packageName": "etcd", + "version": "0.9.2-clusterwide" + } + }, + { + "name":"olm.gvk", + "type": "provided", + "values":{ + "group": "etcd.database.coreos.com", + "kind": "EtcdBackup", + "version": "v1beta2" + } + }, + { + "name":"olm.gvk", + "type": "required", + "values":{ + "group": "testapi.coreos.com", + "kind": "testapi", + "version": "v1" + } + }, + { + "name": "olm.channel", + "value": "singlenamespace-alpha", + "replaces": "etcdopertor.v0.9.2" + } + ], + "relatedImages":[ + { + "name":"etcdv0.9.2", + "image": "quay.io/coreos/etcd-operator@sha256:66a37fd61a06a43969854ee6d3e21087a98b93838e284a6086b13917f96b0d9b" + } + ] +}, +{ + "schema": "olm.bundle", + "name": "etcdoperator.v0.9.4-clusterwide", + "package": "etcd", + "image": "quay.io/operatorhubio/etcd:v0.9.4-clusterwide", + "version": "0.9.4-clusterwide", + "properties":[ + { + "name": "olm.package", + "values": { + "packageName": "etcd", + "version": "0.9.4-clusterwide" + } + }, + { + "name":"olm.gvk", + "type": "provided", + "values":{ + "group": "etcd.database.coreos.com", + "kind": "EtcdBackup", + "version": "v1beta2" + } + }, + { + "name": "olm.channel", + "value": "clusterwide-alpha", + "replaces": "etcdoperator.v0.9.2-clusterwide" + } + ], + "relatedImages":[ + { + "name":"etcdv0.9.2", + "image": "quay.io/coreos/etcd-operator@sha256:66a37fd61a06a43969854ee6d3e21087a98b93838e284a6086b13917f96b0d9b" + } + ] +} +``` + +### Story 2 + +As an index author(with push permission to the namespace my index is hosted in), I can edit the packages in my index (remove bundles from a package, move a bundle to a different channel, etc), using only the json representation of the index/packages inside the index. + +```bash +$ cd community-operators +$ //edit etcd.json to add etcdoperator.v0.9.0 to a the channel `alpha`, and add an upgrade edge from etcdoperator-community.v0.6.1 to etcdoperator.v0.9.0 in channel `alpha` +$ cd .. +$ opm index update community-operators --tag=docker.io/my-namespace/community-operators:latest +$ rm -rf community-operators +$ opm index inspect --image=docker.io/my-namespace/community-operators --output=json +$ cat community-operators/etcd.json +{ + "schema": "olm.package", + "name": "etcd", + "defaultChannel": "singlenamespace-alpha", + "icon": { + "base64data":"iVBORw0KGgoAAAANSUhEUgAAA.....", + "mediatype":"image/png" + }, + "channels": ["alpha", "singlenamespace-alpha", "clusterwide-alpha"], + "description": "A message about etcd operator, a description of channels" +}, +{ + "schema": "olm.bundle", + "name": "etcdoperator-community.v0.6.1", + "package": "etcd", + "image": "quay.io/operatorhubio/etcd:v0.6.1", + "version": "0.6.1", + "properties":[ + { + "name": "olm.package", + "values": { + "packageName": "etcd", + "version": "0.6.1" + } + }, + { + "name":"olm.gvk", + "type": "provided", + "values":{ + "group": "etcd.database.coreos.com", + "kind": "EtcdCluster", + "version": "v1beta2" + } + }, + { + "name": "olm.channel", + "value": "alpha" + } + ], + "relatedImages": [ + { + "name": "etcdv0.6.1", + "image": "quay.io/coreos/etcd-operator@sha256:bd944a211eaf8f31da5e6d69e8541e7cada8f16a9f7a5a570b22478997819943" + } + ] +}, +{ + "schema": "olm.bundle", + "name": "etcdoperator.v0.9.0", + "package": "etcd", + "image": "quay.io/operatorhubio/etcd:v0.9.0", + "version": "0.9.0", + "properties":[ + { + "name": "olm.package", + "values": { + "packageName": "etcd", + "version": "0.9.0" + } + }, + { + "name":"olm.gvk", + "type": "provided", + "values":{ + "group": "etcd.database.coreos.com", + "kind": "EtcdBackup", + "version": "v1beta2" + } + }, + { + "name": "olm.channel", + "value": "alpha", + "replaces":"etcdoperator-community.v0.6.1" + }, + { + "name": "olm.channel", + "value": "singlenamespace-alpha" + }, + { + "name": "olm.channel", + "value": "clusterwide-alpha" + } + ], + "relatedImages" : [ + { + "name": "etcdv0.9.0", + "image": "quay.io/coreos/etcd-operator@sha256:db563baa8194fcfe39d1df744ed70024b0f1f9e9b55b5923c2f3a413c44dc6b8" + } + ] +}, +. +. +. +. +``` + +Similarly, removing a `.json` from `community-operators` and pushing that update up to the container image removes the operator from the index. + +### Story 3 + +As a user with pull permission from the namespace an index is hosted in/as a component of OLM, I can validate the structure of the content of an index using the json representation. + +```bash +$ cd community-operators +$ sed '/defaultChannel/d' etcd.json > etcd.json //delete the line "defaultChannel":"singlenamespace-alpha" +$ git status + modified: etcd.json + +$ cd .. +$ opm index validate community-operators +marshal error: etcd.defaultchannel: cannot convert incomplete value "string" to JSON +$ opm index update community-operator --tag=docker.io/mynamespace/community-operators:latest +$ opm index validate docker.io/mynamespace/community-operators:latest +marshal error: etcd.defaultchannel: cannot convert incomplete value "string" to JSON +$ cd community-operators +$ git checkout etcd.json +$ cd .. +$ opm index validate community-operators +No errors found! +``` + +### Story 4 + +Given a set of package representations, I can author a new index using just those representations. + +```bash +$ tree community-operators +community-operators +├── amqstreams.json +└── etcd.json +└── servicemesh.json +$ rm community-operators/servicemesh.json +$ opm index create --from=community-operators --tag=docker.io/someothernamespace/new-community-operators:latest +``` +## Implementation Details +### Representing a package using json/yaml + +The representation of the content of an index using json/yaml provides a unique opportunity to rethink the structure of an index conceptually. + +![Alt text](assets/new-community-operators.png?raw=true "community-operators") + +Since each bundle in the index belongs to a channel in a package, the index itself can be represented as a collection of packages. Each package is then represented as a json/yaml, a config file that will live inside the index container image alongside the individual bundle metadata. + +#### Contents of the config file + +The config file for each package will have a stream of json objects, representing the package and bundle information for that package. Currently, this information is stored in a sql database inside the index. To capture all the information previously stored in this database but in a normalized way, the config file will have two kinds of json blob: + +1. The json blob capturing package information. +```json +{ + "schema": "olm.package", + "name": "", + "defaultChannel": "", + "icon": "embedded or remote", + "channels": [""], + "description": "A message about the operator, a description of channels..." +} +``` +This information is currently captured in the `package` table. + +2. The json blob capturing the bundle information. +```json +{ + "schema": "olm.bundle", + "name": "", + "package": "", + "image": "", + "version": "", + "properties":[""], + "relatedImages" : [""] +} + +``` + +This information is currently captured in the `operatorbundle`, `properties`, `channel`, `channel_entry`, `api`, `api_provider`, `api_requirer` and `related_image` tables in the sql database. + +#### Representing the upgrade graph in the channel json blob + +Currently, a bundle can be added into the index using `opm index add --bundles --mode replaces|semver|semver-skippatch --tag=` where the bundle images (like `quay.io/operatorhubio/etcd:v0.9.0`) are included in ``. The bundle can also mention bundles it can be upgrade from using the `skips` or `skipRange` fields in the bundle ClusterServiceVersion. With all of these information provided, the upgrade graph of the bundles in the package is calculated and stored in the `channel_entry` table of the sql database that is built inside the index, while the `skips`/`skipRange` information is persisted in the `operatorbundle` table. The `channel_entry` table is always authoritative in terms of calculating the upgrade graph in a package. The operatorbundle table persists the values of `skips`/`skipRange`/`replaces` when the bundle was first unpacked/added to the index, and other index operations could have changed the real graph in `channel_entry`. + +```bash +sqlite> .schema channel_entry +CREATE TABLE channel_entry ( + entry_id INTEGER PRIMARY KEY, + channel_name TEXT, + package_name TEXT, + operatorbundle_name TEXT, + replaces INTEGER, + depth INTEGER, + FOREIGN KEY(replaces) REFERENCES channel_entry(entry_id) DEFERRABLE INITIALLY DEFERRED, + FOREIGN KEY(channel_name, package_name) REFERENCES channel(name, package_name) ON DELETE CASCADE + ); +sqlite> select * from channel_entry where package_name="etcd"; + +entry_id channel_name package_name operatorbundle_name replaces depth +-------- --------------------- ------------ ------------------------------- -------- ----- +1818 alpha etcd etcdoperator-community.v0.6.1 0 +1819 clusterwide-alpha etcd etcdoperator.v0.9.4-clusterwide 1820 0 +1820 clusterwide-alpha etcd etcdoperator.v0.9.2-clusterwide 1821 1 +1821 clusterwide-alpha etcd etcdoperator.v0.9.0 2 +1822 singlenamespace-alpha etcd etcdoperator.v0.9.4 1823 0 +1823 singlenamespace-alpha etcd etcdoperator.v0.9.2 1824 1 +1824 singlenamespace-alpha etcd etcdoperator.v0.9.0 2 + +.schema operatorbundle +CREATE TABLE operatorbundle ( + name TEXT PRIMARY KEY, + csv TEXT, + bundle TEXT, + bundlepath TEXT, skiprange TEXT, version TEXT, replaces TEXT, skips TEXT); + +sqlite> select name,bundlepath,version,skiprange,skips,replaces from operatorbundle where name like 'etcd%'; + +name bundlepath version skiprange skips replaces +------------------------------- --------------------------------------------- ----------------- --------- ----- ------------------------------- +etcdoperator.v0.9.0 quay.io/operatorhubio/etcd:v0.9.0 0.9.0 +etcdoperator-community.v0.6.1 quay.io/operatorhubio/etcd:v0.6.1 0.6.1 +etcdoperator.v0.9.2-clusterwide quay.io/operatorhubio/etcd:v0.9.2-clusterwide 0.9.2-clusterwide etcdoperator.v0.9.0 +etcdoperator.v0.9.2 quay.io/operatorhubio/etcd:v0.9.2 0.9.2 etcdoperator.v0.9.0 +etcdoperator.v0.9.4-clusterwide quay.io/operatorhubio/etcd:v0.9.4-clusterwide 0.9.4-clusterwide etcdoperator.v0.9.2-clusterwide +etcdoperator.v0.9.4 quay.io/operatorhubio/etcd:v0.9.4 0.9.4 etcdoperator.v0.9.2 +``` + +This information will be captured in the `properties.<"olm.channel">.replaces`, `properties.skips` and `properties.skipRange` of the `olm.bundle` blob. In the `properties.<"olm.channel">` object for each channel, the bundle that replaces a previous bundle is captured in the `replaces` field. An upgrade edge in a channel is represented by: bundle.properties<"olm.channel">.replaces <- bundle name. + +#### Creating the json/yaml config file to represent a package + +The `opm index add` command will be enhanced to create a config file for representing the package the bundle is being added to if it is the first bundle in the package that is being added to this index. If the package the bundle is being added to already exists, the `olm.bundle` blob for the bundle will be added to the existing package config file. + +```bash +$ opm index inspect --image=docker.io/my-namespace/community-operators:latest --output=json +$ tree community-operators +. +├── etcd.json + +$ cat community-operators/etcd.json +[ + { + "schema": "olm.package", + "name": "etcd", + "defaultChannel": "singlenamespace-alpha", + "icon": { + "base64data":"iVBORw0KGgoAAAANSUhEUgAAA.....", + "mediatype":"image/png" + }, + "channels": ["alpha"], + "description": "A message about etcd operator, a description of channels" + }, + { + "schema": "olm.bundle", + "name": "etcdoperator-community.v0.6.1", + "package": "etcd", + "image": "quay.io/operatorhubio/etcd:v0.6.1", + "version": "0.6.1", + "properties":[ + { + "name": "olm.package", + "values": { + "packageName": "etcd", + "version": "0.6.1" + } + }, + { + "name":"olm.gvk", + "type": "provided", + "values":{ + "group": "etcd.database.coreos.com", + "kind": "EtcdCluster", + "version": "v1beta2" + } + }, + { + "name": "olm.channel", + "value": "alpha", + } + ], + "relatedImages": [ + { + "name": "etcdv0.6.1", + "image": "quay.io/coreos/etcd-operator@sha256:bd944a211eaf8f31da5e6d69e8541e7cada8f16a9f7a5a570b22478997819943" + } + ] + } +] +$ opm index add --bundles quay.io/operatorhubio/etcd:v0.9.0 --mode replaces --tag docker.io/my-namespace/community-operators:latest +$ docker push docker.io/my-namespace/community-operators:latest +$ opm index inspect --image=docker.io/my-namespace/community-operators:latest --output=json +$ cat community-operators/etcd.json +[ + { + "schema": "olm.package", + "name": "etcd", + "defaultChannel": "singlenamespace-alpha", + "icon": { + "base64data":"iVBORw0KGgoAAAANSUhEUgAAA.....", + "mediatype":"image/png" + }, + "channels": ["alpha", "singlenamespace-alpha"], + "description": "A message about etcd operator, a description of channels" + }, + { + "schema": "olm.bundle", + "name": "etcdoperator-community.v0.6.1", + "package": "etcd", + "image": "quay.io/operatorhubio/etcd:v0.6.1", + "version": "0.6.1", + "properties":[ + { + "name": "olm.package", + "values": { + "packageName": "etcd", + "version": "0.6.1" + } + }, + { + "name":"olm.gvk", + "type": "provided", + "values":{ + "group": "etcd.database.coreos.com", + "kind": "EtcdCluster", + "version": "v1beta2" + } + }, + { + "name": "olm.channel", + "value": "alpha", + } + ], + "relatedImages": [ + { + "name": "etcdv0.6.1", + "image": "quay.io/coreos/etcd-operator@sha256:bd944a211eaf8f31da5e6d69e8541e7cada8f16a9f7a5a570b22478997819943" + } + ] + }, + { + "schema": "olm.bundle", + "name": "etcdoperator.v0.9.0", + "package": "etcd", + "image": "quay.io/operatorhubio/etcd:v0.9.0", + "version": "0.9.0", + "properties":[ + { + "name": "olm.package", + "values": { + "packageName": "etcd", + "version": "0.9.0" + } + }, + { + "name":"olm.gvk", + "type": "provided", + "values":{ + "group": "etcd.database.coreos.com", + "kind": "EtcdBackup", + "version": "v1beta2" + } + }, + { + "name": "olm.channel", + "value": "singlenamespace-alpha", + } + ], + "relatedImages" : [ + { + "name": "etcdv0.9.0", + "image": "quay.io/coreos/etcd-operator@sha256:db563baa8194fcfe39d1df744ed70024b0f1f9e9b55b5923c2f3a413c44dc6b8" + } + ] + } +] +``` + +The `opm index add` command will also be enhanced to create `olm.bundle` json blobs for bundles passed onto the command along with a package config file, and append them to the config file. + +```bash +$ cat community-operators/etcd.json +{ + "schema": "olm.package", + "name": "etcd", + "defaultChannel": "singlenamespace-alpha", + "icon": { + "base64data":"iVBORw0KGgoAAAANSUhEUgAAA.....", + "mediatype":"image/png" + }, + "channels": ["alpha"], + "description": "A message about etcd operator, a description of channels" +}, +{ + "schema": "olm.bundle", + "name": "etcdoperator-community.v0.6.1", + "package": "etcd", + "image": "quay.io/operatorhubio/etcd:v0.6.1", + "version": "0.6.1", + "properties":[ + { + "name": "olm.package", + "values": { + "packageName": "etcd", + "version": "0.6.1" + } + }, + { + "name":"olm.gvk", + "type": "provided", + "values":{ + "group": "etcd.database.coreos.com", + "kind": "EtcdCluster", + "version": "v1beta2" + } + }, + { + "name":"olm.channel", + "value": "alpha" + } + ], + "relatedImages": [ + { + "name": "etcdv0.6.1", + "image": "quay.io/coreos/etcd-operator@sha256:bd944a211eaf8f31da5e6d69e8541e7cada8f16a9f7a5a570b22478997819943" + } + ] +} +$ opm index add --bundles quay.io/operatorhubio/etcd:v0.9.0 --mode replaces --config community-operators/etcd +$ cat community-operators/etcd.json +{ + "schema": "olm.package", + "name": "etcd", + "defaultChannel": "singlenamespace-alpha", + "icon": { + "base64data":"iVBORw0KGgoAAAANSUhEUgAAA.....", + "mediatype":"image/png" + }, + "channels": ["alpha", "singlenamespace-alpha"], + "description": "A message about etcd operator, a description of channels" +}, +{ + "schema": "olm.bundle", + "name": "etcdoperator-community.v0.6.1", + "package": "etcd", + "image": "quay.io/operatorhubio/etcd:v0.6.1", + "version": "0.6.1", + "properties":[ + { + "name": "olm.package", + "values": { + "packageName": "etcd", + "version": "0.6.1" + } + }, + { + "name":"olm.gvk", + "type": "provided", + "values":{ + "group": "etcd.database.coreos.com", + "kind": "EtcdCluster", + "version": "v1beta2" + } + }, + { + "name":"olm.channel", + "value": "alpha" + } + ], + "relatedImages": [ + { + "name": "etcdv0.6.1", + "image": "quay.io/coreos/etcd-operator@sha256:bd944a211eaf8f31da5e6d69e8541e7cada8f16a9f7a5a570b22478997819943" + } + ] +}, +{ + "schema": "olm.bundle", + "name": "etcdoperator.v0.9.0", + "package": "etcd", + "image": "quay.io/operatorhubio/etcd:v0.9.0", + "version": "0.9.0", + "properties":[ + { + "name": "olm.package", + "values": { + "packageName": "etcd", + "version": "0.9.0" + } + }, + { + "name":"olm.gvk", + "type": "provided", + "values":{ + "group": "etcd.database.coreos.com", + "kind": "EtcdBackup", + "version": "v1beta2" + } + }, + { + "name":"olm.channel", + "value": "singlenamespace-alpha" + } + ], + "relatedImages" : [ + { + "name": "etcdv0.9.0", + "image": "quay.io/coreos/etcd-operator@sha256:db563baa8194fcfe39d1df744ed70024b0f1f9e9b55b5923c2f3a413c44dc6b8" + } + ] +} +``` + +### Using the package json representation + +Once every package inside an index is represented using a json/yaml config file, the config files can be leveraged to inspect/update/validate the packages inside the index without needing to rebuild the index from scratch. +#### Inspecting the packages inside an index + +A new sub-command `inspect` will be introduced under `opm index`. + +When `opm index inspect` is summoned, the index image will be downloaded, and the json representations of the packages inside the index will be unfurled in a folder with the same name as the index. + +```bash +$ opm index inspect --image=docker.io/my-namespace/community-operators --output=json +$ cd community-operators +$ tree +. +├── etcd.json +├── amqstreams.json +``` +#### Editing a package inside an index + +A new sub-command `update` will be introduced under `opm index`, which will take a folder containing json representations of packages as it's input along with an existing index image tag, and will replace the edited config files in the index container. + +```bash +$ opm index inspect --image=quay.io/some-namespace/my-index +$ // edit a my-index/package-config.json +$ opm index update my-index --tag=docker.io/some-namespace/my-index:latest +``` + +> Note: For a seamless UX, the following things should be consider during implementation when the `opm index update` command is summoned: +> 1. Validate the files inside the folder given as input to the command to ensure they are valid json representation of packages (and not random files with random content, which could be potential security risks) +> 2. If the files are valid, take a git diff between the present content of the index (i.e the existing json representations) and the content of the folder given as input. Display the diff as an output of the command with the following message +> "The following changes will be updated in the index:" +> If there is no diff between the content in the container image and the content of the local folder, throw an error with the message "No diff found between index and local content to update." + + +#### Creating new indexes using the config files from an existing index + +A new sub-command `create` will be introduced under `opm index`, that will take a folder containing json/yaml representation of packages, and a container image tag as input. The sub-command will create a new index container, walk the tree of files to find the json representations and store them in the container. + +```bash +$ tree community-operators +community-operators +├── amqstreams.json +└── etcd.json +$ opm index create --from=community-operators --tag=docker.io/some-namespace/community-operators +``` + +#### Validating a package inside the index + +A new sub-command `validate` will be introduced under `opm index`, that will validate the content of each package's json representation. These validations will be in the context of rules about the structure of a package config in an index (required fields, naming conventions etc). A best effort is currently being made to aggregate these rules from various sources and maintained in the [api project's validation library](https://github.com/operator-framework/api/tree/master/pkg/validation). The `opm index validate` will be responsible for validating the index for authors to make sure that the packages in the index conforms to these rules. + +#### Usage of the json representation of packages by olm components + +The sqllite database that is currently created inside the index is used to serve contents of the index over a gRPC api. + +```go +rpc ListPackages(ListPackageRequest) returns (stream PackageName) {} +rpc GetPackage(GetPackageRequest) returns (Package) {} +rpc GetBundle(GetBundleRequest) returns (Bundle) {} +rpc GetBundleForChannel(GetBundleInChannelRequest) returns (Bundle) {} +rpc GetChannelEntriesThatReplace(GetAllReplacementsRequest) returns (stream ChannelEntry) {} +rpc GetBundleThatReplaces(GetReplacementRequest) returns (Bundle) {} +rpc GetChannelEntriesThatProvide(GetAllProvidersRequest) returns (stream ChannelEntry) {} +rpc GetLatestChannelEntriesThatProvide(GetLatestProvidersRequest) returns (stream ChannelEntry) {} +rpc GetDefaultBundleThatProvides(GetDefaultProviderRequest) returns (Bundle) {} +rpc ListBundles(ListBundlesRequest) returns (stream Bundle) {} +``` + +Once the declarative package configs are available inside an index, these configs will be used to serve the content for these api endpoints instead of the sqllite database. A new flag `config` will be introduced under `opm registry serve` that will take an aggregated config file as input, and use that file to serve the grpc endpoints (instead of `registry serve --database index.db`). + + +## Migration Plan + +The index images that exists today have the sqllite database in them, and have been built with the following Docker configuration: + +```Dockerfile +ENTRYPOINT ["/bin/opm"] +CMD ["registry", "serve", "--database", "/database/index.db"] +``` + +Since the new `opm` binary will create configs on `add`, the new images will be built with the new configuration: + +```Dockerfile +ENTRYPOINT ["/bin/opm"] +CMD ["registry", "serve", "--config", "config.json"] +``` + +To migrate existing index images built with the old configuration, all existing `opm index` commands that alter the index (i,e `opm index add --from-index`, `opm index prune`, `opm index prune-stranded` and `opm index rm`) will be enhanced to first let the corresponding operation through, and then check if the sqllite database exists in the index. If it does, the sqllite database will be converted over to package representations instead, the sqllite database will be deleted, and the new altered image will be built using the new configuration. `prune`, `prune-stranded` and `rm` sub-commands under the `opm index` command will also be marked for deprecation. If these sub-commands are used on an index that has already been migrated over to package representations, the operations will still be supported on these indexes with package representations for the period of time these sub-commands are marked as deprecated, until they are removed. + +The `opm registry` command contains the same sub-commands as that of `opm index` (`add`, `prune`, `prune-stranded` and `rm`), but accepts a database file with the `--database` flag that it operators on (instead of a container image like the `opm index` command). A new flag `config` will be introduced under `opm registry` that will accept an aggregated `config.json` file that contains the declarative representation of all the packages inside the index. All existing sub-commands of `opm registry` will be continued to be supported for performing operations on the declarative representations using the new `config` flag. The ability to perform `add`, `prune`, `prune-stranded` and `rm` using the `--database` flag will be removed. The only `opm registry` command that will continue to be supported using the `--database` flag is the `serve` command, which will also be marked for deprecation. + +## Test plan + +* New tests that test the behavior of the `add`, `update`, `create`, `validate` sub-commands for `opm index` will be added to `opm`. + +* Since the configs will be used to serve content of the index over the gRPC api instead of the sqllite database, passing of the existing portfolio of tests for the api endpoints listed above will serve as proof that the configs provide the same data as the sqllite database used to, once the switch is made to serve content with the configs. + +