diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f00bacfed..097ae7286 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,14 +11,8 @@ Before contributing to this repository for the first time, please review our pro ### Issues - Open or search for [issues](https://github.com/devfile/devworkspace-operator/issues). - - If a related issue doesn't exist, you can open a new issue using a relevant [issue form](https://github.com/devfile/devworkspace-operator/issues/new/choose). -### Development - -Detailed instructions regarding project development are found [here](README.md#development). - - ### Pull Requests All commits must be signed off with the footer: @@ -27,10 +21,197 @@ All commits must be signed off with the footer: Signed-off-by: Firstname Lastname ``` -Once you set your user.name and user.email in your git config, you can sign your commit automatically with git commit -s. When you think the code is ready for review, create a pull request and link the issue associated with it. +Once you set your `user.name` and `user.email` in your git config, you can sign your commit automatically with +`git commit -s`. When you think the code is ready for review, create a pull request and link the issue associated with +it. Owners of the repository will watch out for and review new PRs. If comments have been given in a review, they have to be addressed before merging. -After addressing review comments, don’t forget to add a comment in the PR afterward, so everyone gets notified by Github and knows to re-review. \ No newline at end of file +After addressing review comments, don’t forget to add a comment in the PR afterward, so everyone gets notified by Github and knows to re-review. + +## CI + +#### GitHub actions + +- [Next Dockerimage](https://github.com/devfile/devworkspace-operator/blob/main/.github/workflows/dockerimage-next.yml) action builds main branch and pushes it to [quay.io/devfile/devworkspace-controller:next](https://quay.io/repository/devfile/devworkspace-controller?tag=latest&tab=tags) +- [Code Coverage Report](./.github/workflows/code-coverage.yml) action creates a code coverage report using [codecov.io](https://about.codecov.io/). + +## Development + +Detailed instructions regarding the DevWorkspace Operator development are provided in this section. + +### Prerequisites + +To build, test and debug the DevWorkspace Operator the following development tools are required: + +- go 1.16 or later +- git +- sed +- jq +- yq (python-yq from https://github.com/kislyuk/yq#installation, other distributions may not work) +- skopeo (if building the OLM catalogsource) +- podman or docker + +Note: kustomize `v4.0.5` is required for most tasks. It is downloaded automatically to the `.kustomize` folder in this +repo when required. This downloaded version is used regardless of whether or not kustomize is already installed on the +system. + +### Makefile + +The repository contains a `Makefile`; building and deploying can be configured via the environment variables: + +|variable|purpose|default value| +|---|---|---| +| `DWO_IMG` | Image used for controller | `quay.io/devfile/devworkspace-controller:next` | +| `DEFAULT_DWO_IMG` | Image used for controller when generating default deployment templates. Can be used to override the controller image in the OLM bundle | `quay.io/devfile/devworkspace-controller:next` | +| `NAMESPACE` | Namespace to use for deploying controller | `devworkspace-controller` | +| `ROUTING_SUFFIX` | Cluster routing suffix (e.g. `$(minikube ip).nip.io`, `apps-crc.testing`). Required for Kubernetes | `192.168.99.100.nip.io` | +| `PULL_POLICY` | Image pull policy for controller | `Always` | +| `DEVWORKSPACE_API_VERSION` | Branch or tag of the github.com/devfile/api to depend on | `v1alpha1` | + +Some of the rules supported by the `Makefile`: + +|rule|purpose| +|---|---| +| docker | build and push docker image | +| install | install controller to cluster | +| restart | restart cluster controller deployment | +| install_cert_manager | installs the cert-manager to the cluster (only required for Kubernetes) | +| uninstall | delete controller namespace `devworkspace-controller` and remove CRDs from cluster | +| help | print all rules and variables | + +To see all rules supported by the makefile, run `make help` + +### DevWorkspace Operator first time development setup + +1. Fork [devfile/devworkspce-operator](https://github.com/devfile/devworkspace-operator) and clone your fork locally +2. Export the `DWO_IMG` environment variable. For example: + ```bash + export DWO_IMG=quay.io/mloriedo/devworkspace-controller:dev + ``` + :warning: _You need write privileges on this container registry repository. The DevWorkspace controller image will be +pushed there during build._ +3. If your changes include some update to the Devfile or DevWorkspace schema set some environment variables and run +`go mod` to point to your fork instead of devfile/api: + ```bash + export DEVFILE_API_REPO=github.com/l0rd/api # <== your devfile/api fork + export DEVFILE_API_BRANCH=my-branch-name # <== the branch of your fork + export DEVWORKSPACE_API_VERSION=$(git ls-remote https://${DEVFILE_API_REPO} | grep refs/heads/${DEVFILE_API_BRANCH} | cut -f 1) + go mod edit -replace github.com/devfile/api/v2=${DEVFILE_API_REPO}/v2@${DEVWORKSPACE_API_VERSION} && \ + go mod download && \ + go mod tidy + ``` +4. Build the controller go code, build the container image and publish it to the container registry: + ```bash + make docker + ``` +5. Install cert-manager (can be skipped on OpenShift): + ```bash + make install_cert_manager && \ + kubectl wait --for=condition=Available -n cert-manager deployment/cert-manager + ``` +6. Finally deploys the CRDs and the controller to the current cluster: + ``` + make install # <== this command copies the CRDs definition + # creates the namespace for the controller in the cluster + # downloads and runs kustomize to build the manifests + # deploys all the manifests (CRDs and controller) + ``` + +### Test run controller + +1. Take a look samples devworkspace configuration in `./samples` folder. +2. Apply any of them by executing `kubectl apply -f ./samples/code-latest.yaml -n ` +3. As soon as devworkspace is started you're able to get IDE url by executing `kubectl get devworkspace -n ` + +### Run controller locally + +```bash +export NAMESPACE="devworkspace-controller" +make install +# Wait for webhook server to start +kubectl rollout status deployment devworkspace-controller-manager -n $NAMESPACE --timeout 90s +kubectl rollout status deployment devworkspace-webhook-server -n $NAMESPACE --timeout 90s +# Scale on-cluster deployment to zero to avoid conflict with locally-running instance +oc patch deployment/devworkspace-controller-manager --patch "{\"spec\":{\"replicas\":0}}" -n $NAMESPACE +make run +``` + +> Note: The operator requires internet access from containers to work. By default, `crc setup` may not provision this, so it's necessary to configure DNS for Docker: +> ``` +> # /etc/docker/daemon.json +> { +> "dns": ["192.168.0.1"] +> } +> ``` + +By default, the controller will expose workspace servers without any authentication; this is not advisable for public +clusters, as any user could access the created workspace via URL. + +### Run controller locally and debug + +Debugging the controller depends on [delve](https://github.com/go-delve/delve) being installed +(`go install github.com/go-delve/delve/cmd/dlv@latest`). Note that `$GOPATH/bin` or `$GOBIN` must be added to `$PATH` in +order for `make debug` to run correctly. + +```bash +make install +# Wait for webhook server to start +kubectl rollout status deployment devworkspace-controller-manager -n $NAMESPACE --timeout 90s +kubectl rollout status deployment devworkspace-webhook-server -n $NAMESPACE --timeout 90s +oc patch deployment/devworkspace-controller-manager --patch "{\"spec\":{\"replicas\":0}}" +# Scale on-cluster deployment to zero to avoid conflict with locally-running instance +make debug +``` + +### Run webhook server locally and debug + +Debugging the webhook server depends on `telepresence` being installed (`https://www.telepresence.io/docs/latest/install/`). Teleprescence works by redirecting traffic going from the webhook-server in the cluster to the local webhook-server you will be running on your computer. + +```bash +make debug-webhook-server +``` + +when you are done debugging you have to manually uninstall the telepresence agent + +```bash +make disconnect-debug-webhook-server +``` + +### Updating devfile API + +[devfile API](https://github.com/devfile/api) is the Kube-native API for cloud development workspaces specification and the core dependency of the devworkspace-operator that should be regularly updated to the latest version. In order to do the update: + +1. update `DEVWORKSPACE_API_VERSION` variable in the `Makefile` and `build/scripts/generate_deployment.sh`. The variable should correspond to the commit SHA from the [devfile API](https://github.com/devfile/api) repository +2. run the following scripts and the open pull request + +```bash +make update_devworkspace_api update_devworkspace_crds # first commit +make generate_all # second commit +``` +Example of the devfile API update [PR](https://github.com/devfile/devworkspace-operator/pull/797) + +### Remove controller from your K8s/OS Cluster +To uninstall the controller and associated CRDs, use the Makefile uninstall rule: +```bash +make uninstall +``` +This will delete all custom resource definitions created for the controller, as well as the `devworkspace-controller` namespace. + +### Build a custom OLM bundle + +In order to build a custom bundle, the following environment variables should be set: +| variable | purpose | default value | +|---|---|---| +| `DWO_BUNDLE_IMG` | Image used for Operator bundle image | `quay.io/devfile/devworkspace-operator-bundle:next` | +| `DWO_INDEX_IMG` | Image used for Operator index image | `quay.io/devfile/devworkspace-operator-index:next` | +| `DEFAULT_DWO_IMG` | Image used for controller when generating defaults | `quay.io/devfile/devworkspace-controller:next` | + +To build the index image and register its catalogsource to the cluster, run +``` +make generate_olm_bundle_yaml build_bundle_and_index register_catalogsource +``` + +Note that setting `DEFAULT_DWO_IMG` while generating sources will result in local changes to the repo which should be `git restored` before committing. This can also be done by unsetting the `DEFAULT_DWO_IMG` env var and re-running `make generate_olm_bundle_yaml` diff --git a/README.md b/README.md index 65fb76e4c..d3d851281 100644 --- a/README.md +++ b/README.md @@ -1,104 +1,80 @@ -# Dev Workspace Operator +

DevWorkspace operator

+ +# DevWorkspace Operator [![codecov](https://codecov.io/gh/devfile/devworkspace-operator/branch/main/graph/badge.svg)](https://codecov.io/gh/devfile/devworkspace-operator) [![OpenSSF Best Practices](https://www.bestpractices.dev/projects/8258/badge)](https://www.bestpractices.dev/projects/8258) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/devfile/devworkspace-operator/badge)](https://securityscorecards.dev/viewer/?uri=github.com/devfile/devworkspace-operator) -Dev Workspace operator repository that contains the controller for the DevWorkspace Custom Resource. The Kubernetes API of the DevWorkspace is defined in the https://github.com/devfile/api repository. +DevWorkspace operator repository that contains the controller for the DevWorkspace Custom Resource. The Kubernetes API of the DevWorkspace is defined in the https://github.com/devfile/api repository. -## Configuration +## What is the DevWorkspace Operator? -### Global configuration for the DevWorkspace Operator +A [Kubernetes Operator](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/) to run **fast**, **repeatable** +and **scalable** Cloud Development Environments. -The DevWorkspace Operator installs the DevWorkspaceOperatorConfig custom resource (short name: `dwoc`). To configure global behavior of the DevWorkspace Operator, create a DevWorkspaceOperatorConfig named `devworkspace-operator-config` in the same namespace where the operator is deployed: -```yaml -apiVersion: controller.devfile.io/v1alpha1 -kind: DevWorkspaceOperatorConfig -metadata: - name: devworkspace-operator-config - namespace: $OPERATOR_INSTALL_NAMESPACE -config: - # Configuration fields -``` +[Install it](#devworkspace-operator-installation) and apply a DevWorkspace to create a Cloud Development Environment:
+![dw apply demo](img/apply-demo.gif) -To apply a configuration to specific workspaces instead of globally, an existing DevWorkspaceOperatorConfig can be referenced in a DevWorkspace's attributes: -```yaml -apiVersion: workspace.devfile.io/v1alpha2 -kind: DevWorkspace -metadata: - name: my-devworkspace -spec: - template: - attributes: - controller.devfile.io/devworkspace-config: - name: - namespace: -``` -Configuration specified as above will be merged into the default global configuration, overriding any values present. +Get the Cloud Developent Environment URI:
+![dw get demo](img/get-demo.gif) -To see all all configuration options, see `kubectl explain dwoc.config`, `kubectl explain dwoc.config.workspace`, etc. +Open the IDE:
+| Visual Studio Code | JetBrains IntelliJ | +| ------------- | ------------- | +| ![vscode](img/vscode.png) | ![intellij](img/intellij.png) | -### Additional configuration +## Example -DevWorkspaces can be further configured through DevWorkspace attributes and Kubernetes labels/annotations. For a list of all options available, see [additional documentation](docs/additional-configuration.adoc). +Here is a sample `DevWorkspace` to provision a Cloud Development Environment for the project +[github.com/l0rd/outyet](https://github.com/l0rd/outyet) with Visual Studio Code as the editor and +`quay.io/devfile/universal-developer-image:ubi8-latest` as the development tooling container image.
-### Restricted Access +![devworkspace](img/devworkspace.png) -The `controller.devfile.io/restricted-access` annotation specifies that a DevWorkspace needs additional access control (in addition to RBAC). When a DevWorkspace is created with the `controller.devfile.io/restricted-access` annotation set to `true`, the webhook server will guarantee -- Only the DevWorkspace Operator ServiceAccount or DevWorkspace creator can modify important fields in the DevWorkspace -- Only the DevWorkspace creator can create `pods/exec` into devworkspace-related containers. +#### DevWorkspace Template -This annotation should be used when a DevWorkspace is expected to contain sensitive information that should be protect above the protection provided by standard RBAC rules (e.g. if the DevWorkspace will store the user's OpenShift token in-memory). +The Template section of a `DevWorkspace` is actually [a Devfile](https://devfile.io/docs/2.3.0/what-is-a-devfile): the +`spec.template` schema matches the [Devfile schema](https://devfile.io/docs/2.3.0/devfile-schema). :warning: A few +`Devfile` APIs are +[not supported yet](https://github.com/devfile/devworkspace-operator/blob/main/docs/unsupported-devfile-api.adoc). -Example: -```yaml -metadata: - annotations: - controller.devfile.io/restricted-access: true -``` +#### DevWorkspace Contributions -## Deploying DevWorkspace Operator +Contributions are extra `Templates` that are added on top of the main `DevWorkspaceTemplate`. Contributions are used to +inject editors such as Visual Studio Code and JetBrains. Contributions are defined as Devfile or DevWorkspace Templates. +Examples are the +[Visual Studio Code devfile](https://eclipse-che.github.io/che-plugin-registry/main/v3/plugins/che-incubator/che-code/latest/devfile.yaml) +and the +[JetBrains IntelliJ devfile](https://eclipse-che.github.io/che-plugin-registry/main/v3/plugins/che-incubator/che-idea/latest/devfile.yaml). -### Prerequisites -- go 1.16 or later -- git -- sed -- jq -- yq (python-yq from https://github.com/kislyuk/yq#installation, other distributions may not work) -- skopeo (if building the OLM catalogsource) -- podman or docker +#### Additional configuration -Note: kustomize `v4.0.5` is required for most tasks. It is downloaded automatically to the `.kustomize` folder in this repo when required. This downloaded version is used regardless of whether or not kustomize is already installed on the system. +DevWorkspaces can be further configured through DevWorkspace `attributes`, `labels` and `annotations`. For a list of all +options available, see [additional documentation](docs/additional-configuration.adoc). -### Running the controller in a cluster +## DevWorkspace Operator Installation -#### With yaml resources +This section describes how to install the Operator on a cluster using the +[Operator Lifecycle Manager (OLM)](https://olm.operatorframework.io). The file [CONTRIBUTING.md](CONTRIBUTING.md) has +instructions to install the Operator, using the `Makefile`, without requiring OLM. -When installing on Kubernetes clusters, the DevWorkspace Operator requires the [cert-manager](https://cert-manager.io) operator in order to properly serve webhooks. To install the latest version of cert-manager in a cluster, the Makefile rule `install_cert_manager` can be used. The minimum version of cert-manager is `v1.0.4`. +#### Installing the Operator Lifecycle Manager -The controller can be deployed to a cluster provided you are logged in with cluster-admin credentials: +The Operator Framework website has +[general instructions to install OLM in your cluster](https://olm.operatorframework.io/docs/getting-started/#installing-olm-in-your-cluster). +On [Minikube](https://minikube.sigs.k8s.io/), OLM is available as +[an addon](https://minikube.sigs.k8s.io/docs/commands/addons/). +OLM is pre-installed on OpenShift. -```bash -export DWO_IMG=quay.io/devfile/devworkspace-controller:next -make install -``` - -By default, the controller will expose workspace servers without any authentication; this is not advisable for public clusters, as any user could access the created workspace via URL. - -See below for all environment variables used in the makefile. +#### Adding the DevWorkspace Operator catalog source -> Note: The operator requires internet access from containers to work. By default, `crc setup` may not provision this, so it's necessary to configure DNS for Docker: -> ``` -> # /etc/docker/daemon.json -> { -> "dns": ["192.168.0.1"] -> } -> ``` +If the DevWorkspace Operator is not already available amongst the `PackageManifests` (use command +`kubectl get packagemanifest -n olm | grep devworkspace` to check it) you should add a `CatalogSource` in the +cluster: -#### With Operator Lifecycle Manager (OLM) - -DevWorkspace Operator has bundle and index images which enable installation via OLM. To enable installing the DevWorkspace Operator through OLM, it may be necessary to create a CatalogSource in the cluster for this index: -```yaml +```bash +kubectl apply -f - <` -3. As soon as devworkspace is started you're able to get IDE url by executing `kubectl get devworkspace -n ` - -### Run controller locally -```bash -export NAMESPACE="devworkspace-controller" -make install -# Wait for webhook server to start -kubectl rollout status deployment devworkspace-controller-manager -n $NAMESPACE --timeout 90s -kubectl rollout status deployment devworkspace-webhook-server -n $NAMESPACE --timeout 90s -# Scale on-cluster deployment to zero to avoid conflict with locally-running instance -oc patch deployment/devworkspace-controller-manager --patch "{\"spec\":{\"replicas\":0}}" -n $NAMESPACE -make run -``` +#### Create the DevWorkspace Operator Subscription -### Run controller locally and debug -Debugging the controller depends on [delve](https://github.com/go-delve/delve) being installed (`go install github.com/go-delve/delve/cmd/dlv@latest`). Note that `$GOPATH/bin` or `$GOBIN` must be added to `$PATH` in order for `make debug` to run correctly. +To install the DevWorkspace Operator, create a OLM Subscription with the following command: ```bash -make install -# Wait for webhook server to start -kubectl rollout status deployment devworkspace-controller-manager -n $NAMESPACE --timeout 90s -kubectl rollout status deployment devworkspace-webhook-server -n $NAMESPACE --timeout 90s -oc patch deployment/devworkspace-controller-manager --patch "{\"spec\":{\"replicas\":0}}" -# Scale on-cluster deployment to zero to avoid conflict with locally-running instance -make debug -``` - -### Run webhook server locally and debug -Debugging the webhook server depends on `telepresence` being installed (`https://www.telepresence.io/docs/latest/install/`). Teleprescence works by redirecting traffic going from the webhook-server in the cluster to the local webhook-server you will be running on your computer. - -```bash -make debug-webhook-server -``` - -when you are done debugging you have to manually uninstall the telepresence agent - -```bash -make disconnect-debug-webhook-server -``` - -### Updating devfile API - -[devfile API](https://github.com/devfile/api) is the Kube-native API for cloud development workspaces specification and the core dependency of the devworkspace-operator that should be regularly updated to the latest version. In order to do the update: - -1. update `DEVWORKSPACE_API_VERSION` variable in the `Makefile` and `build/scripts/generate_deployment.sh`. The variable should correspond to the commit SHA from the [devfile API](https://github.com/devfile/api) repository -2. run the following scripts and the open pull request - -```bash -make update_devworkspace_api update_devworkspace_crds # first commit -make generate_all # second commit -``` -Example of the devfile API update [PR](https://github.com/devfile/devworkspace-operator/pull/797) - -### Controller configuration - -Controller behavior can be configured using the `DevWorkspaceOperatorConfig` custom resource (`dwoc` for short). To configure the controller, create a `DevWorkspaceOperatorConfig` named `devworkspace-operator-config` in the same namespace as the controller. If using the Makefile to deploy the DevWorkspaceOperator, a pre-filled config is created automatically (see `deploy/default-config.yaml`). - -Configuration settings in the `DevWorkspaceOperatorConfig` override default values found in [pkg/config](https://github.com/devfile/devworkspace-operator/tree/main/pkg/config). The only required configuration setting is `.routing.clusterHostSuffix`, which is required when running on Kubernetes. - -To see documentation on configuration settings, including default values, use `kubectl explain` or `oc explain` -- e.g. `kubectl explain dwoc.config.routing.clusterHostSuffix` - -### Remove controller from your K8s/OS Cluster -To uninstall the controller and associated CRDs, use the Makefile uninstall rule: -```bash -make uninstall +kubectl apply -f - < - tolerations: <[]tolerations> - replicas: ----- -**Note:** In order for the `devworkspace-webhook-server` configuration options to take effect: - -- You must place them in the https://github.com/devfile/devworkspace-operator?tab=readme-ov-file#global-configuration-for-the-devworkspace-operator[global DWOC], which has the name `devworkspace-operator-config` and exists in the namespace where the DevWorkspaceOperator is installed. If it does not already exist on the cluster, you must create it. -- You'll need to terminate the `devworkspace-controller-manager` pod so that the replicaset can recreate it. The new pod will update the `devworkspace-webhook-server` deployment. diff --git a/docs/dwo-configuration.md b/docs/dwo-configuration.md new file mode 100644 index 000000000..972016980 --- /dev/null +++ b/docs/dwo-configuration.md @@ -0,0 +1,78 @@ +## DevWorkspace Operator Configuration + +The DevWorkspace Operator installs the `DevWorkspaceOperatorConfig` Custom Resource Definition (short name: `dwoc`). + +### Controller configuration + +A `DevWorkspaceOperatorConfig` Custom Resource defines the behavior of the DevWorkspace Operator Controller. + +To see documentation on configuration settings, including default values, use `kubectl explain` or `oc explain` -- e.g. +`kubectl explain dwoc.config.routing.clusterHostSuffix`. + +**The only required configuration setting is `.routing.clusterHostSuffix`, which is required when running on +Kubernetes.** + +Configuration settings in the `DevWorkspaceOperatorConfig` override default values found in [pkg/config](https://github.com/devfile/devworkspace-operator/tree/main/pkg/config). + +### Global configuration for the DevWorkspace Operator + +To configure global behavior of the DevWorkspace Operator, create a `DevWorkspaceOperatorConfig` named +`devworkspace-operator-config` in the same namespace where the operator is deployed: +```yaml +apiVersion: controller.devfile.io/v1alpha1 +kind: DevWorkspaceOperatorConfig +metadata: + name: devworkspace-operator-config + namespace: $OPERATOR_INSTALL_NAMESPACE +config: + # Configuration fields +``` + +### DevWorkspace specific configuration + +To apply a configuration to a specific `DevWorkspace` instead of globally, an existing `DevWorkspaceOperatorConfig` can +be referenced in a `DevWorkspace`'s attributes: +```yaml +apiVersion: workspace.devfile.io/v1alpha2 +kind: DevWorkspace +metadata: + name: my-devworkspace +spec: + template: + attributes: + controller.devfile.io/devworkspace-config: + name: + namespace: +``` +Configuration specified as above will be merged into the default global configuration, overriding any values present. + +## Configuring the Webhook deployment +The `devworkspace-webhook-server` deployment can be configured in the global `DevWorkspaceOperatorConfig`. +The configuration options include: +[replicas](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#replicas), +[pod tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) and +[nodeSelector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector). + +These configuration options exist in the **global** DWOC's `config.webhook` field: + +```yaml +apiVersion: controller.devfile.io/v1alpha1 +kind: DevWorkspaceOperatorConfig +metadata: +name: devworkspace-operator-config +namespace: $OPERATOR_INSTALL_NAMESPACE +config: +webhook: +nodeSelector: +tolerations: <[]tolerations> +replicas: +``` + +**Note:** In order for the `devworkspace-webhook-server` configuration options to take effect: + +- You must place them in the +[Global configuration for the DevWorkspace Operator](#global-configuration-for-the-devworkspace-operator), which has the +name `devworkspace-operator-config` and exists in the namespace where the DevWorkspaceOperator is installed. If it does +not already exist on the cluster, you must create it. +- You'll need to terminate the `devworkspace-controller-manager` pod so that the replicaset can recreate it. The new pod +will update the `devworkspace-webhook-server` deployment. diff --git a/img/apply-demo.gif b/img/apply-demo.gif new file mode 100644 index 000000000..f8c4a2e00 Binary files /dev/null and b/img/apply-demo.gif differ diff --git a/img/devworkspace.png b/img/devworkspace.png new file mode 100644 index 000000000..4c4e0ce8f Binary files /dev/null and b/img/devworkspace.png differ diff --git a/img/get-demo.gif b/img/get-demo.gif new file mode 100644 index 000000000..98e971510 Binary files /dev/null and b/img/get-demo.gif differ diff --git a/img/intellij.png b/img/intellij.png new file mode 100644 index 000000000..cb3dfca97 Binary files /dev/null and b/img/intellij.png differ diff --git a/img/logo.png b/img/logo.png new file mode 100644 index 000000000..00f483d79 Binary files /dev/null and b/img/logo.png differ diff --git a/img/vscode.png b/img/vscode.png new file mode 100644 index 000000000..21428fee8 Binary files /dev/null and b/img/vscode.png differ