Skip to content

Commit

Permalink
Merge pull request #1215 from njhale/unpack-bundles
Browse files Browse the repository at this point in the history
Unpack bundles
  • Loading branch information
openshift-merge-robot committed Jan 10, 2020
2 parents 7053452 + 4cef16c commit 2b93a4b
Show file tree
Hide file tree
Showing 439 changed files with 43,605 additions and 3,991 deletions.
17 changes: 1 addition & 16 deletions cmd/catalog/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,11 @@ import (
"fmt"
"net/http"
"os"
"strings"
"time"

configv1client "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1"
"github.com/prometheus/client_golang/prometheus/promhttp"
log "github.com/sirupsen/logrus"
v1 "k8s.io/api/core/v1"
utilclock "k8s.io/apimachinery/pkg/util/clock"
"k8s.io/client-go/tools/clientcmd"

Expand Down Expand Up @@ -44,9 +42,6 @@ var (
wakeupInterval = flag.Duration(
"interval", defaultWakeupInterval, "wakeup interval")

watchedNamespaces = flag.String(
"watchedNamespaces", "", "comma separated list of namespaces that catalog watches, leave empty to watch all namespaces")

catalogNamespace = flag.String(
"namespace", defaultCatalogNamespace, "namespace where catalog will run and install catalog resources")

Expand Down Expand Up @@ -91,16 +86,6 @@ func main() {
os.Exit(0)
}

// `namespaces` will always contain at least one entry: if `*watchedNamespaces` is
// the empty string, the resulting array will be `[]string{""}`.
namespaces := strings.Split(*watchedNamespaces, ",")
for _, ns := range namespaces {
if ns == v1.NamespaceAll {
namespaces = []string{v1.NamespaceAll}
break
}
}

logger := log.New()
if *debug {
logger.SetLevel(log.DebugLevel)
Expand Down Expand Up @@ -183,7 +168,7 @@ func main() {
}

// Create a new instance of the operator.
op, err := catalog.NewOperator(ctx, *kubeConfigPath, utilclock.RealClock{}, logger, *wakeupInterval, *configmapServerImage, *catalogNamespace, namespaces...)
op, err := catalog.NewOperator(ctx, *kubeConfigPath, utilclock.RealClock{}, logger, *wakeupInterval, *configmapServerImage, *catalogNamespace)
if err != nil {
log.Panicf("error configuring operator: %s", err.Error())
}
Expand Down
81 changes: 81 additions & 0 deletions deploy/chart/templates/0000_50_olm_04-installplan.crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,87 @@ spec:
uid:
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
type: string
bundleLookups:
type: array
items:
type: object
required:
- catalogSourceRef
- path
- replaces
properties:
catalogSourceRef:
description: ObjectReference contains enough information to let
you inspect or modify the referred object.
type: object
properties:
apiVersion:
description: API version of the referent.
type: string
fieldPath:
description: 'If referring to a piece of an object instead
of an entire object, this string should contain a valid
JSON/Go field access statement, such as desiredState.manifest.containers[2].
For example, if the object reference is to a container within
a pod, this would take on a value like: "spec.containers{name}"
(where "name" refers to the name of the container that triggered
the event) or if no container name is specified "spec.containers[2]"
(container with index 2 in this pod). This syntax is chosen
only to have some well-defined way of referencing a part
of an object. TODO: this design is not final and this field
is subject to change in the future.'
type: string
kind:
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
type: string
namespace:
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
type: string
resourceVersion:
description: 'Specific resourceVersion to which this reference
is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
type: string
uid:
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
type: string
conditions:
type: array
items:
type: object
required:
- status
- type
properties:
lastTransitionTime:
description: Last time the condition transitioned from one
status to another.
type: string
format: date-time
lastUpdateTime:
description: Last time the condition was probed
type: string
format: date-time
message:
description: A human readable message indicating details
about the transition.
type: string
reason:
description: The reason for the condition's last transition.
type: string
status:
description: Status of the condition, one of True, False,
Unknown.
type: string
type:
description: Type of condition.
type: string
path:
type: string
replaces:
type: string
catalogSources:
type: array
items:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@ spec:
command:
- /bin/catalog
args:
{{- if .Values.watchedNamespaces }}
- -watchedNamespaces
- {{ .Values.watchedNamespaces }}
{{- end }}
- '-namespace'
- {{ .Values.catalog_namespace }}
{{- if .Values.debug }}
Expand Down
92 changes: 92 additions & 0 deletions doc/design/resolving-bundle-images.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Resolving Bundle Images

An operator [UpdateGraph](https://operator-framework.github.io/olm-book/docs/glossary.html#upgrade-graph) may refer to an operator [Bundle](https://operator-framework.github.io/olm-book/docs/glossary.html#bundle) with a reference to a [Bundle Image](https://operator-framework.github.io/olm-book/docs/glossary.html#bundle-image) containing its content. This means that the content of these referenced bundles is not immediately available for application to a cluster and must first be pulled and unpacked.

## Resolving

The same metadata available for bundles queried from a [`CatalogSource`](https://operator-framework.github.io/olm-book/docs/glossary.html#catalogsources) is available for bundle images. This lets OLM resolve dependencies and updates without pulling them to the cluster. Once the final set of operators has been identified for install, OLM codifies the information needed to pull any included bundle images in the `status.BundleLookups` field of the resulting `InstallPlan`:

```yaml
status:
bundleLookups:
- path: quay.io/coreos/prometheus-operator@sha256...
replaces: ""
catalogSourceRef:
Namespace: operators
Name: monitoring
```

## Unpacking

OLM uses the `status.bundleLookups` field, added to `InstallPlans` during dependency resolution, to determine which bundle images need to be unpacked.

Given an `InstallPlan` with the following `status`:

```yaml
status:
bundleLookups:
- path: quay.io/coreos/prometheus-operator@sha256...
replaces: ""
catalogSourceRef:
Namespace: operators
Name: monitoring
- path: quay.io/coreos/etcd-operator@sha256...
replaces: "etcd-operator.v4.1"
catalogSourceRef:
Namespace: operators
Name: storage
```

__Note:__ Image tag references may be used in place of digests, but once a tag has been unpacked, updates to the underlying image will not be respected unless the resources described below are deleted._

Each unique `BundlePath` will result in OLM creating four top-level resources in the namespace of the referenced `CatalogSource`:

1. A `ConfigMap` to hold the unpacked manifests
2. A `Role` allowing `create`, `get`, and `update` on that `ConfigMap`
3. A `RoleBinding` granting that `Role` to the default `ServiceAccount`
4. An unpack `Job` using the default `ServiceAccount` to export the bundle image's content into that `ConfigMap`

OLM uses the same reproducible name for all of these resources; the `sha256` checksum of the respective `BundlePath`.

__Note:__ _This choice of name allows OLM to reuse previously unpacked bundles between `InstallPlans` by making them discoverable and ensuring resource uniqueness._

The `Role`, `RoleBinding`, and `Job` have `OwnerReferences` to the `ConfigMap`, while the `ConfigMap` has an `OwnerReference` to the `CatalogSource` referenced by its respective `BundleLookup`. If the referenced `CatalogSource` is not found, a `BundleLookupPending` condition is added to the `BundleLookup`:

```yaml
path: quay.io/coreos/prometheus-operator@sha256...
replaces: ""
catalogSourceRef:
Namespace: operators
Name: monitoring
conditions:
type: BundleLookupPending
status: "True"
reason: CatalogSourceMissing
message: "referenced catalogsource not found"
lastTransitionTime: "2020-01-08T23:42:59Z"
```

A given unpack `Job` will start a `Pod` consisting of two containers:

1. An init container that has a release of the [`opm`](https://github.com/operator-framework/operator-registry/tree/master/cmd/opm) binary
2. A container from the bundle image reference

These two containers share a volume mount into which the init container copies its `opm` binary. After initalization, the bundle image container uses this copy to execute the `opm bundle extract` command, extracting the bundle content from its filesystem into the bundle's respective `ConfigMap`.

When an unpack `Job` exists but is not in a `Complete` state, a `BundleLookupPending` condition is added to its `BundleLookup`:

```yaml
path: quay.io/coreos/prometheus-operator@sha256...
replaces: ""
catalogSourceRef:
Namespace: operators
Name: monitoring
conditions:
type: BundleLookupPending
status: "True"
reason: JobIncomplete
message: "unpack job not completed"
lastTransitionTime: "2020-01-08T23:43:30Z"
```

Once an unpack `Job` runs to completion, the data in the respective `ConfigMap` is converted into a set of install steps and is added to the status the `InstallPlan`. In the same transaction, the `BundleLookup` entry is removed.
27 changes: 12 additions & 15 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,52 +8,49 @@ require (
github.com/coreos/go-semver v0.3.0
github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a // indirect
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect
github.com/emicklei/go-restful v2.9.6+incompatible // indirect
github.com/evanphx/json-patch v4.5.0+incompatible // indirect
github.com/fsnotify/fsnotify v1.4.7
github.com/ghodss/yaml v1.0.0
github.com/go-openapi/spec v0.19.2
github.com/golang/groupcache v0.0.0-20181024230925-c65c006176ff // indirect
github.com/go-openapi/spec v0.19.4
github.com/golang/mock v1.3.1
github.com/google/btree v1.0.0 // indirect
github.com/googleapis/gnostic v0.3.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 // indirect
github.com/grpc-ecosystem/grpc-gateway v1.9.4 // indirect
github.com/maxbrunsfeld/counterfeiter/v6 v6.2.1
github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2
github.com/mikefarah/yq/v2 v2.4.1
github.com/mitchellh/hashstructure v1.0.0
github.com/munnerz/goautoneg v0.0.0-20190414153302-2ae31c8b6b30 // indirect
github.com/openshift/api v3.9.1-0.20190924102528-32369d4db2ad+incompatible
github.com/openshift/client-go v0.0.0-20190923180330-3b6373338c9b
github.com/operator-framework/operator-registry v1.5.3
github.com/operator-framework/operator-registry v1.5.6
github.com/pkg/errors v0.8.1
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829
github.com/prometheus/client_golang v1.2.1
github.com/sirupsen/logrus v1.4.2
github.com/soheilhy/cmux v0.1.4 // indirect
github.com/spf13/cobra v0.0.5
github.com/stretchr/testify v1.4.0
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4
golang.org/x/time v0.0.0-20191024005414-555d28b269f0
gonum.org/v1/gonum v0.0.0-20190710053202-4340aa3071a0 // indirect
google.golang.org/grpc v1.23.0
k8s.io/api v0.0.0
google.golang.org/grpc v1.24.0
k8s.io/api v0.17.0
k8s.io/apiextensions-apiserver v0.0.0
k8s.io/apimachinery v0.0.0
k8s.io/apimachinery v0.17.0
k8s.io/apiserver v0.0.0
k8s.io/client-go v8.0.0+incompatible
k8s.io/code-generator v0.0.0
k8s.io/component-base v0.0.0
k8s.io/klog v0.4.0
k8s.io/klog v1.0.0
k8s.io/kube-aggregator v0.0.0
k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf
k8s.io/kube-openapi v0.0.0-20190918143330-0270cf2f1c1d
k8s.io/kubernetes v1.16.0
sigs.k8s.io/controller-tools v0.2.4
)

replace (
github.com/docker/docker => github.com/moby/moby v0.7.3-0.20190826074503-38ab9da00309 // Required by Helm
github.com/openshift/api => github.com/openshift/api v3.9.1-0.20190924102528-32369d4db2ad+incompatible
github.com/openshift/client-go => github.com/openshift/client-go v0.0.0-20190923180330-3b6373338c9b
github.com/prometheus/client_golang => github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829

// Pin to kube 1.16
k8s.io/api => k8s.io/api v0.0.0-20190918155943-95b840bb6a1f
Expand Down

0 comments on commit 2b93a4b

Please sign in to comment.