<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Operator SDK – Operator SDK Integration with Operator Lifecycle Manager</title>
    <link>/docs/olm-integration/</link>
    <description>Recent content in Operator SDK Integration with Operator Lifecycle Manager on Operator SDK</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    
	  <atom:link href="/docs/olm-integration/index.xml" rel="self" type="application/rss+xml" />
    
    
      
        
      
    
    
    <item>
      <title>Docs: OLM Integration Bundle Quickstart</title>
      <link>/docs/olm-integration/quickstart-bundle/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/olm-integration/quickstart-bundle/</guid>
      <description>
        
        
        &lt;p&gt;The &lt;a href=&#34;https://github.com/operator-framework/operator-lifecycle-manager/&#34;&gt;Operator Lifecycle Manager (OLM)&lt;/a&gt; is a set of cluster resources that manage the lifecycle of an Operator.
The Operator SDK supports both creating manifests for OLM deployment, and testing your Operator on an OLM-enabled
Kubernetes cluster.&lt;/p&gt;
&lt;p&gt;This document is intended to quickly walk through the steps to generate an OLM bundle. For further explanation,
or if you&amp;rsquo;re using package manifests, see the &lt;a href=&#34;/docs/olm-integration/tutorial-bundle&#34;&gt;Bundle Tutorial&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; this guide assumes your project was scaffolded with &lt;code&gt;operator-sdk init --project-version=3&lt;/code&gt;.
These features are unavailable to projects of version &lt;code&gt;2&lt;/code&gt; or less; this information can be found by inspecting
your &lt;code&gt;PROJECT&lt;/code&gt; file&amp;rsquo;s &lt;code&gt;version&lt;/code&gt; value.&lt;/p&gt;
&lt;h2 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Have a working operator that you have uploaded to a container registry. This guide assumes the simple Golang Memcached operator from &lt;a href=&#34;/docs/building-operators/golang/quickstart&#34;&gt;the building operators section&lt;/a&gt; at version &lt;code&gt;0.0.1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Make sure your user is authorized with &lt;code&gt;cluster-admin&lt;/code&gt; permissions.&lt;/li&gt;
&lt;li&gt;Have OLM installed on your cluster. The command &lt;code&gt;operator-sdk olm install&lt;/code&gt; will attempt to install a basic OLM deployment on your cluster.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;steps&#34;&gt;Steps&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Export environment variables&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ &lt;span style=&#34;color:#204a87&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;USERNAME&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&amp;lt;container-registry-username&amp;gt;
$ &lt;span style=&#34;color:#204a87&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;VERSION&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;0.0.1
$ &lt;span style=&#34;color:#204a87&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;IMG&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;docker.io/&lt;span style=&#34;color:#000&#34;&gt;$USERNAME&lt;/span&gt;/memcached-operator:v&lt;span style=&#34;color:#000&#34;&gt;$VERSION&lt;/span&gt; // location where your operator image is hosted
$ &lt;span style=&#34;color:#204a87&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;BUNDLE_IMG&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;docker.io/&lt;span style=&#34;color:#000&#34;&gt;$USERNAME&lt;/span&gt;/memcached-operator-bundle:v&lt;span style=&#34;color:#000&#34;&gt;$VERSION&lt;/span&gt; // location where your bundle will be hosted
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Create a bundle from the root directory of your project&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ make bundle
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This will prompt you to enter basic information about your operator.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Build and push the bundle image&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ make bundle-build bundle-push
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Validate the bundle&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ operator-sdk bundle validate &lt;span style=&#34;color:#000&#34;&gt;$BUNDLE_IMG&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Install the bundle with OLM&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;$ operator-sdk run bundle &lt;span style=&#34;color:#000&#34;&gt;$BUNDLE_IMG&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;next-steps&#34;&gt;Next Steps&lt;/h2&gt;
&lt;p&gt;Read the &lt;a href=&#34;/docs/olm-integration/tutorial-bundle&#34;&gt;full tutorial&lt;/a&gt; for a more in-depth look at creating and using a bundle.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: OLM Integration Bundle Tutorial</title>
      <link>/docs/olm-integration/tutorial-bundle/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/olm-integration/tutorial-bundle/</guid>
      <description>
        
        
        &lt;p&gt;The &lt;a href=&#34;https://github.com/operator-framework/operator-lifecycle-manager/&#34;&gt;Operator Lifecycle Manager (OLM)&lt;/a&gt; is a set of cluster resources that manage the lifecycle of an Operator.
The Operator SDK supports both creating manifests for OLM deployment, and testing your Operator on an OLM-enabled
Kubernetes cluster.&lt;/p&gt;
&lt;p&gt;This document succinctly walks through getting an Operator OLM-ready with &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/v1.16.1/docs/design/operator-bundle.md&#34;&gt;bundles&lt;/a&gt;, and glosses over
explanations of certain steps for brevity. The following documents contain more detail on these steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;All operator-framework manifest commands supported by the SDK: &lt;a href=&#34;/docs/olm-integration/cli-overview&#34;&gt;CLI overview&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Generating operator-framework manifests: &lt;a href=&#34;/docs/olm-integration/generation&#34;&gt;generation overview&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you are working with package manifests, see the &lt;a href=&#34;/docs/olm-integration/tutorial-package-manifests&#34;&gt;package manifests tutorial&lt;/a&gt;
once you have completed the &lt;em&gt;Setup&lt;/em&gt; section below.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; this guide assumes your project was scaffolded with &lt;code&gt;operator-sdk init --project-version=3&lt;/code&gt;.
These features are unavailable to projects of version &lt;code&gt;2&lt;/code&gt; or less; this information can be found by inspecting
your &lt;code&gt;PROJECT&lt;/code&gt; file&amp;rsquo;s &lt;code&gt;version&lt;/code&gt; value.&lt;/p&gt;
&lt;h2 id=&#34;setup&#34;&gt;Setup&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s first walk through creating an Operator for &lt;code&gt;memcached&lt;/code&gt;, a distributed key-value store.&lt;/p&gt;
&lt;p&gt;Follow one of the user guides to develop the memcached-operator in either &lt;a href=&#34;/docs/building-operators/golang/quickstart&#34;&gt;Go&lt;/a&gt;,
&lt;a href=&#34;/docs/building-operators/ansible/quickstart&#34;&gt;Ansible&lt;/a&gt;, or &lt;a href=&#34;/docs/building-operators/helm/quickstart&#34;&gt;Helm&lt;/a&gt;, depending on which Operator type you are interested in.
This guide assumes memcached-operator is on version &lt;code&gt;0.0.1&lt;/code&gt;, which is set in the &lt;code&gt;Makefile&lt;/code&gt; variable &lt;code&gt;VERSION&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;enabling-olm&#34;&gt;Enabling OLM&lt;/h3&gt;
&lt;p&gt;Ensure OLM is enabled on your cluster before following this guide. &lt;a href=&#34;/docs/cli/operator-sdk_olm&#34;&gt;&lt;code&gt;operator-sdk olm&lt;/code&gt;&lt;/a&gt;
has several subcommands that can install, uninstall, and check the status of particular OLM versions in a cluster.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Certain cluster types may already have OLM enabled, but under a non-default (&lt;code&gt;&amp;quot;olm&amp;quot;&lt;/code&gt;) namespace,
which can be configured by setting &lt;code&gt;--olm-namespace=[non-default-olm-namespace]&lt;/code&gt; for &lt;code&gt;operator-sdk olm status|uninstall&lt;/code&gt; subcommands.&lt;/p&gt;
&lt;p&gt;You can check if OLM is already installed by running the following command,
which will detect the installed OLM version automatically (0.15.1 in this example):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ operator-sdk olm status
INFO[0000] Fetching CRDs for version &amp;quot;0.15.1&amp;quot;
INFO[0002] Fetching resources for version &amp;quot;0.15.1&amp;quot;
INFO[0002] Successfully got OLM status for version &amp;quot;0.15.1&amp;quot;

NAME                                            NAMESPACE    KIND                        STATUS
olm                                                          Namespace                   Installed
operatorgroups.operators.coreos.com                          CustomResourceDefinition    Installed
catalogsources.operators.coreos.com                          CustomResourceDefinition    Installed
subscriptions.operators.coreos.com                           CustomResourceDefinition    Installed
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;All resources listed should have status &lt;code&gt;Installed&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The &lt;code&gt;operator-sdk olm status&lt;/code&gt; command is geared to detect the status of OLM that was installed by installation methods like &lt;code&gt;operator-sdk olm install&lt;/code&gt; or by applying OLM &lt;a href=&#34;https://github.com/operator-framework/operator-lifecycle-manager/blob/master/deploy/upstream/quickstart/olm.yaml&#34;&gt;manifests&lt;/a&gt; directly on the cluster. This command retrieves the resources that were compiled into SDK at the time of installation from the OLM &lt;a href=&#34;https://github.com/operator-framework/operator-lifecycle-manager/blob/master/deploy/upstream/quickstart/olm.yaml&#34;&gt;manifests&lt;/a&gt;. However, if OLM was installed in a cluster in a custom fashion (such as in OpenShift clusters), it is possible that some resources will show a &lt;code&gt;Not Found&lt;/code&gt; status when the &lt;code&gt;operator-sdk olm status&lt;/code&gt; command is issued.&lt;/p&gt;
&lt;p&gt;To check the true status of such resources in OCP clusters, run:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;oc get &amp;lt;resource-name&amp;gt; -n &amp;lt;resource-namespace&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If OLM is not already installed, go ahead and install the latest version:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ operator-sdk olm install
INFO[0000] Fetching CRDs for version &amp;quot;latest&amp;quot;
INFO[0001] Fetching resources for version &amp;quot;latest&amp;quot;
INFO[0007] Creating CRDs and resources
INFO[0007]   Creating CustomResourceDefinition &amp;quot;clusterserviceversions.operators.coreos.com&amp;quot;
INFO[0007]   Creating CustomResourceDefinition &amp;quot;installplans.operators.coreos.com&amp;quot;
INFO[0007]   Creating CustomResourceDefinition &amp;quot;subscriptions.operators.coreos.com&amp;quot;
...
NAME                                            NAMESPACE    KIND                        STATUS
clusterserviceversions.operators.coreos.com                  CustomResourceDefinition    Installed
installplans.operators.coreos.com                            CustomResourceDefinition    Installed
subscriptions.operators.coreos.com                           CustomResourceDefinition    Installed
catalogsources.operators.coreos.com                          CustomResourceDefinition    Installed
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; By default, &lt;code&gt;olm status&lt;/code&gt; and &lt;code&gt;olm uninstall&lt;/code&gt; auto-detect the OLM version installed in your cluster.
This can fail if the installation is broken in some way, so the version of OLM can be overridden using the
&lt;code&gt;--version&lt;/code&gt; flag provided with these commands.&lt;/p&gt;
&lt;h2 id=&#34;creating-a-bundle&#34;&gt;Creating a bundle&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;If working with package manifests, see the &lt;a href=&#34;/docs/olm-integration/tutorial-package-manifests&#34;&gt;package manifests tutorial&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;We will now create bundle manifests by running &lt;code&gt;make bundle&lt;/code&gt; in the root of the memcached-operator project.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ make bundle
/home/user/go/bin/controller-gen rbac:roleName=manager-role crd webhook paths=&amp;quot;./...&amp;quot; output:crd:artifacts:config=config/crd/bases
operator-sdk generate kustomize manifests -q
kustomize build config/manifests | operator-sdk generate bundle -q --overwrite --version 0.0.1
INFO[0000] Building annotations.yaml
INFO[0000] Writing annotations.yaml in /home/user/go/src/github.com/test-org/memcached-operator/bundle/metadata
INFO[0000] Building Dockerfile
INFO[0000] Writing bundle.Dockerfile in /home/user/go/src/github.com/test-org/memcached-operator
operator-sdk bundle validate ./bundle
INFO[0000] Found annotations file                        bundle-dir=bundle container-tool=docker
INFO[0000] Could not find optional dependencies file     bundle-dir=bundle container-tool=docker
INFO[0000] All validation tests have completed successfully
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The above command will have created the following bundle artifacts: a manifests directory
(&lt;code&gt;bundle/manifests&lt;/code&gt;) containing a CSV and all CRDs from &lt;code&gt;config/crds&lt;/code&gt;, &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/v1.12.6/docs/design/operator-bundle.md#bundle-annotations&#34;&gt;metadata&lt;/a&gt;
directory (&lt;code&gt;bundle/metadata&lt;/code&gt;), and &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/v1.12.6/docs/design/operator-bundle.md#bundle-dockerfile&#34;&gt;&lt;code&gt;bundle.Dockerfile&lt;/code&gt;&lt;/a&gt; have been created in
the Operator project. These files have been statically validated by &lt;code&gt;operator-sdk bundle validate&lt;/code&gt;
to ensure the on-disk bundle representation is correct.&lt;/p&gt;
&lt;h2 id=&#34;deploying-an-operator-with-olm&#34;&gt;Deploying an Operator with OLM&lt;/h2&gt;
&lt;p&gt;At this point in development we&amp;rsquo;ve generated all files necessary to build the memcached-operator bundle.
Now we&amp;rsquo;re ready to test and deploy the Operator with OLM.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If testing a bundle whose image will be hosted in a registry that is private and/or
has a custom CA, these &lt;a href=&#34;/docs/olm-integration/cli-overview#private-bundle-and-catalog-image-registries&#34;&gt;configuration steps&lt;/a&gt; must be complete.&lt;/p&gt;
&lt;h3 id=&#34;testing-bundles&#34;&gt;Testing bundles&lt;/h3&gt;
&lt;p&gt;Before proceeding, make sure you&amp;rsquo;ve &lt;a href=&#34;#enabling-olm&#34;&gt;Installed OLM&lt;/a&gt; onto your
cluster.&lt;/p&gt;
&lt;p&gt;First, we need to build our bundle. To build a memcached-operator bundle, run:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ make bundle-build bundle-push BUNDLE_IMG=&amp;lt;some-registry&amp;gt;/memcached-operator-bundle:v0.0.1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now that the bundle image is present in a registry, &lt;a href=&#34;/docs/cli/operator-sdk_run_bundle&#34;&gt;&lt;code&gt;operator-sdk run bundle&lt;/code&gt;&lt;/a&gt;
can create a pod to serve that bundle to OLM via a &lt;a href=&#34;https://olm.operatorframework.io/docs/tasks/install-operator-with-olm/#install-your-operator&#34;&gt;&lt;code&gt;Subscription&lt;/code&gt;&lt;/a&gt;,
along with other OLM objects, ephemerally.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ operator-sdk run bundle &amp;lt;some-registry&amp;gt;/memcached-operator-bundle:v0.0.1
INFO[0008] Successfully created registry pod: &amp;lt;some-registry&amp;gt;-memcached-operator-bundle-0-0-1
INFO[0008] Created CatalogSource: memcached-operator-catalog
INFO[0008] OperatorGroup &amp;quot;operator-sdk-og&amp;quot; created
INFO[0008] Created Subscription: memcached-operator-v0-0-1-sub
INFO[0019] Approved InstallPlan install-krv7q for the Subscription: memcached-operator-v0-0-1-sub
INFO[0019] Waiting for ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.1&amp;quot; to reach &#39;Succeeded&#39; phase
INFO[0019]   Waiting for ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.1&amp;quot; to appear
INFO[0031]   Found ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.1&amp;quot; phase: Pending
INFO[0032]   Found ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.1&amp;quot; phase: Installing
INFO[0040]   Found ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.1&amp;quot; phase: Succeeded
INFO[0040] OLM has successfully installed &amp;quot;memcached-operator.v0.0.1&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If the bundle that is being installed has dependencies, the &lt;code&gt;--index-image&lt;/code&gt; flag allows adding a bundle to a catalog that contains that bundle&amp;rsquo;s dependencies.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Version &lt;code&gt;v1.22.0&lt;/code&gt; and later of the &lt;code&gt;operator-sdk&lt;/code&gt; use the new file-based catalog (FBC) bundle format by default. Earlier releases use the deprecated SQLite bundle format. If you use an earlier version of the Operator SDK, you must update to a newer version or specify the index image by adding the &lt;code&gt;--index-image=quay.io/operator-framework/opm:v1.23.0&lt;/code&gt; flag. For more information about this known issue, see the &lt;a href=&#34;https://sdk.operatorframework.io/docs/faqs/#operator-sdk-run-bundle-command-fails-and-the-registry-pod-has-an-error-of-mkdir-cant-create-directory-database-permission-denied&#34;&gt;FAQ&lt;/a&gt;.&lt;/p&gt;
&lt;!-- TODO(jmccormick2001): add `scorecard` usage here --&gt;
&lt;h3 id=&#34;upgrading-a-bundle-to-a-newer-version&#34;&gt;Upgrading a bundle to a newer version&lt;/h3&gt;
&lt;p&gt;We can use the &lt;code&gt;operator-sdk run bundle-upgrade&lt;/code&gt; command with a newer version of bundle image to upgrade
an existing operator bundle deployed on cluster. The command automates the manual orchestration typically required to upgrade an operator
from one version to another. It extracts the package name from bundle, finds the existing subscription, updates the catalog
source, deletes the existing registry pod and creates a new registry pod with the version of bundle image provided in the command.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s upgrade the previously deployed memcached-operator bundle from version &lt;code&gt;0.0.1&lt;/code&gt; to &lt;code&gt;0.0.2&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ operator-sdk run bundle-upgrade &amp;lt;some-registry&amp;gt;/memcached-operator-bundle:v0.0.2
INFO[0002] Found existing subscription with name memcached-operator-bundle-0-0-1-sub and namespace default
INFO[0002] Found existing catalog source with name memcached-operator-catalog and namespace default
INFO[0007] Successfully created registry pod: &amp;lt;some-registry&amp;gt;-memcached-operator-bundle-0-0-2
INFO[0007] Updated catalog source memcached-operator-catalog with address and annotations
INFO[0008] Deleted previous registry pod with name &amp;quot;&amp;lt;some-registry&amp;gt;-memcached-operator-bundle-0-0-1&amp;quot;
INFO[0050] Approved InstallPlan install-c8fkh for the Subscription: memcached-operator-bundle-0-0-1-sub
INFO[0050] Waiting for ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.2&amp;quot; to reach &#39;Succeeded&#39; phase
INFO[0050]   Waiting for ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.2&amp;quot; to appear
INFO[0052]   Found ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.2&amp;quot; phase: Pending
INFO[0057]   Found ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.2&amp;quot; phase: InstallReady
INFO[0058]   Found ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.2&amp;quot; phase: Installing
INFO[0095]   Found ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.2&amp;quot; phase: Succeeded
INFO[0095] Successfully upgraded to &amp;quot;memcached-operator.v0.0.2&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If a bundle was installed using &lt;a href=&#34;https://sdk.operatorframework.io/docs/cli/operator-sdk_run_bundle/&#34;&gt;&lt;code&gt;operator-sdk run bundle&lt;/code&gt;&lt;/a&gt; with a SQLite index image, the &lt;code&gt;replaces&lt;/code&gt; field &lt;em&gt;must&lt;/em&gt; be present and populated in the upgraded CSV&amp;rsquo;s spec.&lt;/p&gt;
&lt;h4 id=&#34;upgrading-a-bundle-that-was-installed-traditionally-using-olm&#34;&gt;Upgrading a bundle that was installed traditionally using OLM&lt;/h4&gt;
&lt;p&gt;An operator bundle can be upgraded even if it was originally deployed using OLM without using the &lt;code&gt;run bundle&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s see how to deploy an operator bundle traditionally using OLM and then upgrade the operator bundle to a newer version.&lt;/p&gt;
&lt;p&gt;First, create a CatalogSource by building the CatalogSource from a catalog.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ oc create -f catalogsource.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# catalogsource.yaml&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;operators.coreos.com/v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;CatalogSource&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;etcdoperator&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;default&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;displayName&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Etcd&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Operators&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;image&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&amp;lt;some-registry&amp;gt;/etcd-catalog&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;latest&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;sourceType&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;grpc&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Next, install the operator bundle by creating a subscription.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ oc create -f subscription.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# subscription.yaml&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;v1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;items&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;&lt;/span&gt;- &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;operators.coreos.com/v1alpha1&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Subscription&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;metadata&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;etcd&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;namespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;default&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;channel&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;stable&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;installPlanApproval&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;Manual&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;etcd&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;source&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;etcdoperator&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;sourceNamespace&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;default&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;startingCSV&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;etcdoperator.v0&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;.0.1&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once the Operator bundle is deployed, you can use the &lt;code&gt;run bundle-upgrade&lt;/code&gt; command by specifying the new bundle image that you want to upgrade to.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ operator-sdk run bundle-upgrade &amp;lt;some-registry&amp;gt;/etcd-bundle:v0.0.2
INFO[0000] Found existing subscription with name etcd and namespace default
INFO[0000] Found existing catalog source with name etcdoperator and namespace default
INFO[0005] Successfully created registry pod: &amp;lt;some-registry&amp;gt;-etcd-bundle-0-0-2
INFO[0005] Updated catalog source etcdoperator with address and annotations
INFO[0005] Deleted previous registry pod with name &amp;quot;&amp;lt;some-registry&amp;gt;-etcd-bundle-0-0-1&amp;quot;
INFO[0005] Approved InstallPlan install-6vrzh for the Subscription: etcd
INFO[0005] Waiting for ClusterServiceVersion &amp;quot;default/etcdoperator.v0.0.2&amp;quot; to reach &#39;Succeeded&#39; phase
INFO[0005]   Waiting for ClusterServiceVersion &amp;quot;default/etcdoperator.v0.0.2&amp;quot; to appear
INFO[0007]   Found ClusterServiceVersion &amp;quot;default/etcdoperator.v0.0.2&amp;quot; phase: Pending
INFO[0008]   Found ClusterServiceVersion &amp;quot;default/etcdoperator.v0.0.2&amp;quot; phase: Installing
INFO[0018]   Found ClusterServiceVersion &amp;quot;default/etcdoperator.v0.0.2&amp;quot; phase: Succeeded
INFO[0018] Successfully upgraded to &amp;quot;etcdoperator.v0.0.2&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;deploying-bundles-in-production&#34;&gt;Deploying bundles in production&lt;/h3&gt;
&lt;p&gt;OLM and Operator Registry consumes Operator bundles via a catalog of Operators, implemented as an
&lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/master/docs/design/opm-tooling.md#index&#34;&gt;index image&lt;/a&gt;, which are composed of one or more bundles. To build and push a
memcached-operator bundle image for version v0.0.1, run:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ make bundle-build bundle-push BUNDLE_IMG=&amp;lt;some-registry&amp;gt;/memcached-operator-bundle:v0.0.1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now you can build and push the catalog by running &lt;code&gt;catalog-*&lt;/code&gt; Makfile targets, which use
the Operator package manager tool &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/master/docs/design/opm-tooling.md&#34;&gt;&lt;code&gt;opm&lt;/code&gt;&lt;/a&gt; to &lt;a href=&#34;https://github.com/operator-framework/operator-registry#building-an-index-of-operators-using-opm&#34;&gt;build&lt;/a&gt; the catalog:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ make catalog-build catalog-push CATALOG_IMG=&amp;lt;some-registry&amp;gt;/memcached-operator-catalog:v0.0.1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Assuming &lt;code&gt;IMAGE_TAG_BASE = &amp;lt;some-registry&amp;gt;/memcached-operator&lt;/code&gt; has the desired tag base, you can inline
the above two commands to:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ make bundle-build bundle-push catalog-build catalog-push
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Which will build and push both &lt;code&gt;&amp;lt;some-registry&amp;gt;/memcached-operator-bundle:v0.0.1&lt;/code&gt;
and &lt;code&gt;&amp;lt;some-registry&amp;gt;/memcached-operator-catalog:v0.0.1&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;further-reading&#34;&gt;Further reading&lt;/h2&gt;
&lt;p&gt;In-depth discussions of OLM concepts mentioned here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://olm.operatorframework.io/docs/concepts/crds/catalogsource/&#34;&gt;CatalogSource&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://olm.operatorframework.io/docs/concepts/crds/subscription/&#34;&gt;Subscription&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://olm.operatorframework.io/docs/tasks/install-operator-with-olm/&#34;&gt;Install an Operator from a catalog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: OLM Integration Package Manifests Quickstart</title>
      <link>/docs/olm-integration/tutorial-package-manifests/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/olm-integration/tutorial-package-manifests/</guid>
      <description>
        
        
        &lt;!-- TODO(2.0.0): remove this document --&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;
As operator framework has moved to using bundle format by default, the package manifest commands have been deprecated and will be removed soon. It is suggested that you follow the &lt;a href=&#34;/docs/olm-integration/quickstart-bundle&#34;&gt;bundle quickstart&lt;/a&gt; to package your operator.&lt;/p&gt;
&lt;p&gt;This guide assumes you have followed the introduction and &lt;em&gt;Setup&lt;/em&gt; section of the &lt;a href=&#34;/docs/olm-integration/quickstart-bundle&#34;&gt;bundle quickstart&lt;/a&gt;,
and have added the &lt;code&gt;packagemanifests&lt;/code&gt; target to your &lt;code&gt;Makefile&lt;/code&gt; as described &lt;a href=&#34;/docs/olm-integration/generation/#package-manifests-format&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; this guide assumes your project was scaffolded with &lt;code&gt;operator-sdk init --project-version=3&lt;/code&gt;.
These features are unavailable to projects of version &lt;code&gt;2&lt;/code&gt; or less; this information can be found by inspecting
your &lt;code&gt;PROJECT&lt;/code&gt; file&amp;rsquo;s &lt;code&gt;version&lt;/code&gt; value.&lt;/p&gt;
&lt;h2 id=&#34;creating-package-manifests&#34;&gt;Creating package manifests&lt;/h2&gt;
&lt;p&gt;We will now create a package manifests format by running &lt;code&gt;make packagemanifests&lt;/code&gt; in the root of the memcached-operator project:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ make packagemanifests
/home/user/go/bin/controller-gen rbac:roleName=manager-role crd webhook paths=&amp;quot;./...&amp;quot; output:crd:artifacts:config=config/crd/bases
operator-sdk generate kustomize manifests -q
kustomize build config/manifests | operator-sdk generate packagemanifests -q --version 0.0.1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A versioned manifests directory &lt;code&gt;packagemanifests/0.0.1&lt;/code&gt; containing a CSV and all CRDs in &lt;code&gt;config/crds&lt;/code&gt; and a
package manifest YAML file &lt;code&gt;packagemanifests/&amp;lt;project-name&amp;gt;.package.yaml&lt;/code&gt; have been created in the Operator project.&lt;/p&gt;
&lt;h2 id=&#34;deploying-an-operator-with-olm&#34;&gt;Deploying an Operator with OLM&lt;/h2&gt;
&lt;p&gt;At this point in development we&amp;rsquo;ve generated all files necessary to build a memcached-operator registry.
Now we&amp;rsquo;re ready to test the Operator with OLM.&lt;/p&gt;
&lt;h3 id=&#34;testing-package-manifests&#34;&gt;Testing package manifests&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;operator-sdk run packagemanifests&lt;/code&gt; will create an Operator &lt;a href=&#34;https://github.com/operator-framework/operator-registry&#34;&gt;registry&lt;/a&gt;
from manifests and metadata in the memcached-operator project, and inform OLM that memcached-operator v0.0.1
is ready to be deployed. This process effectively replicates production deployment in a constrained manner
to make sure OLM can deploy our Operator successfully before attempting real production deployment.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;run packagemanifests&lt;/code&gt; performs some optionally configurable setup &lt;a href=&#34;/docs/olm-integration/testing-deployment&#34;&gt;under the hood&lt;/a&gt;, but for
most use cases the following invocation is all we need:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ operator-sdk run packagemanifests --version 0.0.1
INFO[0000] Running operator from directory packagemanifests
INFO[0000] Creating memcached-operator registry         
INFO[0000]   Creating ConfigMap &amp;quot;olm/memcached-operator-registry-manifests-package&amp;quot;
INFO[0000]   Creating ConfigMap &amp;quot;olm/memcached-operator-registry-manifests-0-0-1&amp;quot;
INFO[0000]   Creating Deployment &amp;quot;olm/memcached-operator-registry-server&amp;quot;
INFO[0000]   Creating Service &amp;quot;olm/memcached-operator-registry-server&amp;quot;
INFO[0000] Waiting for Deployment &amp;quot;olm/memcached-operator-registry-server&amp;quot; rollout to complete
INFO[0000]   Waiting for Deployment &amp;quot;olm/memcached-operator-registry-server&amp;quot; to rollout: 0 of 1 updated replicas are available
INFO[0066]   Deployment &amp;quot;olm/memcached-operator-registry-server&amp;quot; successfully rolled out
INFO[0066] Creating resources                           
INFO[0066]   Creating CatalogSource &amp;quot;default/memcached-operator-ocs&amp;quot;
INFO[0066]   Creating Subscription &amp;quot;default/memcached-operator-v0-0-1-sub&amp;quot;
INFO[0066]   Creating OperatorGroup &amp;quot;default/operator-sdk-og&amp;quot;
INFO[0066] Waiting for ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.1&amp;quot; to reach &#39;Succeeded&#39; phase
INFO[0066]   Waiting for ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.1&amp;quot; to appear
INFO[0073]   Found ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.1&amp;quot; phase: Pending
INFO[0077]   Found ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.1&amp;quot; phase: InstallReady
INFO[0078]   Found ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.1&amp;quot; phase: Installing
INFO[0036]   Found ClusterServiceVersion &amp;quot;default/memcached-operator.v0.0.1&amp;quot; phase: Succeeded
INFO[0037] Successfully installed &amp;quot;memcached-operator.v0.0.1&amp;quot; on OLM version &amp;quot;0.15.1&amp;quot;

NAME                            NAMESPACE    KIND                        STATUS
memcacheds.cache.example.com    default      CustomResourceDefinition    Installed
memcached-operator.v0.0.1       default      ClusterServiceVersion       Installed
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As long as both the &lt;code&gt;ClusterServiceVersion&lt;/code&gt; and all &lt;code&gt;CustomResourceDefinition&lt;/code&gt;&#39;s return an &lt;code&gt;Installed&lt;/code&gt; status,
the memcached-operator has been deployed successfully.&lt;/p&gt;
&lt;p&gt;Now that we&amp;rsquo;re done testing the memcached-operator, we should probably clean up the Operator&amp;rsquo;s resources.
&lt;a href=&#34;/docs/cli/operator-sdk_cleanup&#34;&gt;&lt;code&gt;operator-sdk cleanup&lt;/code&gt;&lt;/a&gt; will do this for you:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ operator-sdk cleanup memcached-operator
INFO[0000] subscription &amp;quot;memcached-operator-v0-0-1-sub&amp;quot; deleted
INFO[0000] customresourcedefinition &amp;quot;memcacheds.cache.example.com&amp;quot; deleted
INFO[0000] clusterserviceversion &amp;quot;memcached-operator.v0.0.1&amp;quot; deleted
INFO[0000] clusterrole &amp;quot;memcached-operator-metrics-reader&amp;quot; deleted
INFO[0000] serviceaccount &amp;quot;default&amp;quot; deleted
INFO[0000] role &amp;quot;memcached-operator.v0.0.1-jhjk7&amp;quot; deleted
INFO[0000] rolebinding &amp;quot;memcached-operator.v0.0.1-jhjk7-default-mxv6m&amp;quot; deleted
INFO[0000] catalogsource &amp;quot;memcached-operator-ocs&amp;quot; deleted
INFO[0000] operatorgroup &amp;quot;operator-sdk-og&amp;quot; deleted
INFO[0001] operator &amp;quot;memcached-operator&amp;quot; uninstalled
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;migrating-packagemanifests-to-bundles&#34;&gt;Migrating packagemanifests to bundles&lt;/h2&gt;
&lt;p&gt;In order to migrate packagemanifests to bundles, &lt;code&gt;operator-sdk pkgman-to-bundle&lt;/code&gt; command can be used.&lt;/p&gt;
&lt;p&gt;As an example, consider the packagemanifests directory to have the following structure:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;packagemanifests
└── etcd
    ├── 0.0.1
    │   ├── etcdcluster.crd.yaml
    │   └── etcdoperator.clusterserviceversion.yaml
    ├── 0.0.2
    │   ├── etcdbackup.crd.yaml
    │   ├── etcdcluster.crd.yaml
    │   ├── etcdoperator.v0.0.2.clusterserviceversion.yaml
    │   └── etcdrestore.crd.yaml
    └── etcd.package.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here, we have manifests for two versions of the &lt;code&gt;etcd&lt;/code&gt; operator. The following command will generate bundles for each of these versions.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ operator-sdk pkgman-to-bundle packagemanifests --output-dir etcd-bundle/
INFO[0000] Packagemanifests will be migrated to bundles in bundle directory
INFO[0000] Creating etcd-bundle/bundle-0.0.1/bundle.Dockerfile
INFO[0000] Creating etcd-bundle/bundle-0.0.1/metadata/annotations.yaml
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This will create output bundles in the directory &lt;code&gt;etcd-bundle&lt;/code&gt;. The output directory will look like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;etcd-bundle/
├── bundle-0.0.1
│   ├── bundle
│   │   ├── manifests
│   │   │   ├── etcdcluster.crd.yaml
│   │   │   ├── etcdoperator.clusterserviceversion.yaml
│   │   ├── metadata
│   │   │   └── annotations.yaml
│   │   └── tests
│   │       └── scorecard
│   │           └── config.yaml
│   └── bundle.Dockerfile
└── bundle-0.0.2
    ├── bundle
    │   ├── manifests
    │   │   ├── etcdbackup.crd.yaml
    │   │   ├── etcdcluster.crd.yaml
    │   │   ├── etcdoperator.v0.0.2.clusterserviceversion.yaml
    │   │   ├── etcdrestore.crd.yaml
    │   └── metadata
    │       └── annotations.yaml
    └── bundle.Dockerfile
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To build images for the bundles, the base container image name can be provided using &lt;code&gt;--image-tag-base&lt;/code&gt; flag. This name should be provided without the tag (&lt;code&gt;:&lt;/code&gt; and characters following), as the command will tag each bundle image with its packagemanifests directory name, i.e. &lt;code&gt;&amp;lt;image-tag-base&amp;gt;:&amp;lt;dir-name&amp;gt;&lt;/code&gt;. For example, the following command for the above &lt;code&gt;packagemnifests&lt;/code&gt; directory would build the bundles &lt;code&gt;quay.io/example/etcd-bundle:0.0.1&lt;/code&gt; and &lt;code&gt;quay.io/example/etcd-bundle:0.0.2&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;operator-sdk pkgman-to-bundle packagemanifests --image-tag-base quay.io/example/etcd-bundle
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A custom command can also be specified to build images, using the &lt;code&gt;--build-cmd&lt;/code&gt; flag. The default command is &lt;code&gt;docker build&lt;/code&gt;. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ operator-sdk pkgman-to-bundle packagemanifests --output-dir etcd-bundle/ --image-tag-base quay.io/example/etcd --build-cmd &amp;quot;podman build -f bundle.Dockerfile . -t&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;However, if using a custom command, it needs to be made sure that the command is in the &lt;code&gt;PATH&lt;/code&gt; or a fully qualified path name is provided as input to the flag.&lt;/p&gt;
&lt;p&gt;Once the command has finished building your bundle images and they have been added to a catalog image, delete all bundle directories except for the latest one. This directory will contain manifests for your operator&amp;rsquo;s head bundle, and should be versioned with version control system like git. Move this directory and its &lt;code&gt;bundle.Dockerfile&lt;/code&gt; to your project&amp;rsquo;s root:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ cp -r ./etcd-bundle/bundle-0.0.2/* .
$ rm -rf ./etcd-bundle
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Try building then running your bundle on a live cluster to make sure it works as expected:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ make bundle bundle-build bundle-push
$ operator-sdk run bundle quay.io/example/etcd-bundle:0.0.2
&lt;/code&gt;&lt;/pre&gt;
      </description>
    </item>
    
    <item>
      <title>Docs: OLM and Bundle CLI Overview</title>
      <link>/docs/olm-integration/cli-overview/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/olm-integration/cli-overview/</guid>
      <description>
        
        
        &lt;p&gt;This document gives an overview of using &lt;code&gt;operator-sdk&lt;/code&gt; to work with Operator manifests related to OLM,
namely &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/v1.16.1/docs/design/operator-bundle.md&#34;&gt;bundles&lt;/a&gt; and &lt;a href=&#34;https://github.com/operator-framework/operator-registry/tree/v1.5.3#manifest-format&#34;&gt;package manifests&lt;/a&gt;. See the &lt;a href=&#34;/docs/olm-integration/generation&#34;&gt;manifests generation&lt;/a&gt;
doc for an in-depth discussion of these commands.&lt;/p&gt;
&lt;h2 id=&#34;olm-installation&#34;&gt;OLM installation&lt;/h2&gt;
&lt;p&gt;The following &lt;code&gt;operator-sdk&lt;/code&gt; subcommands manage an OLM installation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;/docs/cli/operator-sdk_olm_install&#34;&gt;&lt;code&gt;olm install&lt;/code&gt;&lt;/a&gt;: install a particular version of OLM.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/docs/cli/operator-sdk_olm_status&#34;&gt;&lt;code&gt;olm status&lt;/code&gt;&lt;/a&gt;: check the status of a particular version of OLM running in a cluster. This command
can infer the version of an error-free OLM installation.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/docs/cli/operator-sdk_olm_uninstall&#34;&gt;&lt;code&gt;olm uninstall&lt;/code&gt;&lt;/a&gt;: uninstall a particular version of OLM running in a cluster. This command
can infer the version of an error-free OLM installation.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;manifests-and-metadata&#34;&gt;Manifests and metadata&lt;/h2&gt;
&lt;p&gt;The following &lt;code&gt;make&lt;/code&gt; recipes and &lt;code&gt;operator-sdk&lt;/code&gt; subcommands create or interact with Operator package manifests and bundles:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;/docs/cli/operator-sdk_generate_kustomize_manifests&#34;&gt;&lt;code&gt;generate kustomize manifests&lt;/code&gt;&lt;/a&gt;: creates kustomize bases and a &lt;code&gt;kustomization.yaml&lt;/code&gt; in &lt;code&gt;config/manifests&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;bundles&#34;&gt;Bundles&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;make bundle&lt;/code&gt;: runs the following commands:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;generate kustomize manifests&lt;/code&gt;: see &lt;a href=&#34;#manifests-and-metadata&#34;&gt;above&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/docs/cli/operator-sdk_generate_bundle&#34;&gt;&lt;code&gt;generate bundle&lt;/code&gt;&lt;/a&gt;: creates a new or updates an existing bundle in the &lt;code&gt;&amp;lt;project-root&amp;gt;/bundle&lt;/code&gt;
directory. This command generates both manifests and metadata.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/docs/cli/operator-sdk_bundle_validate&#34;&gt;&lt;code&gt;bundle validate&lt;/code&gt;&lt;/a&gt;: validates an Operator bundle image or unpacked manifests and metadata.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;make bundle-build&lt;/code&gt;: builds a bundle image using the &lt;code&gt;bundle.Dockerfile&lt;/code&gt; generated by &lt;code&gt;make bundle&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/docs/cli/operator-sdk_run_bundle&#34;&gt;&lt;code&gt;run bundle&lt;/code&gt;&lt;/a&gt;: runs the given Operator&amp;rsquo;s bundle image with an
existing OLM installation.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/docs/cli/operator-sdk_run_bundle-upgrade&#34;&gt;&lt;code&gt;run bundle-upgrade&lt;/code&gt;&lt;/a&gt;: upgrades the Operator bundle to a specified newer version.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;private-bundle-and-catalog-image-registries&#34;&gt;Private bundle and catalog image registries&lt;/h4&gt;
&lt;p&gt;By default, projects are configured to push to and pull from a &lt;a href=&#34;https://hub.docker.com/&#34;&gt;docker.io&lt;/a&gt; registry
with namespace being the value passed to &lt;code&gt;operator-sdk init --domain=&amp;lt;value&amp;gt;&lt;/code&gt;.
Modify this value to push/pull bundle and catalog images with a different registry host or namespace.&lt;/p&gt;
&lt;p&gt;All bundle and catalog image-related commands invoke &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/496ccce/docs/design/opm-tooling.md&#34;&gt;&lt;code&gt;opm&lt;/code&gt;&lt;/a&gt; (except for bundle image builds,
for which &lt;code&gt;docker&lt;/code&gt; is used directly). &lt;code&gt;opm&lt;/code&gt; leverages the host&amp;rsquo;s image build/pull tools indirectly
to perform various image tasks, so if your image registry is private or has a custom CA you
must ensure the in-use build tool is able to push to/pull from the registry:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;docker&lt;/code&gt;: &lt;a href=&#34;https://docs.docker.com/engine/reference/commandline/login/&#34;&gt;&lt;code&gt;config.json&lt;/code&gt;&lt;/a&gt;, &lt;a href=&#34;https://docs.docker.com/engine/security/certificates/&#34;&gt;certificate configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;podman&lt;/code&gt;: &lt;a href=&#34;http://docs.podman.io/en/latest/markdown/podman-login.1.html#description&#34;&gt;&lt;code&gt;auth.json&lt;/code&gt;&lt;/a&gt;, &lt;a href=&#34;http://docs.podman.io/en/latest/markdown/podman-image-sign.1.html#cert-dir-path&#34;&gt;certificate configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;none&lt;/code&gt; (containerd): uses docker&amp;rsquo;s &lt;code&gt;config.json&lt;/code&gt;, &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/master/docs/design/opm-tooling.md#add&#34;&gt;certificate configuration&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;code&gt;run bundle&lt;/code&gt; or &lt;code&gt;run bundle-upgrade&lt;/code&gt; commands use the &lt;code&gt;none&lt;/code&gt; image tool, described above, in-cluster.
These commands accept the names of secrets available in the deployment namespace that contain configuration file data.
Ideally a cluster admin will provision a namespace and service account for bundle testing,
such that they include and reference these secrets:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create an &lt;a href=&#34;https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/&#34;&gt;image pull secret&lt;/a&gt; for your &lt;code&gt;config.json&lt;/code&gt; and &lt;a href=&#34;https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-image-pull-secret-to-service-account&#34;&gt;add it to your service account&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- TODO(estroz): remove the service account requirement once OLM releases a patch or new
minor release containing https://github.com/operator-framework/operator-lifecycle-manager/pull/1941 --&gt;
&lt;ul&gt;
&lt;li&gt;Create a &lt;a href=&#34;https://kubernetes.io/docs/tasks/configmap-secret/managing-secret-using-kubectl/#create-a-secret&#34;&gt;generic secret&lt;/a&gt; with a &lt;code&gt;cert.pem&lt;/code&gt; key containing root certificate(s) for your registry.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once the above secrets have been created, run the either command with &lt;code&gt;--pull-secret-name=&amp;lt;image pull secret&amp;gt;&lt;/code&gt; and &lt;code&gt;--ca-secret-name=&amp;lt;certificate secret&amp;gt;&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;operator-sdk run bundle private-custom-ca-reg.com/memcached-operator-bundle:v0.0.2 &lt;span style=&#34;color:#4e9a06&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&lt;/span&gt;    --index-image private-custom-ca-reg.com/memcached-operator-catalog:v0.0.1 &lt;span style=&#34;color:#4e9a06&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&lt;/span&gt;    --pull-secret-name foo-pull-sec &lt;span style=&#34;color:#4e9a06&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&lt;/span&gt;    --ca-secret-name foo-cert-sec
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You may have to set &lt;code&gt;--namespace=&amp;lt;provisioned namespace&amp;gt;&lt;/code&gt; if the namespace encoded in your kubeconfig&amp;rsquo;s current context
was not provisioned with these secrets.&lt;/p&gt;
&lt;h3 id=&#34;package-manifests&#34;&gt;Package Manifests&lt;/h3&gt;
&lt;p&gt;The operator-framework is removing support for the packagemanifests format in the near future, and migration efforts are currently underway. Therefore &lt;code&gt;generate packagemanifests&lt;/code&gt; and &lt;code&gt;run packagemanifests&lt;/code&gt; commands have been deprecated. For more
details on bundle format refer &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/v1.16.1/docs/design/operator-bundle.md&#34;&gt;here&lt;/a&gt;. To migrate from packagemanifests to the bundle format, use the &lt;a href=&#34;/docs/cli/operator-sdk_pkgman-to-bundle&#34;&gt;&lt;code&gt;operator-sdk pkgman-to-bundle&lt;/code&gt;&lt;/a&gt; command.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Generating Manifests and Metadata</title>
      <link>/docs/olm-integration/generation/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/olm-integration/generation/</guid>
      <description>
        
        
        &lt;p&gt;This document describes how to manage packaging and shipping your Operator in the following stages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Generate your first release&lt;/strong&gt; - encapsulate the metadata needed to install your Operator with the
&lt;a href=&#34;https://github.com/operator-framework/operator-lifecycle-manager&#34;&gt;Operator Lifecycle Manager&lt;/a&gt; and configure the permissions it needs from the generated SDK files.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Update your Operator&lt;/strong&gt; - apply any updates to Operator manifests made during development.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Upgrade your Operator&lt;/strong&gt; - carry over any customizations you have made and ensure a rolling update to the
next version of your Operator.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;
&lt;p&gt;Several &lt;code&gt;operator-sdk&lt;/code&gt; subcommands manage operator-framework manifests and metadata,
in particular &lt;a href=&#34;https://github.com/operator-framework/operator-lifecycle-manager/blob/0.15.1/doc/design/building-your-csv.md&#34;&gt;&lt;code&gt;ClusterServiceVersion&lt;/code&gt;&#39;s (CSVs)&lt;/a&gt;, for an Operator: &lt;a href=&#34;/docs/cli/operator-sdk_generate_bundle&#34;&gt;&lt;code&gt;generate bundle&lt;/code&gt;&lt;/a&gt; and &lt;a href=&#34;/docs/cli/operator-sdk_generate_kustomize_manifests&#34;&gt;&lt;code&gt;generate kustomize manifests&lt;/code&gt;&lt;/a&gt;.
See this &lt;a href=&#34;/docs/olm-integration/cli-overview&#34;&gt;CLI overview&lt;/a&gt; for details on each command.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The packagemanifests format is deprecated and support will be removed in &lt;code&gt;operator-sdk&lt;/code&gt; v2.0.0.&lt;/p&gt;
&lt;h3 id=&#34;kustomize-files&#34;&gt;Kustomize files&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;operator-sdk generate kustomize manifests&lt;/code&gt; generates a CSV kustomize base
&lt;code&gt;config/manifests/bases/&amp;lt;project-name&amp;gt;.clusterserviceversion.yaml&lt;/code&gt; and a &lt;code&gt;config/manifests/kustomization.yaml&lt;/code&gt;
by default. These files are required as &lt;code&gt;kustomize build&lt;/code&gt; input in downstream commands.&lt;/p&gt;
&lt;p&gt;By default, the command starts an interactive prompt if a CSV base in &lt;code&gt;config/manifests/bases&lt;/code&gt; is not present
to collect &lt;a href=&#34;#csv-fields&#34;&gt;UI metadata&lt;/a&gt;. You can disable the interactive prompt by passing &lt;code&gt;--interactive=false&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ operator-sdk generate kustomize manifests
INFO[0000] Generating CSV manifest version 0.1.0

Display name for the operator (required):
&amp;gt; memcached

Comma-separated list of keywords for your operator (required):
&amp;gt; app, operator
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Once this base is written, you may modify any of the fields labeled &lt;em&gt;user&lt;/em&gt; in the &lt;a href=&#34;#csv-fields&#34;&gt;fields section&lt;/a&gt; below.
These values will persist when generating a bundle, so make necessary metadata changes here and not the generated bundle.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;For Go Operators only:&lt;/strong&gt; the command parses &lt;a href=&#34;/docs/building-operators/golang/references/markers&#34;&gt;CSV markers&lt;/a&gt; from Go API type definitions, located
in &lt;code&gt;./api&lt;/code&gt; for single group projects and &lt;code&gt;./apis&lt;/code&gt; for multigroup projects, to populate certain CSV fields.
You can set an alternative path to the API types root directory with &lt;code&gt;--apis-dir&lt;/code&gt;. These markers are not available
to Ansible or Helm project types.&lt;/p&gt;
&lt;p&gt;The command attempts to process the local types defined in your API.
If you import a package that uses the same name as a local type, running the command causes an infinite loop. For example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;PodStatus&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
  &lt;span style=&#34;color:#000&#34;&gt;SomeField&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;string&lt;/span&gt;
  &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// imported type with the same name will infinitely trigger
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// the parser to process the local PodStatus type
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#000&#34;&gt;Status&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;v1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;PodStatus&lt;/span&gt; 
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To prevent an infinite loop, edit the local type definition to use a different name. For example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;PodStatusWrapper&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
  &lt;span style=&#34;color:#000&#34;&gt;SomeField&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;string&lt;/span&gt;
  &lt;span style=&#34;color:#000&#34;&gt;Status&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;v1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;PodStatus&lt;/span&gt; 
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;clusterserviceversion-manifests&#34;&gt;ClusterServiceVersion manifests&lt;/h3&gt;
&lt;p&gt;CSV&amp;rsquo;s are manifests that define all aspects of an Operator, from what CustomResourceDefinitions (CRDs) it uses to
metadata describing the Operator&amp;rsquo;s maintainers. They are typically versioned by semver, much like Operator projects
themselves; this version is present in both their &lt;code&gt;metadata.name&lt;/code&gt; and &lt;code&gt;spec.version&lt;/code&gt; fields. The CSV generator called
by &lt;code&gt;generate &amp;lt;bundle|packagemanifests&amp;gt;&lt;/code&gt; requires certain input manifests to construct a CSV manifest; all inputs
are read when either command is invoked, along with a CSV&amp;rsquo;s &lt;a href=&#34;#kustomize-files&#34;&gt;base&lt;/a&gt;, to idempotently regenerate a CSV.&lt;/p&gt;
&lt;p&gt;The following resource kinds are typically included in a CSV, which are addressed by &lt;code&gt;config/manifests/kustomization.yaml&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Role&lt;/code&gt;: define Operator permissions within a namespace.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ClusterRole&lt;/code&gt;: define cluster-wide Operator permissions.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Deployment&lt;/code&gt;: define how the Operator&amp;rsquo;s operand is run in pods.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ValidatingWebhookConfiguration&lt;/code&gt;, &lt;code&gt;MutatingWebhookConfiguration&lt;/code&gt;: configures webhooks for your manager to handle.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CustomResourceDefinition&lt;/code&gt;: definitions of custom objects your Operator reconciles.&lt;/li&gt;
&lt;li&gt;Custom resource examples: examples of objects adhering to the spec of a particular CRD.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can optionally specify an input &lt;code&gt;ClusterServiceVersion&lt;/code&gt; manifest to the set of manifests passed to
these &lt;code&gt;generate&lt;/code&gt; subcommands instead of having them read from the &lt;a href=&#34;#kustomize-files&#34;&gt;base path&lt;/a&gt;.
This is advantageous for those who would like to take full advantage of &lt;code&gt;kustomize&lt;/code&gt; for their base.
All fields unlabeled or labeled with &lt;em&gt;marker&lt;/em&gt; &lt;a href=&#34;#csv-fields&#34;&gt;below&lt;/a&gt; will be overwritten by these command,
so make sure you do not &lt;code&gt;kustomize build&lt;/code&gt; those fields!&lt;/p&gt;
&lt;h4 id=&#34;webhooks&#34;&gt;Webhooks&lt;/h4&gt;
&lt;p&gt;A CSV allows you to &lt;a href=&#34;https://olm.operatorframework.io/docs/advanced-tasks/adding-admission-and-conversion-webhooks&#34;&gt;define&lt;/a&gt; both &lt;a href=&#34;https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/&#34;&gt;admission&lt;/a&gt; and &lt;a href=&#34;https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definition-versioning/#webhook-conversion&#34;&gt;conversion&lt;/a&gt; webhooks
at &lt;a href=&#34;https://pkg.go.dev/github.com/operator-framework/api/pkg/operators/v1alpha1#WebhookDefinition&#34;&gt;&lt;code&gt;spec.webhookdefinitions&lt;/code&gt;&lt;/a&gt;. The &lt;code&gt;generate &amp;lt;bundle|packagemanifests&amp;gt;&lt;/code&gt; commands, described below,
will automatically add webhooks to your CSV if the following holds true:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A webhook configuration must be associated with a &lt;code&gt;Service&lt;/code&gt; by name and namespace,
whether in a &lt;a href=&#34;https://pkg.go.dev/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1?utm_source=godoc#ServiceReference&#34;&gt;CRD&lt;/a&gt; or in a &lt;a href=&#34;https://pkg.go.dev/k8s.io/api/admissionregistration/v1?utm_source=godoc#ServiceReference&#34;&gt;&lt;code&gt;*WebhookConfiguration&lt;/code&gt;&lt;/a&gt; file,&lt;/li&gt;
&lt;li&gt;The associated &lt;code&gt;Service&lt;/code&gt; must expose one &lt;code&gt;spec.ports[*].targetPort&lt;/code&gt; that matches both &lt;code&gt;containerPort&lt;/code&gt;
and &lt;code&gt;protocol&lt;/code&gt; of one element in the Operator &lt;code&gt;Deployment&lt;/code&gt;&#39;s &lt;code&gt;spec.template.spec.containers[*].ports&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;By default, the manager&amp;rsquo;s Deployment is configured to mount a volume containing TLS cert data
created by [cert-manager][cert-manager] into the manager&amp;rsquo;s container.
OLM does &lt;a href=&#34;https://olm.operatorframework.io/docs/advanced-tasks/adding-admission-and-conversion-webhooks/#certificate-authority-requirements&#34;&gt;not yet support cert-manager&lt;/a&gt;, so a &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/blob/163c657/testdata/go/v3/memcached-operator/config/manifests/kustomization.yaml#L12&#34;&gt;JSON patch&lt;/a&gt; was added
to remove this volume and mount such that OLM can itself create and manage certs for your Operator.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note (for Go Operators only):&lt;/strong&gt; If targeting OLM &amp;lt; v0.17.0, the manager&amp;rsquo;s default webhook server
is not configured with the correct cert/key paths; the correct path is
&lt;code&gt;/apiserver.local.config/certificates/apiserver.{cert,key}&lt;/code&gt;.
To cover this case, make the following changes to your &lt;code&gt;main.go&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;
  &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;
  &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;sigs.k8s.io/controller-runtime&amp;#34;&lt;/span&gt;
  &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;sigs.k8s.io/controller-runtime/pkg/webhook&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;

&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;main&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
  &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;

  &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Configure a webhook.Server with the correct path and file names.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// If webhookServer is nil, which will be the case of OLM &amp;gt;= 0.17 is available,
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// the manager will create a server for you using Host, Port,
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// and the default CertDir, KeyName, and CertName.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;webhookServer&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;webhook&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Server&lt;/span&gt;
  &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;legacyOLMCertDir&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;/apiserver.local.config/certificates&amp;#34;&lt;/span&gt;
  &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;info&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;os&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Stat&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;legacyOLMCertDir&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;info&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;IsDir&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;webhookServer&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;webhook&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Server&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
      &lt;span style=&#34;color:#000&#34;&gt;Host&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;     &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;some&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;host&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;gt;,&lt;/span&gt; &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Set this only if normally set in ctrl.Options below.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;      &lt;span style=&#34;color:#000&#34;&gt;Port&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;     &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;some&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;port&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;gt;,&lt;/span&gt; &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Set this only if normally set in ctrl.Options below.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;      &lt;span style=&#34;color:#000&#34;&gt;CertDir&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;  &lt;span style=&#34;color:#000&#34;&gt;legacyOLMCertDir&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
      &lt;span style=&#34;color:#000&#34;&gt;CertName&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;apiserver.crt&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
      &lt;span style=&#34;color:#000&#34;&gt;KeyName&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;  &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;apiserver.key&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
  &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;

  &lt;span style=&#34;color:#000&#34;&gt;mgr&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;NewManager&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;GetConfigOrDie&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(),&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ctrl&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Options&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;Host&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;          &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;some&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;host&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;gt;,&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;Port&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;          &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;some&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;port&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;gt;,&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;WebhookServer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;webhookServer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Host/Port will not be used if webhookServer is nil.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;})&lt;/span&gt;
 
  &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Now you can register webhooks.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The &lt;code&gt;Service&lt;/code&gt; itself will still be placed into the &lt;code&gt;manifests/&lt;/code&gt; directory,
in case other Operator resources require routing. Feel free to remove it otherwise.&lt;/p&gt;
&lt;h2 id=&#34;generate-your-first-release&#34;&gt;Generate your first release&lt;/h2&gt;
&lt;p&gt;You&amp;rsquo;ve recently run &lt;code&gt;operator-sdk init&lt;/code&gt; and created your APIs with &lt;code&gt;operator-sdk create api&lt;/code&gt;. Now you&amp;rsquo;d like to
package your Operator for deployment by OLM. Your Operator is at version &lt;code&gt;v0.0.1&lt;/code&gt;; the &lt;code&gt;Makefile&lt;/code&gt; variable &lt;code&gt;VERSION&lt;/code&gt;
should be set to &lt;code&gt;0.0.1&lt;/code&gt;. You&amp;rsquo;ve also built your operator image, &lt;code&gt;example.com/memcached-operator:v0.0.1&lt;/code&gt;;
if this image tag does not match yours, swap in the correct one in the docs below.&lt;/p&gt;
&lt;h3 id=&#34;bundle-format&#34;&gt;Bundle format&lt;/h3&gt;
&lt;p&gt;A &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/v1.16.1/docs/design/operator-bundle.md&#34;&gt;bundle&lt;/a&gt; consists of manifests (CSV, CRDs, and other supported kinds) and metadata that define an Operator
at a particular version, and an optional &lt;a href=&#34;/docs/testing-operators/scorecard/&#34;&gt;scorecard&lt;/a&gt; configuration file. You may have also heard of a
bundle image. From the bundle docs:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;An Operator Bundle is built as a scratch (non-runnable) container image that
contains operator manifests and specific metadata in designated directories
inside the image. Then, it can be pushed and pulled from an OCI-compliant
container registry. Ultimately, an operator bundle will be used by Operator
Registry and OLM to install an operator in OLM-enabled clusters.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;At this stage in your Operator&amp;rsquo;s development, we only need to worry about generating bundle files;
bundle images become important once you&amp;rsquo;re ready to &lt;a href=&#34;https://operatorhub.io/&#34;&gt;publish&lt;/a&gt; your Operator.&lt;/p&gt;
&lt;p&gt;SDK projects are scaffolded with a &lt;code&gt;Makefile&lt;/code&gt; containing the &lt;code&gt;bundle&lt;/code&gt; recipe by default,
which wraps &lt;code&gt;generate kustomize manifests&lt;/code&gt;, &lt;code&gt;generate bundle&lt;/code&gt;, and other related commands.&lt;/p&gt;
&lt;p&gt;By default &lt;code&gt;make bundle&lt;/code&gt; will generate a CSV, copy CRDs and other supported kinds, generate metadata,
and add your scorecard configuration in the bundle format:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ make bundle
$ tree ./bundle
./bundle
├── manifests
│   ├── cache.example.com_memcacheds.yaml
│   ├── memcached-operator.clusterserviceversion.yaml
│   ├── memcached-operator-controller-manager-metrics-monitor_monitoring.coreos.com_v1_servicemonitor.yaml
│   ├── memcached-operator-controller-manager-metrics-service_v1_service.yaml
│   ├── memcached-operator-metrics-reader_rbac.authorization.k8s.io_v1beta1_clusterrole.yaml
│   └── memcached-operator-webhook-service_v1_service.yaml
├── metadata
│   └── annotations.yaml
└── tests
    └── scorecard
        └── config.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; bundle generation is supposed to be idempotent, so any changes to CSV fields able to be persisted
(marked &lt;em&gt;(user)&lt;/em&gt; or &lt;em&gt;(marker)&lt;/em&gt; &lt;a href=&#34;#csv-fields&#34;&gt;below&lt;/a&gt;) must be made to the base set of manifests, typically found in &lt;code&gt;config/&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Bundle metadata in &lt;code&gt;bundle/metadata/annotations.yaml&lt;/code&gt; contains information about a particular Operator version
available in a registry. OLM uses this information to install specific Operator versions and resolve dependencies.
That file and &lt;code&gt;bundle.Dockerfile&lt;/code&gt; contain the same &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/v1.12.6/docs/design/operator-bundle.md#bundle-annotations&#34;&gt;annotations&lt;/a&gt;, the latter as &lt;code&gt;LABEL&lt;/code&gt;s,
which do not need to be modified in most cases; if you do decide to modify them, both sets of annotations &lt;em&gt;must&lt;/em&gt;
be the same to ensure consistent Operator deployment.&lt;/p&gt;
&lt;h5 id=&#34;channels&#34;&gt;Channels&lt;/h5&gt;
&lt;p&gt;Metadata for each bundle contains channel information as well:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Channels allow package authors to write different upgrade paths for different users (e.g. beta vs. stable).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Channels become important when publishing, but we should still be aware of them beforehand as they&amp;rsquo;re required
values in our metadata. &lt;code&gt;make bundle&lt;/code&gt; writes the channel &lt;code&gt;alpha&lt;/code&gt; by default.&lt;/p&gt;
&lt;h4 id=&#34;validation&#34;&gt;Validation&lt;/h4&gt;
&lt;p&gt;The &lt;code&gt;bundle&lt;/code&gt; recipe includes a call to &lt;code&gt;operator-sdk bundle validate&lt;/code&gt;, which runs a set of required object
validators on your bundle that ensure both its format and content meet the &lt;a href=&#34;https://github.com/operator-framework/operator-registry/blob/v1.16.1/docs/design/operator-bundle.md&#34;&gt;bundle specification&lt;/a&gt;.
These will always be run and cannot be disabled.&lt;/p&gt;
&lt;p&gt;You may also have added &lt;a href=&#34;#csv-fields&#34;&gt;CSV fields&lt;/a&gt; containing useful UI metadata for cluster console display,
and want to ensure that metadata matches some hosted catalog&amp;rsquo;s submission requirements.
The &lt;code&gt;bundle validate&lt;/code&gt; command supports optional validators that can validate these bundle metadata.
These validators are disabled by default, and can be selectively enabled with &lt;code&gt;--select-optional &amp;lt;label-selector&amp;gt;&lt;/code&gt;.
You can list all available optional validators by setting the &lt;code&gt;--list-optional&lt;/code&gt; flag:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ operator-sdk bundle validate --list-optional
NAME           LABELS                                                DESCRIPTION
operatorhub    name=operatorhub                                      OperatorHub.io metadata validation. 
               suite=operatorframework    
community      name=community                                        (stage: alpha) Community Operator bundle validation      
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For example, you want to turn on the &lt;code&gt;operatorhub&lt;/code&gt; validator shown above so you can publish the &lt;code&gt;0.0.1&lt;/code&gt; operator
you recently created on &lt;a href=&#34;https://operatorhub.io/&#34;&gt;OperatorHub.io&lt;/a&gt;. To do so, you can modify your Makefile&amp;rsquo;s &lt;code&gt;bundle&lt;/code&gt; recipe
to validate any further changes you make to bundle UI metadata related to OperatorHub requirements:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-make&#34; data-lang=&#34;make&#34;&gt;&lt;span style=&#34;color:#000&#34;&gt;bundle&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:&lt;/span&gt; ...
  ...
  operator-sdk bundle validate ./bundle --select-optional &lt;span style=&#34;color:#000&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;operatorhub
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Also, see that you can test the bundle against the suite of test to ensure it against all criteria:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;operator-sdk bundle validate ./bundle --select-optional &lt;span style=&#34;color:#000&#34;&gt;suite&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;operatorframework 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The &lt;code&gt;OperatorHub.io&lt;/code&gt; validator in the &lt;code&gt;operatorframework&lt;/code&gt; optional suite allows you to validate that your manifests can work with a Kubernetes cluster of a particular version using the &lt;code&gt;k8s-version&lt;/code&gt; optional key value:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;operator-sdk bundle validate ./bundle --select-optional &lt;span style=&#34;color:#000&#34;&gt;suite&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;operatorframework --optional-values&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;k8s-version&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;1.22
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Documentation on optional validators:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://olm.operatorframework.io/docs/tasks/creating-operator-bundle/#validating-your-bundle&#34;&gt;&lt;code&gt;operatorhub&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: (stage: alpha) The &lt;code&gt;Community&lt;/code&gt; validator allows you to validate your &lt;code&gt;bundle.Dockerfile&lt;/code&gt; configuration against its specific criteria using the &lt;code&gt;image-path&lt;/code&gt; optional key value:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;operator-sdk bundle validate ./bundle --select-optional &lt;span style=&#34;color:#000&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;community --optional-values&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;image-path&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;bundle.Dockerfile
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;package-manifests-format&#34;&gt;Package manifests format&lt;/h3&gt;
&lt;p&gt;A [package manifests][package-manifests] format consists of on-disk manifests (CSV, CRDs and other supported kinds)
and metadata that define an Operator at all versions of that Operator. Each version is contained in its own directory,
with a parent package manifest YAML file containing channel-to-version mappings, much like a bundle&amp;rsquo;s metadata.&lt;/p&gt;
&lt;p&gt;If your Operator is already formatted as a package manifests and you do not wish to migrate to the bundle format yet,
you should add the following to your &lt;code&gt;Makefile&lt;/code&gt; to make development easier:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;For Go-based Operator projects&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-make&#34; data-lang=&#34;make&#34;&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# Options for &amp;#34;packagemanifests&amp;#34;.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#a40000&#34;&gt;ifneq&lt;/span&gt; &lt;span style=&#34;color:#a40000&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;origin&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;FROM_VERSION&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#a40000&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#a40000&#34;&gt;undefined)&lt;/span&gt;
&lt;span style=&#34;color:#000&#34;&gt;PKG_FROM_VERSION&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; --from-version&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;FROM_VERSION&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;span style=&#34;color:#a40000&#34;&gt;endif&lt;/span&gt;
&lt;span style=&#34;color:#a40000&#34;&gt;ifneq&lt;/span&gt; &lt;span style=&#34;color:#a40000&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;origin&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;CHANNEL&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#a40000&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#a40000&#34;&gt;undefined)&lt;/span&gt;
&lt;span style=&#34;color:#000&#34;&gt;PKG_CHANNELS&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; --channel&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;CHANNEL&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;span style=&#34;color:#a40000&#34;&gt;endif&lt;/span&gt;
&lt;span style=&#34;color:#a40000&#34;&gt;ifeq&lt;/span&gt; &lt;span style=&#34;color:#a40000&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;IS_CHANNEL_DEFAULT&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#a40000&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#a40000&#34;&gt;1)&lt;/span&gt;
&lt;span style=&#34;color:#000&#34;&gt;PKG_IS_DEFAULT_CHANNEL&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; --default-channel
&lt;span style=&#34;color:#a40000&#34;&gt;endif&lt;/span&gt;
&lt;span style=&#34;color:#000&#34;&gt;PKG_MAN_OPTS&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;?=&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;PKG_FROM_VERSION&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;PKG_CHANNELS&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;PKG_IS_DEFAULT_CHANNEL&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;

&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# Generate package manifests.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;packagemanifests&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;kustomize&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;manifests&lt;/span&gt;
  operator-sdk generate kustomize manifests -q
  &lt;span style=&#34;color:#204a87&#34;&gt;cd&lt;/span&gt; config/manager &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;KUSTOMIZE&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt; edit &lt;span style=&#34;color:#204a87&#34;&gt;set&lt;/span&gt; image &lt;span style=&#34;color:#000&#34;&gt;controller&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;IMG&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;
  &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;KUSTOMIZE&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt; build config/manifests &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&lt;/span&gt; operator-sdk generate packagemanifests -q --version &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;VERSION&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;PKG_MAN_OPTS&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;For Helm/Ansible-based Operator projects&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-make&#34; data-lang=&#34;make&#34;&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# Options for &amp;#34;packagemanifests&amp;#34;.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#a40000&#34;&gt;ifneq&lt;/span&gt; &lt;span style=&#34;color:#a40000&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;origin&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;FROM_VERSION&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#a40000&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#a40000&#34;&gt;undefined)&lt;/span&gt;
&lt;span style=&#34;color:#000&#34;&gt;PKG_FROM_VERSION&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; --from-version&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;FROM_VERSION&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;span style=&#34;color:#a40000&#34;&gt;endif&lt;/span&gt;
&lt;span style=&#34;color:#a40000&#34;&gt;ifneq&lt;/span&gt; &lt;span style=&#34;color:#a40000&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;origin&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;CHANNEL&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#a40000&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#a40000&#34;&gt;undefined)&lt;/span&gt;
&lt;span style=&#34;color:#000&#34;&gt;PKG_CHANNELS&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; --channel&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;CHANNEL&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;span style=&#34;color:#a40000&#34;&gt;endif&lt;/span&gt;
&lt;span style=&#34;color:#a40000&#34;&gt;ifeq&lt;/span&gt; &lt;span style=&#34;color:#a40000&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;IS_CHANNEL_DEFAULT&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#a40000&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#a40000&#34;&gt;1)&lt;/span&gt;
&lt;span style=&#34;color:#000&#34;&gt;PKG_IS_DEFAULT_CHANNEL&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; --default-channel
&lt;span style=&#34;color:#a40000&#34;&gt;endif&lt;/span&gt;
&lt;span style=&#34;color:#000&#34;&gt;PKG_MAN_OPTS&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;?=&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;PKG_FROM_VERSION&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;PKG_CHANNELS&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;PKG_IS_DEFAULT_CHANNEL&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;

&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# Generate package manifests.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;packagemanifests&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;kustomize&lt;/span&gt;
  operator-sdk generate kustomize manifests -q
  &lt;span style=&#34;color:#204a87&#34;&gt;cd&lt;/span&gt; config/manager &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;KUSTOMIZE&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt; edit &lt;span style=&#34;color:#204a87&#34;&gt;set&lt;/span&gt; image &lt;span style=&#34;color:#000&#34;&gt;controller&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;IMG&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;
  &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;KUSTOMIZE&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt; build config/manifests &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&lt;/span&gt; operator-sdk generate packagemanifests -q --version &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;VERSION&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;PKG_MAN_OPTS&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;By default &lt;code&gt;make packagemanifests&lt;/code&gt; will generate a CSV, a package manifest file, and copy CRDs in the package manifests format:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ make packagemanifests IMG=example.com/memcached-operator:v0.0.1
$ tree ./packagemanifests
./packagemanifests
├── 0.0.1
│   ├── cache.my.domain_memcacheds.yaml
│   └── memcached-operator.clusterserviceversion.yaml
└── memcached-operator.package.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;update-your-operator&#34;&gt;Update your Operator&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s say you added a new API &lt;code&gt;App&lt;/code&gt; with group &lt;code&gt;app&lt;/code&gt; and version &lt;code&gt;v1alpha1&lt;/code&gt; to your Operator project,
and added a port to your manager Deployment in &lt;code&gt;config/manager/manager.yaml&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If using a bundle format, the current version of your CSV can be updated by running:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ make bundle IMG=example.com/memcached-operator:v0.0.1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If using a package manifests format, run:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ make packagemanifests IMG=example.com/memcached-operator:v0.0.1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Running the command for either format will append your new CRD to &lt;code&gt;spec.customresourcedefinitions.owned&lt;/code&gt;,
replace the old data at &lt;code&gt;spec.install.spec.deployments&lt;/code&gt; with your updated Deployment,
and update your existing CSV manifest. The SDK will not overwrite &lt;a href=&#34;#csv-fields&#34;&gt;user-defined&lt;/a&gt;
fields like &lt;code&gt;spec.maintainers&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;upgrade-your-operator&#34;&gt;Upgrade your Operator&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s say you&amp;rsquo;re upgrading your Operator to version &lt;code&gt;v0.0.2&lt;/code&gt;, you&amp;rsquo;ve already updated the &lt;code&gt;VERSION&lt;/code&gt; variable
in your &lt;code&gt;Makefile&lt;/code&gt; to &lt;code&gt;0.0.2&lt;/code&gt;, and built a new operator image &lt;code&gt;example.com/memcached-operator:v0.0.2&lt;/code&gt;.
You also want to add a new channel &lt;code&gt;beta&lt;/code&gt;, and use it as the default channel.&lt;/p&gt;
&lt;p&gt;First, update &lt;code&gt;spec.replaces&lt;/code&gt; in your &lt;a href=&#34;#kustomize-files&#34;&gt;base CSV manifest&lt;/a&gt; to the &lt;em&gt;current&lt;/em&gt; CSV name.
In this case, the change would look like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;spec&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;...&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;  &lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;replaces&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt; &lt;/span&gt;memcached-operator.v0&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;.0.1&lt;/span&gt;&lt;span style=&#34;color:#f8f8f8;text-decoration:underline&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Next, upgrade your bundle. If using a bundle format, a new version of your CSV can be created by running:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ make bundle CHANNELS=beta DEFAULT_CHANNEL=beta IMG=example.com/memcached-operator:v0.0.2
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If using a package manifests format, run:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;$ make packagemanifests FROM_VERSION=0.0.1 CHANNEL=beta IS_CHANNEL_DEFAULT=1 IMG=example.com/memcached-operator:v0.0.2
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Running the command for either format will persist user-defined fields, and updates &lt;code&gt;spec.version&lt;/code&gt; and &lt;code&gt;metadata.name&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;For &lt;code&gt;packagemanifests&lt;/code&gt; only&lt;/strong&gt; The command will also populate &lt;code&gt;spec.replaces&lt;/code&gt; with the old CSV version&amp;rsquo;s name.&lt;/p&gt;
&lt;h2 id=&#34;csv-fields&#34;&gt;CSV fields&lt;/h2&gt;
&lt;p&gt;Below are two lists of fields: the first is a list of all fields the SDK and OLM expect in a CSV, and the second are optional.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;For Go Operators only:&lt;/strong&gt; Several fields require user input (labeled &lt;em&gt;user&lt;/em&gt;) or a &lt;a href=&#34;/docs/building-operators/golang/references/markers&#34;&gt;CSV marker&lt;/a&gt;
(labeled &lt;em&gt;marker&lt;/em&gt;). This list may change as the SDK becomes better at generating CSV&amp;rsquo;s.
These markers are not available to Ansible or Helm project types.&lt;/p&gt;
&lt;p&gt;Required:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;metadata.name&lt;/code&gt; _(user*)_: a *unique* name for this CSV of the format &lt;code&gt;&amp;lt;project-name&amp;gt;.vX.Y.Z&lt;/code&gt;, ex. &lt;code&gt;app-operator.v0.0.1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.displayName&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt; : a name to display for the Operator in Operator Hub.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.version&lt;/code&gt; _(user*)_: semantic version of the Operator, ex. &lt;code&gt;0.0.1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.installModes&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt;: what mode of &lt;a href=&#34;https://github.com/operator-framework/operator-lifecycle-manager/blob/4197455/Documentation/design/building-your-csv.md#operator-metadata&#34;&gt;installation namespacing&lt;/a&gt; OLM should use.
Currently all but &lt;code&gt;MultiNamespace&lt;/code&gt; are supported by SDK Operators.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.customresourcedefinitions&lt;/code&gt;: any CRDs the Operator uses. Certain fields in elements of &lt;code&gt;owned&lt;/code&gt; will be filled by the SDK.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;owned&lt;/code&gt;: all CRDs the Operator deploys itself from it&amp;rsquo;s bundle.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;name&lt;/code&gt;: CRD&amp;rsquo;s &lt;code&gt;metadata.name&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kind&lt;/code&gt;: CRD&amp;rsquo;s &lt;code&gt;spec.names.kind&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;version&lt;/code&gt;: CRD&amp;rsquo;s &lt;code&gt;spec.version&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;description&lt;/code&gt; &lt;em&gt;(marker)&lt;/em&gt; : description of the CRD.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;displayName&lt;/code&gt; &lt;em&gt;(marker)&lt;/em&gt; : display name of the CRD.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;resources&lt;/code&gt; &lt;em&gt;(marker)&lt;/em&gt; : any Kubernetes resources used by the CRD, ex. &lt;code&gt;Pod&lt;/code&gt;&#39;s and &lt;code&gt;ConfigMap&lt;/code&gt;&#39;s.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;specDescriptors&lt;/code&gt; &lt;em&gt;(marker)&lt;/em&gt; : UI hints for inputs and outputs of the Operator&amp;rsquo;s spec.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;statusDescriptors&lt;/code&gt; &lt;em&gt;(marker)&lt;/em&gt; : UI hints for inputs and outputs of the Operator&amp;rsquo;s status.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;actionDescriptors&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt; : UI hints for an Operator&amp;rsquo;s in-cluster actions.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;required&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt; : all CRDs the Operator expects to be present in-cluster, if any.
All &lt;code&gt;required&lt;/code&gt; element fields must be populated manually.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Optional:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;spec.description&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt; : a thorough description of the Operator&amp;rsquo;s functionality.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.keywords&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt; : a list of keywords describing the Operator.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.maintainers&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt; : a list of human or organizational entities maintaining the Operator, with a &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;email&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.provider&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt; : the Operator provider, with a &lt;code&gt;name&lt;/code&gt;; usually an organization.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.labels&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt; : a list of &lt;code&gt;key:value&lt;/code&gt; pairs to be used by Operator internals.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;metadata.annotations.alm-examples&lt;/code&gt;: CR examples, in JSON string literal format, for your CRD&amp;rsquo;s. Ideally one per CRD.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;metadata.annotations.capabilities&lt;/code&gt;: level of Operator capability. See the &lt;a href=&#34;/docs/overview/operator-capabilities/&#34;&gt;Operator maturity model&lt;/a&gt;
for a list of valid values.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.replaces&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt;: the name of the CSV being replaced by this CSV.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.links&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt; : a list of URL&amp;rsquo;s to websites, documentation, etc. pertaining to the Operator or application
being managed, each with a &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;url&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.selector&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt; : selectors by which the Operator can pair resources in a cluster.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.icon&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt; : a base64-encoded icon unique to the Operator, set in a &lt;code&gt;base64data&lt;/code&gt; field with a &lt;code&gt;mediatype&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.maturity&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt;: the Operator&amp;rsquo;s maturity, ex. &lt;code&gt;alpha&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.minKubeVersion&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt;: the minimal Kubernetes version supported by the Operator, ex. &lt;code&gt;1.16.0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.webhookdefinitions&lt;/code&gt;: any webhooks the Operator uses.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.relatedImages&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt;: a list of image tags containing SHA digests &lt;a href=&#34;https://pkg.go.dev/github.com/operator-framework/api@v0.8.1/pkg/operators/v1alpha1#RelatedImage&#34;&gt;mapped to in-CSV names&lt;/a&gt;
that your Operator might require to perform their functions.
&lt;ul&gt;
&lt;li&gt;To get the correct tag for an image available in some remote registry, run &lt;code&gt;docker inspect --format=&#39;{{range $i, $d := .RepoDigests}}{{$d}}{{&amp;quot;\n&amp;quot;}}{{end}}&#39;&lt;/code&gt;
and choose the tag for the desired registry.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.skips&lt;/code&gt; &lt;em&gt;(user)&lt;/em&gt;: the names of one or more CSVs that should be skipped in a catalog&amp;rsquo;s upgrade graph.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;*&lt;/strong&gt; &lt;code&gt;metadata.name&lt;/code&gt; and &lt;code&gt;spec.version&lt;/code&gt; will only be automatically updated from the base CSV
when you set &lt;code&gt;--version&lt;/code&gt; when running &lt;code&gt;generate &amp;lt;bundle|packagemanifests&amp;gt;&lt;/code&gt;.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Testing Operator Deployment with OLM</title>
      <link>/docs/olm-integration/testing-deployment/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/docs/olm-integration/testing-deployment/</guid>
      <description>
        
        
        &lt;p&gt;This document discusses the behavior of &lt;code&gt;operator-sdk &amp;lt;run|cleanup&amp;gt;&lt;/code&gt; subcommands related to OLM deployment,
and assumes you are familiar with &lt;a href=&#34;https://github.com/operator-framework/operator-lifecycle-manager/&#34;&gt;OLM&lt;/a&gt;, related terminology,
and have read the SDK-OLM integration &lt;a href=&#34;https://github.com/operator-framework/operator-sdk/blob/master/proposals/sdk-integration-with-olm.md&#34;&gt;design proposal&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;caveats&#34;&gt;Caveats&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;run bundle&lt;/code&gt;, &lt;code&gt;run bundle-upgrade&lt;/code&gt;, &lt;code&gt;run packagemanifests&lt;/code&gt;, and &lt;code&gt;cleanup&lt;/code&gt; are intended to be used for testing purposes only,
since these commands create a transient image registry that should not be used in production.
Typically a registry is deployed separately and a set of catalog manifests are created in the cluster
to inform OLM of that registry and which Operator versions it can deploy and where to deploy the Operator.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;run bundle&lt;/code&gt; and &lt;code&gt;run packagemanifests&lt;/code&gt; can only deploy one Operator and one version of that Operator at a time,
and &lt;code&gt;run bundle-upgrade&lt;/code&gt; can only upgrade one Operator and one version of that Operator at a time,
hence their intended purpose being testing only.&lt;/li&gt;
&lt;li&gt;If testing a bundle or catalog whose image will be hosted in a registry that is private and/or
has a custom CA, these &lt;a href=&#34;/docs/olm-integration/cli-overview#private-bundle-and-catalog-image-registries&#34;&gt;configuration steps&lt;/a&gt; must be complete.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;operator-sdk-run-bundle-command-overview&#34;&gt;&lt;code&gt;operator-sdk run bundle&lt;/code&gt; command overview&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;operator-sdk run bundle&lt;/code&gt; assumes OLM is already installed and running on your
cluster. It also assumes that your Operator has a valid &lt;a href=&#34;https://github.com/operator-framework/operator-registry/tree/v1.15.3#manifest-format&#34;&gt;bundle&lt;/a&gt;.
See the [creating a bundle][creating-bundle] guide for more information. See the
&lt;a href=&#34;/docs/olm-integration/cli-overview&#34;&gt;CLI overview&lt;/a&gt; for commands to work with an OLM installation
and generate a bundle.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;operator-sdk run bundle &amp;lt;bundle-image&amp;gt; [--index-image=] [--kubeconfig=] [--namespace=] [--timeout=] [--install-mode=(AllNamespace|OwnNamespace|SingleNamespace=)]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let&amp;rsquo;s look at the configuration shared between &lt;code&gt;run bundle&lt;/code&gt;, &lt;code&gt;run packagemanifests&lt;/code&gt;, &lt;code&gt;run bundle-upgrade&lt;/code&gt; and &lt;code&gt;cleanup&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;kubeconfig&lt;/strong&gt;: the local path to a kubeconfig. This uses well-defined default
loading rules to load the config if empty.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;namespace&lt;/strong&gt;: the cluster namespace in which Operator resources are created.
This namespace must already exist in the cluster. This is an optional field
which will default to the kubeconfig context if not provided.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;timeout&lt;/strong&gt;: a time string dictating the maximum time that &lt;code&gt;run&lt;/code&gt; can run. The
command will return an error if the timeout is exceeded.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&amp;rsquo;s look at the anatomy of the &lt;code&gt;run bundle&lt;/code&gt; configuration model:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;bundle-image&lt;/strong&gt;: specifies the Operator bundle image, this is a
required parameter. The bundle image must be pullable.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;index-image&lt;/strong&gt;: specifies an index image in which to inject the given bundle.
This is an optional field which will default to
&lt;code&gt;quay.io/operator-framework/opm:latest&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;install-mode&lt;/strong&gt;: specifies which supported &lt;a href=&#34;https://github.com/operator-framework/operator-lifecycle-manager/blob/master/doc/design/building-your-csv.md#operator-metadata&#34;&gt;&lt;code&gt;installMode&lt;/code&gt;&lt;/a&gt;
should be used to create an &lt;code&gt;OperatorGroup&lt;/code&gt; by configuring its
&lt;code&gt;spec.targetNamespaces&lt;/code&gt; field. The &lt;code&gt;InstallModeType&lt;/code&gt; string passed must be
marked as &amp;ldquo;supported&amp;rdquo; in the CSV being installed.
&lt;ul&gt;
&lt;li&gt;This option understands the following strings (assuming your CSV does as
well):
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;AllNamespaces&lt;/code&gt;: the Operator will watch all namespaces (cluster-scoped
Operators). This is the default.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OwnNamespace&lt;/code&gt;: the Operator will watch its own namespace (from
&lt;strong&gt;namespace&lt;/strong&gt; or the kubeconfig default).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SingleNamespace=&amp;quot;my-ns&amp;quot;&lt;/code&gt;: the Operator will watch a namespace, not
necessarily its own.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;This is an optional parameter, but if the CSV does not support
&lt;code&gt;AllNamespaces&lt;/code&gt; then this parameter becomes &lt;strong&gt;required&lt;/strong&gt; to instruct
&lt;code&gt;run bundle&lt;/code&gt; with the appropriate &lt;code&gt;InstallModeType&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;operator-sdk-run-packagemanifests-command-overview&#34;&gt;&lt;code&gt;operator-sdk run packagemanifests&lt;/code&gt; command overview&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;operator-sdk run packagemanifests&lt;/code&gt; assumes OLM is already installed and
running on your cluster, and that your Operator has a valid
&lt;a href=&#34;https://github.com/operator-framework/operator-registry/tree/v1.5.3#manifest-format&#34;&gt;package manifests format&lt;/a&gt;. See the
&lt;a href=&#34;/docs/olm-integration/cli-overview&#34;&gt;CLI overview&lt;/a&gt; for commands to work with an OLM installation
and generate a package manifests format.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;operator-sdk run packagemanifests &amp;lt;packagemanifests-root-dir&amp;gt; [--version=] [--kubeconfig=] [--namespace=] [--timeout=] [--install-mode=(AllNamespace|OwnNamespace|SingleNamespace=)]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let&amp;rsquo;s look at the configuration shared between &lt;code&gt;run bundle&lt;/code&gt;, &lt;code&gt;run packagemanifests&lt;/code&gt; and &lt;code&gt;cleanup&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;kubeconfig&lt;/strong&gt;: the local path to a kubeconfig. This uses well-defined default
loading rules to load the config if empty.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;namespace&lt;/strong&gt;: the cluster namespace in which Operator resources are created.
This namespace must already exist in the cluster. This is an optional field
which will default to the kubeconfig context if not provided.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;timeout&lt;/strong&gt;: a time string dictating the maximum time that &lt;code&gt;run&lt;/code&gt; can run. The
command will return an error if the timeout is exceeded.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&amp;rsquo;s look at the anatomy of the &lt;code&gt;run packagemanifests&lt;/code&gt; configuration model:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;packagemanifests-root-dir&lt;/strong&gt;: a directory containing the Operator&amp;rsquo;s package
manifests, this is a required parameter.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;install-mode&lt;/strong&gt;: specifies which supported &lt;a href=&#34;https://github.com/operator-framework/operator-lifecycle-manager/blob/master/doc/design/building-your-csv.md#operator-metadata&#34;&gt;&lt;code&gt;installMode&lt;/code&gt;&lt;/a&gt;
should be used to create an &lt;code&gt;OperatorGroup&lt;/code&gt; by configuring its
&lt;code&gt;spec.targetNamespaces&lt;/code&gt; field. The &lt;code&gt;InstallModeType&lt;/code&gt; string passed must be
marked as &amp;ldquo;supported&amp;rdquo; in the CSV being installed.
&lt;ul&gt;
&lt;li&gt;This option understands the following strings (assuming your CSV does as
well):
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;AllNamespaces&lt;/code&gt;: the Operator will watch all namespaces (cluster-scoped
Operators). This is the default.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OwnNamespace&lt;/code&gt;: the Operator will watch its own namespace (from
&lt;strong&gt;namespace&lt;/strong&gt; or the kubeconfig default).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SingleNamespace=&amp;quot;my-ns&amp;quot;&lt;/code&gt;: the Operator will watch a namespace, not
necessarily its own.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;This is an optional parameter, but if the CSV does not support
&lt;code&gt;AllNamespaces&lt;/code&gt; then this parameter becomes &lt;strong&gt;required&lt;/strong&gt; to instruct
&lt;code&gt;run packagemanifests&lt;/code&gt; with the appropriate &lt;code&gt;InstallModeType&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;version&lt;/strong&gt;: the version of the Operator to deploy. It must be a semantic
version, ex. 0.0.1. This version must match the version of the CSV manifest
found in &lt;strong&gt;manifests-dir&lt;/strong&gt;, e.g. &lt;code&gt;packagemanifests/0.0.1&lt;/code&gt; in an Operator
SDK project.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;operator-sdk-run-bundle-upgrade-command-overview&#34;&gt;&lt;code&gt;operator-sdk run bundle-upgrade&lt;/code&gt; command overview&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;operator-sdk run bundle-upgrade&lt;/code&gt; assumes OLM is already installed and running on your
cluster and that the Operator has a valid &lt;a href=&#34;https://github.com/operator-framework/operator-registry/tree/v1.15.3#manifest-format&#34;&gt;bundle&lt;/a&gt;. It also assumes that
the previous version of the Operator was either deployed on the cluster using &lt;code&gt;run bundle&lt;/code&gt;
command or traditionally via OLM. Another assumption of this command is that the newer operator bundle
should not exist in the index image, if the previous version of the operator bundle was installed
traditionally using OLM. This will cause the registry pod to fail as the bundle is already added to the
index that provides package and csv. See the &lt;a href=&#34;/docs/olm-integration/cli-overview&#34;&gt;CLI overview&lt;/a&gt; for commands to work with
an OLM installation and generate a bundle.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;operator-sdk run bundle-upgrade &amp;lt;bundle-image&amp;gt; [--kubeconfig=] [--namespace=] [--timeout=] 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let&amp;rsquo;s look at the anatomy of the &lt;code&gt;run bundle-upgrade&lt;/code&gt; configuration model:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;bundle-image&lt;/strong&gt;: specifies the Operator bundle image, this is a
required parameter. The bundle image must be pullable.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;operator-sdk-cleanup-command-overview&#34;&gt;&lt;code&gt;operator-sdk cleanup&lt;/code&gt; command overview&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;operator-sdk cleanup&lt;/code&gt; assumes an Operator was deployed using &lt;code&gt;run bundle&lt;/code&gt; or
&lt;code&gt;run packagemanifests&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;operator-sdk cleanup &amp;lt;operatorPackageName&amp;gt; [--delete-all=] [--delete-crds=] [--delete-operator-groups=] [--kubeconfig=] [--namespace=] [--timeout=]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let&amp;rsquo;s look at the configuration shared between &lt;code&gt;run bundle&lt;/code&gt;, &lt;code&gt;run packagemanifests&lt;/code&gt; and &lt;code&gt;cleanup&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;kubeconfig&lt;/strong&gt;: the local path to a kubeconfig. This uses well-defined default
loading rules to load the config if empty.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;namespace&lt;/strong&gt;: the cluster namespace in which Operator resources are created.
This namespace must already exist in the cluster. This is an optional field
which will default to the kubeconfig context if not provided.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;timeout&lt;/strong&gt;: a time string dictating the maximum time that &lt;code&gt;run&lt;/code&gt; can run. The
command will return an error if the timeout is exceeded.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&amp;rsquo;s look at the anatomy of the &lt;code&gt;cleanup&lt;/code&gt; configuration model:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;operatorPackageName&lt;/strong&gt;: the Operator&amp;rsquo;s package name which you want to remove
from the cluster, e.g. memcached-operator. This is a required parameter.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;delete-all&lt;/strong&gt;: a boolean indicating to enable all the delete flags that are present. This is an optional
field which will default to true if not provided. If set to true, it will enable all the delete flags to be true. If set to false, it will enable specific delete flags.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;delete-crds&lt;/strong&gt;: a boolean indicating to delete all owned CRDs and CRs. This is an optional field
which will default to false if not provided. If set to true, owned CRDs and CRs
will be deleted.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;delete-operator-groups&lt;/strong&gt;: a boolean indicating to delete all operator groups. This is an optional field
which will default to false if not provided. If set to true, operator groups will be deleted.&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
  </channel>
</rss>
