Skip to content

Commit 45f78d6

Browse files
authored
Merge pull request #1054 from tkashem/proposal
[WIP] (proposal) Make bundle accessible to a cluster
2 parents 28e4f25 + ca8efed commit 45f78d6

File tree

1 file changed

+131
-0
lines changed

1 file changed

+131
-0
lines changed
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# Pull Bundle on a Cluster
2+
3+
The purpose of this proposal is to allow bundle data to be pulled at install time. At a high level, this starts with launching the bundle inside a pod and then writing the data found inside of the container into a configmap.
4+
5+
## Launching a bundle image for data extraction
6+
7+
The function to call for launching the bundle looks like:
8+
9+
LaunchBundleImage(kubeclient kubernetes.Interface, bundleImage, initImage, namespace string) (*corev1.ConfigMap, *batchv1.Job, error)
10+
11+
Here the bundle image, init image, and namespace are the core parameters. Note that it is a requirement that the service account have permissions to update configmaps in the specified namespace. In the expected usage however, the namespace of OLM will be used and permissions will not be a problem. The configmap and job are returned for the caller to delete when done.
12+
13+
Within the launch function a job is called using a spec simliar to what is described below. Unique random names are able to be depended upon by using generateName for both the job and configmap.
14+
15+
```yaml
16+
apiVersion: batch/v1
17+
kind: Job
18+
metadata:
19+
generateName: deploy-bundle-image-
20+
spec:
21+
#ttlSecondsAfterFinished: 0 # alpha feature - https://github.com/kubernetes/enhancements/issues/592, https://github.com/kubernetes/kubernetes/pull/82082
22+
template:
23+
metadata:
24+
name: bundle-image
25+
spec:
26+
containers:
27+
- name: bundle-image
28+
image: &image bundle-image
29+
command: ['/injected/operator-registry', 'serve']
30+
env:
31+
- name: CONTAINER_IMAGE
32+
value: *image
33+
volumeMounts:
34+
- name: copydir
35+
mountPath: /injected
36+
initContainers:
37+
- name: copy-binary
38+
image: init-operator-manifest
39+
imagePullPolicy: Never
40+
command: ['/bin/cp', '/operator-registry', '/copy-dest']
41+
volumeMounts:
42+
- name: copydir
43+
mountPath: /copy-dest
44+
volumes:
45+
- name: copydir
46+
emptyDir: {}
47+
restartPolicy: OnFailure
48+
```
49+
50+
## Serving the bundle data
51+
52+
A new command will be made in operator-registry to provide functionality for traversing the directies of the bundle image for writing to a configmap (example above is "operator-registry serve"). The configmap format is described in more detail in the next section. The pre-generated configmap name is specified to be updated with the bundle data. As previously noted, after the configmap data has been read it is the responsibility of the caller to delete both the job and configmap. As a sanity check, the configmap is also updated with the image name as an annotation (olm.imageSource).
53+
54+
## Store a bundle in a `ConfigMap`
55+
Below is the directory layout of the operator bundle inside the image.
56+
```bash
57+
$ tree
58+
/
59+
├── manifests
60+
│ ├── testbackup.crd.yaml
61+
│ ├── testcluster.crd.yaml
62+
│ ├── testoperator.v0.1.0.clusterserviceversion.yaml
63+
│ └── testrestore.crd.yaml
64+
└── metadata
65+
└── annotations.yaml
66+
67+
$ cat /annotations.yaml
68+
annotations:
69+
operators.coreos.com.bundle.resources: "manifests+metadata"
70+
operators.coreos.com.bundle.mediatype: "operator-registry+v1"
71+
```
72+
73+
The following `ConfigMap` maps to the above operator bundle
74+
```yaml
75+
apiVersion: v1
76+
kind: ConfigMap
77+
metadata:
78+
name: test
79+
namespace: test
80+
annotations:
81+
operators.coreos.com.bundle.resources: "manifests+metadata"
82+
operators.coreos.com.bundle.mediatype: "registry+v1"
83+
data:
84+
testbackup.crd.yaml: content of testbackup.crd.yaml
85+
testcluster.crd.yaml: content of testcluster.crd.yaml
86+
testoperator.v0.1.0.clusterserviceversion.yaml: content oftestoperator.v0.1.0.clusterserviceversion.yaml
87+
testrestore.crd.yaml: content of testrestore.crd.yaml
88+
```
89+
90+
The `key` of a `ConfigMap` has the following format
91+
```go
92+
// Data contains the configuration data.
93+
// Each key must consist of alphanumeric characters, '-', '_' or '.'.
94+
// Values with non-UTF-8 byte sequences must use the BinaryData field.
95+
// The keys stored in Data must not overlap with the keys in
96+
// the BinaryData field, this is enforced during validation process.
97+
// +optional
98+
Data map[string]string `json:"data,omitempty" protobuf:"bytes,2,rep,name=data"`
99+
```
100+
101+
Notes:
102+
* The resource file name needs to be manipulated if it contains special characters.
103+
* The consumer of the `ConfigMap` does not use the key name in `Data` section to identify the type of resource. It should inspect the content.
104+
* The consumer will iterate through the `Data` section and and add each resource to the bundle.
105+
* The annotations from the `annotations.yaml` file is copied to `metadata.annotations` to the `ConfigMap`.
106+
* The `ConfigMap` may have a resource that contains a `PackageManifest` resource. The consumer needs to handle this properly.
107+
108+
109+
## Build a Bundle from ConfigMap
110+
```go
111+
import (
112+
"github.com/operator-framework/operator-registry/pkg/registry"
113+
corev1 "k8s.io/api/core/v1"
114+
)
115+
116+
// Manifest contains a bundle and a PackageManifest.
117+
type Manifest struct {
118+
Bundle *registry.Bundle
119+
PackageManifest *registry.PackageManifest
120+
}
121+
122+
type Loader interface {
123+
Load(cm *corev1.ConfigMap) (manifest *Manifest, err error)
124+
}
125+
```
126+
127+
## Managing Lifecycle of the `ConfigMap`
128+
129+
## Things that Happen after reading the configmap
130+
131+

0 commit comments

Comments
 (0)