diff --git a/docs/bundles/plain.md b/docs/bundles/plain.md index 489bf414..bf607c1a 100644 --- a/docs/bundles/plain.md +++ b/docs/bundles/plain.md @@ -2,43 +2,151 @@ ## Overview -This document is meant to define the `plain` bundle format as a reference for those publishing `plain` bundles -for use with RukPak. For more information on the concept of a bundle, click [here](https://github.com/operator-framework/rukpak#bundle). +This document is meant to define the plain bundle format as a reference for those publishing plain bundles for use with +RukPak. A bundle is a collection of Kubernetes resources that are packaged together for the purposes of installing onto +a Kubernetes cluster. + +Users can specify a resource bundle to unpack or install via the +[`Bundle`](https://github.com/operator-framework/rukpak#bundle) +and [`BundleDeployment`](https://github.com/operator-framework/rukpak#bundledeployment) resources. +Controllers, called provisioners, consume the bundle referenced in the `Bundle(Deployment)` resource and store or apply the embedded manifests + +A plain bundle is a static collection of arbitrary Kubernetes YAML manifests. These manifests are contained in a directory +that can be packaged in a container image layer , a `git` repository or any other content source that the +[plain bundle provisioner](../provisioners/plain.md) supports. + +Supported source types for a plain bundle currently include the following: + +* A directory in a [container image](../sources/image.md) +* A directory in a [`git` repository](../sources/git.md) +* A set of keys in a [`ConfigMap`](../sources/local.md) +* An [upload](../sources/upload.md) +* A `.tgz` file returned by a [http endpoint](../sources/http.md) -A plain bundle is simply a collection of static, arbitrary, Kubernetes YAML manifests in a given directory. The currently implemented plain bundle format is the `plain+v0` format. The name of the bundle format, `plain+v0` -combines the type of bundle (plain) with the current schema version (v0). +combines the type of bundle (plain) with the current schema version (v0). The +[plain bundle provisioner](../provisioners/plain.md) is able to source +`plain+v0` bundles and install them onto a Kubernetes cluster. -> Note: the plain+v0 bundle format is at schema version v0, which means it's an experimental format that is subject +> Note: the `plain+v0` bundle format is at schema version v0, which means it's an experimental format that is subject > to change. -## Example +## Common Terminology + +* *bundle* is a collection of Kubernetes manifests that define content to be deployed to a cluster +* *bundle image* is a container image that contains a bundle within its filesystem +* *bundle git repo* is a git repository that contains a bundle within a directory + +## Technical Details + +* The [plain bundle provisioner](../provisioners/plain.md) is opinionated and expects the +plain bundle to be located in the root-level `/manifests` directory. +* The manifests directory should be flat: all manifests should be at the top-level with no subdirectories. +* It is required that `kubectl apply` is able to process all .yaml files in the directory that make up a plain bundle. For example, +multi-object YAML files are acceptable, but Ansible playbooks would not be. -For example, below is an example of a file tree in a `plain+v0` bundle. It must have a `manifests` directory contains -the Kubernetes resources required to deploy an application. +## Building a plain bundle +### Prerequisites -```tree +In order to create a plain bundle for RukPak, ensure your Kubernetes manifests are in a flat directory at the root of +your project called `manifests/`. This allows the contents to be sourced and unpacked by the +[plain provisioner](..provisioners/plain.md). It should look similar to: + +```bash +$ tree manifests manifests ├── namespace.yaml +├── service_account.yaml ├── cluster_role.yaml -├── role.yaml -├── serviceaccount.yaml ├── cluster_role_binding.yaml -├── role_binding.yaml └── deployment.yaml ``` > Note: there must be at least one resource in the manifests directory in order for the bundle to be a valid -> plain+v0 bundle. +> `plain+v0` bundle. -## Technical Details +If you are using [kustomize](https://kustomize.io/) for building your manifests from templates, redirect the output into a single file under the `manifests/` directory. For example: +```bash +$ tree templates +templates +├── namespace.yaml +├── service_account.yaml +├── cluster_role.yaml +├── cluster_role_binding.yaml +├── deployment.yaml.yaml +└── kustomization.yaml +``` -* The static manifests must be located in the /manifests directory for the bundle to be a -valid `plain+v0` bundle that the provisioner can unpack. A plain bundle image without a /manifests directory is -invalid and will not be successfully unpacked onto the cluster. -* The manifests directory should be flat: all manifests should be at the top-level with no subdirectories. -* Including any content in the /manifests directory of a plain bundle that is not static manifests will result in -a failure when creating content on-cluster from that bundle. Essentially, any file that would not -successfully `kubectl apply` will result in an error, but multi-object YAML files, or JSON files, are fine. There will -be validation tooling provided that can determine whether a given artifact is a valid bundle. \ No newline at end of file +```bash +kustomize build templates > manifests/manifests.yaml +``` + +### Git source + +For using the bundle with a [`git` source](../sources/git.md), commit your `manifests/` directory to your `git` repository. + +### HTTP source + +For using the bundle with a [HTTP source](../sources/http.md), create a `.tgz` file that contains the `manifests/` directory and its manifests. This `.tgz` file should be served when hitting the HTTP endpoint. + +### Image source + +For using the bundle with an [image source](../sources/image.md), follow the below steps: + +1. Create a Dockerfile at the root of the project +```bash +touch Dockerfile.plainbundle +``` + +2. Edit the Dockerfile to include the following: +```bash +cat <Dockerfile.plainbundle +FROM scratch +COPY manifests /manifests +EOF +``` + +> Note: The Dockerfile can have any `FROM ...` directive, but it is recommended to use the `FROM scratch` +> directive to keep the resulting image size minimal + +3. Build an OCI-compliant image using any build tooling you prefer. Use an image tag that references a repository that you have push access to. For example, + +```bash +docker build -f Dockerfile.plainbundle -t quay.io/operator-framework/rukpak:example . +``` + +4. Push the image to the remote registry + +```bash +docker push quay.io/operator-framework/rukpak:example +``` + +If you are looking to use a private image registry for sourcing your bundle content, see the ["Private image registries" section of the image source documentation](../sources/image.md#private-image-registries) + +### Upload source + +For using the bundle with an [upload source](../sources/upload.md), follow the below steps: + +1. Download the `rukpakctl` CLI tool +```bash +go install github.com/operator-framework/rukpak/cmd/rukpakctl +``` + +2. Ensure RukPak is running. For more info on how to install RukPak on your cluster see the [Installation section of the README](../../README.md#installation) + +3. Use `rukpakctl` to create a `BundleDeployment` using the `manifests/` directory +```bash +rukpakctl run . +``` + +### ConfigMap source + +For using the bundle with a [`ConfigMap` source (also known as a local source)](../sources/local.md), follow the below steps: + +1. Ensure RukPak is running. For more info on how to install RukPak on your cluster see the [Installation section of the README](../../README.md#installation) + +2. Create a `ConfigMap` from the `manifests/` directory +```bash +kubectl create configmap my-configmap --from-file=manifests -n rukpak-system +``` diff --git a/docs/concepts/plain-bundle-spec.md b/docs/concepts/plain-bundle-spec.md deleted file mode 100644 index 7c261414..00000000 --- a/docs/concepts/plain-bundle-spec.md +++ /dev/null @@ -1,223 +0,0 @@ -# Plain Bundle Spec - -## Overview - -This document is meant to define the plain bundle format as a reference for those publishing plain bundles for use with -RukPak. A bundle is a collection of Kubernetes resources that are packaged together for the purposes of installing onto -a Kubernetes cluster. A bundle can be unpacked onto a running cluster, where controllers can then create the underlying -content embedded in the bundle. The bundle can be used as the underlying `spec.source` for -a [Bundle](https://github.com/operator-framework/rukpak#bundle) resource. - -A plain bundle is simply a collection of static, arbitrary, Kubernetes YAML manifests in a given directory. A plain -bundle can consist of a container image, a directory in a git repository, or any other content source that -the [plain bundle provisioner](https://github.com/operator-framework/rukpak/blob/main/internal/provisioner/plain/README.md) -supports. - -The currently implemented plain bundle format is the `plain+v0` format. The name of the bundle format, `plain+v0` -combines the type of bundle (plain) with the current schema version (v0). -The [plain bundle provisioner](https://github.com/operator-framework/rukpak/blob/main/internal/provisioner/plain/README.md) -is able to source `plain+v0` bundles and install them onto a Kubernetes cluster. - -> Note: the plain+v0 bundle format is at schema version v0, which means it's an experimental format that is subject -> to change. - -Supported source types for a plain bundle currently include the following: - -* A container image -* A [directory in a git repository](git-bundles.md) -* A [configmap](local-bundles.md) -* An [upload](uploading-bundles.md) - -Additional source types, such as a local volume or a generic URI-based resource, are on the roadmap. These source types -all present the same content, a directory containing static Kubernetes YAML manifests, in a different ways. - -## Common Terminology - -* `bundle` is a collection of files that define content to be deployed to a cluster -* `bundle image` is a container image that contains a bundle within its filesystem -* `bundle git repo` is a git repository that contains a bundle within a directory - -## Example - -For example, below is a minimal example of a Dockerfile that builds a `plain+v0` bundle image from a directory -containing static Kubernetes manifests. - -```dockerfile -FROM scratch -COPY /manifests /manifests -``` - -where the given `manifests` directory contains the Kubernetes resources required to deploy an application, for example: - -```tree -manifests -├── namespace.yaml -├── cluster_role.yaml -├── role.yaml -├── serviceaccount.yaml -├── cluster_role_binding.yaml -├── role_binding.yaml -└── deployment.yaml -``` - -For a bundle git repo, any directory that contains only static Kubernetes manifests checked into a git repository -accessible via a remote URL can be considered a plain bundle and sourced by the plain provisioner. For more information -on bundles backed by git repositories, see the [git based bundles doc](git-bundles.md). - -> Note: there must be at least one resource in the manifests directory in order for the bundle to be a valid -> plain+v0 bundle. - -## Technical Details - -* The static manifests must be located in the root-level /manifests directory in a bundle image for the bundle to be a - valid `plain+v0` bundle that the provisioner can unpack. A plain bundle image without a /manifests directory is - invalid and will not be successfully unpacked onto the cluster. -* For a bundle git repo, the manifests directory can be anywhere in the repository, not just at the root-level. The - location can be specified via `spec.source.git.directory`. There must be a `manifests` directory at the provided - location in order to have a valid bundle git repo. If a specific directory is not provided, it is assumed to be - ./manifests in a bundle git repo. -* The manifests directory should be flat: all manifests should be at the top-level with no subdirectories. -* The plain bundle image can be built from any base image, but `scratch` is recommended as it keeps the resulting bundle - image a minimal size. -* Including any content in the root `manifests` directory of a plain bundle that is not static manifests will result in - a failure when creating content on-cluster from that bundle via - a [BundleDeployment](https://github.com/operator-framework/rukpak#bundledeployment). Essentially, any file that would not - successfully `kubectl apply` will result in an error, but multi-object YAML files, or JSON files, are fine. There will - be validation tooling provided that can determine whether a given artifact is a valid bundle. - -## Quickstart - -As an example, we can package the [combo operator](https://github.com/operator-framework/combo) into a `plain+v0` bundle -image by taking the following steps: - -1. First let's pull down the combo repository. - -```bash -git clone https://github.com/operator-framework/combo -``` - -2. Let's take a look at the combo manifests directory to make sure it is a valid bundle. - -```bash -$ tree combo/manifests -combo/manifests -├── 00_combo.io_templates_crd.yaml -├── 01_combo.io_combinations_crd.yaml -├── 02_namespace.yaml -├── 03_service_account.yaml -├── 04_cluster_role.yaml -├── 05_cluster_role_binding.yaml -└── 06_deployment.yaml -``` - -This manifests directory is a flattened directory that contains arbitrary Kubernetes manifests and therefore can be -sourced and unpacked by the plain provisioner. Let's package it up as a plain bundle image. - -3. Create a new Dockerfile at the root of the RukPak repository named Dockerfile.example - -```bash -touch Dockerfile.example -``` - -4. Edit the Dockerfile to include the following: - -```bash -cat < Dockerfile.example -FROM scratch -COPY combo/manifests /manifests -EOF -``` - -5. Build the image using a container tool like docker or podman. Use an image tag that references a repository that you - have push access to. For example, - -```bash -docker build -f Dockerfile.example -t quay.io/operator-framework/rukpak:example . -``` - -6. Push the image to the remote registry - -```bash -docker push quay.io/operator-framework/rukpak:example -``` - -7. Make sure rukpak is installed locally on a running cluster. - -```bash -make run -``` - -8. Now that the plain bundle image has been built, it can be referenced in a Bundle and applied to the cluster. - -```bash -kubectl apply -f -<