├── .bingo ├── .gitignore ├── README.md ├── Variables.mk ├── go.mod ├── hugo.mod ├── hugo.sum └── variables.env ├── .github └── workflows │ └── lint.yaml ├── .gitignore ├── .nvmrc ├── CODEOWNERS ├── Makefile ├── README.md ├── assets └── scss │ ├── _breadcrumb.scss │ ├── _docs.scss │ ├── _footer.scss │ ├── _functions.scss │ ├── _global.scss │ ├── _header.scss │ ├── _homepage.scss │ ├── _of-variables.scss │ ├── _reset.scss │ ├── _sidebar-tree.scss │ ├── _styles_project.scss │ └── _type.scss ├── config.toml ├── content └── en │ ├── _index.html │ ├── about │ └── _index.html │ ├── docs │ ├── Concepts │ │ ├── _index.md │ │ ├── crds │ │ │ ├── CatalogSource.md │ │ │ ├── _index.md │ │ │ ├── clusterserviceversion.md │ │ │ ├── installplan.md │ │ │ ├── operatorcondition.md │ │ │ ├── operatorgroup.md │ │ │ └── subscription.md │ │ ├── olm-architecture │ │ │ ├── _index.md │ │ │ ├── dependency-resolution │ │ │ │ └── _index.md │ │ │ └── operator-catalog │ │ │ │ └── creating-an-update-graph.md │ │ └── operators-on-cluster.md │ ├── Glossary │ │ └── _index.md │ ├── Reference │ │ ├── _index.md │ │ ├── admission-webhooks.md │ │ ├── catalog-templates.md │ │ └── file-based-catalogs.md │ ├── Tasks │ │ ├── _index.md │ │ ├── creating-a-catalog.md │ │ ├── creating-operator-bundle.md │ │ ├── creating-operator-manifests.md │ │ ├── install-operator-with-olm.md │ │ ├── list-operators-available-to-install.md │ │ ├── make-catalog-available-on-cluster.md │ │ └── uninstall-operator.md │ ├── Troubleshooting │ │ ├── _index.md │ │ ├── catalogsource.md │ │ ├── clusterserviceversion.md │ │ ├── olm-and-catalog-operators.md │ │ └── subscription.md │ ├── _index.md │ ├── advanced-tasks │ │ ├── _index.md │ │ ├── adding-admission-and-conversion-webhooks.md │ │ ├── catalog-update-formulary.md │ │ ├── communicating-operator-conditions-to-olm.md │ │ ├── configuring-olm.md │ │ ├── operator-scoping-with-operatorgroups.md │ │ ├── overriding-catalog-source-pod-scheduling-configuration.md │ │ ├── overriding-operator-pod-affinity-configuration.md │ │ ├── performance-profiling.md │ │ ├── ship-operator-supporting-multiarch.md │ │ └── unsafe-fail-forward-upgrades.md │ ├── best-practices │ │ ├── _index.md │ │ ├── channel-naming.md │ │ ├── common.md │ │ └── images │ │ │ ├── channel-naming1.png │ │ │ └── channel-naming2.png │ ├── contribution-guidelines │ │ ├── _index.md │ │ ├── local-docs.md │ │ └── upgrade-graphs.md │ └── getting-started │ │ └── _index.md │ └── images │ ├── 4498B411F22DC186.png │ ├── Asset 1.png │ ├── Asset 2.png │ ├── arrow.svg │ ├── bg-masthead-green.svg │ ├── bg-masthead-red.svg │ ├── bg-masthead.svg │ ├── header-bg.svg │ ├── ico-build.svg │ ├── ico-discover.svg │ ├── ico-manage.svg │ ├── logo-sm.svg │ ├── logo.svg │ └── sprite.svg ├── go.mod ├── go.sum ├── hack └── ci │ └── link-check.sh ├── layouts ├── 404.html ├── _default │ └── baseof.html ├── docs │ ├── baseof.html │ └── list.html ├── partials │ ├── footer.html │ ├── hooks │ │ ├── body-end.html │ │ └── head-end.html │ ├── navbar-version-selector.html │ ├── navbar.html │ ├── section-index.html │ └── sidebar-tree.html └── shortcodes │ ├── code_callout.html │ └── mermaid.html ├── netlify.toml ├── package-lock.json ├── package.json └── static └── favicons ├── apple-touch-icon-180x180.png ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon.ico ├── pwa-192x192.png ├── pwa-512x512.png ├── tile150x150.png ├── tile310x150.png ├── tile310x310.png └── tile70x70.png /.bingo/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Ignore everything 3 | * 4 | 5 | # But not these files: 6 | !.gitignore 7 | !*.mod 8 | !*.sum 9 | !README.md 10 | !Variables.mk 11 | !variables.env 12 | 13 | *tmp.mod 14 | -------------------------------------------------------------------------------- /.bingo/README.md: -------------------------------------------------------------------------------- 1 | # Project Development Dependencies. 2 | 3 | This is directory which stores Go modules with pinned buildable package that is used within this repository, managed by https://github.com/bwplotka/bingo. 4 | 5 | * Run `bingo get` to install all tools having each own module file in this directory. 6 | * Run `bingo get ` to install that have own module file in this directory. 7 | * For Makefile: Make sure to put `include .bingo/Variables.mk` in your Makefile, then use $() variable where is the .bingo/.mod. 8 | * For shell: Run `source .bingo/variables.env` to source all environment variable for each tool. 9 | * For go: Import `.bingo/variables.go` to for variable names. 10 | * See https://github.com/bwplotka/bingo or -h on how to add, remove or change binaries dependencies. 11 | 12 | ## Requirements 13 | 14 | * Go 1.14+ 15 | -------------------------------------------------------------------------------- /.bingo/Variables.mk: -------------------------------------------------------------------------------- 1 | # Auto generated binary variables helper managed by https://github.com/bwplotka/bingo v0.8. DO NOT EDIT. 2 | # All tools are designed to be build inside $GOBIN. 3 | BINGO_DIR := $(dir $(lastword $(MAKEFILE_LIST))) 4 | GOPATH ?= $(shell go env GOPATH) 5 | GOBIN ?= $(firstword $(subst :, ,${GOPATH}))/bin 6 | GO ?= $(shell which go) 7 | 8 | # Below generated variables ensure that every time a tool under each variable is invoked, the correct version 9 | # will be used; reinstalling only if needed. 10 | # For example for hugo variable: 11 | # 12 | # In your main Makefile (for non array binaries): 13 | # 14 | #include .bingo/Variables.mk # Assuming -dir was set to .bingo . 15 | # 16 | #command: $(HUGO) 17 | # @echo "Running hugo" 18 | # @$(HUGO) 19 | # 20 | HUGO := $(GOBIN)/hugo-v0.111.1 21 | $(HUGO): $(BINGO_DIR)/hugo.mod 22 | @# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies. 23 | @echo "(re)installing $(GOBIN)/hugo-v0.111.1" 24 | @cd $(BINGO_DIR) && GOWORK=off CGO_ENABLED=1 $(GO) build -tags=extended -mod=mod -modfile=hugo.mod -o=$(GOBIN)/hugo-v0.111.1 "github.com/gohugoio/hugo" 25 | 26 | -------------------------------------------------------------------------------- /.bingo/go.mod: -------------------------------------------------------------------------------- 1 | module _ // Fake go.mod auto-created by 'bingo' for go -moddir compatibility with non-Go projects. Commit this file, together with other .mod files. -------------------------------------------------------------------------------- /.bingo/hugo.mod: -------------------------------------------------------------------------------- 1 | module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT 2 | 3 | go 1.20 4 | 5 | require github.com/gohugoio/hugo v0.111.1 // CGO_ENABLED=1 -tags=extended 6 | -------------------------------------------------------------------------------- /.bingo/variables.env: -------------------------------------------------------------------------------- 1 | # Auto generated binary variables helper managed by https://github.com/bwplotka/bingo v0.8. DO NOT EDIT. 2 | # All tools are designed to be build inside $GOBIN. 3 | # Those variables will work only until 'bingo get' was invoked, or if tools were installed via Makefile's Variables.mk. 4 | GOBIN=${GOBIN:=$(go env GOBIN)} 5 | 6 | if [ -z "$GOBIN" ]; then 7 | GOBIN="$(go env GOPATH)/bin" 8 | fi 9 | 10 | 11 | HUGO="${GOBIN}/hugo-v0.111.1" 12 | 13 | -------------------------------------------------------------------------------- /.github/workflows/lint.yaml: -------------------------------------------------------------------------------- 1 | name: test 2 | on: pull_request 3 | 4 | jobs: 5 | lint: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - name: Checkout 9 | uses: actions/checkout@v3 10 | - uses: actions/setup-go@v4 11 | with: 12 | go-version-file: go.mod 13 | cache-dependency-path: | 14 | go.sum 15 | .bingo/**.sum 16 | - name: Build and lint the site 17 | run: make lint 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | public/ 2 | resources/ 3 | node_modules/ 4 | tech-doc-hugo 5 | .hugo_build.lock 6 | 7 | ### JetBrains template 8 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 9 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 10 | .idea/ 11 | 12 | # User-specific stuff: 13 | .idea/**/workspace.xml 14 | .idea/**/tasks.xml 15 | .idea/dictionaries 16 | 17 | # Sensitive or high-churn files: 18 | .idea/**/dataSources/ 19 | .idea/**/dataSources.ids 20 | .idea/**/dataSources.xml 21 | .idea/**/dataSources.local.xml 22 | .idea/**/sqlDataSources.xml 23 | .idea/**/dynamic.xml 24 | .idea/**/uiDesigner.xml 25 | 26 | # Gradle: 27 | .idea/**/gradle.xml 28 | .idea/**/libraries 29 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | lts/* 2 | 3 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @operator-framework/team-olm 2 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # bingo manages consistent tooling versions for things like kind, kustomize, etc. 2 | include .bingo/Variables.mk 3 | 4 | CONTAINER_ENGINE ?= docker 5 | 6 | .DEFAULT_GOAL := build 7 | 8 | ##@ General 9 | 10 | # The help target prints out all targets with their descriptions organized 11 | # beneath their categories. The categories are represented by '##@' and the 12 | # target descriptions by '##'. The awk commands is responsible for reading the 13 | # entire set of makefiles included in this invocation, looking for lines of the 14 | # file as xyz: ## something, and then pretty-format the target and help. Then, 15 | # if there's a line with ##@ something, that gets pretty-printed as a category. 16 | # More info on the usage of ANSI control characters for terminal formatting: 17 | # https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters 18 | # More info on the awk command: 19 | # http://linuxcommand.org/lc3_adv_awk.php 20 | 21 | .PHONY: help 22 | help: ## Display this help. 23 | @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) 24 | 25 | ##@ Development 26 | 27 | node_modules: package.json package-lock.json 28 | npm ci 29 | 30 | .PHONY: build 31 | build: $(HUGO) node_modules ## Build the site. 32 | HUGO_ENV=production $(HUGO) 33 | 34 | .PHONY: serve 35 | serve: $(HUGO) ## Build and serves the site locally. 36 | $(HUGO) serve 37 | 38 | .PHONY: lint 39 | lint: build ## Run docs linting. 40 | CONTAINER_ENGINE="$(CONTAINER_ENGINE)" \ 41 | CONTAINER_RUN_EXTRA_OPTIONS="$(CONTAINER_RUN_EXTRA_OPTIONS)" \ 42 | ./hack/ci/link-check.sh 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OLM Documentation 2 | 3 | We use [Hugo](https://gohugo.io/) to format and generate our website, the 4 | [Docsy](https://github.com/google/docsy) theme for styling and site structure, 5 | and [Netlify](https://www.netlify.com/) to manage the deployment of the site. 6 | Hugo is an open-source static site generator that provides us with templates, 7 | content organisation in a standard directory structure, and a website generation 8 | engine. You write the pages in Markdown (or HTML if you want), and Hugo wraps them up into a website. 9 | 10 | All submissions, including submissions by project members, require review. We 11 | use GitHub pull requests for this purpose. Consult 12 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more 13 | information on using pull requests. 14 | 15 | ## Quick start with Netlify 16 | 17 | Here's a quick guide to updating the docs. It assumes you're familiar with the 18 | GitHub workflow and you're happy to use the automated preview of your doc 19 | updates: 20 | 21 | 1. Fork [olm-docs](https://github.com/operator-framework/olm-docs) on GitHub. 22 | 1. Make your changes and send a pull request (PR). 23 | 1. If you're not yet ready for a review, create a draft PR to indicate it's a work in progress. (**Don't** add the Hugo property 24 | "draft = true" to the page front matter, because that prevents the 25 | auto-deployment of the content preview described in the next point.) 26 | 1. Wait for the automated PR workflow to do some checks. When it's ready, 27 | you should see a comment like this: **deploy/netlify — Deploy preview ready!** 28 | 1. Click **Details** to the right of "Deploy preview ready" to see a preview 29 | of your updates. 30 | 1. Continue updating your doc and pushing your changes until you're happy with 31 | the content. 32 | 1. When you're ready for a review, remove any "WIP" markers and mark PR ready for review. 33 | 34 | ## Updating a single page 35 | 36 | If you've just spotted something you'd like to change while using the docs, Docsy has a shortcut for you: 37 | 38 | 1. Click **Edit this page** in the top right hand corner of the page. 39 | 1. If you don't already have an up to date fork of the project repo, you are prompted to get one - click **Fork this repository and propose changes** or **Update your Fork** to get an up to date version of the project to edit. The appropriate page in your fork is displayed in edit mode. 40 | 1. Follow the rest of the [Quick start with Netlify](#quick-start-with-netlify) process above to make, preview, and propose your changes. 41 | 42 | ## Previewing your changes locally 43 | 44 | If you want to run your own local Hugo server to preview your changes as you work follow [this guide](/content/en/docs/contribution-guidelines/local-docs.md). 45 | 46 | ## Creating an issue 47 | 48 | If you've found a problem in the docs, but you're not sure how to fix it yourself, please create an issue in the [olm-docs repo](https://github.com/operator-framework/olm-docs). You can also create an issue about a specific page by clicking the **Create Issue** button in the top right hand corner of the page. 49 | 50 | ## Useful resources 51 | 52 | * [Docsy user guide](https://www.docsy.dev/docs/): All about Docsy, including how it manages navigation, look and feel, and multi-language support. 53 | * [Hugo documentation](https://gohugo.io/documentation/): Comprehensive reference for Hugo. 54 | -------------------------------------------------------------------------------- /assets/scss/_breadcrumb.scss: -------------------------------------------------------------------------------- 1 | .breadcrumb { 2 | display: flex; 3 | flex-wrap: wrap; 4 | //padding: $breadcrumb-padding-y; 5 | padding-left: 0rem; 6 | padding-top: 0.75rem; 7 | //padding-right: 1 rem; 8 | //padding-bottom: 0.75 rem; 9 | 10 | margin-bottom: $breadcrumb-margin-bottom; 11 | list-style: none; 12 | background-color: initial; 13 | //@include border-radius($breadcrumb-border-radius); 14 | margin-left: 0px; 15 | border-bottom-left-radius: 0rem; 16 | border-top-left-radius: 0rem; 17 | } 18 | 19 | .breadcrumb-item { 20 | display: -ms-flexbox; 21 | display: flex; 22 | } 23 | 24 | .breadcrumb-item + .breadcrumb-item { 25 | padding-left: 0.5rem; 26 | } 27 | 28 | .breadcrumb-item + .breadcrumb-item::before { 29 | display: inline-block; 30 | padding-right: 0.5rem; 31 | color: $breadcrumb-divider-color; 32 | content: "/"; 33 | } 34 | 35 | .breadcrumb-item + .breadcrumb-item:hover::before { 36 | text-decoration: underline; 37 | } 38 | 39 | .breadcrumb-item + .breadcrumb-item:hover::before { 40 | text-decoration: none; 41 | } 42 | 43 | .breadcrumb-item.active { 44 | color: $breadcrumb-active-color;; 45 | } 46 | -------------------------------------------------------------------------------- /assets/scss/_docs.scss: -------------------------------------------------------------------------------- 1 | .td-sidebar-nav .td-sidebar-link__page { 2 | color: #222; 3 | //font-weight: normal; 4 | } 5 | 6 | .td-sidebar__inner { 7 | width: 100%; 8 | } 9 | 10 | 11 | .td-sidebar-nav > .td-sidebar-nav__section { 12 | padding-top: .5rem; 13 | padding-left: 1.5rem; 14 | } 15 | 16 | .of-docs__wrapper { 17 | pre, p, ol, ul { 18 | margin-bottom: var(--of--spacer--md); 19 | } 20 | ul { 21 | list-style: disc; 22 | margin-left: 2rem; 23 | } 24 | ol { 25 | list-style: decimal; 26 | margin-left: 2rem; 27 | } 28 | .td-sidebar-nav .td-sidebar-link__page { 29 | font-weight: normal; 30 | } 31 | 32 | h1,h2,h3,h4,h5,h6 { 33 | color: var(--of--Color--brand--200); 34 | font-weight: 800; 35 | letter-spacing: 2px; 36 | margin: var(--of--spacer--md) 0 var(--of--spacer--sm); 37 | 38 | a:hover { 39 | text-decoration: none; 40 | } 41 | } 42 | 43 | h5, h6 { 44 | font-size: var(--of--FontSize--xs); 45 | } 46 | h4 { 47 | font-size: var(--of--FontSize--sm); 48 | } 49 | h3 { 50 | font-size: var(--of--FontSize--md); 51 | } 52 | h2 { 53 | font-size: var(--of--FontSize--md); 54 | } 55 | h1 { 56 | font-size: var(--of--FontSize--lg); 57 | } 58 | 59 | @media (min-width: $ov--breakpoint--lg) { 60 | h6 { 61 | font-size: var(--of--FontSize--xs); 62 | } 63 | h5 { 64 | font-size: var(--of--FontSize--xs); 65 | } 66 | h4 { 67 | font-size: var(--of--FontSize--sm); 68 | } 69 | h3 { 70 | font-size: var(--of--FontSize--md); 71 | } 72 | h2 { 73 | font-size: var(--of--FontSize--lg); 74 | } 75 | h1 { 76 | font-size: var(--of--FontSize--xl); 77 | } 78 | } 79 | } 80 | 81 | .td-main { 82 | main { 83 | @include media-breakpoint-up(md) { 84 | padding-top: var(--of--spacer--lg); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /assets/scss/_footer.scss: -------------------------------------------------------------------------------- 1 | .of-footer-main { 2 | background: var(--of--color-brand--300); 3 | color: var(--of--color-white--100); 4 | position: relative; 5 | width: 100%; 6 | @media (min-width: $ov--breakpoint--lg) { 7 | display: grid; 8 | grid-template-columns: minmax(50%, 600px) 1fr; 9 | grid-gap: var(--of--spacer--xl); 10 | grid-template-areas: 11 | "meta social" 12 | "copy copy " 13 | ; 14 | 15 | } 16 | &:before { 17 | content:''; 18 | height: 5px; 19 | width: 100%; 20 | position: absolute; 21 | top: 0; 22 | left: 0; 23 | background: linear-gradient(to right, var(--of--color-brand--50) 25%, var(--of--color-brand--100) 25%, var(--of--color-brand--100) 50%, var(--of--color-brand--100) 50%, var(--of--color-brand--200) 50%, var(--of--color-brand--200) 75%, var(--of--color-brand--300) 75%); 24 | } 25 | padding-top: var(--of--spacer--2xl); 26 | .of-heading { 27 | margin-bottom: var(--of--spacer--sm); 28 | } 29 | &__meta { 30 | grid-area: meta; 31 | padding: 0 var(--of--spacer--lg) var(--of--spacer--lg) var(--of--spacer--lg); 32 | & > *:not(:last-child){ 33 | margin-bottom: var(--of--spacer--sm); 34 | } 35 | .of-link-list { 36 | flex-direction: column; 37 | @media (min-width: $ov--breakpoint--lg) { 38 | flex-direction: row; 39 | } 40 | } 41 | @media (min-width: $ov--breakpoint--lg) { 42 | flex-direction: row; 43 | padding: 0 0 0 var(--of--spacer--2xl); 44 | .of-link-list__li { 45 | 46 | &:not(:last-of-type) { 47 | margin-right: var(--of--spacer--sm); 48 | border-right: 1px solid var(--of--color-brand--100); 49 | padding-right: var(--of--spacer--sm); 50 | } 51 | } 52 | .of-link-list__a { 53 | text-decoration: underline; 54 | } 55 | } 56 | img { 57 | max-width: 200px; 58 | } 59 | } 60 | &__social { 61 | grid-area: social; 62 | padding:var(--of--spacer--lg); 63 | @media (min-width: $ov--breakpoint--lg){ 64 | padding:0; 65 | } 66 | .of-link-list { 67 | &__li { 68 | margin-right: var(--of--spacer--md); 69 | display: flex; 70 | } 71 | &__a { 72 | display: flex; 73 | align-items: center; 74 | font-size: 2rem; 75 | &:hover, &:active, &:focus { 76 | text-decoration: none; 77 | opacity: .8; 78 | } 79 | } 80 | } 81 | input { 82 | margin-bottom: var(--of--spacer--lg); 83 | border-radius: var(--of--BorderRadius--lg); 84 | border: none; 85 | text-indent: 1ch; 86 | min-width: 250px; 87 | } 88 | } 89 | &__copyright { 90 | grid-area: copy; 91 | display: flex; 92 | color: var(--of--color-white--100); 93 | padding: var(--of--spacer--xl); 94 | background: var(--of--color-black--300); 95 | .of-link-list__li { 96 | margin-left: var(--of--spacer--sm); 97 | } 98 | } 99 | &__badge { 100 | margin-left: auto; 101 | } 102 | .of-link-list { 103 | display: flex; 104 | flex-wrap: wrap; 105 | } 106 | } 107 | 108 | -------------------------------------------------------------------------------- /assets/scss/_functions.scss: -------------------------------------------------------------------------------- 1 | $font_size: 16; 2 | @function rem($pixels){ 3 | @return $pixels / $font_size + rem; 4 | } -------------------------------------------------------------------------------- /assets/scss/_header.scss: -------------------------------------------------------------------------------- 1 | .of-header-main { 2 | position: fixed; 3 | top: 0; 4 | min-height: 71px; 5 | z-index: var(--of--header-main); 6 | display: grid; 7 | grid-template-columns: max-content 1fr max-content; 8 | align-items: center; 9 | grid-template-areas: 10 | "brand search search" 11 | "nav nav nav"; 12 | 13 | @media (min-width: $ov--breakpoint--lg) { 14 | display: flex; 15 | align-items: center; 16 | } 17 | 18 | background: var(--of--color-black--300); 19 | width: 100%; 20 | .of-brand { 21 | grid-area: brand; 22 | display: flex; 23 | margin: var(--of--spacer--sm); 24 | 25 | @media (min-width: $ov--breakpoint--lg) { 26 | &__picture { 27 | min-width: 177px; 28 | display: flex; 29 | align-items: center; 30 | } 31 | margin: 0 var(--of--spacer--xl); 32 | } 33 | } 34 | .of-header-main__search { 35 | grid-area: search; 36 | width: 80%; 37 | display: flex; 38 | align-items: center; 39 | justify-self: center; 40 | @media (min-width: $ov--breakpoint--lg) { 41 | width: auto; 42 | margin: 0 var(--of--spacer--lg) 0 auto; 43 | } 44 | &__input { 45 | border-radius: var(--of--BorderRadius--lg); 46 | border: none; 47 | width: 100%; 48 | // padding: 0 var(--of--spacer--sm); 49 | background: var(--of--color-white--100); 50 | } 51 | } 52 | } 53 | 54 | .of-nav-main { 55 | grid-area: nav; 56 | width: 100%; 57 | @media (min-width: $ov--breakpoint--lg) { 58 | width: auto; 59 | } 60 | &__items { 61 | display: flex; 62 | justify-content: space-around; 63 | 64 | } 65 | .of-link-list { 66 | display: grid; 67 | grid-template-columns: 1fr 1fr; 68 | grid-template-rows: min-content min-content; 69 | @media (min-width: $ov--breakpoint--lg) { 70 | display: flex; 71 | margin: 0; 72 | } 73 | 74 | &__li { 75 | @media (min-width: $ov--breakpoint--lg) { 76 | border: none; 77 | } 78 | border: 1px solid var(--of--color-black--200); 79 | &:nth-of-type(even),&:nth-of-type(odd) { 80 | border-left: none; 81 | } 82 | &:nth-of-type(even) { 83 | border-right: none; 84 | } 85 | &:not(:last-of-type):not(:nth-last-child(-n+2)){ 86 | border-bottom: none; 87 | } 88 | 89 | } 90 | &__a { 91 | width: 100%; 92 | display: inline-block; 93 | position: relative; 94 | padding: var(--of--spacer--xs) var(--of--spacer--md); 95 | transition: background .25s linear; 96 | color: var(--of--color-white--100); 97 | min-height: 45px; 98 | @media (min-width: $ov--breakpoint--lg) { 99 | width: auto; 100 | padding: var(--of--spacer--lg) .9vw; 101 | &.of-m-active, &:focus, &:hover { 102 | text-decoration: none; 103 | background: var(--of--color-brand--100); 104 | } 105 | } 106 | // &.has-dropdown { 107 | // grid-area: link; 108 | // } 109 | 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /assets/scss/_homepage.scss: -------------------------------------------------------------------------------- 1 | .of-message { 2 | background: var(--of--color-black--300); 3 | display: flex; 4 | justify-content: center; 5 | } 6 | 7 | .of-masthead--home { 8 | background: var(--of--color-black--100) url("/images/bg-masthead-red.svg") no-repeat; 9 | background-position: -22vw -30vw ; 10 | background-size: 70% auto; 11 | padding: calc(2 * var(--of--spacer--2xl)) var(--of--spacer--md) var(--of--spacer--xl); 12 | @media (min-width: $ov--breakpoint--sm) { 13 | background-position:-35vw 50.5%; 14 | background-size: 100% auto; 15 | display: grid; 16 | grid-template-columns: 2fr 1fr 1fr 1fr; 17 | grid-column-gap: var(--of--spacer--md); 18 | grid-template-areas: 19 | ". title title title" 20 | ". content content content" 21 | ". action-1 . ." 22 | } 23 | @media (min-width: $ov--breakpoint--lg) { 24 | padding: var(--of--spacer--2xl) calc(var(--of--spacer--3xl) + var(--of--spacer--md)) var(--of--spacer--2xl); 25 | } 26 | .of-heading { 27 | color: var(--of--color-white--100); 28 | letter-spacing: normal; 29 | } 30 | &__title { 31 | display: flex; 32 | flex-direction: column; 33 | line-height: 3rem; 34 | font-weight: normal; 35 | grid-area: title; 36 | span { 37 | &:first-of-type { 38 | font-size: 2.625rem; 39 | } 40 | &:last-of-type { 41 | font-size: 3.5625rem; 42 | } 43 | } 44 | } 45 | &__content { 46 | @media (min-width: $ov--breakpoint--sm) { 47 | max-width: 55vw; 48 | margin: var(--of--spacer--xl) 0; 49 | } 50 | grid-area: content; 51 | margin: var(--of--spacer--md) 0; 52 | text-transform: none; 53 | } 54 | .of-button { 55 | justify-self: start; 56 | white-space: nowrap; 57 | grid-area: action-1; 58 | } 59 | } 60 | 61 | .of-section-page-intro { 62 | display: flex; 63 | flex-wrap: wrap; 64 | 65 | &__header { 66 | background: var(--of--color-white--200); 67 | padding: var(--of--spacer--lg); 68 | 69 | @media (min-width: $ov--breakpoint--lg) { 70 | padding: var(--of--spacer--2xl) 0 var(--of--spacer--2xl) calc(var(--of--spacer--2xl) + var(--of--spacer--xl)); 71 | &--overlay { 72 | padding-bottom: calc(var(--of--spacer--3xl) + var(--of--spacer--3xl)); 73 | margin-bottom: calc(calc(var(--of--spacer--3xl) + var(--of--spacer--md) + 1px) * -1); 74 | } 75 | } 76 | width: 100%; 77 | & > * { 78 | @media (min-width: $ov--breakpoint--lg) { 79 | max-width: 55vw; 80 | } 81 | } 82 | .of-heading { 83 | color: var(--of--color-brand--200); 84 | } 85 | } 86 | .of-heading { 87 | margin-bottom: var(--of--spacer--sm); 88 | } 89 | &__content { 90 | background: var(--of--color-white--100); 91 | margin: var(--of--spacer--lg); 92 | padding-bottom: var(--of--spacer--lg); 93 | &:not(&--overlay){ 94 | &__columns { 95 | padding: var(--of--spacer--lg); 96 | } 97 | } 98 | 99 | @media (min-width: $ov--breakpoint--lg) { 100 | margin: var(--of--spacer--xl) calc(var(--of--spacer--2xl) + var(--of--spacer--xl)) var(--of--spacer--2xl) calc(var(--of--spacer--2xl) + var(--of--spacer--xl)); 101 | &--overlay { 102 | border: 1px solid var(--of--color-white--200); 103 | padding: var(--of--spacer--lg); 104 | margin-top: 0; 105 | } 106 | &__columns { 107 | column-count: 2; 108 | column-gap: calc(var(--of--spacer--2xl) * 2); 109 | margin-bottom: calc(var(--of--spacer--md) * -1); 110 | padding-bottom: var(--of--spacer--xl); 111 | > * { 112 | margin-bottom: var(--of--spacer--md); 113 | } 114 | } 115 | 116 | } 117 | } 118 | &__footer { 119 | padding: 0 var(--of--spacer--xl) var(--of--spacer--xl); 120 | @media (min-width: $ov--breakpoint--lg) { 121 | padding: 0 calc(var(--of--spacer--2xl) + var(--of--spacer--xl)) var(--of--spacer--2xl) calc(var(--of--spacer--2xl) + var(--of--spacer--xl)); 122 | } 123 | } 124 | &__items { 125 | @media (min-width: $ov--breakpoint--lg) { 126 | display: grid; 127 | grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); 128 | margin: 0 var(--of--spacer--2xl); 129 | .of-heading { 130 | min-height: 115px; 131 | } 132 | } 133 | 134 | 135 | } 136 | 137 | &__item { 138 | background: var(--of--color-white--100); 139 | &:nth-child(1) { 140 | .of-heading { 141 | background: var(--of--color-brand--50); 142 | } 143 | } 144 | &:nth-child(2) { 145 | .of-heading { 146 | background: var(--of--color-brand--100); 147 | } 148 | } 149 | &:nth-child(3) { 150 | .of-heading { 151 | background: var(--of--color-brand--200); 152 | } 153 | } 154 | &:nth-child(4) { 155 | .of-heading { 156 | background: var(--of--color-brand--300); 157 | } 158 | } 159 | &:nth-child(5) { 160 | .of-heading { 161 | background: var(--of--color-brand--400); 162 | } 163 | } 164 | &__content { 165 | padding: var(--of--spacer--lg); 166 | display: flex; 167 | flex-direction: column; 168 | } 169 | .of-heading { 170 | color: var(--of--color-white--100); 171 | padding:var(--of--spacer--lg) var(--of--spacer--md); 172 | } 173 | } 174 | 175 | } 176 | -------------------------------------------------------------------------------- /assets/scss/_of-variables.scss: -------------------------------------------------------------------------------- 1 | :root { 2 | //type 3 | --of--font-family: 'overpass', sans-serif; 4 | --of--FontSize--xs: .875rem; //14 5 | --of--FontSize--sm: 1rem; //16 6 | --of--FontSize--md: 1.125rem; //18 7 | --of--FontSize--lg: 1.375rem; //22 8 | --of--FontSize--xl: 1.5rem;//24 9 | --of--FontSize--2xl: 2.625rem; //40 10 | 11 | //spacers 12 | --of--spacer--xs: .25rem; //4 purple 13 | --of--spacer--sm: .5rem; //8 light blue 14 | --of--spacer--md: 1rem; //16 green 15 | --of--spacer--lg: 1.5rem; //24 yellow 16 | --of--spacer--xl: 2rem; //32 pink 17 | --of--spacer--2xl: 3rem; //48 blue 18 | --of--spacer--3xl: 4rem; //64 purple 19 | 20 | //color 21 | --of--color-brand--50: #b12239; 22 | --of--color-brand--100: #921c2f; 23 | --of--color-brand--200: #651524; 24 | --of--color-brand--300: #51101a; 25 | --of--color-brand--400: #2f090f; 26 | --of--color-white--100: #FFF; 27 | --of--color-white--150: #F0F0F0; 28 | --of--color-white--200: #EDEDED; 29 | --of--color-blue--100: #dfe7f4; 30 | --of--color-blue--200: #cad3e5; 31 | --of--color-grey--100: #979797; 32 | --of--color-grey--200: #666; 33 | --of--color-black--100: #040404; 34 | --of--color-black--200: #202020; 35 | --of--color-black--300: #000; 36 | 37 | //transparencies 38 | --of--color-transparent-background--100: rgba(32,32,32,.90); 39 | 40 | //borders 41 | --of--BorderWidth--sm: 2px; 42 | --of--BorderWidth--lg: 4px; 43 | --of--BorderRadius--sm: .1875rem; 44 | --of--BorderRadius--md: .75rem; 45 | --of--BorderRadius--lg: 40rem; 46 | 47 | //text 48 | --of--Color--100: var(--of--color-white--100); 49 | --of--Color--200: var(--of--color-white--200); 50 | --of--Color--300: var(--of--color-brand--100); 51 | --of--Color--400: var(--of--color-black--200); 52 | --of--Color--500: var(--of--color-brand--400); 53 | --of--Color--600: var(--of--color-brand--300); 54 | 55 | --of--LineHeight--sm: 1.3; 56 | --of--LineHeight--lg: 1.5; 57 | 58 | --of--FontWeight--100: 400; 59 | --of--FontWeight--200: 700; 60 | 61 | //animation 62 | --of--animation: all .15s linear; 63 | 64 | //shadows 65 | --of--BoxShadow--sm: 0px 1px 4px rgba(0,0,0,0.5); 66 | 67 | //misc 68 | --of--menu-offset: 56px; 69 | 70 | // z-indexes 71 | --of--header-main: 10000; 72 | } 73 | 74 | //media queries (no custom properties as MQs :( 75 | $ov--breakpoint--xs: 0; 76 | $ov--breakpoint--sm: 576px; 77 | $ov--breakpoint--md: 768px; 78 | $ov--breakpoint--lg: 992px; 79 | $ov--breakpoint--xl: 1200px; 80 | $ov--breakpoint--2xl: 1450px; 81 | 82 | // Breadcrumbs 83 | $breadcrumb-font-size: null !default; 84 | $breadcrumb-padding-y: .75rem !default; 85 | $breadcrumb-margin-bottom: 1rem !default; 86 | $breadcrumb-bg: $gray-100 !default; 87 | $breadcrumb-divider-color: $gray-600 !default; 88 | $breadcrumb-active-color: $gray-600 !default; 89 | $breadcrumb-divider: quote("/") !default; 90 | $breadcrumb-border-radius: $border-radius !default; 91 | -------------------------------------------------------------------------------- /assets/scss/_reset.scss: -------------------------------------------------------------------------------- 1 | // Reset 2 | html, 3 | body, 4 | p, 5 | ol, 6 | ul, 7 | li, 8 | dl, 9 | dt, 10 | dd, 11 | blockquote, 12 | figure, 13 | fieldset, 14 | legend, 15 | textarea, 16 | pre, 17 | iframe, 18 | hr, 19 | h1, 20 | h2, 21 | h3, 22 | h4, 23 | h5, 24 | h6 { 25 | padding: 0; 26 | margin: 0; 27 | } 28 | 29 | html, 30 | body { 31 | height: 100%; 32 | } 33 | 34 | h1, 35 | h2, 36 | h3, 37 | h4, 38 | h5, 39 | h6 { 40 | font-size: 100%; 41 | font-weight: normal; 42 | } 43 | 44 | ul { 45 | list-style: none; 46 | } 47 | 48 | button, 49 | input, 50 | optgroup, 51 | select, 52 | textarea { 53 | margin: 0; 54 | font-family: inherit; 55 | font-size: 100%; 56 | line-height: 1.5; 57 | } 58 | 59 | img, 60 | embed, 61 | iframe, 62 | object, 63 | audio, 64 | video { 65 | max-width: 100%; 66 | height: auto; 67 | } 68 | 69 | iframe { 70 | border: 0; 71 | } 72 | 73 | table { 74 | border-spacing: 0; 75 | border-collapse: collapse; 76 | } 77 | 78 | td, 79 | th { 80 | padding: 0; 81 | text-align: left; 82 | } 83 | 84 | *, 85 | *::before, 86 | *::after { 87 | box-sizing: border-box; 88 | } 89 | 90 | 91 | body { 92 | font-family:var(--of--font-family); 93 | font-size: var(--of--FontSize--sm); 94 | font-weight: normal; 95 | line-height: 1.5; 96 | text-align: left; 97 | color: var(--of--color-black--100); 98 | } 99 | 100 | a{ 101 | color: var(--of--color-brand--100); 102 | text-decoration: none; 103 | &:hover { 104 | text-decoration: underline; 105 | } 106 | } 107 | // a, a:before, a:after, button, button:before, button:after { 108 | // transition: var(--of--animation); 109 | // } 110 | button, 111 | a { 112 | cursor: pointer; 113 | } 114 | 115 | button, 116 | [type="button"], 117 | [type="reset"], 118 | [type="submit"] { 119 | // Remove the inner border and padding in Firefox. 120 | &::-moz-focus-inner { 121 | padding: 0; 122 | border-style: none; 123 | } 124 | 125 | // Restore the focus styles unset by the previous rule. 126 | &:-moz-focusring { 127 | outline: 1px dotted ButtonText; 128 | } 129 | } -------------------------------------------------------------------------------- /assets/scss/_sidebar-tree.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Left side navigation 3 | // 4 | .td-sidebar-nav { 5 | padding-right: 0.5rem; 6 | margin-right: -15px; 7 | margin-left: -15px; 8 | 9 | @include media-breakpoint-up(md) { 10 | @supports (position: sticky) { 11 | // max-height: calc(100vh - 10rem); 12 | max-height: calc(100vh - 4rem); 13 | overflow-y: auto; 14 | } 15 | } 16 | 17 | 18 | @include media-breakpoint-up(md) { 19 | display: block !important; 20 | } 21 | 22 | 23 | &__section { 24 | li { 25 | list-style: none; 26 | } 27 | 28 | ul { 29 | padding: 0; 30 | margin: 0; 31 | } 32 | 33 | @include media-breakpoint-up(md) { 34 | & > ul { 35 | padding-left: .5rem; 36 | } 37 | } 38 | 39 | 40 | padding-left: 0; 41 | } 42 | 43 | &__section-title { 44 | display: block; 45 | //font-weight: $font-weight-medium; 46 | font-weight: 550; 47 | 48 | .active { 49 | //font-weight: $font-weight-bold; 50 | font-weight: 800; 51 | color: $gray-900; 52 | } 53 | 54 | a { 55 | color: $gray-700; 56 | } 57 | } 58 | 59 | .td-sidebar-link { 60 | display: block; 61 | padding-bottom: 0.375rem; 62 | 63 | &__page { 64 | color: $gray-600; 65 | font-weight: $font-weight-light; 66 | } 67 | } 68 | 69 | a { 70 | &:hover { 71 | color: $blue; 72 | text-decoration: none; 73 | } 74 | 75 | &.active { 76 | //font-weight: $font-weight-bold; 77 | font-weight: 800; 78 | color: $gray-800; 79 | 80 | } 81 | } 82 | 83 | .dropdown { 84 | a { 85 | color: $gray-700; 86 | } 87 | 88 | .nav-link { 89 | padding: 0 0 1rem; 90 | } 91 | } 92 | } 93 | 94 | .td-sidebar { 95 | padding-top: 4rem; 96 | margin-bottom: var(--of--spacer--md); 97 | display:flex; 98 | justify-content: center; 99 | background: var(--of--color-white--200); 100 | span { 101 | margin-left: var(--of--spacer--md); 102 | font-family: var(--of--font-family); 103 | } 104 | @include media-breakpoint-up(md) { 105 | padding-top: var(--of--spacer--md); 106 | padding-bottom: 4rem; 107 | background-color: $td-sidebar-bg-color; 108 | margin-bottom: 0; 109 | padding-right: 1rem; 110 | border-right: 1px solid $td-sidebar-border-color; 111 | } 112 | 113 | &__toggle { 114 | line-height: 1; 115 | color: $gray-900; 116 | margin: 1rem; 117 | } 118 | 119 | &__search { 120 | padding: 1rem 15px; 121 | margin-right: -15px; 122 | margin-left: -15px; 123 | } 124 | 125 | &__inner { 126 | order: 0; 127 | 128 | @include media-breakpoint-up(md) { 129 | @supports (position: sticky) { 130 | position: sticky; 131 | top:71px; 132 | z-index: 10; 133 | height: calc(100vh - 6rem); 134 | } 135 | } 136 | 137 | 138 | @include media-breakpoint-up(xl) { 139 | flex: 0 1 320px; 140 | } 141 | 142 | 143 | .td-search-box { 144 | width: 100%; 145 | } 146 | 147 | &__heading { 148 | padding: var(--of--spacer--md); 149 | background: var(--of--color-brand--300); 150 | color: var(--of--color-white--100); 151 | margin-left: -15px; 152 | margin-right: -15px; 153 | } 154 | } 155 | } -------------------------------------------------------------------------------- /assets/scss/_styles_project.scss: -------------------------------------------------------------------------------- 1 | @if $td-enable-google-fonts { 2 | @import url($web-font-path); 3 | } 4 | 5 | footer { 6 | min-height: 150px; 7 | 8 | @include media-breakpoint-down(md) { 9 | min-height: 200px; 10 | } 11 | } 12 | 13 | // Adjust anchors vs the fixed menu. 14 | @include media-breakpoint-up(md) { 15 | .td-offset-anchor:target { 16 | display: block; 17 | position: relative; 18 | top: -4rem; 19 | visibility: hidden; 20 | } 21 | 22 | h2[id]:before, h3[id]:before, h4[id]:before, h5[id]:before { 23 | display: block; 24 | content: " "; 25 | margin-top: -5rem; 26 | height: 5rem; 27 | visibility: hidden; 28 | } 29 | } 30 | 31 | 32 | 33 | @import "functions"; 34 | @import "of-variables"; 35 | @import "reset"; 36 | @import "type"; 37 | @import "sidebar-tree"; 38 | @import "breadcrumb"; 39 | 40 | //components 41 | @import "header"; 42 | @import "footer"; 43 | 44 | //layout 45 | @import "homepage"; 46 | @import "docs"; 47 | 48 | //global 49 | @import "global"; 50 | -------------------------------------------------------------------------------- /assets/scss/_type.scss: -------------------------------------------------------------------------------- 1 | //type 2 | .of-heading { 3 | color: var(--of--Color--brand--200); 4 | text-transform: uppercase; 5 | font-weight: 800; 6 | letter-spacing: 2px; 7 | } 8 | .of-heading--secondary { 9 | color: var(--of--color-brand--200); 10 | margin-bottom: var(--of--spacer--md); 11 | } 12 | .of-heading--xs, .of-heading--sm { 13 | font-size: var(--of--FontSize--xs); 14 | } 15 | .of-heading--md { 16 | font-size: var(--of--FontSize--sm); 17 | } 18 | .of-heading--lg { 19 | font-size: var(--of--FontSize--md); 20 | } 21 | .of-heading--xl { 22 | font-size: var(--of--FontSize--md); 23 | } 24 | .of-heading--2xl { 25 | font-size: var(--of--FontSize--lg); 26 | } 27 | 28 | @media (min-width: $ov--breakpoint--lg) { 29 | .of-heading--xs { 30 | font-size: var(--of--FontSize--xs); 31 | } 32 | .of-heading--sm { 33 | font-size: var(--of--FontSize--sm); 34 | } 35 | .of-heading--md { 36 | font-size: var(--of--FontSize--md); 37 | } 38 | .of-heading--lg { 39 | font-size: var(--of--FontSize--lg); 40 | } 41 | .of-heading--xl { 42 | font-size: var(--of--FontSize--xl); 43 | } 44 | .of-heading--2xl { 45 | font-size: var(--of--FontSize--2xl); 46 | } 47 | } -------------------------------------------------------------------------------- /config.toml: -------------------------------------------------------------------------------- 1 | baseURL = "/" 2 | languageCode = "en-us" 3 | title = "Operator Lifecycle Manager" 4 | 5 | enableRobotsTXT = true 6 | 7 | # Language settings 8 | contentDir = "content/en" 9 | defaultContentLanguage = "en" 10 | defaultContentLanguageInSubdir = false 11 | # Useful when translating. 12 | enableMissingTranslationPlaceholders = true 13 | 14 | 15 | disableKinds = ["taxonomy", "taxonomyTerm"] 16 | 17 | # Highlighting config 18 | pygmentsCodeFences = true 19 | pygmentsUseClasses = false 20 | # Use the new Chroma Go highlighter in Hugo. 21 | pygmentsUseClassic = false 22 | #pygmentsOptions = "linenos=table" 23 | # See https://help.farbox.com/pygments.html 24 | pygmentsStyle = "tango" 25 | 26 | ## Configuration for Goldmark markdown parser: https://github.com/yuin/goldmark 27 | [markup] 28 | [markup.goldmark] 29 | [markup.goldmark.renderer] 30 | unsafe = true 31 | [markup.tableOfContents] 32 | endLevel = 4 33 | 34 | # Image processing configuration. 35 | [imaging] 36 | resampleFilter = "CatmullRom" 37 | quality = 75 38 | anchor = "smart" 39 | 40 | # Language configuration 41 | 42 | [languages] 43 | [languages.en] 44 | description = "Operator Lifecyle Manager" 45 | languageName ="English" 46 | # Weight used for sorting. 47 | weight = 1 48 | 49 | # Everything below this are Site Params 50 | 51 | [params] 52 | copyright = "The Operator Lifecycle Manager Authors" 53 | # privacy_policy = "https://policies.google.com/privacy" 54 | 55 | # First one is picked as the Twitter card image if not set on page. 56 | # images = ["images/project-illustration.png"] 57 | 58 | # Menu title if your navbar has a versions selector to access old versions of your site. 59 | # This menu appears only if you have at least one [params.versions] set. 60 | version_menu = "Releases" 61 | 62 | # Repository configuration (URLs for in-page links to opening issues and suggesting changes) 63 | github_repo = "https://github.com/operator-framework/olm-docs" 64 | # An optional link to a related project repo. For example, the sibling repository where your product code lives. 65 | github_project_repo = "https://github.com/operator-framework/operator-lifecycle-manager" 66 | github_branch = "master" 67 | 68 | # Enable Algolia DocSearch 69 | algolia_docsearch = true 70 | 71 | [[params.versions]] 72 | version = "master" 73 | url = "https://olm.operatorframework.io" 74 | primary = true 75 | 76 | [[params.versions]] 77 | version = "v0.16.z" 78 | url = "https://v0-16-z.olm.operatorframework.io/" 79 | 80 | [[params.versions]] 81 | version = "v0.18.z" 82 | url = "https://v0-18-z.olm.operatorframework.io/" 83 | 84 | [[params.versions]] 85 | version = "legacy" 86 | url = "https://legacy.olm.operatorframework.io/" 87 | 88 | # User interface configuration 89 | [params.ui] 90 | # Set to true to disable breadcrumb navigation. 91 | breadcrumb_disable = false 92 | # Set to true to hide the sidebar search box (the top nav search box will still be displayed if search is enabled) 93 | sidebar_search_disable = true 94 | # Set to false if you don't want to display a logo (/assets/icons/logo.svg) in the top nav bar 95 | navbar_logo = true 96 | 97 | # Adds a H2 section titled "Feedback" to the bottom of each doc. The responses are sent to Google Analytics as events. 98 | # This feature depends on [services.googleAnalytics] and will be disabled if "services.googleAnalytics.id" is not set. 99 | # If you want this feature, but occasionally need to remove the "Feedback" section from a single page, 100 | # add "hide_feedback: true" to the page's front matter. 101 | [params.ui.feedback] 102 | enable = true 103 | # The responses that the user sees after clicking "yes" (the page was helpful) or "no" (the page was not helpful). 104 | yes = 'Glad to hear it! Please tell us how we can improve.' 105 | no = 'Sorry to hear that. Please tell us how we can improve.' 106 | 107 | [params.links] 108 | # End user relevant links. These will show up on left side of footer and in the community page if you have one. 109 | 110 | [[params.links.social]] 111 | name = "Slack" 112 | url = "https://kubernetes.slack.com/archives/C0181L6JYQ2" 113 | icon = "fab fa-slack" 114 | desc = "Chat with OLM contributors" 115 | 116 | [[params.links.social]] 117 | name = "Forum" 118 | url = "https://groups.google.com/g/operator-framework" 119 | icon = "fas fa-comment" 120 | 121 | [[params.links.social]] 122 | name = "github" 123 | url = "https://github.com/operator-framework/operator-lifecycle-manager" 124 | icon = "fab fa-github" 125 | 126 | [module] 127 | [module.hugoVersion] 128 | extended = true 129 | min = "0.111.1" 130 | [[module.imports]] 131 | path = "github.com/google/docsy" 132 | disable = false 133 | [[module.imports]] 134 | path = "github.com/google/docsy/dependencies" 135 | disable = false 136 | -------------------------------------------------------------------------------- /content/en/_index.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: "homepage" 3 | date: 2020-02-12T15:41:36-03:00 4 | draft: false 5 | --- 6 |
7 |

OperatorLIFECYCLE MANAGER

8 |

The Operator Lifecycle Manager (OLM) extends Kubernetes to provide a declarative way to install, manage, and upgrade Operators on a cluster.

9 | Install an Operator 10 | 11 |
12 |
13 |
14 |

WHAT IS OPERATOR Lifecycle manager?

15 |

This project is a component of the Operator Framework, an open source toolkit to manage Kubernetes native applications, called Operators, in a streamlined and scalable way.

16 |
17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |
34 |

OLM Features

35 |
36 |
37 |

OVER-THE-AIR UPDATES AND CATALOGS

38 |
39 |

OLM provides rich update mechanisms to keep Kubernetes native applications up to date automatically.

40 |
41 |
42 |
43 |

DEPENDENCY MODEL

44 |
45 |

With OLMs packaging format Operators can express dependencies on the platform and on other Operators.

46 |
47 |
48 |
49 |

DISCOVERABILITY

50 |
51 |

OLM makes Operators and their services available for cluster users to select and install.

52 |
53 |
54 |
55 |

CLUSTER STABILITY

56 |
57 |

OLM will prevent conflicting Operators owning the same APIs being installed, ensuring cluster stability.

58 |
59 |
60 |
61 |

DECLARATIVE UI CONTROLS

62 |
63 |

OLM enables Operators to behave like managed service providers through the APIs they expose.

64 |
65 |
66 |
67 | 73 |
74 |
75 |
76 |

Contribute!

77 | 79 | 82 | 83 | 85 | 86 | 88 | 91 | 97 | 98 |
99 | 100 |

The Operator Lifecycle Manager project is open source, and participation from members of the community is highly valued. If you want to get involved, discuss your experiences with OLM, or have questions, join the Operator Framework forum and visit us on GitHub.

101 |
102 | -------------------------------------------------------------------------------- /content/en/about/_index.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Build 3 | linkTitle: Build 4 | menu: 5 | main: 6 | weight: 10 7 | 8 | --- 9 |
10 |

Building Operators using the Operator SDK

11 |
12 |
13 |
14 |

How can I write an Operator with Operator SDK?

15 |

There are many ways to build an Operator with SDK. To get started building today, follow the steps in this quick start guide.

16 |
17 |
18 |
19 |
20 |
21 |
22 |

Installing the SDK CLI

23 |
24 |

Follow the steps in the installation guide to learn how to install the Operator SDK CLI tool. If you are using a release version of the SDK, make sure to follow the documentation for that version. You make use any of the following installation processes:

25 |
    26 |
  1. Install the Homebrew (macOS)
  2. 27 |
  3. Install from GitHub release
  4. 28 |
  5. Compile and install from master
  6. 29 |
30 |
31 | Learn More 32 | 33 | 34 | 35 | 36 |

homebrew, 37 | github, 38 | master.

39 |
40 |
41 |

READ THE USER GUIDES

42 |

Operators can be created with the SDK using Ansible, Helm, or Go. Follow the one of the quickstart guides to dive in.

43 | 63 |

Go Ansible Helm

64 |
65 |
66 |

PUBLISH YOUR OPERATOR

67 |

Learn about how you can package your Operator and share with the Kubernetes community using Operator Lifecycle Manager's package management.

68 | Learn More 69 | 70 | 71 | 72 | 73 |

package & deploy

74 |
75 |
76 |

evolve & mature

77 |

LEVEL UP YOUR OPERATOR

78 |

Learn about operator maturity and the requirements to approach full auto 79 | pilot.

80 | Learn More 81 | 83 | 85 | 86 | 87 |
88 |
89 |
90 |
91 | -------------------------------------------------------------------------------- /content/en/docs/Concepts/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Concepts" 3 | linkTitle: "Concepts" 4 | weight: 4 5 | description: > 6 | This section is the knowledge base for all concepts, glossary, etc that are associated with OLM 7 | --- 8 | 9 | 10 | -------------------------------------------------------------------------------- /content/en/docs/Concepts/crds/CatalogSource.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "CatalogSource" 3 | weight: 3 4 | --- 5 | 6 | A CatalogSource represents a store of metadata that OLM can query to discover and install operators and their dependencies. 7 | 8 | There are three primary types of CatalogSource(`spec.sourceType`): 9 | 10 | - `grpc` with an `image` reference: OLM will pull the image and run a pod that has an api endpoint that can be queried for the metadata in the store 11 | - `grpc` with an `address` field: OLM will attempt to contact the grpc api at the given address. This should not be used in most cases. 12 | - `internal` or `configmap`: OLM will parse the configmap's data and spin up a pod that can serve the grpc api over it. 13 | 14 | ## Example - OperatorHub.io 15 | 16 | ```yaml 17 | apiVersion: operators.coreos.com/v1alpha1 18 | kind: CatalogSource 19 | metadata: 20 | name: operatorhubio-catalog 21 | namespace: olm 22 | spec: 23 | sourceType: grpc 24 | image: quay.io/operatorhubio/catalog:latest 25 | displayName: Community Operators 26 | publisher: OperatorHub.io 27 | ``` 28 | 29 | This defines a CatalogSource for OperatorHub.io's content. The `name` of the CatalogSource is used as input to a `Subscription`, which tells OLM where to look to find a requested operator: 30 | 31 | ```yaml 32 | apiVersion: operators.coreos.com/v1alpha1 33 | kind: Subscription 34 | metadata: 35 | name: my-operator 36 | namespace: olm 37 | spec: 38 | channel: stable 39 | name: my-operator 40 | source: operatorhubio-catalog 41 | ``` 42 | -------------------------------------------------------------------------------- /content/en/docs/Concepts/crds/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "CustomResourceDefinitions" 3 | weight: 2 4 | description: > 5 | A list of [CustomResourceDefinitions](https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/) defined by OLM. 6 | --- 7 | -------------------------------------------------------------------------------- /content/en/docs/Concepts/crds/clusterserviceversion.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "ClusterServiceVersion" 3 | weight: 2 4 | --- 5 | 6 | A ClusterServiceVersion (CSV) represents a particular version of a running operator on a cluster. It includes metadata such as name, description, version, repository link, labels, icon, etc. It declares `owned`/`required` CRDs, cluster requirements, and install strategy that tells OLM how to create required resources and set up the operator as a [deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/). 7 | 8 | OLM requires you to provide metadata about your operator in order to ensure that it can be kept running safely on a cluster, and to provide information about how updates should be applied as you publish new versions of your operator. 9 | 10 | 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`, `deb`, or `apk` bundle. 11 | 12 | ## Writing your Operator Manifests 13 | 14 | OLM uses an api called `ClusterServiceVersion` (CSV) to describe a single instance of a version of an operator. This is the main entrypoint for packaging an operator for OLM. 15 | 16 | There are two important ways to think about the CSV: 17 | 18 | 1. Like an `rpm` or `deb`, it collects metadata about the operator that is required to install it onto the cluster. 19 | 2. Like a `Deployment` that can stamp out `Pod`s from a template, the `ClusterServiceVersion` describes a template for the operator `Deployment` and can stamp them out. 20 | 21 | 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. 22 | 23 | ## Example ClusterServiceVersion 24 | 25 | ```yaml 26 | apiVersion: operators.coreos.com/v1alpha1 27 | kind: ClusterServiceVersion 28 | metadata: 29 | annotations: 30 | name: memcached-operator.v0.10.0 31 | spec: 32 | # metadata 33 | description: This is an operator for memcached. 34 | displayName: Memcached Operator 35 | keywords: 36 | - memcached 37 | - app 38 | maintainers: 39 | - email: corp@example.com 40 | name: Some Corp 41 | maturity: alpha 42 | provider: 43 | name: Example 44 | url: www.example.com 45 | version: 0.10.0 46 | minKubeVersion: 1.16.0 47 | 48 | # operator scope 49 | installModes: 50 | - supported: true 51 | type: OwnNamespace 52 | - supported: true 53 | type: SingleNamespace 54 | - supported: false 55 | type: MultiNamespace 56 | - supported: true 57 | type: AllNamespaces 58 | 59 | # installation 60 | install: 61 | # strategy indicates what type of deployment artifacts are used 62 | strategy: deployment 63 | # spec for the deployment strategy is a list of deployment specs and required permissions - similar to a pod template used in a deployment 64 | spec: 65 | permissions: 66 | - serviceAccountName: memcached-operator 67 | rules: 68 | - apiGroups: 69 | - "" 70 | resources: 71 | - pods 72 | verbs: 73 | - '*' 74 | # the rest of the rules 75 | # permissions required at the cluster scope 76 | clusterPermissions: 77 | - serviceAccountName: memcached-operator 78 | rules: 79 | - apiGroups: 80 | - "" 81 | resources: 82 | - serviceaccounts 83 | verbs: 84 | - '*' 85 | # the rest of the rules 86 | deployments: 87 | - name: memcached-operator 88 | spec: 89 | replicas: 1 90 | # the rest of a deployment spec 91 | 92 | # apis provided by the operator 93 | customresourcedefinitions: 94 | owned: 95 | # a list of CRDs that this operator owns 96 | # name is the metadata.name of the CRD (which is of the form .) 97 | - name: memcacheds.cache.example.com 98 | # version is the spec.versions[].name value defined in the CRD 99 | version: v1alpha1 100 | # kind is the CamelCased singular value defined in spec.names.kind of the CRD. 101 | kind: Memcached 102 | required: 103 | # a list of CRDs that this operator requires 104 | # see field descriptions above 105 | - name: others.example.com 106 | version: v1alpha1 107 | kind: Other 108 | ``` 109 | -------------------------------------------------------------------------------- /content/en/docs/Concepts/crds/installplan.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "InstallPlan" 3 | weight: 5 4 | --- 5 | 6 | {{% alert title="Warning" color="warning" %}} This page is under construction{{% /alert %}} 7 | 8 | An InstallPlan defines a set of resources to be created in order to install or upgrade to a specific version of a ClusterService defined by a CSV. 9 | -------------------------------------------------------------------------------- /content/en/docs/Concepts/crds/operatorcondition.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "OperatorCondition" 3 | weight: 4 4 | --- 5 | 6 | An `OperatorCondition` is CustomResourceDefinition that creates a communication between OLM and an operator it manages. Operators may write to the `Status.Conditions` array to modify OLM management the operator. 7 | 8 | Here's an example of an `OperatorCondition` CustomResource: 9 | 10 | ```yaml 11 | apiVersion: operators.coreos.com/v1 12 | kind: OperatorCondition 13 | metadata: 14 | name: foo-operator 15 | namespace: operators 16 | spec: 17 | overrides: 18 | - type: Upgradeable # Allows the cluster admin to change operator's Upgrade readiness to True 19 | status: "True" 20 | reason: "upgradeIsSafe" # optional 21 | message: "The cluster admin wants to make the operator eligible for an upgrade." # optional 22 | status: 23 | conditions: 24 | - type: Upgradeable 25 | status: "False" 26 | reason: "migration" 27 | message: "The operator is performing a migration." 28 | lastTransitionTime: "2020-08-24T23:15:55Z" 29 | ``` 30 | -------------------------------------------------------------------------------- /content/en/docs/Concepts/crds/subscription.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Subscription" 3 | weight: 4 4 | --- 5 | 6 | 7 | A Subscription represents an intention to install an operator. It is the CustomResource that relate an operator to a CatalogSource. Subscriptions describe which [channel](/docs/glossary/#channel) of an operator package to subscribe to, and whether to perform updates automatically or manually. If set to automatic, the Subscription ensures OLM will manage and upgrade the operator to ensure the latest version is always running in the cluster. 8 | 9 | Here's an example of a Subscription definition: 10 | 11 | ```yaml 12 | apiVersion: operators.coreos.com/v1alpha1 13 | kind: Subscription 14 | metadata: 15 | name: my-operator 16 | namespace: operators 17 | spec: 18 | channel: stable 19 | name: my-operator 20 | source: my-catalog 21 | sourceNamespace: operators 22 | ``` 23 | 24 | This Subscription object defines the name and namespace of the operator, as well as the catalog from which the operator data can be found. The channel (such as alpha, beta, or stable) helps determine which stream of the operator should be installed from the CatalogSource. 25 | 26 | ## Manually Approving Upgrades via Subscriptions 27 | 28 | By default, OLM will automatically approve updates to an operator as new versions become available via a CatalogSource. When creating a subscription, it is possible to disable automatic updates by setting the `installPlanApproval` field to `Manual` like so: 29 | 30 | ```yaml 31 | apiVersion: operators.coreos.com/v1alpha1 32 | kind: Subscription 33 | metadata: 34 | name: my-operator 35 | namespace: operators 36 | spec: 37 | channel: stable 38 | name: my-operator 39 | source: my-catalog 40 | sourceNamespace: operators 41 | installPlanApproval: Manual 42 | ``` 43 | 44 | Setting the `installPlanApproval` field to manual will prevent OLM from automatically installing the operator. As such, you will need to approve the installPlan which can be done with the following commands: 45 | 46 | ```bash 47 | kubectl -n operators get installplans 48 | NAME CSV APPROVAL APPROVED 49 | install-bfmxd my-operator.v0.1.0 Manual false 50 | 51 | $ kubectl -n operators patch installplan install-bfmxd -p '{"spec":{"approved":true}}' --type merge 52 | installplan.operators.coreos.com/install-bfmxd patched 53 | 54 | $ kubectl -n operators get installplans 55 | NAME CSV APPROVAL APPROVED 56 | install-bfmxd my-operator.v0.1.0 Manual true 57 | ``` 58 | 59 | Now that the `install-bfmxd` installPlan is in the approved state, OLM will install the operator defined by the `my-operator.v0.1.0` CSV. 60 | 61 | When the CatalogSource is updated with a newer version of that operator in the channel you selected, a new installPlan will be created in the namespace that you installed the operator to, as shown below: 62 | 63 | ```bash 64 | $ kubectl -n operators get installplans 65 | NAME CSV APPROVAL APPROVED 66 | install-bfmxd my-operator.v0.1.0 Manual true 67 | install-svojy my-operator.v0.2.0 Manual false 68 | ``` 69 | 70 | From here, you can approve `install-svojy` using the patch command shown earlier. 71 | 72 | With the new installPlan in the approve state, the `my-operator.v0.2.0` CSV will be deployed to the cluster and if the CSV reaches the `Succeeded` state the old CSV will be deleted. If the new CSV fails to reach the `Succeeded` state, both CSVs will continue to exist and it is up to the user to resolve the failure. In either case, OLM will not delete old installPlans as they act as a record of CSVs that were installed on your cluster. 73 | 74 | ## How do I know when an update is available for an operator 75 | 76 | It is possible to identify when there is a newer version of an operator available by inspecting the status of the operator's subscription. The value associated with the `currentCSV` field is the newest version that is known to OLM, and `installedCSV` is the version that is installed on the cluster. 77 | -------------------------------------------------------------------------------- /content/en/docs/Concepts/olm-architecture/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "OLM Architecture" 3 | linkTitle: "OLM Architecture" 4 | date: 2020-03-25 5 | weight: 4 6 | description: > 7 | A discussion on the architecture of Operator Lifecycle Manager (OLM). 8 | --- 9 | 10 | 11 | The Operator Lifecycle Manager is composed of two Operators: the OLM Operator and the Catalog Operator. 12 | 13 | Each of these Operators are responsible for managing the CRDs that are the basis for the OLM framework: 14 | 15 | **_Table 1. CRDs managed by OLM and Catalog Operators_** 16 | 17 | | Resource | Short Name | Owner | Description | 18 | |-----------------------|-------------|---------|---------------------------------------| 19 | | ClusterServiceVersion | **csv** | OLM | Application metadata: name, version, icon, required resources, installation, etc. | 20 | | InstallPlan | **ip** | Catalog | Calculated list of resources to be created in order to automatically install or upgrade a CSV. | 21 | | CatalogSource | **catsrc** | Catalog | A repository of CSVs, CRDs, and packages that define an application. | 22 | | Subscription | **sub** | Catalog | Used to keep CSVs up to date by tracking a channel in a package. | 23 | | OperatorGroup | **og** | OLM | Used to group multiple namespaces and prepare them for use by an Operator. | 24 | ---------------- 25 | 26 | Each of these Operators are also responsible for creating resources: 27 | 28 | **_Table 2. Resources created by OLM and Catalog Operator_** 29 | 30 | | Resource | Owner | 31 | |------------------------------------|---------| 32 | | Deployments | OLM | 33 | | ServiceAccounts | OLM | 34 | | (Cluster)Roles | OLM | 35 | | (Cluster)RoleBindings | OLM | 36 | | Custom Resource Definitions (CRDs) | Catalog | 37 | | ClusterServiceVersions (CSVs) | Catalog | 38 | ---------------- 39 | 40 | ## OLM Operator 41 | 42 | OLM Operator is responsible for deploying applications defined by CSV resources after the required resources specified in the CSV are present in the cluster. 43 | 44 | OLM Operator is not concerned with the creation of the required resources; users can choose to manually create these resources using the CLI, or users can choose to create these resources using the Catalog Operator. This separation of concern enables users incremental buy-in in terms of how much of the OLM framework they choose to leverage for their application. 45 | 46 | While the OLM Operator is often configured to watch all namespaces, it can also be operated alongside other OLM Operators so long as they all manage separate namespaces. 47 | 48 | ### _OLM Operator workflow_ 49 | 50 | * Watches for ClusterServiceVersion (CSVs) in a namespace and checks that requirements are met. If so, runs the install strategy for the CSV. 51 | 52 | {{% alert title="Note" %}}A CSV must be an active member of an OperatorGroup in order for the install strategy to be run.{{% /alert %}} 53 | 54 | ## Catalog Operator 55 | 56 | The Catalog Operator is responsible for resolving and installing CSVs and the required resources they specify. It is also responsible for watching CatalogSources for updates to packages in channels and upgrading them (optionally automatically) to the latest available versions. 57 | 58 | A user that wishes to track a package in a channel creates a Subscription resource configuring the desired package, channel, and the CatalogSource from which to pull updates. When updates are found, an appropriate InstallPlan is written into the namespace on behalf of the user. 59 | 60 | Users can also create an InstallPlan resource directly, containing the names of the desired CSV and an approval strategy, and the Catalog Operator creates an execution plan for the creation of all of the required resources. After it is approved, the Catalog Operator creates all of the resources in an InstallPlan; this then independently satisfies the OLM Operator, which proceeds to install the CSVs. 61 | 62 | ### _Catalog Operator workflow_ 63 | 64 | * Has a cache of CRDs and CSVs, indexed by name. 65 | * Watches for unresolved InstallPlans created by a user: 66 | * Finds the CSV matching the name requested and adds it as a resolved resource. 67 | * For each managed or required CRD, adds it as a resolved resource. 68 | * For each required CRD, finds the CSV that manages it. 69 | * Watches for resolved InstallPlans and creates all of the discovered resources for it (if approved by a user or automatically). 70 | * Watches for CatalogSources and Subscriptions and creates InstallPlans based on them. 71 | 72 | ## Catalog Registry 73 | 74 | The Catalog Registry stores CSVs and CRDs for creation in a cluster and stores metadata about packages and channels. 75 | 76 | A _package manifest_ is an entry in the Catalog Registry that associates a package identity with sets of CSVs. Within a package, channels point to a particular CSV. Because CSVs explicitly reference the CSV that they replace, a package manifest provides the Catalog Operator all of the information that is required to update a CSV to the latest version in a channel, stepping through each intermediate version. 77 | -------------------------------------------------------------------------------- /content/en/docs/Concepts/operators-on-cluster.md: -------------------------------------------------------------------------------- 1 | # When to use operators on a cluster 2 | 3 | Operators are good for automating the knowledge of how to operate a complex system. Operators are a high-privilege component and by design, they run persistently inside your cluster. An operators can handle features like automatic scaling in response to load, backup and restore etc. 4 | 5 | # How does OLM help and install operators on a cluster? 6 | 7 | OLM requires you to provide metadata about your operator in order to ensure that it can be kept running safely on a cluster, and to provide information about how updates should be applied as you publish new versions of your operator. A ClusterServiceVersion (CSV) represents a particular version a running operator on a cluster. It includes metadata such as name, description, version, repository link, labels, icon, etc. It declares `owned`/`required` CRDs, cluster requirements, and install strategy that tells OLM how to create required resources and set up the operator. 8 | 9 | As a cluster administrator, you can install an Operator from the OperatorHub using the OpenShift Container Platform web console or the CLI. You can then subscribe the Operator to one or more namespaces to make it available for developers on your cluster. 10 | 11 | Example: Install the latest version of an Operator 12 | 13 | Before installing an operator into a namespace, you will need to create an OperatorGroup that targets the namespaces your operator is planning to watch, to generate the required RBACs for your operator in those namespaces. 14 | 15 | If you want to install an operator named `my-operator` in the namespace `foo` that is cluster scoped (i.e installModes:AllNamespaces), from a catalog named `my-catalog` that is in the namespace `olm`. 16 | 17 | Create a global OperatorGroup (which selects all namespaces): 18 | ``` 19 | $ cat og.yaml 20 | 21 | apiVersion: operators.coreos.com/v1 22 | kind: OperatorGroup 23 | metadata: 24 | name: my-group 25 | namespace: foo 26 | 27 | $ kubectl apply og.yaml 28 | operatorgroup.operators.coreos.com/my-group created 29 | ``` 30 | Then, create a subscription for the operator: 31 | ``` 32 | $ cat sub.yaml 33 | 34 | apiVersion: operators.coreos.com/v1alpha1 35 | kind: Subscription 36 | metadata: 37 | name: sub-to-my-operator 38 | namespace: foo 39 | spec: 40 | channel: stable 41 | name: my-operator 42 | source: my-catalog 43 | sourceNamespace: olm 44 | installPlanApproval: Manual 45 | 46 | $ kubectl apply -f sub.yaml 47 | subscription.operators.coreos.com/sub-to-my-operator created 48 | ``` 49 | 50 | Since the approval is Manual, we need to manually go in and approve the InstallPlan 51 | 52 | ``` 53 | $ kubectl get ip -n foo 54 | 55 | NAME CSV APPROVAL APPROVED 56 | install-nlwcw my-operator.v0.9.2 Automatic false 57 | 58 | $ kubectl edit ip install-nlwcw -n foo 59 | ``` 60 | And then change the `spec.approved` from `false` to `true` 61 | 62 | This should spin up the `ClusterServiceVersion` of the operator in the `foo` namespace`, following which the operator pod will spin up. 63 | 64 | To ensure the operator installed successfully, check for the `ClusterServiceVersion` and the operator deployment in the namespace it was installed in. 65 | ``` 66 | $ kubectl get csv -n 67 | 68 | NAME DISPLAY VERSION REPLACES PHASE 69 | Succeeded 70 | ... 71 | $ kubectl get deployments -n 72 | NAME READY UP-TO-DATE AVAILABLE AGE 73 | 1/1 1 1 9m48s 74 | ``` 75 | -------------------------------------------------------------------------------- /content/en/docs/Glossary/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Glossary" 3 | linkTitle: "Glossary" 4 | weight: 6 5 | description: > 6 | A list of jargon used in the context of OLM, along with their definitions. 7 | --- 8 | 9 | ### Bundle 10 | 11 | **Definition**: A collection of Operator [CSV](/docs/concepts/crds/clusterserviceversion), manifests, and metadata which together form a unique version of an Operator that can be installed onto the cluster. 12 | 13 | ### Bundle Image 14 | 15 | **Definition**: An image of a bundle is built from operator manifests and contains exactly one [bundle](#bundle). The bundle images are stored and distributed by OCI spec container registries such as Quay.io or DockerHub. 16 | 17 | ### Channel 18 | 19 | **Definition**: The channel defines a stream of updates for an operator and is used to roll out updates for subscribers. The head points at the latest version of that channel. For example, a stable channel would have all stable versions of an operator arranged from the earliest to the latest. An operator can have several channels, and a subscription binding to a certain channel would only look for updates in that channel. 20 | 21 | ### Channel Head 22 | 23 | **Definition**: Head refers to the latest known update in a particular [channel](#channel). 24 | 25 | ### Catalog Image 26 | 27 | **Definition**: A catalog image is a containerized datastore that describes a set of operator and update metadata that can be installed onto a cluster via OLM. 28 | 29 | **Aliases**: OPM Index 30 | 31 | ### Dependency 32 | 33 | **Definition**: An Operator may have a dependency on another Operator being present in the cluster. For example, the Vault Operator has a dependency on the Etcd Operator for its data persistence layer. OLM resolves these dependencies by ensuring all specified versions of Operators and CRDs are installed on the cluster during the installation phase. This dependency is resolved by finding and installing an Operator in a catalog that satisfies the required CRD API, and not related to [packages](#package)/[bundles](#bundle). 34 | 35 | **Aliases**: Operator Dependency, GVK Dependency, API Dependency, Required CRD 36 | 37 | ### Index 38 | 39 | **Definition**: The Index refers to an image of a database (a database snapshot) that contains information about Operator bundles including CSVs, CRDs, etc of all versions. This index can host a history of used operators on a cluster and be maintained by adding or removing operators. 40 | 41 | **Aliases**: Registry DB, Catalog DB, OPM registry 42 | 43 | ### Package 44 | 45 | **Definition**: A package is a directory that encloses all released history of an Operator with each version contained 46 | in the bundle format. A released version of an Operator is described in a ClusterServiceVersion manifest alongside the CustomResourceDefinitions. 47 | 48 | ### Registry 49 | 50 | **Definition**: A database which stores [Bundle Images](#bundle-image) of Operators, each with all of its latest/historical versions in all [channels](#channel). 51 | 52 | ### Update Graph 53 | 54 | **Definition**: An upgrade graph links versions of [CSV](/docs/concepts/crds/clusterserviceversion) together, similar to the upgrade graph of any other packaged software. Operators can be installed sequentially, or certain versions can be skipped. The update graph is expected to grow only at the head with newer versions being added. 55 | -------------------------------------------------------------------------------- /content/en/docs/Reference/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Reference" 3 | linkTitle: "Reference" 4 | weight: 9 5 | --- 6 | -------------------------------------------------------------------------------- /content/en/docs/Reference/admission-webhooks.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Admission Webhook Reference" 3 | linkTitle: "Admission Webhook Reference" 4 | weight: 3 5 | date: 2020-04-24 6 | --- 7 | 8 | After a request has been authenticated and authorized, admission webhooks intercept requests against the Kubernetes API and have an opportunity to validate or update the object before it is saved in the object store. Please refer to the following table that highlights what each webhook is capable of: 9 | 10 | | | Validating Webhooks | Mutating Webhooks | 11 | |--------------------|---------------------|-------------------| 12 | | Validating Objects | x | x | 13 | | Mutating Objects | | x | 14 | 15 | If you are interested in learning more about admission webhooks, please review the [official kubernetes documentation](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#what-are-they). 16 | -------------------------------------------------------------------------------- /content/en/docs/Tasks/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Core Tasks" 3 | linkTitle: "Core Tasks" 4 | weight: 2 5 | description: > 6 | Configuring and installing operators with OLM 7 | --- 8 | -------------------------------------------------------------------------------- /content/en/docs/Tasks/install-operator-with-olm.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Install your operator with OLM" 3 | date: 2021-04-30 4 | weight: 6 5 | description: > 6 | Install your operator from a catalog of operators 7 | --- 8 | 9 | [Once you have a catalog of operators loaded onto the cluster via a `CatalogSource`][create-catsrc-doc], you can install your operator by creating a [`Subscription`][subscription-doc] to a specific [channel][channel-def]. 10 | 11 | ## Prerequisites 12 | 13 | Before installing an operator into a namespace, you will need to create an `OperatorGroup` 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 `OperatorGroup` [here](/docs/concepts/crds/operatorgroup). 14 | 15 | > Note: The namespaces targeted by the OperatorGroup must align with the `installModes` specified in the `ClusterServiceVersion` of the operator's package. To know the `installModes` of an operator, inspect the packagemanifest: 16 | 17 | ```bash 18 | kubectl get packagemanifest -o jsonpath="{.status.channels[0].currentCSVDesc.installModes}" 19 | 20 | ``` 21 | 22 | > Note: This document uses a global OperatorGroup in the examples to install operators. To learn more about installing namespaced scoped operators, check out [operator scoping with OperatorGroups](/docs/advanced-tasks/operator-scoping-with-operatorgroups). 23 | 24 | ## Install your operator 25 | 26 | To install an Operator, simply create a `Subscription` for your operator. This represents the intent to subscribe to a stream of available versions of this Operator from a `CatalogSource`: 27 | 28 | ```yaml 29 | apiVersion: operators.coreos.com/v1alpha1 30 | kind: Subscription 31 | metadata: 32 | name: 33 | namespace: 34 | spec: 35 | channel: 36 | name: 37 | source: 38 | sourceNamespace: 39 | installPlanApproval: 40 | ``` 41 | 42 | You can read more about the `Subscription` object and what the different fields mean [here](/docs/concepts/crds/subscription). 43 | 44 | The `Subscription` object creates an [InstallPlan](/docs/concepts/crds/installplan), which is either automatically approved (if `sub.spec.installPlanApproval: Automatic`), or needs to be approved (if `sub.spec.installPlanApproval: Manual`), following which the operator is installed in the namespace you want. 45 | 46 | ## Example: Install the latest version of an Operator 47 | 48 | If you want to install an operator named `my-operator` in the namespace `foo` that is cluster scoped (i.e `installModes:AllNamespaces`), from a catalog named `my-catalog` that is in the namespace `olm`, and you want to subscribe to the channel `stable`, 49 | 50 | create a _global_ `OperatorGroup` (which selects all namespaces): 51 | 52 | ```bash 53 | $ cat og.yaml 54 | 55 | apiVersion: operators.coreos.com/v1 56 | kind: OperatorGroup 57 | metadata: 58 | name: my-group 59 | namespace: foo 60 | 61 | $ kubectl apply -f og.yaml 62 | operatorgroup.operators.coreos.com/my-group created 63 | ``` 64 | 65 | Then, create a subscription for the operator: 66 | 67 | ```bash 68 | $ cat sub.yaml 69 | 70 | apiVersion: operators.coreos.com/v1alpha1 71 | kind: Subscription 72 | metadata: 73 | name: sub-to-my-operator 74 | namespace: foo 75 | spec: 76 | channel: stable 77 | name: my-operator 78 | source: my-catalog 79 | sourceNamespace: olm 80 | installPlanApproval: Manual 81 | 82 | $ kubectl apply -f sub.yaml 83 | subscription.operators.coreos.com/sub-to-my-operator created 84 | ``` 85 | 86 | Since `installPlanApproval` is set to `Manual`, we need to manually go in and approve the `InstallPlan` 87 | 88 | ```bash 89 | $ kubectl get ip -n foo 90 | 91 | NAME CSV APPROVAL APPROVED 92 | install-nlwcw my-operator.v0.9.2 Automatic false 93 | 94 | $ kubectl edit ip install-nlwcw -n foo 95 | ``` 96 | 97 | And then change the `spec.approved` from `false` to `true`. 98 | 99 | This should spin up the `ClusterServiceVersion` of the operator in the `foo` namespace, following which the operator pod will spin up. 100 | 101 | To ensure the operator installed successfully, check for the ClusterServiceVersion and the operator deployment in the namespace it was installed in. 102 | 103 | ```bash 104 | $ kubectl get csv -n 105 | 106 | NAME DISPLAY VERSION REPLACES PHASE 107 | Succeeded 108 | ... 109 | $ kubectl get deployments -n 110 | NAME READY UP-TO-DATE AVAILABLE AGE 111 | 1/1 1 1 9m48s 112 | ``` 113 | 114 | If the ClusterServiceVersion fails to show up or does not reach the `Succeeded` phase, please check the [troubleshooting documentation](/docs/troubleshooting/clusterserviceversion/) to debug your installation. 115 | 116 | ## Example: Install a specific version of an Operator 117 | 118 | If you want to install a particular version of your Operator, specify the `startingCSV` property in your `Subscription` like so: 119 | 120 | ```yaml 121 | apiVersion: operators.coreos.com/v1alpha1 122 | kind: Subscription 123 | metadata: 124 | name: sub-to-my-operator 125 | namespace: foo 126 | spec: 127 | channel: stable 128 | name: my-operator 129 | source: my-catalog 130 | sourceNamespace: olm 131 | installPlanApproval: Manual 132 | startingCSV: 1.1.0 133 | ``` 134 | 135 | Notice that `approval` has been set to `Manual` as well in order to keep OLM from immediately updating your Operator, if `1.1.0` happens to be superseded by a newer version in `my-catalog`. Follow the instructions from the [previous example](#example-install-the-latest-version-of-an-operator) to approve the initial `InstallPlan` for this `Subscription`, so `1.1.0` is allowed to be installed. 136 | 137 | If your intent is to pin an installed Operator to the particular version `1.1.0` you don't need to do anything. After approving the initial `InstallPlan` OLM will install version `1.1.0` 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. 138 | 139 | [create-catsrc-doc]: /docs/tasks/make-catalog-available-on-cluster 140 | [subscription-doc]: /docs/concepts/crds/subscription 141 | [channel-def]: /docs/glossary/#channel 142 | -------------------------------------------------------------------------------- /content/en/docs/Tasks/list-operators-available-to-install.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "List operators available to install on cluster" 3 | date: 2017-01-05 4 | weight: 5 5 | description: > 6 | List operators from a collection of catalogs 7 | --- 8 | 9 | ## List your operator 10 | 11 | The `PackageManifest` API exposes content from existing [CatalogSources](/docs/concepts/crds/catalogsource) on cluster. Querying that API reveals the list of operators available to install. 12 | 13 | >Note: [CatalogSources](/docs/concepts/crds/catalogsource) 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. 14 | 15 | ### Using the PackageManifest API 16 | 17 | The `PackageManifest` API when queried, will return the union of globally available as well as namespaced available operators, from the namespace you're querying in. 18 | 19 | ```bash 20 | kubectl get packagemanifest -n 21 | ``` 22 | 23 | The list of available operators will be displayed as an output of those above commands: 24 | 25 | ```bash 26 | $ kubectl get packagemanifest 27 | NAME CATALOG AGE 28 | cassandra-operator Community Operators 26m 29 | etcd Community Operators 26m 30 | postgres-operator Community Operators 26m 31 | prometheus Community Operators 26m 32 | wildfly Community Operators 26m 33 | ``` 34 | -------------------------------------------------------------------------------- /content/en/docs/Tasks/make-catalog-available-on-cluster.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Make a Catalog available on Cluster" 3 | date: 2021-04-28 4 | weight: 4 5 | description: > 6 | Create a CatalogSource with your catalog image 7 | --- 8 | 9 | Once you have a catalog of operators, you can make it available on cluster by referencing it from a `CatalogSource`. 10 | 11 | 12 | For example, if you have a catalog image `quay.io/my-namespace/cool-catalog:latest`, you can create a CatalogSource with your image: 13 | 14 | ```yaml 15 | apiVersion: operators.coreos.com/v1alpha1 16 | kind: CatalogSource 17 | metadata: 18 | name: cool-catalog 19 | namespace: operator 20 | spec: 21 | sourceType: grpc 22 | image: quay.io/my-namespace/cool-catalog:latest 23 | displayName: Coolest Catalog 24 | publisher: Me 25 | updateStrategy: 26 | registryPoll: 27 | interval: 10m 28 | ``` 29 | 30 | ### Explanation of spec.updateStrategy 31 | 32 | When you create a `CatalogSource`, it deploys a pod that serves the content you've stored in the catalog via a grpc API endpoint. 33 | 34 | ```bash 35 | $ kubectl apply -f cool-catalog.yaml 36 | catalogsource.operators.coreos.com/cool-catalog created 37 | 38 | $ kubectl get catsrc 39 | NAME DISPLAY TYPE PUBLISHER AGE 40 | cool-catalog Coolest Catalog grpc Me 38s 41 | 42 | 43 | $ kubectl get pods 44 | NAME READY STATUS RESTARTS AGE 45 | cool-catalog-dtqv2 1/1 Running 0 30s 46 | ``` 47 | 48 | It is possible to configure the `CatalogSource` 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. 49 | 50 | For example, say currently you have Operator X v1.0 installed in the cluster from the catalog `quay.io/my-namespace/cool-catalog:main`. 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 [creating catalog doc][creating-a-catalog-steps], then the catalog image can be rebuilt and pushed to the same `main` tag. With catalog polling enabled, OLM will pull down the newer version of the catalog image and make the new information available. 51 | 52 | Each type of check for an updated catalog source is called an `updateStrategy`. Only one `updateStrategy` is supported at a time. `registryPoll` is a type of `updateStrategy` that checks an image registry for an updated version of the same tag(via image SHAs). The `interval` defines the amount of time between each successive poll. 53 | 54 | #### Caveats 55 | 56 | - 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. 57 | - 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. 58 | - 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. 59 | - The polling interval should be reasonably high to ensure the update functionality works as intended. Avoid intervals less than 15m. 60 | 61 | ### Using registry images that require authentication as Catalog/bundle/operator/operand images 62 | 63 | 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 `CatalogSource`, OLM can handle placing the secrets in the operator and catalog namespace to allow installation. 64 | 65 | > 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 `default` service accounts of the target tenant namespaces. 66 | 67 | To use images from private registries as Catalog/bundle images, create a secret for each required private registry. Once you have the secrets, `kubectl apply` your secrets to the cluster, and the create or update an existing `CatalogSource` object to reference one or more secrets to add a `spec.secrets` section and specify all secrets. 68 | 69 | ```yaml 70 | apiVersion: operators.coreos.com/v1alpha1 71 | kind: CatalogSource 72 | metadata: 73 | name: cool-catalog 74 | namespace: operator 75 | spec: 76 | sourceType: grpc 77 | secrets: 78 | - "" 79 | - "" 80 | image: quay.io/my-namespace/cool-catalog:latest 81 | displayName: Coolest Catalog 82 | publisher: Me 83 | updateStrategy: 84 | registryPoll: 85 | interval: 10m 86 | ``` 87 | 88 | If the `imagePullSecret` 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 `imagePullSecrets`. As a consequence, permissions to pull the image should be added directly to the operator Deployment's manifest by adding the required secret name to the list `deployment.spec.template.spec.imagePullSecrets`. 89 | 90 | For the [operator-sdk](https://sdk.operatorframework.io/) abstraction, the operator Deployment's manifest is found under `config/manager/manager.yaml`. Below is an example of a controller-manager Deployment's manifest configured with an `imagePullSecret` to pull container images from a private registry. 91 | 92 | ```yaml 93 | # config/manager/manager.yaml 94 | apiVersion: apps/v1 95 | kind: Deployment 96 | metadata: 97 | name: controller-manager 98 | namespace: system 99 | ... 100 | spec: 101 | ... 102 | spec: 103 | imagePullSecrets: 104 | - name: "registry-auth-secret-name" 105 | ``` 106 | 107 | > Note: It is required for the `imagePullSecret` to be present in the same namespace where the controller is deployed for the controller pod to start. 108 | 109 | 110 | [creating-a-catalog-steps]: /docs/tasks/creating-a-catalog/#creating-a-catalog 111 | -------------------------------------------------------------------------------- /content/en/docs/Tasks/uninstall-operator.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Uninstall your operator" 3 | date: 2020-03-25 4 | weight: 7 5 | description: > 6 | Uninstall your operator from the cluster 7 | --- 8 | 9 | When uninstalling an operator managed by OLM, a Cluster Admin must decide whether or not to remove the `CustomResourceDefinitions (CRD)`, `APIServices`, 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's owned `CRDs`, `APIServices`, or `CRs` 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. 10 | 11 | ## Step 1: Identifying Resources to Remove 12 | 13 | The cluster admin should first understand which types (`CRDs` and `APIServices`) are owned by the operator, which is available in the operator's `ClusterServiceVersion (CSV)` under the `spec.customresourcedefinitions.owned` and `spec.apiservicedefinitions.owned` 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. 14 | 15 | > Note: Although deleting the `CRD` or `APIService` removes all resource of the type from the cluster, this action may lead to unintended consequences. Operators often use [finalizers](https://book.kubebuilder.io/reference/using-finalizers.html) to execute application specific cleanup routines before removing the `CR`. If the API is removed, the operator will be unable to properly remove the resource, and the cluster may appear to be "stuck" as defined in this [Kubernetes issue](https://github.com/kubernetes/kubernetes/issues/60807). 16 | 17 | ## Step 2: Unsubscribe from the Operator 18 | 19 | OLM uses the `Subscription` resource to convey a user's intent to subscribe to the latest version of an operator. If the operator was installed with Automatic Updates (`spec.InstallPlanApproval: "Automatic"`), OLM will reinstall a new version of the operator even if the operator's `CSV` 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 `Subscription` associated with the operator. It should be noted that opting out of future upgrades by deleting a `Subscription` does not delete the associated `CSV` as this ensures that a specific version of the operator is available on cluster and is never upgraded. 20 | 21 | You can list existing `Subscription` in a specific namespace with the following `kubectl` command: 22 | 23 | ```bash 24 | $ kubectl get subscription -n 25 | # Example output 26 | NAME PACKAGE SOURCE CHANNEL 27 | foo-sub foo foo-catalog alpha 28 | ``` 29 | 30 | > Note: The name of the operator installed by the `Subscription` is available under the `Package` column. 31 | 32 | The `Subscription` can be deleted by running this command: 33 | 34 | ```bash 35 | kubectl delete subscription -n 36 | ``` 37 | 38 | ## Step 3: Delete the Operator's ClusterServiceVersion (CSV) 39 | 40 | The `CSV` 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 `CSV`, OLM will delete the resources it created for the operator such as the `deployment`, `RBAC`, and any corresponding `CSVs` that OLM "Copied" into other namespaces watched by the operator. 41 | 42 | 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's `permissions` and `clusterPermissions` fields will be deleted, any RBAC resources included directly in the bundle itself will remain on the cluster. 43 | 44 | If you wish to look up a list of `ClusterServiceVersion` in a specific namespace to see which `ClusterServiceVersion` you need to delete, you can use the example `kubectl` command: 45 | 46 | ```bash 47 | $ kubectl get clusterserviceversion -n 48 | # Example output 49 | NAME DISPLAY VERSION REPLACES PHASE 50 | foo Foo Operator 1.0.0 Succeeded 51 | ``` 52 | 53 | You can delete the `ClusterServiceVersion` in the namespace that the operator was installed into using this command: 54 | 55 | ```bash 56 | kubectl delete clusterserviceversion -n 57 | ``` 58 | 59 | ### Combine steps 2 and 3 60 | 61 | Alternatively, you can delete both `Subscription` and its `CSV` using a sequence of commands: 62 | 63 | ```bash 64 | CSV=$(kubectl get subscription -n -o json | jq -r '.status.installedCSV') 65 | kubectl delete subscription -n 66 | kubectl delete csv $CSV -n 67 | ``` 68 | 69 | ## Step 4: Deciding whether or not to delete the CRDs and APIServices 70 | 71 | The fourth step consists of deciding whether or not to delete the `CRDs` and `APIServices` 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 `CRD` or `APISerivces`. Otherwise, you should not delete the type as the wanted resources will be deleted automatically when the CRD or `APISerivce` is deleted. 72 | 73 | ## Step 5: Deleting the Operator CR 74 | 75 | OLM recently introduced the view-only [operator CRD](https://github.com/operator-framework/api/blob/7339a22050af53df7b6f97a652b8e2d73698765a/crds/operators.coreos.com_operators.yaml) which communicates the list of resources associated with an [operator bundle](https://olm.operatorframework.io/docs/tasks/creating-operator-bundle/#operator-bundle) installed by OLM. When installing an `operator bundle`, OLM will create an `operator` CR named: 76 | - `` if the operator is All Namespaced scoped. 77 | - `.` if the operator is not All Namespaced scoped. 78 | 79 | OLM will then the update the [operator's status.Components.Refs](https://github.com/operator-framework/api/blob/7339a22050af53df7b6f97a652b8e2d73698765a/crds/operators.coreos.com_operators.yaml#L76-L77) array to include all resources associated with the `operator`. Let's consider OLM's behavior after creating the `operator` CR named `foo`: 80 | - All resources associated with the `foo operator` CR will have the `operators.coreos.com/foo` label applied to it. 81 | - OLM will create or recreate the `foo operator` CR if any resources exist with the `operators.coreos.com/foo` label. 82 | 83 | This ultimately means that in order to delete the `foo operator` CR, users will need to ensure that no resources are labeled with the `operators.coreos.com/foo` label. Typically, OLM should not attempt to recreate the `foo operator` after a user deletes it if they have completed steps 1 through 4 above. However, if OLM is still recreating the `foo operator`, a user should: 84 | - Delete each resource found in the `foo operator's status.Components.Refs` array. Alternatively, if you have deleted the `foo operator's CSV` and `Subscription` you may remove the `operators.coreos.com/foo` label from any resources you do not wish to delete. 85 | - Delete the `foo operator` CR. 86 | The final step consists of deciding whether or not to delete the `CRDs` and `APIServices` 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 `CRD` or `APISerivces`. Otherwise, you should not delete the type as the wanted resources will be deleted automatically when the `CRD` or `APISerivce` is deleted. 87 | -------------------------------------------------------------------------------- /content/en/docs/Troubleshooting/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Troubleshooting" 3 | linkTitle: "Troubleshooting" 4 | description: > 5 | Tips and tricks for troubleshooting unexpected behavior when installing and managing operators with OLM. 6 | --- 7 | 8 | ## Prereqs 9 | 10 | Some of the commands listed in this section assume that you have [yq](https://github.com/mikefarah/yq) installed on your system. While `yq` is not required, it is a useful tool when parsing yaml. You can install `yq` by following the [official installation steps](https://github.com/mikefarah/yq#install). 11 | -------------------------------------------------------------------------------- /content/en/docs/Troubleshooting/catalogsource.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "CatalogSource" 3 | linkTitle: "CatalogSource" 4 | date: 2020-03-25 5 | weight: 2 6 | description: > 7 | Tips and tricks related to troubleshooting the configuration of a `CatalogSource`. 8 | --- 9 | 10 | ## Prerequisites 11 | 12 | - [yq](https://github.com/mikefarah/yq) 13 | 14 | ## How to debug a failing CatalogSource 15 | 16 | The [Catalog operator][olm-arch-doc] will constantly update the `Status` of `CatalogSources` to reflect its current state. You can check the `Status` of your `CatalogSource` with the following command: 17 | 18 | `$ kubectl get catsrc my-catalog -n -o yaml | yq e '.status' -` 19 | 20 | >Note: It is possible that the `Status` is missing, which suggests that the Catalog operator is encountering an issue when processing the `CatalogSource` in a very early stage. 21 | 22 | If the `Status` block does not provide enough information, check the [Catalog operator's logs](/docs/troubleshooting/olm-and-catalog-operators/#how-to-view-the-catalog-operator-logs). 23 | 24 | If you are still unable to identify the cause of the failure, check if a pod was created for the `CatalogSource`. If a pod exists, review the pod's yaml and logs: 25 | 26 | ```bash 27 | $ kubectl -n my-namespace get pods 28 | NAME READY STATUS RESTARTS AGE 29 | my-catalog-ltdlp 1/1 Running 0 8m31s 30 | 31 | $ kubectl -n my-namespace get pod my-catalog-ltdlp -o yaml 32 | ... 33 | 34 | $ kubectl -n my-namespace logs my-catalog-ltdlp 35 | ... 36 | ``` 37 | 38 | ### I'm not sure if a specific version of an operator is available in a CatalogSource 39 | 40 | First verify that the `CatalogSource` contains the operator that you want to install: 41 | 42 | ```bash 43 | $ kubectl -n my-namespace get packagemanifests 44 | NAME CATALOG AGE 45 | ... 46 | portworx My Catalog Source 14m 47 | postgres-operator My Catalog Source 14m 48 | postgresql My Catalog Source 14m 49 | postgresql-operator-dev4devs-com My Catalog Source 14m 50 | prometheus My Catalog Source 14m 51 | ... 52 | ``` 53 | 54 | If the operator is present, check if the version you want is available: 55 | 56 | `$ kubectl -n my-namespace get packagemanifests my-operator -o yaml` 57 | 58 | ### My CatalogSource cannot pull images from a private registry 59 | 60 | If you are attempting to pull images from a private registry, make sure to specify a secret key in the `CatalogSource.Spec.Secrets` field. 61 | 62 | [olm-arch-doc]: /docs/concepts/olm-architecture#catalog-operator 63 | -------------------------------------------------------------------------------- /content/en/docs/Troubleshooting/clusterserviceversion.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "ClusterServiceVersion" 3 | linkTitle: "ClusterServiceVersion" 4 | date: 2020-03-25 5 | weight: 4 6 | description: > 7 | Tips and tricks related to troubleshooting a `ClusterServiceVersion`. 8 | --- 9 | 10 | ## Prerequisites 11 | 12 | - [yq](https://github.com/mikefarah/yq) 13 | 14 | ### How to debug a failing CSV 15 | 16 | If the OLM operator encounters an unrecoverable error when attempting to install the operator, the `CSV` will be placed in the `failed` phase. The OLM operator will constantly update the `Status` with useful information regarding the state of the `CSV`. You can check the `Status` of your `CSV` with the following command: 17 | 18 | `$ kubectl get csv prometheusoperator.0.32.0 -n -o yaml | yq e '.status' -` 19 | 20 | >Note: It is possible that the Status is missing, which suggests that the OLM operator is encountering an issue when processing the `CSV` in a very early stage. You should respond by reviewing the logs of the OLM operator. 21 | 22 | You should typically pay special attention to the information within the `status.reason` and `status.message` fields. Please look in the [failed CSV reasons](#failed-csv-reasons) 23 | 24 | If the `Status` block does not provide enough information, check the [OLM operator's logs](/docs/troubleshooting/olm-and-catalog-operators/#how-to-view-the-olm-operator-logs). 25 | 26 | ### Failed CSV Reasons 27 | 28 | #### Reason: NoOperatorGroup 29 | 30 | The `CSV` failed to install because it has been deployed in a namespace that does not include an [OperatorGroup](/docs/concepts/crds/operatorgroup/). 31 | 32 | #### Reason: UnsupportedOperatorGroup 33 | 34 | The `CSV` is failing to install because it does not support the [OperatorGroup](/docs/concepts/crds/operatorgroup/) defined in the namespace. 35 | 36 | ### Failed CSV Messages 37 | 38 | #### Messages Ending with "field is immutable" 39 | 40 | The `CSV` is failing because its install strategy changes some immutable field of an existing `Deployment`. This usually happens on upgrade, after an operator author publishes a new version of the operator containing such a change. In this case, the issue can be resolved by publishing a new version of the operator that uses a different `Deployment` name, which will cause OLM to generate a completely new `Deployment` instead of attempting to patch any existing one. 41 | -------------------------------------------------------------------------------- /content/en/docs/Troubleshooting/olm-and-catalog-operators.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Debugging OLM and Catalog Operator" 3 | linkTitle: "Debugging OLM/Catalog Operator" 4 | date: 2020-03-25 5 | weight: 4 6 | description: > 7 | Tips and tricks related to debugging the OLM or Catalog Operator. 8 | --- 9 | 10 | ### How to enable verbose logging on the OLM and Catalog operators 11 | 12 | Both the [OLM and Catalog operators][olm-arch-doc] have `-debug` flags available that display much more useful information when diagnosing a problem. If necessary, add this flag to their deployments and perform the action that is showing undersired behavior. 13 | 14 | ### How to view the Catalog operator logs 15 | 16 | To view the Catalog Operator logs, use the following commands: 17 | 18 | ```bash 19 | $ kubectl -n olm get pods 20 | NAME READY STATUS RESTARTS AGE 21 | catalog-operator-5bdc79c56b-zbqbl 1/1 Running 0 5m30s 22 | olm-operator-6999db5767-5r5zs 1/1 Running 0 5m31s 23 | operatorhubio-catalog-ltdlp 1/1 Running 0 5m28s 24 | packageserver-5c76df75bb-mq4qd 1/1 Running 0 5m26s 25 | 26 | $ kubectl -n olm logs catalog-operator-5bdc79c56b-zbqbl 27 | ... 28 | ``` 29 | 30 | ### How to view the OLM operator logs 31 | 32 | To view the OLM Operator logs, use the following commands: 33 | 34 | ```bash 35 | $ kubectl -n olm get pods 36 | NAME READY STATUS RESTARTS AGE 37 | catalog-operator-5bdc79c56b-zbqbl 1/1 Running 0 5m30s 38 | olm-operator-6999db5767-5r5zs 1/1 Running 0 5m31s 39 | operatorhubio-catalog-ltdlp 1/1 Running 0 5m28s 40 | packageserver-5c76df75bb-mq4qd 1/1 Running 0 5m26s 41 | 42 | $ kubectl -n olm logs olm-operator-6999db5767-5r5zs 43 | ... 44 | ``` 45 | 46 | [olm-arch-doc]: /docs/concepts/olm-architecture 47 | -------------------------------------------------------------------------------- /content/en/docs/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Operator Lifecycle Manager(OLM) 3 | linkTitle: "Documentation" 4 | menu: 5 | main: 6 | weight: 10 7 | --- 8 | 9 | [OLM](https://github.com/operator-framework/operator-lifecycle-manager) is a component of the [Operator Framework](https://github.com/operator-framework), an open source toolkit to manage Kubernetes native applications, called Operators, in an effective, automated, and scalable way. OLM extends Kubernetes to provide a declarative way to install, manage, and upgrade Operators and their dependencies in a cluster. 10 | 11 | Read more in the [introduction blog post](https://operatorhub.io/what-is-an-operator). 12 | 13 | ## Features provided by OLM 14 | 15 | ### Over-the-Air Updates and Catalogs 16 | 17 | Kubernetes clusters are being kept up to date using elaborate update mechanisms today, more often automatically and in the background. Operators, being cluster extensions, should follow that. OLM has a concept of catalogs from which Operators are available to install and being kept up to date. In this model OLM allows maintainers granular authoring of the update path and gives commercial vendors a flexible publishing mechanism using channels. 18 | 19 | ### Dependency Model 20 | 21 | With OLMs packaging format Operators can express dependencies on the platform and on other Operators. They can rely on OLM to respect these requirements as long as the cluster is up. In this way, OLMs dependency model ensures Operators stay working during their long lifecycle across multiple updates of the platform or other Operators. 22 | 23 | ### Discoverability 24 | 25 | OLM advertises installed Operators and their services into the namespaces of tenants. They can discover which managed services are available and which Operator provides them. Administrators can rely on catalog content projected into a cluster, enabling discovery of Operators available to install. 26 | 27 | ### Cluster Stability 28 | 29 | Operators must claim ownership of their APIs. OLM will prevent conflicting Operators owning the same APIs being installed, ensuring cluster stability. 30 | 31 | ### Declarative UI controls 32 | 33 | Operators can behave like managed service providers. Their user interface on the command line are APIs. For graphical consoles OLM annotates those APIs with descriptors that drive the creation of rich interfaces and forms for users to interact with the Operator in a natural, cloud-like way. 34 | 35 | ## Get started with OLM 36 | -------------------------------------------------------------------------------- /content/en/docs/advanced-tasks/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Advanced Tasks" 3 | weight: 3 4 | --- 5 | -------------------------------------------------------------------------------- /content/en/docs/advanced-tasks/communicating-operator-conditions-to-olm.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Communicating Operator Conditions to OLM" 3 | linkTitle: "Communicating Operator Conditions to OLM" 4 | weight: 3 5 | --- 6 | 7 | ## Communicating Operator Conditions to OLM 8 | 9 | As part of its role in managing the lifecycle of an operator, the Operator-Lifecycle-Manager (OLM) infers the state of an operator from the state of Kubernetes resources that define the operator. While this approach provides some level of assurance that an operator is in a given state, there are many instances where an operator may wish to communicate information to OLM that could not be inferred otherwise. This information can then be used by OLM to better manage the lifecycle of the operator. 10 | 11 | ## OperatorConditions 12 | 13 | OLM introduced a new [CustomResourceDefinition](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) called the [OperatorCondition](/docs/concepts/crds/operatorcondition) allowing operators to communicate conditions to OLM. There are a set of "OLM Supported Conditions" which influence OLM's management of the operator when present in the OperatorCondition's [Status.Conditions](https://github.com/operator-framework/api/blob/b55a341f6560db4adec39d69aab1ff3092ea202a/pkg/operators/v1/operatorcondition_types.go#L22) array. 14 | 15 | ### OLM Supported Conditions 16 | 17 | The set of "OLM Supported Conditions" include: 18 | 19 | * The [Upgradeable](#upgradeable) Condition 20 | 21 | #### Upgradeable 22 | 23 | The `Upgradeable` "OLM Supported Condition" prevents the existing CSV from being replaced by a newer version of the CSV. When the `Upgradeable` condition is set to `False`, OLM will: 24 | 25 | * Prevent a channel entry in a subscribed package that replaces the operator's existing CSV from leaving the PendingPhase. 26 | 27 | The `Upgradeable` condition might be useful when: 28 | 29 | * An operator is about to start a critical process and should not be upgraded until after the process is completed. 30 | * The operator is performing a migration of CRs that must be completed before the operator is ready to be upgraded. 31 | 32 | ##### Example Upgradeable OperatorCondition 33 | 34 | ```yaml 35 | apiVersion: operators.coreos.com/v1 36 | kind: OperatorCondition 37 | metadata: 38 | name: foo-operator 39 | namespace: operators 40 | status: 41 | conditions: 42 | - type: Upgradeable # The name of the `Upgradeable` OLM Supported Condition. 43 | status: "False" # The operator is not ready to be upgraded. 44 | reason: "migration" 45 | message: "The operator is performing a migration." 46 | lastTransitionTime: "2020-08-24T23:15:55Z" 47 | ``` 48 | 49 | Given that the `Upgradable Condition`'s status is set to `False`, OLM will understand that it should not upgrade the operator. 50 | 51 | ### Overriding OperatorConditions 52 | 53 | There are times as a Cluster Admin that you may want to ignore an "OLM Supported Condition" reported by an Operator. For example, imagine that a known version of an operator always communicates that it is not upgradeable. In this instance, you may want to upgrade the operator despite the operator communicating that it is not upgradeable. This could be accomplished by overriding the `OLM Supported Condition` by adding the condition's type and status to the `spec.overrides` array in the `OperatorCondition` CR: 54 | 55 | "OLM Supported Conditions" can be overridden by Cluster Admins by appending the desired OperatorCondition to the opertor's OperatorCondition's [Spec.Overrides](https://github.com/operator-framework/api/blob/b55a341f6560db4adec39d69aab1ff3092ea202a/pkg/operators/v1/operatorcondition_types.go#L16) Condition Array. When present, "OLM Supported Conditions" in the `Spec.Overrides` array will override the Conditions in the `Status.conditions` array, allowing Cluster Admins to deal with situations where an operator is incorrectly reporting a state to OLM. 56 | 57 | #### Example Override 58 | 59 | ```yaml 60 | apiVersion: operators.coreos.com/v1 61 | kind: OperatorCondition 62 | metadata: 63 | name: foo-operator 64 | namespace: operators 65 | spec: 66 | overrides: 67 | - type: Upgradeable # Allows the cluster admin to change operator's Upgrade readiness to True 68 | status: "True" 69 | reason: "upgradeIsSafe" 70 | message: "This is a known issue with the operator where it always reports that it cannot be upgraded." 71 | status: 72 | conditions: 73 | - type: Upgradeable 74 | status: "False" 75 | reason: "migration" 76 | message: "The operator is performing a migration." 77 | lastTransitionTime: "2020-08-24T23:15:55Z" 78 | ``` 79 | 80 | ## Updating your operator to use OLM OperatorCondition 81 | 82 | OLM will automatically create an `OperatorCondition` for each `ClusterServiceVersion` that it reconciles. All service accounts in the CSV will be granted the RBAC to interact with the `OperatorCondition` owned by the operator. 83 | 84 | Operators deployed by OLM may then use the [operator-library](https://github.com/operator-framework/operator-lib/tree/main/conditions) to set conditions on their operator. 85 | 86 | ### Setting Defaults 87 | 88 | In an effort to remain backwards compatible, OLM treats the absence of an `OperatorConditions` as opting out of the condition. Therefore, an operator that opts in to using `OperatorConditions` should set default conditions before the pod's [ready probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-readiness-probes) is set to true. This provides the operator with a grace period to update the condition to the correct state. 89 | -------------------------------------------------------------------------------- /content/en/docs/advanced-tasks/configuring-olm.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Configuring OLM" 3 | linkTitle: "Configuring OLM" 4 | weight: 3 5 | --- 6 | 7 | ## Configuring OLM 8 | 9 | The [Operator-Lifecycle-Manager (OLM)](https://github.com/operator-framework/operator-lifecycle-manager) controller can be configured through an [OLMConfig CustomResourceDefinition (CRD)](https://github.com/operator-framework/api/blob/v0.11.0/crds/operators.coreos.com_olmconfigs.yaml) named `cluster`. This document will outline what configurations OLM currently supports. 10 | 11 | ### Disabling Copied CSVs 12 | 13 | #### Background 14 | 15 | When an operator is installed by OLM, a stripped down copy of its CSV is created in every namespace the operator is configured to watch. These stripped down CSVs are known as "Copied CSVs" and communicate to users which controllers are actively reconciling resource events in a given namespace. When operators are installed in the AllNamespace mode, a Copied CSV is created in every namespace on the cluster. On especially large clusters, with namespaces and installed operators tending in the hundreds or thousands, Copied CSVs consume an untenable amount of resources; e.g. OLM's memory usage, cluster Etcd limits, networking, etc. 16 | 17 | #### Usage 18 | 19 | In an effort to support these larger cluster, OLM allows users to disable Copied CSVs for operators installed in the AllNamespace mode by setting the `cluster` olmConfig's `spec.features.disableCopiedCSVs` field to true. 20 | 21 | ```bash= 22 | $ kubectl apply -f - < 5 | The goal of this document is to familiarize you with the steps to enable and review OLM's performance profiling instrumentation. 6 | --- 7 | 8 | ## Prerequisites 9 | 10 | - [go](https://golang.org/dl/) 11 | 12 | ## Background 13 | 14 | OLM utilizes the [pprof package](https://golang.org/pkg/net/http/pprof/) from the standard go library to expose performance profiles for the OLM and Catalog Operator. 15 | 16 | Due to the sensitive nature of profiling data, the profiling endpoints will reject any clients that do not present a verifiable certificate. Both operators must be configured with a serving certificate and a client CA bundle in order to access the profiling endpoints. 17 | 18 | This document will dive into the steps to [enable olm performance profiling](#enabling-performance-profiling) and retrieving pprof data from each component. 19 | 20 | ## Enabling Performance Profiling 21 | 22 | ### Creating a Certificate 23 | 24 | A valid server certificate must be created for each component before the Performance Profiling functionality can be enabled. If you are unfamiliar with certificate generation, we recommend using the [OpenSSL](https://www.openssl.org/) tool-kit and refer to the [request certificate](https://www.openssl.org/docs/man1.1.1/man1/openssl-req.html) documentation. 25 | 26 | Once you have generated a private and public key, this data should be stored in a `TLS Secret`: 27 | 28 | ```bash 29 | $ export PRIVATE_KEY_FILENAME=private.key # Replace with the name of the file that contains the private key you generated. 30 | $ export PUBLIC_KEY_FILENAME=certificate.crt # Replace with the name of the file that contains the public key you generated. 31 | 32 | $ kubectl -n my-namespace create secret tls my-name --cert=$PUBLIC_KEY_FILENAME --key=$PRIVATE_KEY_FILENAME 33 | ``` 34 | 35 | ### Updating OLM to Use the TLS Secret 36 | 37 | Patch the OLM or Catalog Deployment's pod template to use the generated TLS secret: 38 | 39 | - Defining a volume and volumeMount 40 | - Adding the `client-ca`, `tls-key` and `tls-cert` arguments 41 | - Replacing all mentions of port `8080` with `8443` 42 | - Updating the `livenessProbe` and `readinessProbe` to use HTTPS as the scheme 43 | 44 | The steps to patch an existing OLM deployment can be seen below: 45 | 46 | ```bash 47 | $ export TLS_SECRET=my-tls-secret 48 | $ export CERT_PATH=/var/run/secrets # Define where to mount the certs. 49 | # Set Deployment name to olm-operator or catalog-operator 50 | $ export DEPLOYMENT_NAME=olm-operator 51 | 52 | $ kubectl patch deployment $DEPLOYMENT_NAME -n olm --type json -p='[ 53 | # Mount the secret to the pod 54 | {"op": "add", "path": "/spec/template/spec/volumes", "value":[{"name": '$TLS_SECRET', "secret": {"secretName": '$TLS_SECRET'}}]}, 55 | {"op": "add", "path": "/spec/template/spec/containers/0/volumeMounts", "value":[{"name": '$TLS_SECRET', "mountPath": '$CERT_PATH'}]}, 56 | 57 | # Add startup arguments 58 | {"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value":"--client-ca"}, 59 | {"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value":"'$CERT_PATH'/tls.crt"}, 60 | {"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value":"--tls-key"}, 61 | {"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value":"'$CERT_PATH'/tls.key"}, 62 | {"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value":"--tls-cert"}, 63 | {"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value":"'$CERT_PATH'/tls.crt"}, 64 | 65 | # Replace port 8080 with 8443 66 | {"op": "replace", "path": "/spec/template/spec/containers/0/ports/0", "value":{"containerPort": 8443}}, 67 | {"op": "replace", "path": "/spec/template/spec/containers/0/livenessProbe/httpGet/port", "value":8443}, 68 | {"op": "replace", "path": "/spec/template/spec/containers/0/readinessProbe/httpGet/port", "value":8443}, 69 | 70 | # Update livenessProbe and readinessProbe to use HTTPS 71 | {"op": "replace", "path": "/spec/template/spec/containers/0/readinessProbe/httpGet/scheme", "value":"HTTPS"}, 72 | {"op": "replace", "path": "/spec/template/spec/containers/0/livenessProbe/httpGet/scheme", "value":"HTTPS"}, 73 | ]' 74 | deployment.apps/olm-operator patched 75 | 76 | ``` 77 | 78 | ## Accessing PPROF Data 79 | 80 | You will need to be able to access OLM port, for dev purposes the following commands may prove useful: 81 | 82 | ```bash 83 | # Set Deployment name to olm-operator or catalog-operator 84 | $ export DEPLOYMENT_NAME=olm-operator 85 | $ kubectl port-forward deployment/$DEPLOYMENT_NAME 8443:8443 -n olm 86 | ``` 87 | 88 | You can then curl the OLM `/debug/pprof` endpoint to retrieve default pprof profiles like so: 89 | 90 | ```bash 91 | $ curl https://localhost:8443/debug/pprof/heap --cert certificate.crt --key private.key --insecure -o olm-heap 92 | 93 | $ go tool pprof --top olm-heap 94 | ``` 95 | 96 | Please review [the official pprof documentation](https://blog.golang.org/pprof) to learn more about pprof. 97 | -------------------------------------------------------------------------------- /content/en/docs/advanced-tasks/ship-operator-supporting-multiarch.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Shipping an operator that supports Multiple Architectures" 3 | linkTitle: "Multiarch Operators" 4 | weight: 3 5 | --- 6 | 7 | An operator's target OS and architecture can be specified by labelling its respective `ClusterServiceVersion`. 8 | 9 | ## Supported Labels 10 | 11 | The following label convention defines the target OSes and architectures supported by an operator: 12 | 13 | ```yaml 14 | labels: 15 | operatorframework.io/arch.: supported 16 | operatorframework.io/os.: supported 17 | ``` 18 | 19 | Where `` and `` are one of the values [listed here](https://github.com/golang/go/blob/master/src/internal/syslist/syslist.go). 20 | 21 | ## Multiple Architectures 22 | 23 | Some operators may support multiple node architectures or OSes. In this case, multiple labels can be added. For example, an operator that support both windows and linux workloads will sport the following labels: 24 | 25 | ```yaml 26 | labels: 27 | operatorframework.io/os.windows: supported 28 | operatorframework.io/os.linux: supported 29 | ``` 30 | 31 | ## Defaults 32 | 33 | If a ClusterServiceVersion does not include an `os` label, a target OS is assumed to be `linux`. 34 | 35 | ```yaml 36 | labels: 37 | operatorframework.io/os.linux: supported 38 | ``` 39 | 40 | If a ClusterServiceVersion does not include an `arch` label, a target architecture is assumed to be `amd64`. 41 | 42 | ```yaml 43 | labels: 44 | operatorframework.io/arch.amd64: supported 45 | ``` 46 | 47 | ## Filtering available operators by os or arch 48 | 49 | Only windows: 50 | 51 | ```sh 52 | kubectl get packagemanifests -l operatorframework.io/os.windows=supported 53 | ``` 54 | 55 | ## Caveats 56 | 57 | Only the labels on the [HEAD of the default channel](/docs/glossary/#channel-head) are considered for filtering PackageManifests by label. 58 | 59 | This means, for example, that providing an alternate architecture for an operator in the non-default channel is possible, but will not be available for filtering in the PackageManifest API. 60 | -------------------------------------------------------------------------------- /content/en/docs/advanced-tasks/unsafe-fail-forward-upgrades.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Opting into UnsafeFailForward upgrades" 3 | linkTitle: "Opting into UnsafeFailForward upgrades" 4 | weight: 4 5 | description: > 6 | UnsafeFailForward upgrades is a feature that allows for the automatic upgrade of failed installs and upgrades. 7 | It is ultimately unsafe and should only be used in specific circumstances. 8 | --- 9 | 10 | ## Warning 11 | 12 | This feature is not recommended in a majority of cases as enabling UnsafeFailForward upgrades no longer guarantees sane upgrade paths, possibly causing unrecoverable failures resulting in data loss. Only use this feature if you: 13 | 14 | - Know every operator installed in the namespace. 15 | - Have deep knowledge regarding the upgrade paths for each operator in the namespace. 16 | - Have control over the contents of the catalogs providing the operators in the namespace. 17 | - Do not want to manually upgrade your failed operators. 18 | 19 | ## What "UnsafeFailForward" upgrades add 20 | 21 | A failed installation/upgrade is typically caused by one of two scenarios: 22 | 23 | - **A Failed CSV:** The [CSV](https://olm.operatorframework.io/docs/concepts/crds/clusterserviceversion/) is in the FAILED phase. 24 | - **A Failed InstallPlan:** Usually occurs because a resource listed in the [InstallPlan](https://olm.operatorframework.io/docs/concepts/crds/installplan/) fails to be created or updated. An InstallPlan may fail independently of its CSV and may fail to create the CSV. 25 | 26 | By opting into "UnsafeFailForward" upgrades, OLM will allow you to recover from failed installations and upgrades by: 27 | - Allowing CSVs to move from the FAILED phase to the REPLACING phase. 28 | - Allowing OLM to calculate new InstallPlans for a set of installables if: 29 | - The InstallPlan referenced by a Subscription is in the FAILED phase. 30 | - The CatalogSource has been updated to include a new upgrade for one or more CSVs in the namespace. 31 | 32 | ## Using UnsafeFailForward Upgrades 33 | 34 | Since resolution is namespace scoped, the toggle for allowing "UnsafeFailForward" upgrades is namespace scoped as well. Accordingly, the namespace scoped resource, OperatorGroup, has the `upgradeStrategy` field. 35 | 36 | ```yaml 37 | apiVersion: operators.coreos.com/v1 38 | kind: OperatorGroup 39 | metadata: 40 | name: foo 41 | namespace: bar 42 | spec: 43 | # Possible values include "Default" or "TechPreviewUnsafeFailForward". 44 | upgradeStrategy: TechPreviewUnsafeFailForward 45 | ``` 46 | 47 | With the upgradeStrategy type set to `TechPreviewUnsafeFailForward`, OLM will allow operators to "UnsafeFailForward" in adherence with the principles discussed below. If the upgradeStrategy is unset or set to `Default` OLM will exhibit existing behavior. 48 | 49 | ## Understanding "UnsafeFailForward" upgrades 50 | 51 | Before using UnsafeFailForward upgrades, it is important to understand how OLM and the Resolver calculate what needs to be installed. When determining what to install, OLM provides the Resolver with the set of CSVs in a namespace. The Resolver treats these CSVs differently depending on whether or not they are claimed by a Subscription, where the Subscription lists the CSV's name in its `.status.currentCSV` field. 52 | - If a CSV is claimed by a Subscription, the Resolver will allow it to be upgraded by a bundle that replaces it. 53 | - If a CSV is not claimed by a Subscription, it is assumed that the user installed the CSV themselves, that OLM should not upgrade the CSV, and that it must appear in the next set of installables. 54 | 55 | OLM's Resolver is deterministic, meaning that the set of installables will not change for a given set of arguments if no new upgrades have been declared in the existing CatalogSources. When an upgrade fails due to a CSV entering the FAILED phase, the CSV being replaced still exists and is not referenced by a Subscription. Today, OLM would send both `Operator v1` and `Operator v2` to the Resolver which will normally be unsatisfiable because `Operator v1` is marked as required and `Operator v2` cannot be upgraded further since it provides the same APIs as `Operator v1`. In order to support "failing forward", OLM needs to omit CSVs in the REPLACING phase from the set of arguments sent to the Resolver when "UnsafeFailForward" upgrades are enabled. 56 | 57 | ### When an InstallPlan failed 58 | 59 | Let's review what steps must be taken to recover from a failed InstallPlan today: 60 | 61 | - `Operator v1` is being upgraded to `Operator v2`. 62 | - The InstallPlan for `Operator v2` fails. 63 | - `Operator v3` is added to the catalog and is defined as the upgrade for `Operator v1`. 64 | - The user deletes the InstallPlan created for `Operator v2`. 65 | - A new InstallPlan is generated for `Operator v3` and the upgrade succeeds. 66 | 67 | With "UnsafeFailForward" upgrades, OLM allows new InstallPlans to be generated if: 68 | - The failed InstallPlan is referenced by a Subscription in the namespace. 69 | - The CatalogSource has been updated to include a new upgrade for the set of arguments. 70 | 71 | In practice, the fourth step from the previous workflow would be removed, meaning that the you simply need to update the CatalogSource and wait for the cluster to move past the failed install. With catalog polling enabled, you can even skip updating the CatalogSource directly by pushing a new catalog image to the same tag. 72 | 73 | > BEST PRACTICE NOTE: If a bundle is known to fail, it should be skipped in the upgrade graph using the [skips](https://olm.operatorframework.io/docs/concepts/olm-architecture/operator-catalog/creating-an-update-graph/#skips) or [skipRange](https://olm.operatorframework.io/docs/concepts/olm-architecture/operator-catalog/creating-an-update-graph/#skiprange) feature. 74 | 75 | To further understand, let's visualize this. 76 | 77 | {{}} 78 | graph TD; 79 | A(Operavtor V1 installed) --> B(Starts upgrading to Operator V2) 80 | 81 | B --> |Install succeeds| F(Operator V2 is installed and succeeds) 82 | 83 | B --> |InstallPlan fails| C(Operator V3 added to catalog replacing V2) 84 | C --> |Upgrade blocked as V1 is in solution set still| D(Manually delete Operator V2 InstallPlan) 85 | D --> |New InstallPlan generated and approved| E(Operator V3 is installed and succeeds) 86 | 87 | B --> |InstallPlan fails with UnsafeFailForward upgrades| H(Operator V3 added to catalog replacing V2) 88 | H --> |New InstallPlan generated and approved| J(Operator V3 is installed and succeeds) 89 | {{}} 90 | 91 | ### When one or more CSVs have failed 92 | 93 | Let's review what steps must be taken to recover from a failed CSV today: 94 | 95 | - `Operator v1` is being upgraded to `Operator v2`. 96 | - The CSV for `Operator v2` enters the FAILED phase. 97 | - `Operator v3` is added to the catalog which replaces or skips `Operator v2`. 98 | - The Resolver cannot upgrade `Operator v2` while including `Operator v1` in the solution set, upgrade is blocked. 99 | - User manually deletes the existing CSVs, a new InstallPlan is generated and approved. 100 | - `Operator v3` is installed and the upgrade succeeds. 101 | 102 | To further understand, let's visualize this. 103 | 104 | {{}} 105 | graph TD; 106 | A(Operator V1 installed) --> B(Starts upgrading to Operator V2) 107 | 108 | B --> |Install succeeds| F(Operator V2 is installed and succeeds) 109 | 110 | B --> |CSV enters FAILED phase| C(Operator V3 added to catalog replacing V2) 111 | C --> |Upgrade blocked as V1 is in solution set still| D(Manually delete Operator V2 CSV) 112 | D --> |New InstallPlan generated and approved| E(Operator V3 is installed and succeeds) 113 | 114 | B --> |CSV enters FAILED phase with UnsafeFailForward upgrades| H(Operator V3 added to catalog replacing V2) 115 | H --> |New InstallPlan generated and approved| J(Operator V3 is installed and succeeds) 116 | {{}} 117 | 118 | When you opt into "UnsafeFailForward" upgrades, OLM: 119 | - Does not include CSVs in the REPLACING phase in the set of arguments sent to the Resolver if the final CSV in the upgrade chain is in the FAILED phase and all other CSVs are in the REPLACING phase. 120 | - Allows CSVs to move from the FAILED phase to the REPLACING phase. 121 | 122 | These changes allow OLM to recover from any number of failed CSVs in an upgrade path, replacing the latest FAILED CSV with the next upgrade. 123 | -------------------------------------------------------------------------------- /content/en/docs/best-practices/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Best Practices" 3 | linkTitle: "Best Practices" 4 | weight: 5 5 | description: Best practices, conventions and recommendations to work with OLM 6 | --- 7 | 8 | -------------------------------------------------------------------------------- /content/en/docs/best-practices/common.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Common recommendations and suggestions" 3 | linkTitle: "Common suggestions" 4 | weight: 2 5 | description: Common recommendations and suggestions to distribute solutions with Operator OLM 6 | --- 7 | 8 | ## Overview 9 | 10 | Any recommendation or good practice suggested by the Kubernetes community such as to develop [Operator pattern][operator-pattern] solutions or to manage them are good recommendations for who is looking for to build the operator projects and distribute them with OLM. Also, see [Operator Best Practices][operator-best-practices] and ensure that you check out [Running On-Cluster][running-on-cluster]. 11 | 12 | ## Validate your bundle before publish it 13 | 14 | Check and test your operator bundle before you publish it. Note that the [`operator-sdk`][operator-sdk] CLI can help with that process. You can validate a bundle via [`operator-sdk bundle validate`][sdk-cli-bundle-validate] against the entire suite of validators for Operator Framework, in addition to required bundle validators: 15 | 16 | ```sh 17 | operator-sdk bundle validate ./bundle --select-optional suite=operatorframework 18 | ``` 19 | 20 | The `OperatorHub.io` validator in the `operatorframework` optional suite allows you to validate that your manifests can work with a Kubernetes cluster of a particular version using the `k8s-version` optional key value: 21 | 22 | ```sh 23 | operator-sdk bundle validate ./bundle --select-optional suite=operatorframework --optional-values=k8s-version=1.22 24 | ``` 25 | 26 | Also, you can validate a bundle via [`operator-sdk scorecard`][sdk-cli-scorecard-bundle] to insure it against a suite of tests: 27 | 28 | ```sh 29 | operator-sdk scorecard bundle 30 | ``` 31 | 32 | ## Provide what are the k8s versions supported by your project 33 | 34 | In the [CSV](/docs/concepts/crds/clusterserviceversion) manifest of your operator bundle, you can set the `spec.minKubeVersion` property to inform what is the minimal Kubernetes version which your project supports: 35 | 36 | ```yaml 37 | ... 38 | spec: 39 | maturity: alpha 40 | version: 0.4.0 41 | minKubeVersion: 1.16.0 42 | ``` 43 | 44 | It is recommended you provide this information. Otherwise, it would mean that your operator project can be distributed and installed in any cluster version available, which is not necessarily the case for all projects. 45 | 46 | [operator-best-practices]: https://sdk.operatorframework.io/docs/best-practices/best-practices/ 47 | [operator-pattern]: https://kubernetes.io/docs/concepts/extend-kubernetes/operator/ 48 | [operator-sdk]: https://github.com/operator-framework/operator-sdk 49 | [sdk-cli-bundle-validate]: https://sdk.operatorframework.io/docs/cli/operator-sdk_bundle_validate/ 50 | [sdk-cli-scorecard-bundle]: https://sdk.operatorframework.io/docs/cli/operator-sdk_scorecard/ 51 | [running-on-cluster]: https://master.sdk.operatorframework.io/docs/best-practices/best-practices/#running-on-cluster -------------------------------------------------------------------------------- /content/en/docs/best-practices/images/channel-naming1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/olm-docs/2c28ed58b799ec788bc21d889f48e7141a8e43ce/content/en/docs/best-practices/images/channel-naming1.png -------------------------------------------------------------------------------- /content/en/docs/best-practices/images/channel-naming2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/olm-docs/2c28ed58b799ec788bc21d889f48e7141a8e43ce/content/en/docs/best-practices/images/channel-naming2.png -------------------------------------------------------------------------------- /content/en/docs/contribution-guidelines/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Contribution Guidelines" 3 | linkTitle: "Contribution Guidelines" 4 | weight: 7 5 | description: > 6 | How to contribute to the docs 7 | --- 8 | 9 | We use [Hugo](https://gohugo.io/) to format and generate our website, the 10 | [Docsy](https://github.com/google/docsy) theme for styling and site structure, 11 | and [Netlify](https://www.netlify.com/) to manage the deployment of the site. 12 | Hugo is an open-source static site generator that provides us with templates, 13 | content organisation in a standard directory structure, and a website generation 14 | engine. You write the pages in Markdown (or HTML if you want), and Hugo wraps them up into a website. 15 | 16 | All submissions, including submissions by project members, require review. We 17 | use GitHub pull requests for this purpose. Consult 18 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more 19 | information on using pull requests. 20 | 21 | ## Quick start with Netlify 22 | 23 | Here's a quick guide to updating the docs. It assumes you're familiar with the 24 | GitHub workflow and you're happy to use the automated preview of your doc 25 | updates: 26 | 27 | 1. Fork [olm-docs](https://github.com/operator-framework/olm-docs) on GitHub. 28 | 1. Make your changes and send a pull request (PR). 29 | 1. If you're not yet ready for a review, create a draft PR to indicate it's a work in progress. (**Don't** add the Hugo property 30 | "draft = true" to the page front matter, because that prevents the 31 | auto-deployment of the content preview described in the next point.) 32 | 1. Wait for the automated PR workflow to do some checks. When it's ready, 33 | you should see a comment like this: **deploy/netlify — Deploy preview ready!** 34 | 1. Click **Details** to the right of "Deploy preview ready" to see a preview 35 | of your updates. 36 | 1. Continue updating your doc and pushing your changes until you're happy with 37 | the content. 38 | 1. When you're ready for a review, remove any "WIP" markers and mark PR ready for review. 39 | 40 | ## Updating a single page 41 | 42 | If you've just spotted something you'd like to change while using the docs, Docsy has a shortcut for you: 43 | 44 | 1. Click **Edit this page** in the top right hand corner of the page. 45 | 1. If you don't already have an up to date fork of the project repo, you are prompted to get one - click **Fork this repository and propose changes** or **Update your Fork** to get an up to date version of the project to edit. The appropriate page in your fork is displayed in edit mode. 46 | 1. Follow the rest of the [Quick start with Netlify](#quick-start-with-netlify) process above to make, preview, and propose your changes. 47 | 48 | ## Previewing your changes locally 49 | 50 | If you want to run your own local Hugo server to preview your changes as you work follow [this guide](/docs/contribution-guidelines/local-docs/). 51 | 52 | ## Creating an issue 53 | 54 | If you've found a problem in the docs, but you're not sure how to fix it yourself, please create an issue in the [olm-docs repo](https://github.com/operator-framework/olm-docs). You can also create an issue about a specific page by clicking the **Create Issue** button in the top right hand corner of the page. 55 | 56 | ## Useful resources 57 | 58 | * [Docsy user guide](https://www.docsy.dev/docs/): All about Docsy, including how it manages navigation, look and feel, and multi-language support. 59 | * [Hugo documentation](https://gohugo.io/documentation/): Comprehensive reference for Hugo. 60 | -------------------------------------------------------------------------------- /content/en/docs/contribution-guidelines/local-docs.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Build and serve the docs locally 3 | linkTitle: Local Docs 4 | --- 5 | 6 | ## Prerequisites 7 | 8 | For running local dev server you will only need to install stable version of [Go](https://go.dev/) 9 | and clone the repository: 10 | 11 | ```bash 12 | git clone https://github.com/operator-framework/olm-docs/ 13 | ``` 14 | 15 | For other tasks such as building production version of the site 16 | and linting you will also need to: 17 | * Install Node.js LTS 18 | * Install Docker or Podman 19 | 20 | 21 | ## Build and Serve 22 | 23 | You can build and serve your docs to with: 24 | 25 | ```bash 26 | make serve 27 | ``` 28 | 29 | Any changes will be included in real time. 30 | 31 | ## Running the Linting Script Locally 32 | 33 | To run linting locally you will need to run the following command: 34 | 35 | ```bash 36 | make lint 37 | ``` 38 | 39 | This assumes `docker` command is available. If you want to specify different engine such as `podman`: 40 | 41 | ```bash 42 | make lint CONTAINER_ENGINE=podman 43 | ``` 44 | 45 | Behind this target, the `hack/ci/link-check.sh` script is responsible for running [html-proofer](https://github.com/gjtorikian/html-proofer) that validates the generated HTML output. 46 | 47 | **Note**: In the case you're getting permission denied errors when reading from that mounted volume, set the following environment variable and re-run the linting script: 48 | 49 | ```bash 50 | make lint CONTAINER_RUN_EXTRA_OPTIONS="--security-opt label=disable" 51 | ``` 52 | -------------------------------------------------------------------------------- /content/en/docs/getting-started/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "QuickStart" 3 | linkTitle: "QuickStart" 4 | weight: 1 5 | description: > 6 | Install OLM in a kubernetes cluster, then install an operator using OLM. 7 | --- 8 | 9 | ## Prerequisites 10 | 11 | - Access to a Kubernetes `v1.11.3+` cluster. 12 | - [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) `v1.11.3+`. 13 | 14 | ## Installing OLM in your cluster 15 | 16 | The `operator-sdk` binary provides a command to easily install and uninstall OLM in a Kubernetes cluster. See the [SDK installation guide][sdk-installation-guide] on how to install `operator-sdk` tooling. 17 | 18 | After you have the `operator-sdk` binary installed, you can install OLM on your cluster by running `operator-sdk olm install`. 19 | 20 | ```bash 21 | $ operator-sdk olm install 22 | INFO[0000] Fetching CRDs for version "latest" 23 | INFO[0000] Fetching resources for resolved version "latest" 24 | I0302 14:26:13.947244 61268 request.go:682] Waited for 1.041225333s due to client-side throttling, not priority and fairness, request: GET:https://127.0.0.1:63693/apis/flowcontrol.apiserver.k8s.io/v1beta2?timeout=32s 25 | INFO[0006] Creating CRDs and resources 26 | INFO[0006] Creating CustomResourceDefinition "catalogsources.operators.coreos.com" 27 | INFO[0006] Creating CustomResourceDefinition "clusterserviceversions.operators.coreos.com" 28 | INFO[0006] Creating CustomResourceDefinition "installplans.operators.coreos.com" 29 | INFO[0006] Creating CustomResourceDefinition "olmconfigs.operators.coreos.com" 30 | INFO[0006] Creating CustomResourceDefinition "operatorconditions.operators.coreos.com" 31 | INFO[0006] Creating CustomResourceDefinition "operatorgroups.operators.coreos.com" 32 | INFO[0006] Creating CustomResourceDefinition "operators.operators.coreos.com" 33 | INFO[0006] Creating CustomResourceDefinition "subscriptions.operators.coreos.com" 34 | INFO[0006] Creating Namespace "olm" 35 | INFO[0006] Creating Namespace "operators" 36 | INFO[0006] Creating ServiceAccount "olm/olm-operator-serviceaccount" 37 | INFO[0006] Creating ClusterRole "system:controller:operator-lifecycle-manager" 38 | INFO[0006] Creating ClusterRoleBinding "olm-operator-binding-olm" 39 | INFO[0006] Creating OLMConfig "cluster" 40 | INFO[0009] Creating Deployment "olm/olm-operator" 41 | INFO[0009] Creating Deployment "olm/catalog-operator" 42 | INFO[0009] Creating ClusterRole "aggregate-olm-edit" 43 | INFO[0009] Creating ClusterRole "aggregate-olm-view" 44 | INFO[0009] Creating OperatorGroup "operators/global-operators" 45 | INFO[0009] Creating OperatorGroup "olm/olm-operators" 46 | INFO[0009] Creating ClusterServiceVersion "olm/packageserver" 47 | INFO[0010] Creating CatalogSource "olm/operatorhubio-catalog" 48 | INFO[0010] Waiting for deployment/olm-operator rollout to complete 49 | INFO[0010] Waiting for Deployment "olm/olm-operator" to rollout: 0 of 1 updated replicas are available 50 | INFO[0021] Deployment "olm/olm-operator" successfully rolled out 51 | INFO[0021] Waiting for deployment/catalog-operator rollout to complete 52 | INFO[0021] Deployment "olm/catalog-operator" successfully rolled out 53 | INFO[0021] Waiting for deployment/packageserver rollout to complete 54 | INFO[0021] Waiting for Deployment "olm/packageserver" to rollout: 0 of 2 updated replicas are available 55 | INFO[0032] Deployment "olm/packageserver" successfully rolled out 56 | INFO[0032] Successfully installed OLM version "latest" 57 | 58 | NAME NAMESPACE KIND STATUS 59 | catalogsources.operators.coreos.com CustomResourceDefinition Installed 60 | clusterserviceversions.operators.coreos.com CustomResourceDefinition Installed 61 | installplans.operators.coreos.com CustomResourceDefinition Installed 62 | olmconfigs.operators.coreos.com CustomResourceDefinition Installed 63 | operatorconditions.operators.coreos.com CustomResourceDefinition Installed 64 | operatorgroups.operators.coreos.com CustomResourceDefinition Installed 65 | operators.operators.coreos.com CustomResourceDefinition Installed 66 | subscriptions.operators.coreos.com CustomResourceDefinition Installed 67 | olm Namespace Installed 68 | operators Namespace Installed 69 | olm-operator-serviceaccount olm ServiceAccount Installed 70 | system:controller:operator-lifecycle-manager ClusterRole Installed 71 | olm-operator-binding-olm ClusterRoleBinding Installed 72 | cluster OLMConfig Installed 73 | olm-operator olm Deployment Installed 74 | catalog-operator olm Deployment Installed 75 | aggregate-olm-edit ClusterRole Installed 76 | aggregate-olm-view ClusterRole Installed 77 | global-operators operators OperatorGroup Installed 78 | olm-operators olm OperatorGroup Installed 79 | packageserver olm ClusterServiceVersion Installed 80 | operatorhubio-catalog olm CatalogSource Installed 81 | ``` 82 | 83 | ## Installing an Operator using OLM 84 | 85 | When you install OLM, it comes packaged with a number of Operators developed by the community that you can install instantly. 86 | You can use the `packagemanifest` api to see the operators available for you to install in your cluster: 87 | 88 | ```sh 89 | $ kubectl get packagemanifest -n olm 90 | NAME CATALOG AGE 91 | # ... 92 | noobaa-operator Community Operators 2m17s 93 | project-quay Community Operators 2m17s 94 | ack-eks-controller Community Operators 2m17s 95 | # ... 96 | ``` 97 | 98 | To install the quay operator in the default namespace, first create an `OperatorGroup` for the default namespace: 99 | 100 | ```sh 101 | $ cat operatorgroup.yaml 102 | kind: OperatorGroup 103 | apiVersion: operators.coreos.com/v1 104 | metadata: 105 | name: og-single 106 | namespace: default 107 | spec: 108 | targetNamespaces: 109 | - default 110 | 111 | $ kubectl apply -f operatorgroup.yaml 112 | operatorgroup.operators.coreos.com/og-single created 113 | ``` 114 | 115 | Then create a subscription for the quay operator: 116 | 117 | ```sh 118 | $ cat subscription.yaml 119 | apiVersion: operators.coreos.com/v1alpha1 120 | kind: Subscription 121 | metadata: 122 | name: quay 123 | namespace: default 124 | spec: 125 | channel: stable-3.8 126 | installPlanApproval: Automatic 127 | name: project-quay 128 | source: operatorhubio-catalog 129 | sourceNamespace: olm 130 | startingCSV: quay-operator.v3.8.1 131 | 132 | $ kubectl apply -f subscription.yaml 133 | subscription.operators.coreos.com/quay created 134 | ``` 135 | 136 | This installs the v3.8.1 version of the quay operator, and then upgrades to the latest version of the quay operator in your cluster. 137 | 138 | ```sh 139 | $ kubectl get sub -n default 140 | NAME PACKAGE SOURCE CHANNEL 141 | quay project-quay operatorhubio-catalog stable-3.8 142 | 143 | $ kubectl get csv -n default 144 | NAME DISPLAY VERSION REPLACES PHASE 145 | quay-operator.v3.8.3 Quay 3.8.3 quay-operator.v3.8.1 Succeeded 146 | 147 | $ kubectl get deployment -n default 148 | NAME READY UP-TO-DATE AVAILABLE AGE 149 | quay-operator-tng 1/1 1 1 40s 150 | ``` 151 | 152 | To learn more about packaging your operator for OLM, installing/uninstalling an operator etc, visit the [Core Tasks](/docs/tasks/) and the [Advanced Tasks](/docs/advanced-tasks/) sections of this site. 153 | 154 | 155 | [sdk-installation-guide]: https://sdk.operatorframework.io/docs/installation/ 156 | -------------------------------------------------------------------------------- /content/en/images/4498B411F22DC186.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/olm-docs/2c28ed58b799ec788bc21d889f48e7141a8e43ce/content/en/images/4498B411F22DC186.png -------------------------------------------------------------------------------- /content/en/images/Asset 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/olm-docs/2c28ed58b799ec788bc21d889f48e7141a8e43ce/content/en/images/Asset 1.png -------------------------------------------------------------------------------- /content/en/images/Asset 2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/olm-docs/2c28ed58b799ec788bc21d889f48e7141a8e43ce/content/en/images/Asset 2.png -------------------------------------------------------------------------------- /content/en/images/arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /content/en/images/bg-masthead-green.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 23 | bg-masthead 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | -------------------------------------------------------------------------------- /content/en/images/bg-masthead-red.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 19 | bg-masthead 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 4B0D17 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /content/en/images/bg-masthead.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 23 | bg-masthead 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /content/en/images/header-bg.svg: -------------------------------------------------------------------------------- 1 | Artboard 6 -------------------------------------------------------------------------------- /content/en/images/ico-build.svg: -------------------------------------------------------------------------------- 1 | Asset 3 -------------------------------------------------------------------------------- /content/en/images/ico-discover.svg: -------------------------------------------------------------------------------- 1 | Asset 1 -------------------------------------------------------------------------------- /content/en/images/ico-manage.svg: -------------------------------------------------------------------------------- 1 | Asset 2 -------------------------------------------------------------------------------- /content/en/images/logo-sm.svg: -------------------------------------------------------------------------------- 1 | Asset 8 -------------------------------------------------------------------------------- /content/en/images/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 11 | logo 12 | 13 | 15 | 17 | 18 | 19 | 20 | 21 | 22 | 24 | 25 | 26 | 28 | 29 | 30 | 31 | 32 | 33 | 35 | 36 | 37 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 52 | 53 | 54 | 55 | 56 | 57 | 60 | 61 | 62 | 63 | 64 | 66 | 68 | 70 | 71 | 72 | 74 | 75 | 76 | 79 | 80 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /content/en/images/sprite.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 48 | 49 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/operator-framework/olm-docs 2 | 3 | go 1.20 4 | 5 | require github.com/google/docsy v0.6.0 // indirect 6 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/FortAwesome/Font-Awesome v0.0.0-20220831210243-d3a7818c253f/go.mod h1:IUgezN/MFpCDIlFezw3L8j83oeiIuYoj28Miwr/KUYo= 2 | github.com/google/docsy v0.6.0 h1:43bVF18t2JihAamelQjjGzx1vO2ljCilVrBgetCA8oI= 3 | github.com/google/docsy v0.6.0/go.mod h1:VKKLqD8PQ7AglJc98yBorATfW7GrNVsn0kGXVYF6G+M= 4 | github.com/google/docsy/dependencies v0.6.0/go.mod h1:EDGc2znMbGUw0RW5kWwy2oGgLt0iVXBmoq4UOqstuNE= 5 | github.com/twbs/bootstrap v4.6.2+incompatible/go.mod h1:fZTSrkpSf0/HkL0IIJzvVspTt1r9zuf7XlZau8kpcY0= 6 | -------------------------------------------------------------------------------- /hack/ci/link-check.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -ev 3 | 4 | CONTAINER_RUN_EXTRA_OPTIONS=${CONTAINER_RUN_EXTRA_OPTIONS:=""} 5 | CONTAINER_ENGINE=${CONTAINER_ENGINE:="docker"} 6 | 7 | # ignore 8 | # 1: links going back to help.github.com are rate-limited and can make this flaky 9 | # 2: docsy autogenerated edit links to original markdown source, which will fail if the markdown file is new 10 | # 3: ignore localhost link to a hugo site 11 | ${CONTAINER_ENGINE} run --rm -v $(pwd)/public:/target mtlynch/htmlproofer /target --ignore-empty-alt --ignore-status-codes 429 --allow-hash-href --no-check-external-hash --ignore-urls '/help.github.com/,/edit\/master\/.*\.md/,/tree\/master\/.*\.md/,/new\/master\/.*filename=change-me\.md/,/localhost:1313/' 12 | -------------------------------------------------------------------------------- /layouts/404.html: -------------------------------------------------------------------------------- 1 | {{ define "main"}} 2 |
3 |
4 |

Not found

5 |

Oops! This page doesn't exist. Try going back to our home page.

6 | 7 |

You can learn how to make a 404 page like this in Custom 404 Pages.

8 |
9 |
10 | {{ end }} 11 | -------------------------------------------------------------------------------- /layouts/_default/baseof.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ partial "head.html" . }} 5 | 6 | 7 | {{ partial "navbar.html" . }} 8 | {{ block "masthead" . }}{{ end }} 9 | {{ block "main" . }}{{ end }} 10 | {{ partial "footer.html" . }} 11 | {{ partialCached "scripts.html" . }} 12 | 13 | 14 | -------------------------------------------------------------------------------- /layouts/docs/baseof.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ partial "head.html" . }} 5 | 6 | 7 | {{ partial "navbar.html" . }} 8 |
9 |
10 |
11 | 14 | 18 |
19 | {{ partial "version-banner.html" . }} 20 | {{ if not .Site.Params.ui.breadcrumb_disable }}{{ partial "breadcrumb.html" . }}{{ end }} 21 | {{ block "main" . }}{{ end }} 22 |
23 |
24 |
25 |
26 | {{ partial "footer.html" . }} 27 |
28 |
29 | {{ partial "scripts.html" . }} 30 | 31 | 32 | -------------------------------------------------------------------------------- /layouts/docs/list.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 |
3 |

{{ .Title }}

4 | {{ with .Params.description }}
{{ . | markdownify }}
{{ end }} 5 | {{ .Content }} 6 | {{ partial "section-index.html" . }} 7 | {{ if (and (not .Params.hide_feedback) (.Site.Params.ui.feedback.enable) (.Site.GoogleAnalytics)) }} 8 | {{ partial "feedback.html" .Site.Params.ui.feedback }} 9 |
10 | {{ end }} 11 | {{ if (.Site.DisqusShortname) }} 12 |
13 | {{ partial "disqus-comment.html" . }} 14 | {{ end }} 15 | {{ partial "page-meta-lastmod.html" . }} 16 |
17 | {{ end }} 18 | -------------------------------------------------------------------------------- /layouts/partials/footer.html: -------------------------------------------------------------------------------- 1 | {{ $links := .Site.Params.links }} 2 |
3 | 15 | 24 | 34 |
35 | 36 | {{ define "footer-links-block" }} 37 | 46 | {{ end }} 47 | -------------------------------------------------------------------------------- /layouts/partials/hooks/body-end.html: -------------------------------------------------------------------------------- 1 | {{ with .Site.Params.algolia_docsearch }} 2 | 3 | 9 | {{ end }} 10 | -------------------------------------------------------------------------------- /layouts/partials/hooks/head-end.html: -------------------------------------------------------------------------------- 1 | {{ with .Site.Params.algolia_docsearch }} 2 | 3 | 8 | {{ end }} 9 | -------------------------------------------------------------------------------- /layouts/partials/navbar-version-selector.html: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /layouts/partials/navbar.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | 6 | 7 | 8 | 22 | 25 |
26 | -------------------------------------------------------------------------------- /layouts/partials/section-index.html: -------------------------------------------------------------------------------- 1 |
2 | {{ $pages := (where .Site.Pages "Section" .Section).ByWeight }} 3 | {{ $parent := .Page }} 4 | {{ if $parent.Params.no_list }} 5 | {{/* If no_list is true we don't show a list of subpages */}} 6 | {{ else if $parent.Params.simple_list }} 7 | {{/* If simple_list is true we show a bulleted list of subpages */}} 8 |
    9 | {{ range $pages }} 10 | {{ if eq .Parent $parent }} 11 |
  • {{- .Title -}}
  • 12 | {{ end }} 13 | {{ end }} 14 |
15 | {{ else }} 16 | {{/* Otherwise we show a nice formatted list of subpages with page descriptions */}} 17 |
18 | {{ range $pages }} 19 | {{ if eq .Parent $parent }} 20 |
21 |

22 | {{- .Title -}} 23 |

24 |

{{ .Description | markdownify }}

25 |
26 | {{ end }} 27 | {{ end }} 28 | {{ end }} 29 |
30 | -------------------------------------------------------------------------------- /layouts/partials/sidebar-tree.html: -------------------------------------------------------------------------------- 1 | {{/* We cache this partial for bigger sites and set the active class client side. */}} 2 | {{ $shouldDelayActive := ge (len .Site.Pages) 2000 }} 3 |
4 | {{ if not .Site.Params.ui.sidebar_search_disable }} 5 | 9 | {{ end }} 10 | 13 | 21 |
22 | {{ define "section-tree-nav-section" }} 23 | {{ $s := .section }} 24 | {{ $p := .page }} 25 | {{ $shouldDelayActive := .delayActive }} 26 | {{ $active := eq $p.CurrentSection $s }} 27 | {{ $show := or (and (not $p.Site.Params.ui.sidebar_menu_compact) ($p.IsAncestor $s)) (or (eq $p $s) ($p.IsDescendant $s)) }} 28 | {{ $sid := $s.RelPermalink | anchorize }} 29 |
    30 |
  • 31 | {{ $s.LinkTitle }} 32 |
  • 33 |
      34 |
    • 35 | {{ $pages := where (union $s.Pages $s.Sections).ByWeight ".Params.toc_hide" "!=" true }} 36 | {{ $pages := $pages | first 50 }} 37 | {{ range $pages }} 38 | {{ if .IsPage }} 39 | {{ $mid := printf "m-%s" (.RelPermalink | anchorize) }} 40 | {{ $active := eq . $p }} 41 | {{ .LinkTitle }} 42 | {{ else }} 43 | {{ template "section-tree-nav-section" (dict "page" $p "section" .) }} 44 | {{ end }} 45 | {{ end }} 46 |
    • 47 |
    48 |
49 | {{ end }} 50 | -------------------------------------------------------------------------------- /layouts/shortcodes/code_callout.html: -------------------------------------------------------------------------------- 1 | {{ index .Params 0 }} -------------------------------------------------------------------------------- /layouts/shortcodes/mermaid.html: -------------------------------------------------------------------------------- 1 | {{ .Page.Store.Set "hasmermaid" true -}} 2 | 3 |
4 | {{- .Inner | safeHTML }} 5 |
6 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | command = "hugo --gc --minify -b $URL" 3 | publish = "public" 4 | 5 | [build.environment] 6 | HUGO_VERSION = "0.111.1" 7 | 8 | [context.production.environment] 9 | HUGO_ENV = "production" 10 | 11 | [context.deploy-preview] 12 | command = "hugo --gc --minify --buildFuture -b $DEPLOY_PRIME_URL" 13 | 14 | [context.branch-deploy] 15 | command = "hugo --gc --minify -b $DEPLOY_PRIME_URL" 16 | 17 | [[headers]] 18 | for = "*.webmanifest" 19 | [headers.values] 20 | Content-Type = "application/manifest+json; charset=UTF-8" 21 | 22 | [[headers]] 23 | for = "index.xml" 24 | [headers.values] 25 | Content-Type = "application/rss+xml" 26 | 27 | [[redirects]] 28 | from = "/docs/tasks/creating-an-index" 29 | to = "/docs/tasks/creating-a-catalog" 30 | 31 | [[redirects]] 32 | from = "/docs/tasks/make-index-available-on-cluster" 33 | to = "/docs/tasks/make-catalog-available-on-cluster" 34 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "olm-docs", 3 | "version": "0.0.1", 4 | "description": "Operator Lifecycle Manager (OLM) documentation.", 5 | "main": "none.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+github.com/operator-framework/olm-docs.git" 12 | }, 13 | "author": "", 14 | "license": "ISC", 15 | "bugs": { 16 | "url": "https://github.com/operator-framework/olm-docs/issues" 17 | }, 18 | "homepage": "https://github.com/operator-framework/olm-docs#readme", 19 | "dependencies": {}, 20 | "devDependencies": { 21 | "autoprefixer": "^10.4.13", 22 | "postcss": "^8.4.31", 23 | "postcss-cli": "^10.1.0" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /static/favicons/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/olm-docs/2c28ed58b799ec788bc21d889f48e7141a8e43ce/static/favicons/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /static/favicons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/olm-docs/2c28ed58b799ec788bc21d889f48e7141a8e43ce/static/favicons/favicon-16x16.png -------------------------------------------------------------------------------- /static/favicons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/olm-docs/2c28ed58b799ec788bc21d889f48e7141a8e43ce/static/favicons/favicon-32x32.png -------------------------------------------------------------------------------- /static/favicons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/olm-docs/2c28ed58b799ec788bc21d889f48e7141a8e43ce/static/favicons/favicon.ico -------------------------------------------------------------------------------- /static/favicons/pwa-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/olm-docs/2c28ed58b799ec788bc21d889f48e7141a8e43ce/static/favicons/pwa-192x192.png -------------------------------------------------------------------------------- /static/favicons/pwa-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/olm-docs/2c28ed58b799ec788bc21d889f48e7141a8e43ce/static/favicons/pwa-512x512.png -------------------------------------------------------------------------------- /static/favicons/tile150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/olm-docs/2c28ed58b799ec788bc21d889f48e7141a8e43ce/static/favicons/tile150x150.png -------------------------------------------------------------------------------- /static/favicons/tile310x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/olm-docs/2c28ed58b799ec788bc21d889f48e7141a8e43ce/static/favicons/tile310x150.png -------------------------------------------------------------------------------- /static/favicons/tile310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/olm-docs/2c28ed58b799ec788bc21d889f48e7141a8e43ce/static/favicons/tile310x310.png -------------------------------------------------------------------------------- /static/favicons/tile70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operator-framework/olm-docs/2c28ed58b799ec788bc21d889f48e7141a8e43ce/static/favicons/tile70x70.png --------------------------------------------------------------------------------