<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Operator Lifecycle Manager – Core Tasks</title><link>https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/tasks/</link><description>Recent content in Core Tasks on Operator Lifecycle Manager</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Fri, 30 Apr 2021 00:00:00 +0000</lastBuildDate><atom:link href="https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/tasks/index.xml" rel="self" type="application/rss+xml"/><item><title>Docs: Creating operator manifests</title><link>https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/tasks/creating-operator-manifests/</link><pubDate>Wed, 25 Mar 2020 00:00:00 +0000</pubDate><guid>https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/tasks/creating-operator-manifests/</guid><description>
&lt;p>OLM requires you to provide metadata about your operator, so that the operator&amp;rsquo;s lifecycle can be managed safely on a cluster. This section introduces you to the process of packaging the metadata in a format that is compatible with OLM.&lt;/p>
&lt;p>This is very similar to packaging software for a traditional operating system - think of the packaging step for OLM as the stage at which you make your rpm, dep, or apk bundle.&lt;/p>
&lt;h2 id="writing-your-operator-manifests">Writing your Operator Manifests&lt;/h2>
&lt;p>OLM uses a CRD called &lt;code>ClusterServiceVersion&lt;/code> (CSV) to describe a single instance of a version of an operator. This is the main entry point for packaging an operator for OLM.&lt;/p>
&lt;p>There are two important ways to think about the CSV:&lt;/p>
&lt;ol>
&lt;li>Like an &lt;code>rpm&lt;/code> or &lt;code>deb&lt;/code>, it collects metadata about the operator that is required to install it onto the cluster.&lt;/li>
&lt;li>Like a &lt;code>Deployment&lt;/code> that can stamp out &lt;code>Pod&lt;/code>s from a template, the &lt;code>ClusterServiceVersion&lt;/code> describes a template for the operator &lt;code>Deployment&lt;/code> and can stamp them out.&lt;/li>
&lt;/ol>
&lt;p>This is all in service of ensuring that when a user installs an operator from OLM, they can understand what changes are happening to the cluster, and OLM can ensure that installing the operator is a safe operation.&lt;/p>
&lt;h3 id="starting-from-an-existing-set-of-operator-manifests">Starting from an existing set of operator manifests&lt;/h3>
&lt;p>For this example, we&amp;rsquo;ll use the example manifests from &lt;a href="https://github.com/operator-framework/operator-sdk-samples/tree/v0.19.2/go/memcached-operator/deploy">the example memcached operator&lt;/a>.&lt;/p>
&lt;p>These manifests consist of:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>CRDs&lt;/strong> that define the APIs your operator will manage.&lt;/li>
&lt;li>&lt;strong>Operator&lt;/strong> (&lt;code>operator.yaml&lt;/code>), containing the&lt;code>Deployment&lt;/code> that runs your operator pods.&lt;/li>
&lt;li>&lt;strong>RBAC&lt;/strong> (&lt;code>role.yaml&lt;/code>, &lt;code>role_binding.yaml&lt;/code>, &lt;code>service_account.yaml&lt;/code>) that configures the service account permissions your operator requires.&lt;/li>
&lt;/ul>
&lt;p>Building a minimal &lt;code>ClusterServiceVersion&lt;/code> from these manifests requires transplanting the contents of the Operator definition and the RBAC definitions into a CSV. Together, your CSV and CRDs will form the package that you give to OLM to install an operator.&lt;/p>
&lt;h4 id="basic-metadata-optional">Basic Metadata (Optional)&lt;/h4>
&lt;p>Let&amp;rsquo;s start with a CSV that only contains some descriptive metadata:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">apiVersion&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">operators.coreos.com/v1alpha1&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">kind&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">ClusterServiceVersion&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">metadata&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">annotations&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">name&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">memcached-operator.v0.10.0&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">spec&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">description&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">This is an operator for memcached.&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">displayName&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">Memcached Operator&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">keywords&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#000">memcached&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#000">app&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">maintainers&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#204a87;font-weight:bold">email&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">corp@example.com&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">name&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">Some Corp&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">maturity&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">alpha&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">provider&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">name&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">Example&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">url&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">www.example.com&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">version&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">0.10.0&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">minKubeVersion&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1.20.0&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Most of these fields are optional, but they provide an opportunity to describe your operator to potential or current users.&lt;/p>
&lt;h4 id="installation-metadata-required">Installation Metadata (Required)&lt;/h4>
&lt;p>The next section to add to the CSV is the Install Strategy - this tells OLM about the runtime components of your operator and their requirements.&lt;/p>
&lt;p>Here is an example of the basic structure of an install strategy:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">apiVersion&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">operators.coreos.com/v1alpha1&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">kind&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">ClusterServiceVersion&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">metadata&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">annotations&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">name&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">memcached-operator.v0.10.0&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">spec&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">install&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic"># strategy indicates what type of deployment artifacts are used&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">strategy&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">deployment&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic"># spec for the deployment strategy is a list of deployment specs and required permissions - similar to a pod template used in a deployment&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">spec&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">permissions&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#204a87;font-weight:bold">serviceAccountName&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">memcached-operator&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">rules&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#204a87;font-weight:bold">apiGroups&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#4e9a06">&amp;#34;&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">resources&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#000">pods&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">verbs&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#4e9a06">&amp;#39;*&amp;#39;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic"># the rest of the rules&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic"># permissions required at the cluster scope&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">clusterPermissions&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#204a87;font-weight:bold">serviceAccountName&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">memcached-operator&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">rules&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#204a87;font-weight:bold">apiGroups&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#4e9a06">&amp;#34;&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">resources&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#000">serviceaccounts&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">verbs&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#4e9a06">&amp;#39;*&amp;#39;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic"># the rest of the rules&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">deployments&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#204a87;font-weight:bold">name&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">memcached-operator&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">spec&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">replicas&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic"># the rest of a deployment spec&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>deployments&lt;/code> is an array - your operator may be composed of several seperate components that should all be deployed and versioned together.&lt;/p>
&lt;p>It&amp;rsquo;s also important to tell OLM the ways in which your operator can be deployed, or its &lt;code>installModes&lt;/code>. InstallModes indicate if your operator can be configured to watch, one, some, or all namespaces. Please see the &lt;a href="https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/advanced-tasks/operator-scoping-with-operatorgroups">document on operator scoping with operatorgroups&lt;/a> for more information.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">apiVersion&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">operators.coreos.com/v1alpha1&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">kind&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">ClusterServiceVersion&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">metadata&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">name&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">memcached-operator.v0.10.0&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">spec&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic"># ...&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">installModes&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#204a87;font-weight:bold">supported&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">true&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">type&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">OwnNamespace&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#204a87;font-weight:bold">supported&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">true&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">type&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">SingleNamespace&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#204a87;font-weight:bold">supported&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">false&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">type&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">MultiNamespace&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#204a87;font-weight:bold">supported&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">true&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">type&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">AllNamespaces&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>Using &lt;code>faq&lt;/code> to build an install strategy from an existing deployment and rbac&lt;/strong>&lt;/p>
&lt;p>&lt;code>faq&lt;/code> is a wrapper around &lt;code>jq&lt;/code> that can handle multiple input and output formats, like the yaml we&amp;rsquo;re working with now. The following example requires that &lt;a href="https://github.com/jzelinskie/faq#installation">faq be installed&lt;/a> and references &lt;a href="https://github.com/operator-framework/operator-sdk-samples/tree/v0.19.2/go/memcached-operator/deploy">the example memcached operator&lt;/a>.&lt;/p>
&lt;p>Here is a simple &lt;code>faq&lt;/code> script that can generate an install strategy from a single deployment:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>faq -f yaml &lt;span style="color:#4e9a06">&amp;#39;{install: {strategy: &amp;#34;deployment&amp;#34;, spec:{ deployments: [{name: .metadata.name, template: .spec }] }}}&amp;#39;&lt;/span> operator.yaml
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If you have an existing CSV &lt;code>csv.yaml&lt;/code> (refer to the example from Basic Metadata) and you&amp;rsquo;d like to insert or update an install strategy from a deployment &lt;code>operator.yaml&lt;/code>, a role &lt;code>role.yaml&lt;/code>, and a service account &lt;code>service_account.yaml&lt;/code>, that is also possible:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>faq -f yaml -o yaml --slurp &lt;span style="color:#4e9a06">&amp;#39;.[0].spec.install = {strategy: &amp;#34;deployment&amp;#34;, spec:{ deployments: [{name: .[1].metadata.name, template: .[1].spec }], permissions: [{serviceAccountName: .[3].metadata.name, rules: .[2].rules }]}} | .[0]&amp;#39;&lt;/span> csv.yaml operator.yaml role.yaml service_account.yaml
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="defining-apis-required">Defining APIs (Required)&lt;/h4>
&lt;p>By definition, operators are programs that can talk to the Kubernetes API. Often, they are also programs that &lt;em>extend&lt;/em> the Kubernetes API, by providing an interface via &lt;code>CustomResourceDefinition&lt;/code>s or, less frequently, &lt;code>APIService&lt;/code>s.&lt;/p>
&lt;h5 id="owned-apis">Owned APIs&lt;/h5>
&lt;p>Exactly which APIs are used and which APIs are watched or owned is important metadata for OLM. OLM uses this information to determine if dependencies are met and ensure that no two operators fight over the same resources in a cluster.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">apiVersion&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">operators.coreos.com/v1alpha1&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">kind&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">ClusterServiceVersion&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">metadata&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">name&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">memcached-operator.v0.10.0&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">spec&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic"># ...&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">customresourcedefinitions&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">owned&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic"># a list of CRDs that this operator owns&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic"># name is the metadata.name of the CRD (which is of the form &amp;lt;plural&amp;gt;.&amp;lt;group&amp;gt;)&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#204a87;font-weight:bold">name&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">memcacheds.cache.example.com&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic"># version is the spec.versions[].name value defined in the CRD&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">version&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">v1alpha1&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic"># kind is the CamelCased singular value defined in spec.names.kind of the CRD.&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">kind&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">Memcached&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic"># human-friendly display name of the CRD for rendering in graphical consoles (optional)&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">displayName&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">Memcached Cluster&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic"># a short description of the CRDs purpose for rendering in graphical consoles (optional)&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">description&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">Represents a memcached cluster&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="required-apis">Required APIs&lt;/h5>
&lt;p>Similarly, there is a section &lt;code>spec.customresourcedefinitions.required&lt;/code>, where dependencies can be specified. The operators that provide those APIs will be discovered and installed by OLM if they have not been installed.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">apiVersion&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">operators.coreos.com/v1alpha1&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">kind&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">ClusterServiceVersion&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">metadata&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">name&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">other-operator.v1.0&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">spec&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic"># ...&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">customresourcedefinitions&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">required&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic"># a list of CRDs that this operator requires&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic"># name is the metadata.name of the CRD (which is of the form &amp;lt;plural&amp;gt;.&amp;lt;group&amp;gt;)&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#204a87;font-weight:bold">name&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">others.example.com&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic"># version is the spec.versions[].name value defined in the CRD&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">version&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">v1alpha1&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic"># kind is the CamelCased singular value defined in spec.names.kind of the CRD.&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">kind&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">Other&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Dependency resolution and ownership is discussed more in depth in the &lt;a href="https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/concepts/olm-architecture/dependency-resolution/">here&lt;/a>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">apiVersion&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">operators.coreos.com/v1alpha1&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">kind&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">ClusterServiceVersion&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">metadata&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">name&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">memcached-operator.v0.10.0&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">spec&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic"># ...&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">customresourcedefinitions&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">owned&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic"># a list of CRDs that this operator owns&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic"># name is the metadata.name of the CRD (which is of the form &amp;lt;plural&amp;gt;.&amp;lt;group&amp;gt;)&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#204a87;font-weight:bold">name&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">memcacheds.cache.example.com&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic"># version is the spec.versions[].name value defined in the CRD&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">version&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">v1alpha1&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#8f5902;font-style:italic"># kind is the CamelCased singular value defined in spec.names.kind of the CRD.&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">kind&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">Memcached&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="nativeapis-recommended">NativeAPIs (recommended)&lt;/h5>
&lt;p>There are often cases where you wish to depend on an API that is either provided natively by the platform (i.e. &lt;code>Pod&lt;/code>) or sometimes by another operator that is outside the control of OLM.&lt;/p>
&lt;p>In those cases, those dependencies can be described in the CSV as well, via &lt;code>nativeAPIs&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">apiVersion&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">operators.coreos.com/v1alpha1&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">kind&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">ClusterServiceVersion&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">metadata&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">name&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">other-operator.v1.0&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">spec&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">nativeAPIs&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#204a87;font-weight:bold">group&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">version&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">v1&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">kind&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">Pod&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The absence of any required &lt;code>nativeAPIs&lt;/code> from a cluster will pause the installation of the operator, and &lt;code>OLM&lt;/code> will write a status into the &lt;code>CSV&lt;/code> indicating the missing APIs.&lt;/p>
&lt;p>TODO: example status&lt;/p>
&lt;p>&lt;code>nativeAPIs&lt;/code> is an optional field, but the more information you give OLM about the context in which your operator should be running, the more informed decisions OLM can make.&lt;/p>
&lt;h2 id="packaging-additional-objects-alongside-an-operator">Packaging Additional Objects Alongside an Operator&lt;/h2>
&lt;p>Operators can include additional objects alongside their &lt;code>CSV&lt;/code> in the &lt;code>/manifests&lt;/code> directory. These objects should be YAML files and valid kubernetes objects. The following objects are supported as of OLM 0.16.0:&lt;/p>
&lt;ul>
&lt;li>Secret&lt;/li>
&lt;li>ClusterRole&lt;/li>
&lt;li>ClusterRoleBinding&lt;/li>
&lt;li>ConfigMap&lt;/li>
&lt;li>ServiceAccount&lt;/li>
&lt;li>Service&lt;/li>
&lt;li>Role&lt;/li>
&lt;li>RoleBinding&lt;/li>
&lt;li>PrometheusRule&lt;/li>
&lt;li>ServiceMonitor&lt;/li>
&lt;li>&lt;a href="https://github.com/operator-framework/operator-lifecycle-manager/blob/master/doc/design/adding-pod-disruption-budgets.md">PodDisruptionBudget&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/operator-framework/operator-lifecycle-manager/blob/master/doc/design/adding-priority-classes.md">PriorityClass&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/operator-framework/operator-lifecycle-manager/blob/master/doc/design/adding-vertical-pod-autoscaler.md">VerticalPodAutoscaler&lt;/a>&lt;/li>
&lt;li>ConsoleYAMLSample&lt;/li>
&lt;li>ConsoleQuickStart&lt;/li>
&lt;li>ConsoleCLIDownload&lt;/li>
&lt;li>ConsoleLink&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Note&lt;/strong>: some of these objects can affect an upgrade of the cluster and potentially cause problems for workloads unrelated to your operator. Be sure to understand the safe use of these objects before packaging them with your operator. See the docs linked above for more information on these objects as they relate to OLM.*&lt;/p>
&lt;h3 id="limitations-on-pod-disruption-budgets">Limitations on Pod Disruption Budgets&lt;/h3>
&lt;p>No limitations are placed on the contents of a PDB at this time when installing on-cluster.
However, the following are suggested guidelines to follow when including PDB objects in a bundle.&lt;/p>
&lt;ul>
&lt;li>maxUnavailable field cannot be set to 0 or 0%.
&lt;ul>
&lt;li>This can make a node impossible to drain and block important lifecycle actions like operator upgrades or even cluster upgrades.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>minAvailable field cannot be set to 100%.
&lt;ul>
&lt;li>This can make a node impossible to drain and block important lifecycle actions like operator upgrades or even cluster upgrades.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h3 id="limitations-on-priority-classes">Limitations on Priority Classes&lt;/h3>
&lt;p>No limitations are placed on the contents of a PriorityClass manifest at this time when installing on-cluster.
However, the following is a suggested guideline to follow when including PriorityClass objects in a bundle.&lt;/p>
&lt;ul>
&lt;li>globalDefault should always be false on a PriorityClass included in a bundle.
&lt;ul>
&lt;li>Setting globalDefault on a PriorityClass means that all pods in the cluster without an explicit priority class will use this default PriorityClass. This can unintentionally affect other pods running in the cluster.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h4 id="extension-apiservers-and-apiservices">Extension apiservers and APIServices&lt;/h4>
&lt;p>TODO: Document on extension apiservers for operators that do not rely on CRDs to provide its API.&lt;/p>
&lt;h4 id="advanced-and-optional-features">Advanced and Optional features&lt;/h4>
&lt;p>TODO: Documentation for advanced operator configuration which includes additional suggestions for further integration with OLM.&lt;/p>
&lt;h3 id="operator-sdk">Operator SDK&lt;/h3>
&lt;p>You can also generate the manifests for your bundle using the &lt;code>operator-sdk&lt;/code> binary. Checkout the documentation for generating CSV using &lt;code>operator-sdk&lt;/code> &lt;a href="https://sdk.operatorframework.io/docs/olm-integration/generation/">here&lt;/a>.&lt;/p></description></item><item><title>Docs: Creating an Operator Bundle</title><link>https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/tasks/creating-operator-bundle/</link><pubDate>Mon, 11 Jan 2021 00:00:00 +0000</pubDate><guid>https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/tasks/creating-operator-bundle/</guid><description>
&lt;h2 id="prerequisites">Prerequisites&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://github.com/operator-framework/operator-registry/releases">opm&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://docs.docker.com/install/">docker&lt;/a> version &lt;code>17.03&lt;/code>+ or &lt;a href="https://github.com/containers/libpod/blob/master/install.md">podman&lt;/a> &lt;code>v1.2.0+&lt;/code> or &lt;a href="https://github.com/containers/buildah/blob/master/install.md">buildah&lt;/a> &lt;code>v1.7+&lt;/code>.&lt;/li>
&lt;/ul>
&lt;h1 id="operator-bundle">Operator Bundle&lt;/h1>
&lt;p>An Operator Bundle is a container image that stores Kubernetes manifests and metadata associated with an operator. A bundle is meant to represent a specific version of an operator on cluster. Once you have the &lt;a href="https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/tasks/creating-operator-manifests">ClusterServiceVersion(CSV) for your operator&lt;/a>, you can create an operator bundle using the CSV and the CRDs for your operator.&lt;/p>
&lt;p>We refer to a directory of files with one ClusterServiceVersion as a &lt;code>bundle&lt;/code> that includes a CSV and the CRDs in its manifest directory, though additional kubernetes objects may be included. The directory also includes an annotations file in its metadata folder which defines some higher level aggregate data that helps to describe the format and package information about how the bundle should be added into a catalog of bundles. Finally, a Dockerfile can be built from the information in the directory to build the operator bundle image.&lt;/p>
&lt;pre tabindex="0">&lt;code> # example bundle
etcd
├── manifests
│ ├── etcdcluster.crd.yaml
│ └── etcdoperator.clusterserviceversion.yaml
├── metadata
│ └── annotations.yaml
└── Dockerfile
&lt;/code>&lt;/pre>&lt;h3 id="contents-of-annotationsyaml-and-the-dockerfile">Contents of annotations.yaml and the Dockerfile&lt;/h3>
&lt;p>The &lt;code>annotations.yaml&lt;/code> and the &lt;code>Dockerfile&lt;/code> can be generated using the &lt;code>opm&lt;/code> tool&amp;rsquo;s &lt;code>alpha bundle generate&lt;/code> command.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>Usage:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> opm alpha bundle generate &lt;span style="color:#ce5c00;font-weight:bold">[&lt;/span>flags&lt;span style="color:#ce5c00;font-weight:bold">]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Flags:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> -c, --channels string The list of channels that bundle image belongs to
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> -e, --default string The default channel &lt;span style="color:#204a87;font-weight:bold">for&lt;/span> the bundle image
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> -d, --directory string The directory where bundle manifests &lt;span style="color:#204a87;font-weight:bold">for&lt;/span> a specific version are located.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> -h, --help &lt;span style="color:#204a87">help&lt;/span> &lt;span style="color:#204a87;font-weight:bold">for&lt;/span> generate
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> -u, --output-dir string Optional output directory &lt;span style="color:#204a87;font-weight:bold">for&lt;/span> operator manifests
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> -p, --package string The name of the package that bundle image belongs to
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Note:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> * All manifests yaml must be in the same directory.
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>For example, to generate the &lt;code>annotations.yaml&lt;/code> and &lt;code>Dockerfile&lt;/code> for the example bundle mentioned above, the command for the &lt;code>generate&lt;/code> task is:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ opm alpha bundle generate --directory ./etcd --package etcd --channels stable --default stable
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>After the generate command is executed, the &lt;code>Dockerfile&lt;/code> is generated in the directory where command is run. By default, the &lt;code>annotations.yaml&lt;/code> file is located in a folder named &lt;code>metadata&lt;/code> in the same root directory as the input directory containing manifests.&lt;/p>
&lt;p>If the &lt;code>--output-dir&lt;/code> parameter is specified, that directory becomes the parent for a new pair of folders &lt;code>manifests/&lt;/code> and &lt;code>metadata/&lt;/code>, where &lt;code>manifests/&lt;/code> is a copy of the passed in directory of manifests and &lt;code>metadata/&lt;/code> is the folder containing annotations.yaml:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ tree etcd
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>etcd
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── manifests
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│ ├── etcdcluster.crd.yaml
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│ └── etcdoperator.clusterserviceversion.yaml
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── my-output-manifest-dir
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│ ├── manifests
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│ │ ├── etcdcluster.crd.yaml
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│ │ └── etcdoperator.clusterserviceversion.yaml
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│ └── metadata
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│ └── annotations.yaml
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>└── Dockerfile
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The &lt;code>annotations.yaml&lt;/code> contains the following information as labels that are used to annotate the operator bundle container image:&lt;/p>
&lt;ul>
&lt;li>The label &lt;code>operators.operatorframework.io.bundle.mediatype.v1&lt;/code> reflects the media type or format of the operator bundle. It could be helm charts, plain Kubernetes manifests etc.&lt;/li>
&lt;li>The label &lt;code>operators.operatorframework.io.bundle.manifests.v1&lt;/code> reflects the path in the image to the directory that contains the operator manifests. This label is reserved for the future use and is set to &lt;code>manifests/&lt;/code> for the time being.&lt;/li>
&lt;li>The label &lt;code>operators.operatorframework.io.bundle.metadata.v1&lt;/code> reflects the path in the image to the directory that contains metadata files about the bundle. This label is reserved for the future use and is set to &lt;code>metadata/&lt;/code> for the time being.&lt;/li>
&lt;li>The &lt;code>manifests.v1&lt;/code> and &lt;code>metadata.v1&lt;/code> labels imply the bundle type:
&lt;ul>
&lt;li>The value &lt;code>manifests.v1&lt;/code> implies that this bundle contains operator manifests.&lt;/li>
&lt;li>The value &lt;code>metadata.v1&lt;/code> implies that this bundle has operator metadata.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>The label &lt;code>operators.operatorframework.io.bundle.package.v1&lt;/code> reflects the package name of the bundle.&lt;/li>
&lt;li>The label &lt;code>operators.operatorframework.io.bundle.channels.v1&lt;/code> reflects the list of channels the bundle is subscribing to when added into an operator registry&lt;/li>
&lt;li>The label &lt;code>operators.operatorframework.io.bundle.channel.default.v1&lt;/code> reflects the default channel an operator should be subscribed to when installed from a registry. This label is optional if the default channel has been set by previous bundles and the default channel is unchanged for this bundle.&lt;/li>
&lt;/ul>
&lt;p>The &lt;code>annotations.yaml&lt;/code> file generated in the example above would look like:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">annotations&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">operators.operatorframework.io.bundle.mediatype.v1&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;registry+v1&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">operators.operatorframework.io.bundle.manifests.v1&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;manifests/&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">operators.operatorframework.io.bundle.metadata.v1&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;metadata/&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">operators.operatorframework.io.bundle.package.v1&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;etcd&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">operators.operatorframework.io.bundle.channels.v1&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;stable&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">operators.operatorframework.io.bundle.channel.default.v1&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;stable&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The &lt;code>Dockerfile&lt;/code> generated in the example above would look like:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-Dockerfile" data-lang="Dockerfile">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">FROM&lt;/span>&lt;span style="color:#4e9a06"> scratch&lt;/span>&lt;span style="color:#a40000">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a40000">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a40000">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">LABEL&lt;/span> operators.operatorframework.io.bundle.mediatype.v1&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>registry+v1&lt;span style="color:#a40000">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a40000">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">LABEL&lt;/span> operators.operatorframework.io.bundle.manifests.v1&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>manifests/&lt;span style="color:#a40000">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a40000">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">LABEL&lt;/span> operators.operatorframework.io.bundle.metadata.v1&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>metadata/&lt;span style="color:#a40000">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a40000">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">LABEL&lt;/span> operators.operatorframework.io.bundle.package.v1&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>test-operator&lt;span style="color:#a40000">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a40000">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">LABEL&lt;/span> operators.operatorframework.io.bundle.channels.v1&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>beta,stable&lt;span style="color:#a40000">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a40000">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">LABEL&lt;/span> operators.operatorframework.io.bundle.channel.default.v1&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>stable&lt;span style="color:#a40000">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a40000">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a40000">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">ADD&lt;/span> test/*.yaml /manifests&lt;span style="color:#a40000">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a40000">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">ADD&lt;/span> test/metadata/annotations.yaml /metadata/annotations.yaml&lt;span style="color:#a40000">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h1 id="bundle-images">Bundle images&lt;/h1>
&lt;p>An Operator Bundle is built as a scratch (i.e non-runnable) container image that contains information about the operator manifests and metadata inside the image(stored in a database inside the image). The image can then be pushed and pulled from an &lt;a href="https://github.com/opencontainers/image-spec/blob/master/spec.md">OCI-compliant&lt;/a> container registry.&lt;/p>
&lt;p>The &lt;code>opm&lt;/code> tool can be used to interact directly with these images. Once you have your manifests defined and have created a directory in the format defined above, building the image is as simple as defining a Dockerfile and building that image:&lt;/p>
&lt;pre tabindex="0">&lt;code>&lt;/code>&lt;/pre>&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>$ podman build -t quay.io/my-container-registry-namespace/my-manifest-bundle:latest -f bundle.Dockerfile .
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Once you have built the container, you can publish it like any other container image:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>$ podman push quay.io/my-container-registry-namespace/my-manifest-bundle:latest
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Of course, this build step can be done with any other OCI spec container tools like &lt;code>docker&lt;/code>, &lt;code>buildah&lt;/code>, &lt;code>libpod&lt;/code>, etc&lt;/p>
&lt;h2 id="validating-your-bundle">Validating your bundle&lt;/h2>
&lt;p>Once you&amp;rsquo;ve created your bundle, you will want to ensure that your bundle is valid and in the correct format. The &lt;a href="https://github.com/operator-framework/api/tree/master/pkg/validation">api&lt;/a> library contains a validation library that is used by operator-framework tools like &lt;code>operator-sdk&lt;/code> and &lt;code>opm&lt;/code> to validate operator bundles. For more information on validating via the &lt;code>operator-sdk&lt;/code> see the &lt;a href="https://sdk.operatorframework.io/docs/cli/operator-sdk_bundle_validate/#operator-sdk-bundle-validate">&lt;code>operator-sdk bundle validate&lt;/code> documentation&lt;/a>.&lt;/p>
&lt;p>The &lt;code>opm alpha bundle validate&lt;/code> command will validate a bundle image from a remote registry to determine if its format and content information are accurate.
The following validators will run by default on every invocation of the command.&lt;/p>
&lt;ul>
&lt;li>CSV validator - validates the CSV name and replaces fields.&lt;/li>
&lt;li>CRD validator - validates the CRDs OpenAPI V3 schema.&lt;/li>
&lt;li>Bundle validator - validates the bundle format and annotations.yaml file as well as the optional dependencies.yaml file.&lt;/li>
&lt;/ul>
&lt;p>For example:&lt;/p>
&lt;p>&lt;code>$ opm alpha bundle validate --tag quay.io/test/test-operator:latest --image-builder docker&lt;/code>&lt;/p>
&lt;h3 id="optional-validation">Optional Validation&lt;/h3>
&lt;p>Some validators are disabled by default and can be optionally enabled via the &lt;code>--optional-validators&lt;/code> or &lt;code>-o&lt;/code> flag.&lt;/p>
&lt;ul>
&lt;li>Operatorhub validator - performs operatorhub.io validation which will check your bundle against the common criteria to distributed with OLM. To validate a bundle using custom categories use the &lt;code>OPERATOR_BUNDLE_CATEGORIES&lt;/code> environmental variable to point to a json-encoded categories file. Enable this option via &lt;code>--optional-validators=operatorhub&lt;/code>. This validator allows you to validate that your manifests can work with a Kubernetes cluster of a particular version using the &lt;code>k8s-version&lt;/code> optional key value. (e.g. &lt;code>--optional-values=k8s-version=1.22&lt;/code>)&lt;/li>
&lt;li>Bundle objects validator - performs validation on resources like &lt;code>PodDisruptionBudgets&lt;/code> and &lt;code>PriorityClasses&lt;/code>. Enable this option via &lt;code>--optional-validators=bundle-objects&lt;/code>.
Multiple optional validators can be enabled at once, for example &lt;code>--optional-validators=operatorhub,bundle-objects&lt;/code>.&lt;/li>
&lt;li>Community validator - performs community operator bundle validation which will check your bundle against the criteria to distribute your project on the &lt;a href="https://github.com/operator-framework/community-operators">Community Catalogs&lt;/a>. For further information see its &lt;a href="https://operator-framework.github.io/community-operators/">docs&lt;/a>. This validator allows you to validate the required labels in the catalog image by using the &lt;code>index-path&lt;/code> optional key value. (e.g. &lt;code>--optional-values=index-path=bundle.Dockerfile&lt;/code>).&lt;/li>
&lt;/ul>
&lt;h4 id="custom-bundle-categories">Custom bundle categories&lt;/h4>
&lt;p>The operatorhub validator can verify against custom bundle categories by setting the &lt;code>OPERATOR_BUNDLE_CATEGORIES&lt;/code> environment variable.
Setting the &lt;code>OPERATOR_BUNDLE_CATEGORIES&lt;/code> environment variable to the path to a json file containing a list of categories will enable those categories to be used when comparing CSV categories for operatorhub validation. The json file should be in the following format:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-json" data-lang="json">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">&amp;#34;categories&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">:[&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#4e9a06">&amp;#34;Cloud Pak&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#4e9a06">&amp;#34;Registry&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#4e9a06">&amp;#34;MyCoolThing&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>For example:&lt;/p>
&lt;p>&lt;code>$ OPERATOR_BUNDLE_CATEGORIES=./validate/categories.json ./bin/opm alpha bundle validate --tag &amp;lt;bundle-tag&amp;gt; --image-builder docker -o operatorhub&lt;/code>
will validate the bundle using the provided categories file.&lt;/p>
&lt;p>If &lt;code>OPERATOR_BUNDLE_CATEGORIES&lt;/code> is not set, and operatorhub validation is enabled, the default categories will be used when performing operatorhub validation. The default categories are the following:&lt;/p>
&lt;ul>
&lt;li>AI/Machine Learning&lt;/li>
&lt;li>Application Runtime&lt;/li>
&lt;li>Big Data&lt;/li>
&lt;li>Cloud Provider&lt;/li>
&lt;li>Developer Tools&lt;/li>
&lt;li>Database&lt;/li>
&lt;li>Integration &amp;amp; Delivery&lt;/li>
&lt;li>Logging &amp;amp; Tracing&lt;/li>
&lt;li>Monitoring&lt;/li>
&lt;li>Networking&lt;/li>
&lt;li>OpenShift Optional&lt;/li>
&lt;li>Security&lt;/li>
&lt;li>Storage&lt;/li>
&lt;li>Streaming &amp;amp; Messaging&lt;/li>
&lt;/ul></description></item><item><title>Docs: Creating a Catalog of operators</title><link>https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/tasks/creating-a-catalog/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/tasks/creating-a-catalog/</guid><description>
&lt;h2 id="prerequisites">Prerequisites&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://github.com/operator-framework/operator-registry/releases">opm&lt;/a> &lt;code>v1.19.0+&lt;/code> (for file-based catalogs), &lt;strong>OR&lt;/strong>&lt;/li>
&lt;li>&lt;a href="https://github.com/operator-framework/operator-registry/releases">opm&lt;/a> &lt;code>v1.23.1+&lt;/code> (for catalog templates)&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>Note: This document discusses creating a catalog of operators using plaintext files to store catalog metadata, which is the &lt;a href="https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/reference/file-based-catalogs">latest feature&lt;/a> of OLM catalogs. If you are looking to build catalogs using the deprecated sqlite database format to store catalog metadata instead, please read the &lt;a href="https://v0-18-z.olm.operatorframework.io/docs/tasks/make-index-available-on-cluster/">v0.18.z version&lt;/a> of this doc instead.&lt;/p>
&lt;/blockquote>
&lt;blockquote>
&lt;p>Note: &lt;code>catalog templates&lt;/code> are &lt;strong>ALPHA&lt;/strong> functionality and may adopt breaking changes&lt;/p>
&lt;/blockquote>
&lt;h2 id="creating-a-catalog">Creating a Catalog&lt;/h2>
&lt;p>&lt;code>OLM&lt;/code>&amp;rsquo;s &lt;code>CatalogSource&lt;/code> &lt;a href="https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/concepts/crds/catalogsource">CRD&lt;/a> accepts a container image reference to a catalog of operators that can
be made available to install in a cluster. You can make your operator bundle available to install in a cluster by adding
it to a catalog, packaging the catalog in a container image, and then using that image reference in the &lt;code>CatalogSource&lt;/code>.
This image contains all of the metadata required for OLM to manage the lifecycle of all of the operators it contains.&lt;/p>
&lt;p>OLM uses a plaintext &lt;a href="https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/reference/file-based-catalogs">file-based catalog&lt;/a> format (JSON or YAML) to store these records in a Catalog, and there are two approaches we can take to creating a Catalog, adding operators to it, and validating it.
Let&amp;rsquo;s walk through a simple example for both approaches.&lt;/p>
&lt;h3 id="catalog-creation-using-catalog-templates">Catalog Creation Using Catalog Templates&lt;/h3>
&lt;p>&lt;a href="https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/reference/catalog-templates">Catalog Templates&lt;/a> are a purpose-built simplification of &lt;a href="https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/reference/file-based-catalogs">File-Based Catalogs&lt;/a> to ease common catalog operations. For this example, we&amp;rsquo;ll be using the &lt;a href="https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/reference/catalog-templates#semver-template">semver template&lt;/a>.&lt;/p>
&lt;blockquote>
&lt;p>Note: We strongly recommend that authors create and maintain their templates in a version-controlled environment discrete from their generated catalogs. Further, we recommend that authors focus on the template as the sole artifact connecting the operator to the catalog (even going so far as only generating the file-based catalog during CI/CD tooling so it is only provided for catalog contribution.)&lt;/p>
&lt;/blockquote>
&lt;h4 id="catalog-creation">Catalog Creation&lt;/h4>
&lt;p>First we need to create the Catalog hierarchy and Dockerfile for generating the image&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>$ mkdir -p cool-catalog/example-operator
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ opm generate dockerfile cool-catalog
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="organizing-the-bundles-into-channels">Organizing the Bundles into Channels&lt;/h4>
&lt;p>Let&amp;rsquo;s assume that this isn&amp;rsquo;t the first time that we have released this operator into the catalog, but it&amp;rsquo;s our first foray into templates. We need to ensure an upgrade graph edge between the older bundle version and the new one. We also want to promote this latest version in a &amp;ldquo;stable&amp;rdquo; channel. Lastly, we already use &lt;a href="https://semver.org">Semantic Versioning&lt;/a> for our release numbering, and we really only care about new major (e.g. X.#.#) releases.&lt;/p>
&lt;blockquote>
&lt;p>Note: we presume this step and template processing are performed in the source-controlled location related to operator bundle release, or at least separate from the catalog&lt;/p>
&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>$ cat &lt;span style="color:#4e9a06">&amp;lt;&amp;lt; EOF &amp;gt;&amp;gt; example-operator-template.yaml
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4e9a06">Schema: olm.semver
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4e9a06">GenerateMajorChannels: true
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4e9a06">GenerateMinorChannels: false
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4e9a06">Stable:
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4e9a06"> Bundles:
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4e9a06"> - Image: repository-uri/example-operator:v0.8.9
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4e9a06"> - Image: repository-uri/example-operator:v0.9.0
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4e9a06">EOF&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="generating-the-catalog">Generating the Catalog&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-console" data-lang="console">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-style:italic">opm alpha render-template semver -o yaml &amp;lt; example-operator-template.yaml &amp;gt; cool-catalog/catalog.yaml
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Validate the catalog to ensure that the result is functional&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>$ opm validate cool-catalog
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ &lt;span style="color:#204a87">echo&lt;/span> &lt;span style="color:#000">$?&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#0000cf;font-weight:bold">0&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="catalog-creation-with-raw-file-based-catalogs">Catalog Creation with Raw File-Based Catalogs&lt;/h3>
&lt;h4 id="catalog-creation-1">Catalog Creation&lt;/h4>
&lt;p>First, we need to initialize our Catalog, so we&amp;rsquo;ll make a directory for it, generate a Dockerfile that can build a Catalog
image, and then populate our catalog with our operator.&lt;/p>
&lt;h4 id="initializing-the-catalog">Initializing the Catalog&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>$ mkdir cool-catalog
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ opm generate dockerfile cool-catalog
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ opm init example-operator &lt;span style="color:#4e9a06">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4e9a06">&lt;/span> --default-channel&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>preview &lt;span style="color:#4e9a06">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4e9a06">&lt;/span> --description&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>./README.md &lt;span style="color:#4e9a06">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4e9a06">&lt;/span> --icon&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>./example-operator.svg &lt;span style="color:#4e9a06">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4e9a06">&lt;/span> --output yaml &amp;gt; cool-catalog/operator.yaml
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Let&amp;rsquo;s validate our catalog to see if we&amp;rsquo;re ready to ship!&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>$ opm validate cool-catalog
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>FATA&lt;span style="color:#ce5c00;font-weight:bold">[&lt;/span>0000&lt;span style="color:#ce5c00;font-weight:bold">]&lt;/span> invalid index:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>└── invalid package &lt;span style="color:#4e9a06">&amp;#34;example-operator&amp;#34;&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> └── invalid channel &lt;span style="color:#4e9a06">&amp;#34;preview&amp;#34;&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> └── channel must contain at least one bundle
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Alright, so it&amp;rsquo;s not valid. It looks like we need to add a bundle, so let&amp;rsquo;s do
that next&amp;hellip;&lt;/p>
&lt;h4 id="add-a-bundle-to-the-catalog">Add a bundle to the Catalog&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>$ opm render quay.io/example-inc/example-operator-bundle:v0.1.0 &lt;span style="color:#4e9a06">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4e9a06">&lt;/span> --output&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>yaml &amp;gt;&amp;gt; cool-catalog/operator.yaml
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Let&amp;rsquo;s validate again:&lt;/p>
&lt;pre tabindex="0">&lt;code>$ opm validate cool-catalog
FATA[0000] package &amp;#34;example-operator&amp;#34;, bundle &amp;#34;example-operator.v0.1.0&amp;#34; not found in any channel entries
&lt;/code>&lt;/pre>&lt;h4 id="add-a-channel-entry-for-the-bundle">Add a channel entry for the bundle&lt;/h4>
&lt;p>We rendered the bundle, but we still haven&amp;rsquo;t yet added it to any channels.
Let&amp;rsquo;s initialize a channel:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>cat &lt;span style="color:#4e9a06">&amp;lt;&amp;lt; EOF &amp;gt;&amp;gt; cool-catalog/operator.yaml
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4e9a06">---
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4e9a06">schema: olm.channel
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4e9a06">package: example-operator
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4e9a06">name: preview
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4e9a06">entries:
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4e9a06"> - name: example-operator.v0.1.0
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4e9a06">EOF&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Is the third time the charm for &lt;code>opm validate&lt;/code>?&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>$ opm validate cool-catalog
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ &lt;span style="color:#204a87">echo&lt;/span> &lt;span style="color:#000">$?&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#0000cf;font-weight:bold">0&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Success! There were no errors and we got a &lt;code>0&lt;/code> error code.&lt;/p>
&lt;h4 id="raw-file-based-catalogs-summary">Raw File-Based Catalogs Summary&lt;/h4>
&lt;p>In the general case, adding a bundle involves three discrete steps:&lt;/p>
&lt;ul>
&lt;li>Render the bundle into the catalog using &lt;code>opm render &amp;lt;bundleImage&amp;gt;&lt;/code>.&lt;/li>
&lt;li>Add the bundle into desired channels and update the channels&amp;rsquo; upgrade edges
to stitch the bundle into the correct place.&lt;/li>
&lt;li>Validate the resulting catalog.&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>NOTE: catalog metadata should be stored in a version control system (e.g. &lt;code>git&lt;/code>) and catalog images should be rebuilt from source
whenever updates are made to ensure that all changes to the catalog are auditable. Here is an example of catalog metadata being stored
in github: &lt;a href="https://github.com/operator-framework/cool-catalog">https://github.com/operator-framework/cool-catalog&lt;/a>, with the catalog image being rebuilt whenever there is a change:
&lt;a href="https://github.com/operator-framework/cool-catalog/blob/main/.github/workflows/build-push.yml">https://github.com/operator-framework/cool-catalog/blob/main/.github/workflows/build-push.yml&lt;/a>.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;strong>Step 1&lt;/strong> is just a simple &lt;code>opm render&lt;/code> command.&lt;/p>
&lt;p>&lt;strong>Step 2&lt;/strong> has no defined standards other than that the result must pass validation in step 3. Some operator authors may
decide to hand edit channels and upgrade edges. Others may decide to implement automation (e.g. to idempotently
build semver-based channels and upgrade graphs based solely on the versions of the operators in the package). There is
no right or wrong answer for implementing this step as long as &lt;code>opm validate&lt;/code> is successful.&lt;/p>
&lt;p>There are some guidelines to keep in mind though:&lt;/p>
&lt;ul>
&lt;li>Once a bundle is present in a Catalog, you should assume that one of your users has installed it. With that in mind,
you should take care to avoid stranding users that have that version installed. Put another way, make sure that
all previously published bundles in a catalog have a path to the current/new channel head.&lt;/li>
&lt;li>Keep the semantics of the upgrade edges you use in mind. &lt;code>opm validate&lt;/code> is not able to tell you if you have a sane
upgrade graph. To learn more about the upgrade graph of an operator, checkout the
&lt;a href="https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/concepts/olm-architecture/operator-catalog/creating-an-update-graph">creating an upgrade graph doc&lt;/a>.&lt;/li>
&lt;/ul>
&lt;h3 id="build-and-push-the-catalog-image">Build and push the catalog image&lt;/h3>
&lt;p>The last step is building and pushing the catalog image. For either approach, this is the same:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>$ docker build . &lt;span style="color:#4e9a06">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4e9a06">&lt;/span> -f cool-catalog.Dockerfile &lt;span style="color:#4e9a06">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4e9a06">&lt;/span> -t quay.io/example-inc/cool-catalog:latest
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ docker push quay.io/example-inc/cool-catalog:latest
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now the catalog image is available for clusters to use and reference with &lt;code>CatalogSources&lt;/code> on their cluster.&lt;/p></description></item><item><title>Docs: Make a Catalog available on Cluster</title><link>https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/tasks/make-catalog-available-on-cluster/</link><pubDate>Wed, 28 Apr 2021 00:00:00 +0000</pubDate><guid>https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/tasks/make-catalog-available-on-cluster/</guid><description>
&lt;p>Once you have a catalog of operators, you can make it available on cluster by referencing it from a &lt;code>CatalogSource&lt;/code>.&lt;/p>
&lt;p>For example, if you have a catalog image &lt;code>quay.io/my-namespace/cool-catalog:latest&lt;/code>, you can create a CatalogSource with your image:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">apiVersion&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">operators.coreos.com/v1alpha1&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">kind&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">CatalogSource&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">metadata&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">name&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">cool-catalog&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">namespace&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">operator&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">spec&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">sourceType&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">grpc&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">image&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">quay.io/my-namespace/cool-catalog:latest&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">displayName&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">Coolest Catalog&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">publisher&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">Me&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">updateStrategy&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">registryPoll&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">interval&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">10m&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="explanation-of-specupdatestrategy">Explanation of spec.updateStrategy&lt;/h3>
&lt;p>When you create a &lt;code>CatalogSource&lt;/code>, it deploys a pod that serves the content you&amp;rsquo;ve stored in the catalog via a grpc API endpoint.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ kubectl apply -f cool-catalog.yaml
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>catalogsource.operators.coreos.com/cool-catalog created
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ kubectl get catsrc
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME DISPLAY TYPE PUBLISHER AGE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cool-catalog Coolest Catalog grpc Me 38s
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ kubectl get pods
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME READY STATUS RESTARTS AGE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cool-catalog-dtqv2 1/1 Running &lt;span style="color:#0000cf;font-weight:bold">0&lt;/span> 30s
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>It is possible to configure the &lt;code>CatalogSource&lt;/code> to poll a source, such as an image registry, to check whether the catalog source pod should be updated. A common use case would be pushing new bundles to the same catalog source tag, and seeing updated operators from those bundles being installed in the cluster.&lt;/p>
&lt;p>For example, say currently you have Operator X v1.0 installed in the cluster from the catalog &lt;code>quay.io/my-namespace/cool-catalog:main&lt;/code>. This is the latest version of the X operator in the catalog. When a new v2.0 of Operator X is published, the v2.0 version of the X operator can be included in the catalog using the same steps described in the &lt;a href="https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/tasks/creating-a-catalog/#creating-a-catalog">creating catalog doc&lt;/a>, then the catalog image can be rebuilt and pushed to the same &lt;code>main&lt;/code> tag. With catalog polling enabled, OLM will pull down the newer version of the catalog image and make the new information available.&lt;/p>
&lt;p>Each type of check for an updated catalog source is called an &lt;code>updateStrategy&lt;/code>. Only one &lt;code>updateStrategy&lt;/code> is supported at a time. &lt;code>registryPoll&lt;/code> is a type of &lt;code>updateStrategy&lt;/code> that checks an image registry for an updated version of the same tag(via image SHAs). The &lt;code>interval&lt;/code> defines the amount of time between each successive poll.&lt;/p>
&lt;h4 id="caveats">Caveats&lt;/h4>
&lt;ul>
&lt;li>The polling sequence is not instantaneous - it can take up to 15 minutes from each poll for the new catalog source pod to be deployed into the cluster. It may take longer for larger clusters.&lt;/li>
&lt;li>Because OLM pulls down the image every poll interval and starts the pod, to see if its updated, the updated catalog pod must be able to be scheduled onto the cluster. If the cluster is at absolutely maximum capacity, without autoscaling enabled, this feature may not work.&lt;/li>
&lt;li>OLM checks to see whether the container ImageID has changed between the old and new catalog source image when determining if an upgrade is in order. It does not actually parse the image content itself to check for later CSVs. If there is a bad upgrade to the catalog source image, simply overwrite the tag with another version and it will be pulled down, or delete and recreate the catalog source.&lt;/li>
&lt;li>The polling interval should be reasonably high to ensure the update functionality works as intended. Avoid intervals less than 15m.&lt;/li>
&lt;/ul>
&lt;h3 id="using-registry-images-that-require-authentication-as-catalogbundleoperatoroperand-images">Using registry images that require authentication as Catalog/bundle/operator/operand images&lt;/h3>
&lt;p>If certain images are hosted in an authenticated container image registry, i.e a private registry, OLM is unable to pull the images by default. To enable access, you can create a pull secret that contains the authentication credentials for the registry. By referencing one or more pull secrets in a &lt;code>CatalogSource&lt;/code>, OLM can handle placing the secrets in the operator and catalog namespace to allow installation.&lt;/p>
&lt;blockquote>
&lt;p>Note: Bundle images that require authentication to pull are handled by this method. Other images required by an Operator or its Operands might require access to private registries as well. OLM does not handle placing the secrets in target tenant namespaces for this scenario, but authentication credentials can be added to the global cluster pull secret or individual namespace service accounts to enable the required access. Alternatively, if providing access to the entire cluster is not permissible, the pull secret can be added to the &lt;code>default&lt;/code> service accounts of the target tenant namespaces.&lt;/p>
&lt;/blockquote>
&lt;p>To use images from private registries as Catalog/bundle images, create a secret for each required private registry. Once you have the secrets, &lt;code>kubectl apply&lt;/code> your secrets to the cluster, and the create or update an existing &lt;code>CatalogSource&lt;/code> object to reference one or more secrets to add a &lt;code>spec.secrets&lt;/code> section and specify all secrets.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">apiVersion&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">operators.coreos.com/v1alpha1&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">kind&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">CatalogSource&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">metadata&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">name&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">cool-catalog&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">namespace&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">operator&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">spec&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">sourceType&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">grpc&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">secrets&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#4e9a06">&amp;#34;&amp;lt;secret_name_1&amp;gt;&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#4e9a06">&amp;#34;&amp;lt;secret_name_2&amp;gt;&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">image&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">quay.io/my-namespace/cool-catalog:latest&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">displayName&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">Coolest Catalog&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">publisher&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">Me&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">updateStrategy&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">registryPoll&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">interval&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">10m&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If the &lt;code>imagePullSecret&lt;/code> is referenced in the bundle, for instance when the controller-manager image is pulled from a private registry, there is no place in the API to tell OLM to attach the &lt;code>imagePullSecrets&lt;/code>. As a consequence, permissions to pull the image should be added directly to the operator Deployment&amp;rsquo;s manifest by adding the required secret name to the list &lt;code>deployment.spec.template.spec.imagePullSecrets&lt;/code>.&lt;/p>
&lt;p>For the &lt;a href="https://sdk.operatorframework.io/">operator-sdk&lt;/a> abstraction, the operator Deployment&amp;rsquo;s manifest is found under &lt;code>config/manager/manager.yaml&lt;/code>. Below is an example of a controller-manager Deployment&amp;rsquo;s manifest configured with an &lt;code>imagePullSecret&lt;/code> to pull container images from a private registry.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic"># config/manager/manager.yaml&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">apiVersion&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">apps/v1&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">kind&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">Deployment&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">metadata&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">name&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">controller-manager&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">namespace&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">system&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">...&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">spec&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">...&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">spec&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">imagePullSecrets&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>- &lt;span style="color:#204a87;font-weight:bold">name&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#4e9a06">&amp;#34;registry-auth-secret-name&amp;#34;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>Note: It is required for the &lt;code>imagePullSecret&lt;/code> to be present in the same namespace where the controller is deployed for the controller pod to start.&lt;/p>
&lt;/blockquote></description></item><item><title>Docs: List operators available to install on cluster</title><link>https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/tasks/list-operators-available-to-install/</link><pubDate>Thu, 05 Jan 2017 00:00:00 +0000</pubDate><guid>https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/tasks/list-operators-available-to-install/</guid><description>
&lt;h2 id="list-your-operator">List your operator&lt;/h2>
&lt;p>The &lt;code>PackageManifest&lt;/code> API exposes content from existing &lt;a href="https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/concepts/crds/catalogsource">CatalogSources&lt;/a> on cluster. Querying that API reveals the list of operators available to install.&lt;/p>
&lt;blockquote>
&lt;p>Note: &lt;a href="https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/concepts/crds/catalogsource">CatalogSources&lt;/a> in OLM are either global or namespaced. Global CatalogSources contain operators that will be available for installing in all namespaces, while namespaced CatalogSources only contains operators that are available to be installed in a specific namespace.&lt;/p>
&lt;/blockquote>
&lt;h3 id="using-the-packagemanifest-api">Using the PackageManifest API&lt;/h3>
&lt;p>The &lt;code>PackageManifest&lt;/code> API when queried, will return the union of globally available as well as namespaced available operators, from the namespace you&amp;rsquo;re querying in.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>kubectl get packagemanifest -n &amp;lt;namespace&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The list of available operators will be displayed as an output of those above commands:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ kubectl get packagemanifest
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME CATALOG AGE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cassandra-operator Community Operators 26m
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>etcd Community Operators 26m
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>postgres-operator Community Operators 26m
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>prometheus Community Operators 26m
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>wildfly Community Operators 26m
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Docs: Install your operator with OLM</title><link>https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/tasks/install-operator-with-olm/</link><pubDate>Fri, 30 Apr 2021 00:00:00 +0000</pubDate><guid>https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/tasks/install-operator-with-olm/</guid><description>
&lt;p>&lt;a href="https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/tasks/make-catalog-available-on-cluster">Once you have a catalog of operators loaded onto the cluster via a &lt;code>CatalogSource&lt;/code>&lt;/a>, you can install your operator by creating a &lt;a href="https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/concepts/crds/subscription">&lt;code>Subscription&lt;/code>&lt;/a> to a specific &lt;a href="https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/glossary/#channel">channel&lt;/a>.&lt;/p>
&lt;h2 id="prerequisites">Prerequisites&lt;/h2>
&lt;p>Before installing an operator into a namespace, you will need to create an &lt;code>OperatorGroup&lt;/code> that targets the namespaces your operator is planning to watch, to generate the required RBACs for your operator in those namespaces. You can read more about &lt;code>OperatorGroup&lt;/code> &lt;a href="https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/concepts/crds/operatorgroup">here&lt;/a>.&lt;/p>
&lt;blockquote>
&lt;p>Note: The namespaces targeted by the OperatorGroup must align with the &lt;code>installModes&lt;/code> specified in the &lt;code>ClusterServiceVersion&lt;/code> of the operator&amp;rsquo;s package. To know the &lt;code>installModes&lt;/code> of an operator, inspect the packagemanifest:&lt;/p>
&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>kubectl get packagemanifest &amp;lt;operator-name&amp;gt; -o &lt;span style="color:#000">jsonpath&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;{.status.channels[0].currentCSVDesc.installModes}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>Note: This document uses a global OperatorGroup in the examples to install operators. To learn more about installing namespaced scoped operators, check out &lt;a href="https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/advanced-tasks/operator-scoping-with-operatorgroups">operator scoping with OperatorGroups&lt;/a>.&lt;/p>
&lt;/blockquote>
&lt;h2 id="install-your-operator">Install your operator&lt;/h2>
&lt;p>To install an Operator, simply create a &lt;code>Subscription&lt;/code> for your operator. This represents the intent to subscribe to a stream of available versions of this Operator from a &lt;code>CatalogSource&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">apiVersion&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">operators.coreos.com/v1alpha1&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">kind&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">Subscription&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">metadata&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">name&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">&amp;lt;name-of-your-subscription&amp;gt;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">namespace&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">&amp;lt;namespace-you-want-your-operator-installed-in&amp;gt;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">spec&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">channel&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">&amp;lt;channel-you-want-to-subscribe-to&amp;gt;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">name&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">&amp;lt;name-of-your-operator&amp;gt;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">source&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">&amp;lt;name-of-catalog-operator-is-part-of&amp;gt;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">sourceNamespace&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">&amp;lt;namespace-that-has-catalog&amp;gt;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">installPlanApproval&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">&amp;lt;Automatic/Manual&amp;gt;&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>You can read more about the &lt;code>Subscription&lt;/code> object and what the different fields mean &lt;a href="https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/concepts/crds/subscription">here&lt;/a>.&lt;/p>
&lt;p>The &lt;code>Subscription&lt;/code> object creates an &lt;a href="https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/concepts/crds/installplan">InstallPlan&lt;/a>, which is either automatically approved (if &lt;code>sub.spec.installPlanApproval: Automatic&lt;/code>), or needs to be approved (if &lt;code>sub.spec.installPlanApproval: Manual&lt;/code>), following which the operator is installed in the namespace you want.&lt;/p>
&lt;h2 id="example-install-the-latest-version-of-an-operator">Example: Install the latest version of an Operator&lt;/h2>
&lt;p>If you want to install an operator named &lt;code>my-operator&lt;/code> in the namespace &lt;code>foo&lt;/code> that is cluster scoped (i.e &lt;code>installModes:AllNamespaces&lt;/code>), from a catalog named &lt;code>my-catalog&lt;/code> that is in the namespace &lt;code>olm&lt;/code>, and you want to subscribe to the channel &lt;code>stable&lt;/code>,&lt;/p>
&lt;p>create a &lt;em>global&lt;/em> &lt;code>OperatorGroup&lt;/code> (which selects all namespaces):&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ cat og.yaml
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> apiVersion: operators.coreos.com/v1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> kind: OperatorGroup
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> metadata:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> name: my-group
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> namespace: foo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ kubectl apply -f og.yaml
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> operatorgroup.operators.coreos.com/my-group created
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Then, create a subscription for the operator:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ cat sub.yaml
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>apiVersion: operators.coreos.com/v1alpha1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>kind: Subscription
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>metadata:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> name: sub-to-my-operator
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> namespace: foo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>spec:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> channel: stable
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> name: my-operator
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> source: my-catalog
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> sourceNamespace: olm
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> installPlanApproval: Manual
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ kubectl apply -f sub.yaml
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>subscription.operators.coreos.com/sub-to-my-operator created
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Since &lt;code>installPlanApproval&lt;/code> is set to &lt;code>Manual&lt;/code>, we need to manually go in and approve the &lt;code>InstallPlan&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ kubectl get ip -n foo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME CSV APPROVAL APPROVED
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>install-nlwcw my-operator.v0.9.2 Automatic &lt;span style="color:#204a87">false&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ kubectl edit ip install-nlwcw -n foo
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>And then change the &lt;code>spec.approved&lt;/code> from &lt;code>false&lt;/code> to &lt;code>true&lt;/code>.&lt;/p>
&lt;p>This should spin up the &lt;code>ClusterServiceVersion&lt;/code> of the operator in the &lt;code>foo&lt;/code> namespace, following which the operator pod will spin up.&lt;/p>
&lt;p>To ensure the operator installed successfully, check for the ClusterServiceVersion and the operator deployment in the namespace it was installed in.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ kubectl get csv -n &amp;lt;namespace-operator-was-installed-in&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME DISPLAY VERSION REPLACES PHASE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;name-of-csv&amp;gt; &amp;lt;operator-name&amp;gt; &amp;lt;version&amp;gt; &amp;lt;csv-of-previous-version&amp;gt; Succeeded
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>...
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ kubectl get deployments -n &amp;lt;namespace-operator-was-installed-in&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME READY UP-TO-DATE AVAILABLE AGE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;lt;name-of-your-operator&amp;gt; 1/1 &lt;span style="color:#0000cf;font-weight:bold">1&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">1&lt;/span> 9m48s
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If the ClusterServiceVersion fails to show up or does not reach the &lt;code>Succeeded&lt;/code> phase, please check the &lt;a href="https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/troubleshooting/clusterserviceversion/">troubleshooting documentation&lt;/a> to debug your installation.&lt;/p>
&lt;h2 id="example-install-a-specific-version-of-an-operator">Example: Install a specific version of an Operator&lt;/h2>
&lt;p>If you want to install a particular version of your Operator, specify the &lt;code>startingCSV&lt;/code> property in your &lt;code>Subscription&lt;/code> like so:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">apiVersion&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">operators.coreos.com/v1alpha1&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">kind&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">Subscription&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">metadata&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">name&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">sub-to-my-operator&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">namespace&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">foo&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline">&lt;/span>&lt;span style="color:#204a87;font-weight:bold">spec&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">channel&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">stable&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">name&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">my-operator&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">source&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">my-catalog&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">sourceNamespace&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">olm&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">installPlanApproval&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#000">Manual&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#204a87;font-weight:bold">startingCSV&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline"> &lt;/span>&lt;span style="color:#0000cf;font-weight:bold">1.1.0&lt;/span>&lt;span style="color:#f8f8f8;text-decoration:underline">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Notice that &lt;code>approval&lt;/code> has been set to &lt;code>Manual&lt;/code> as well in order to keep OLM from immediately updating your Operator, if &lt;code>1.1.0&lt;/code> happens to be superseded by a newer version in &lt;code>my-catalog&lt;/code>. Follow the instructions from the &lt;a href="#example-install-the-latest-version-of-an-operator">previous example&lt;/a> to approve the initial &lt;code>InstallPlan&lt;/code> for this &lt;code>Subscription&lt;/code>, so &lt;code>1.1.0&lt;/code> is allowed to be installed.&lt;/p>
&lt;p>If your intent is to pin an installed Operator to the particular version &lt;code>1.1.0&lt;/code> you don&amp;rsquo;t need to do anything. After approving the initial &lt;code>InstallPlan&lt;/code> OLM will install version &lt;code>1.1.0&lt;/code> of your Operator and keep it at that version. When updates are discovered in the catalog, OLM will wait not proceed unless you manually approve the update.&lt;/p></description></item><item><title>Docs: Uninstall your operator</title><link>https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/tasks/uninstall-operator/</link><pubDate>Wed, 25 Mar 2020 00:00:00 +0000</pubDate><guid>https://deploy-preview-345--operator-lifecycle-manager.netlify.app/docs/tasks/uninstall-operator/</guid><description>
&lt;p>When uninstalling an operator managed by OLM, a Cluster Admin must decide whether or not to remove the &lt;code>CustomResourceDefinitions (CRD)&lt;/code>, &lt;code>APIServices&lt;/code>, and resources related to these types owned by the operator. By design, when OLM uninstalls an operator it does not remove any of the operator&amp;rsquo;s owned &lt;code>CRDs&lt;/code>, &lt;code>APIServices&lt;/code>, or &lt;code>CRs&lt;/code> in order to prevent data loss. Instead, it is left to the Cluster Admin to remove any unwanted types and resources from the cluster. This document will discuss the steps a Cluster Admin should take when uninstalling an operator.&lt;/p>
&lt;h2 id="step-1-identifying-resources-to-remove">Step 1: Identifying Resources to Remove&lt;/h2>
&lt;p>The cluster admin should first understand which types (&lt;code>CRDs&lt;/code> and &lt;code>APIServices&lt;/code>) are owned by the operator, which is available in the operator&amp;rsquo;s &lt;code>ClusterServiceVersion (CSV)&lt;/code> under the &lt;code>spec.customresourcedefinitions.owned&lt;/code> and &lt;code>spec.apiservicedefinitions.owned&lt;/code> arrays. It is likely that users have created resources for these types since the operator was installed. The cluster admin should should decide which of these resources to delete on a case-by-case basis. If the resource is not required, delete it. The Cluster Admin should delete all unwanted resources before moving to the next step.&lt;/p>
&lt;blockquote>
&lt;p>Note: Although deleting the &lt;code>CRD&lt;/code> or &lt;code>APIService&lt;/code> removes all resource of the type from the cluster, this action may lead to unintended consequences. Operators often use &lt;a href="https://book.kubebuilder.io/reference/using-finalizers.html">finalizers&lt;/a> to execute application specific cleanup routines before removing the &lt;code>CR&lt;/code>. If the API is removed, the operator will be unable to properly remove the resource, and the cluster may appear to be &amp;ldquo;stuck&amp;rdquo; as defined in this &lt;a href="https://github.com/kubernetes/kubernetes/issues/60807">Kubernetes issue&lt;/a>.&lt;/p>
&lt;/blockquote>
&lt;h2 id="step-2-unsubscribe-from-the-operator">Step 2: Unsubscribe from the Operator&lt;/h2>
&lt;p>OLM uses the &lt;code>Subscription&lt;/code> resource to convey a user&amp;rsquo;s intent to subscribe to the latest version of an operator. If the operator was installed with Automatic Updates (&lt;code>spec.InstallPlanApproval: &amp;quot;Automatic&amp;quot;&lt;/code>), OLM will reinstall a new version of the operator even if the operator&amp;rsquo;s &lt;code>CSV&lt;/code> was deleted earlier. In effect, you must tell OLM that you do not want new versions of the operator to be installed by deleting the &lt;code>Subscription&lt;/code> associated with the operator. It should be noted that opting out of future upgrades by deleting a &lt;code>Subscription&lt;/code> does not delete the associated &lt;code>CSV&lt;/code> as this ensures that a specific version of the operator is available on cluster and is never upgraded.&lt;/p>
&lt;p>You can list existing &lt;code>Subscription&lt;/code> in a specific namespace with the following &lt;code>kubectl&lt;/code> command:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ kubectl get subscription -n &amp;lt;namespace&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic"># Example output&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME PACKAGE SOURCE CHANNEL
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>foo-sub foo foo-catalog alpha
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>Note: The name of the operator installed by the &lt;code>Subscription&lt;/code> is available under the &lt;code>Package&lt;/code> column.&lt;/p>
&lt;/blockquote>
&lt;p>The &lt;code>Subscription&lt;/code> can be deleted by running this command:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>kubectl delete subscription &amp;lt;subscription-name&amp;gt; -n &amp;lt;namespace&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="step-3-delete-the-operators-clusterserviceversion-csv">Step 3: Delete the Operator&amp;rsquo;s ClusterServiceVersion (CSV)&lt;/h2>
&lt;p>The &lt;code>CSV&lt;/code> contains all the information that OLM needs to manage an operator, and it effectively represents an operator that is installed on cluster. By deleting a &lt;code>CSV&lt;/code>, OLM will delete the resources it created for the operator such as the &lt;code>deployment&lt;/code>, &lt;code>RBAC&lt;/code>, and any corresponding &lt;code>CSVs&lt;/code> that OLM &amp;ldquo;Copied&amp;rdquo; into other namespaces watched by the operator.&lt;/p>
&lt;p>Note that deleting a CSV only deletes objects derived from the CSV and does not delete objects from the bundle. For example, while RBAC resources derived from the CSV&amp;rsquo;s &lt;code>permissions&lt;/code> and &lt;code>clusterPermissions&lt;/code> fields will be deleted, any RBAC resources included directly in the bundle itself will remain on the cluster.&lt;/p>
&lt;p>If you wish to look up a list of &lt;code>ClusterServiceVersion&lt;/code> in a specific namespace to see which &lt;code>ClusterServiceVersion&lt;/code> you need to delete, you can use the example &lt;code>kubectl&lt;/code> command:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ kubectl get clusterserviceversion -n &amp;lt;namespace&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic"># Example output&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME DISPLAY VERSION REPLACES PHASE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>foo Foo Operator 1.0.0 Succeeded
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>You can delete the &lt;code>ClusterServiceVersion&lt;/code> in the namespace that the operator was installed into using this command:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>kubectl delete clusterserviceversion &amp;lt;csv-name&amp;gt; -n &amp;lt;namespace&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="combine-steps-2-and-3">Combine steps 2 and 3&lt;/h3>
&lt;p>Alternatively, you can delete both &lt;code>Subscription&lt;/code> and its &lt;code>CSV&lt;/code> using a sequence of commands:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000">CSV&lt;/span>&lt;span style="color:#ce5c00;font-weight:bold">=&lt;/span>&lt;span style="color:#204a87;font-weight:bold">$(&lt;/span>kubectl get subscription &amp;lt;subscription-name&amp;gt; -n &amp;lt;namespace&amp;gt; -o json &lt;span style="color:#000;font-weight:bold">|&lt;/span> jq -r &lt;span style="color:#4e9a06">&amp;#39;.status.installedCSV&amp;#39;&lt;/span>&lt;span style="color:#204a87;font-weight:bold">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>kubectl delete subscription &amp;lt;subscription-name&amp;gt; -n &amp;lt;namespace&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>kubectl delete csv &lt;span style="color:#000">$CSV&lt;/span> -n &amp;lt;namespace&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="step-4-deciding-whether-or-not-to-delete-the-crds-and-apiservices">Step 4: Deciding whether or not to delete the CRDs and APIServices&lt;/h2>
&lt;p>The fourth step consists of deciding whether or not to delete the &lt;code>CRDs&lt;/code> and &lt;code>APIServices&lt;/code> that were introduced to the cluster by the operator. Assuming you have already deleted all unwanted resources on cluster as enumerated in Step 1, if no resources remain it is safe to remove the &lt;code>CRD&lt;/code> or &lt;code>APISerivces&lt;/code>. Otherwise, you should not delete the type as the wanted resources will be deleted automatically when the CRD or &lt;code>APISerivce&lt;/code> is deleted.&lt;/p>
&lt;h2 id="step-5-deleting-the-operator-cr">Step 5: Deleting the Operator CR&lt;/h2>
&lt;p>OLM recently introduced the view-only &lt;a href="https://github.com/operator-framework/api/blob/7339a22050af53df7b6f97a652b8e2d73698765a/crds/operators.coreos.com_operators.yaml">operator CRD&lt;/a> which communicates the list of resources associated with an &lt;a href="https://olm.operatorframework.io/docs/tasks/creating-operator-bundle/#operator-bundle">operator bundle&lt;/a> installed by OLM. When installing an &lt;code>operator bundle&lt;/code>, OLM will create an &lt;code>operator&lt;/code> CR named:&lt;/p>
&lt;ul>
&lt;li>&lt;code>&amp;lt;packageName&amp;gt;&lt;/code> if the operator is All Namespaced scoped.&lt;/li>
&lt;li>&lt;code>&amp;lt;packageName&amp;gt;.&amp;lt;Namespace&amp;gt;&lt;/code> if the operator is not All Namespaced scoped.&lt;/li>
&lt;/ul>
&lt;p>OLM will then the update the &lt;a href="https://github.com/operator-framework/api/blob/7339a22050af53df7b6f97a652b8e2d73698765a/crds/operators.coreos.com_operators.yaml#L76-L77">operator&amp;rsquo;s status.Components.Refs&lt;/a> array to include all resources associated with the &lt;code>operator&lt;/code>. Let&amp;rsquo;s consider OLM&amp;rsquo;s behavior after creating the &lt;code>operator&lt;/code> CR named &lt;code>foo&lt;/code>:&lt;/p>
&lt;ul>
&lt;li>All resources associated with the &lt;code>foo operator&lt;/code> CR will have the &lt;code>operators.coreos.com/foo&lt;/code> label applied to it.&lt;/li>
&lt;li>OLM will create or recreate the &lt;code>foo operator&lt;/code> CR if any resources exist with the &lt;code>operators.coreos.com/foo&lt;/code> label.&lt;/li>
&lt;/ul>
&lt;p>This ultimately means that in order to delete the &lt;code>foo operator&lt;/code> CR, users will need to ensure that no resources are labeled with the &lt;code>operators.coreos.com/foo&lt;/code> label. Typically, OLM should not attempt to recreate the &lt;code>foo operator&lt;/code> after a user deletes it if they have completed steps 1 through 4 above. However, if OLM is still recreating the &lt;code>foo operator&lt;/code>, a user should:&lt;/p>
&lt;ul>
&lt;li>Delete each resource found in the &lt;code>foo operator's status.Components.Refs&lt;/code> array. Alternatively, if you have deleted the &lt;code>foo operator's CSV&lt;/code> and &lt;code>Subscription&lt;/code> you may remove the &lt;code>operators.coreos.com/foo&lt;/code> label from any resources you do not wish to delete.&lt;/li>
&lt;li>Delete the &lt;code>foo operator&lt;/code> CR.
The final step consists of deciding whether or not to delete the &lt;code>CRDs&lt;/code> and &lt;code>APIServices&lt;/code> that were introduced to the cluster by the operator. Assuming you have already deleted all unwanted resources on cluster as enumerated in Step 1, if no resources remain it is safe to remove the &lt;code>CRD&lt;/code> or &lt;code>APISerivces&lt;/code>. Otherwise, you should not delete the type as the wanted resources will be deleted automatically when the &lt;code>CRD&lt;/code> or &lt;code>APISerivce&lt;/code> is deleted.&lt;/li>
&lt;/ul></description></item></channel></rss>