github.com/operator-framework/operator-lifecycle-manager@v0.30.0/doc/contributors/design-proposals/pull-bundle-on-a-cluster.md (about) 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