Skip to content

Commit b19af06

Browse files
authored
feat(23570): Add controller for workspace backup (#1530)
A new backup controller orchestrates a backup process for workspace PVC. A new configuration option is added to DevWorkspaceOperatorConfig that enables running regular cronjob that is responsible for backup mechanism. The job executes following steps: - Find a workspaces - Finds out that workspace has been recently stopped - Detect a workspace PVC - Execute a job in the same namespace that does the backup Signed-off-by: Ales Raszka <araszka@redhat.com>
1 parent 1a8a0e8 commit b19af06

37 files changed

+2985
-22
lines changed

.github/workflows/next-build.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,17 @@ jobs:
7373
quay.io/devfile/project-clone:sha-${{ steps.git-sha.outputs.sha }}
7474
file: ./project-clone/Dockerfile
7575

76+
- name: Build and push
77+
uses: docker/build-push-action@0a97817b6ade9f46837855d676c4cca3a2471fc9 #v4.2.1
78+
with:
79+
context: ./project-backup
80+
push: true
81+
platforms: linux/amd64, linux/arm64, linux/ppc64le, linux/s390x
82+
tags: |
83+
quay.io/devfile/project-backup:next
84+
quay.io/devfile/project-backup:sha-${{ steps.git-sha.outputs.sha }}
85+
file: ./project-backup/Dockerfile
86+
7687
build-next-olm-imgs:
7788
runs-on: ubuntu-latest
7889
needs: build-next-imgs
@@ -147,6 +158,7 @@ jobs:
147158
export TAG="sha-${{ needs.build-next-imgs.outputs.git-sha }}"
148159
export DEFAULT_DWO_IMG="quay.io/devfile/devworkspace-controller:$TAG"
149160
export PROJECT_CLONE_IMG="quay.io/devfile/project-clone:$TAG"
161+
export PROJECT_BACKUP_IMG="quay.io/devfile/project-backup:$TAG"
150162
151163
# Next builds are not rolled out unless the version is incremented. We want to use semver
152164
# prerelease tags to make sure each new build increments on the previous one, e.g.

.github/workflows/pr.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,6 @@ jobs:
130130
-
131131
name: Check if project-clone dockerimage build is working
132132
run: docker build -f ./project-clone/Dockerfile .
133+
-
134+
name: Check if project-backup containerimage build is working
135+
run: docker build -f ./project-backup/Containerfile project-backup/

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export DWO_IMG ?= quay.io/devfile/devworkspace-controller:next
2626
export DWO_BUNDLE_IMG ?= quay.io/devfile/devworkspace-operator-bundle:next
2727
export DWO_INDEX_IMG ?= quay.io/devfile/devworkspace-operator-index:next
2828
export PROJECT_CLONE_IMG ?= quay.io/devfile/project-clone:next
29+
export PROJECT_BACKUP_IMG ?= quay.io/devfile/project-backup:next
2930
export PULL_POLICY ?= Always
3031
export DEFAULT_ROUTING ?= basic
3132
export KUBECONFIG ?= ${HOME}/.kube/config
@@ -128,6 +129,7 @@ _print_vars:
128129
@echo " DWO_BUNDLE_IMG=$(DWO_BUNDLE_IMG)"
129130
@echo " DWO_INDEX_IMG=$(DWO_INDEX_IMG)"
130131
@echo " PROJECT_CLONE_IMG=$(PROJECT_CLONE_IMG)"
132+
@echo " PROJECT_BACKUP_IMG=$(PROJECT_BACKUP_IMG)"
131133
@echo " PULL_POLICY=$(PULL_POLICY)"
132134
@echo " ROUTING_SUFFIX=$(ROUTING_SUFFIX)"
133135
@echo " DEFAULT_ROUTING=$(DEFAULT_ROUTING)"
@@ -369,6 +371,7 @@ help: Makefile
369371
@echo 'Supported environment variables:'
370372
@echo ' DWO_IMG - Image used for controller'
371373
@echo ' PROJECT_CLONE_IMG - Image used for project-clone init container'
374+
@echo ' PROJECT_BACKUP_IMG - Image used for project-backup workspace backup container'
372375
@echo ' NAMESPACE - Namespace to use for deploying controller'
373376
@echo ' KUBECONFIG - Kubeconfig which should be used for accessing to the cluster. Currently is: $(KUBECONFIG)'
374377
@echo ' ROUTING_SUFFIX - Cluster routing suffix (e.g. $$(minikube ip).nip.io, apps-crc.testing)'

apis/controller/v1alpha1/devworkspaceoperatorconfig_types.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,47 @@ type CleanupCronJobConfig struct {
7272
Schedule string `json:"schedule,omitempty"`
7373
}
7474

75+
type RegistryConfig struct {
76+
// A registry where backup images are stored. Images are stored
77+
// in {path}/${DEVWORKSPACE_NAMESPACE}/${DEVWORKSPACE_NAME}:latest
78+
// +kubebuilder:validation:Required
79+
Path string `json:"path,omitempty"`
80+
// AuthSecret is the name of a Kubernetes secret of
81+
// type kubernetes.io/dockerconfigjson.
82+
// The secret is expected to be in the same namespace the workspace is running in.
83+
// If secret is not found in the workspace namespace, the operator will look for the secret
84+
// in the namespace where the operator is running in.
85+
// as the DevWorkspaceOperatorCongfig.
86+
// The secret must contain "controller.devfile.io/watch-secret=true" label so that it can be
87+
// recognized by the operator.
88+
// +kubebuilder:validation:Optional
89+
AuthSecret string `json:"authSecret,omitempty"`
90+
}
91+
92+
type OrasConfig struct {
93+
// ExtraArgs are additional arguments passed to the oras CLI
94+
// +kubebuilder:validation:Optional
95+
ExtraArgs string `json:"extraArgs,omitempty"`
96+
}
97+
98+
type BackupCronJobConfig struct {
99+
// Enable determines whether backup CronJobs should be created for workspace PVCs.
100+
// Defaults to false if not specified.
101+
// +kubebuilder:validation:Optional
102+
Enable *bool `json:"enable,omitempty"`
103+
// RegistryConfig defines the registry configuration where backup images are stored.
104+
// +kubebuilder:validation:Required
105+
Registry *RegistryConfig `json:"registry,omitempty"`
106+
// OrasConfig defines additional configuration options for the oras CLI used to
107+
// push and pull backup images.
108+
OrasConfig *OrasConfig `json:"oras,omitempty"`
109+
// Schedule specifies the cron schedule for the backup cron job.
110+
// For example, "0 1 * * *" runs daily at 1 AM.
111+
// +kubebuilder:default:="0 1 * * *"
112+
// +kubebuilder:validation:Optional
113+
Schedule string `json:"schedule,omitempty"`
114+
}
115+
75116
type RoutingConfig struct {
76117
// DefaultRoutingClass specifies the routingClass to be used when a DevWorkspace
77118
// specifies an empty `.spec.routingClass`. Supported routingClasses can be defined
@@ -189,6 +230,8 @@ type WorkspaceConfig struct {
189230
RuntimeClassName *string `json:"runtimeClassName,omitempty"`
190231
// CleanupCronJobConfig defines configuration options for a cron job that automatically cleans up stale DevWorkspaces.
191232
CleanupCronJob *CleanupCronJobConfig `json:"cleanupCronJob,omitempty"`
233+
// BackupCronJobConfig defines configuration options for a cron job that automatically backs up workspace PVCs.
234+
BackupCronJob *BackupCronJobConfig `json:"backupCronJob,omitempty"`
192235
// PostStartTimeout defines the maximum duration the PostStart hook can run
193236
// before it is automatically failed. This timeout is used for the postStart lifecycle hook
194237
// that is used to run commands in the workspace container. The timeout is specified in seconds.
@@ -331,14 +374,26 @@ type ConfigmapReference struct {
331374
Namespace string `json:"namespace"`
332375
}
333376

377+
type OperatorConfigurationStatus struct {
378+
// Conditions represent the latest available observations of the OperatorConfiguration's state
379+
Conditions []metav1.Condition `json:"conditions,omitempty"`
380+
// LastBackupTime is the timestamp of the last successful backup. Nil if
381+
// no backup is configured or no backup has yet succeeded.
382+
LastBackupTime *metav1.Time `json:"lastBackupTime,omitempty"`
383+
}
384+
334385
// DevWorkspaceOperatorConfig is the Schema for the devworkspaceoperatorconfigs API
335386
// +kubebuilder:object:root=true
387+
// +kubebuilder:subresource:status
336388
// +kubebuilder:resource:path=devworkspaceoperatorconfigs,scope=Namespaced,shortName=dwoc
337389
type DevWorkspaceOperatorConfig struct {
338390
metav1.TypeMeta `json:",inline"`
339391
metav1.ObjectMeta `json:"metadata,omitempty"`
340392

341393
Config *OperatorConfiguration `json:"config,omitempty"`
394+
// Status represents the current status of the DevWorkspaceOperatorConfig
395+
// automatically managed by the DevWorkspace Operator.
396+
Status *OperatorConfigurationStatus `json:"status,omitempty"`
342397
}
343398

344399
// DevWorkspaceOperatorConfigList contains a list of DevWorkspaceOperatorConfig

apis/controller/v1alpha1/zz_generated.deepcopy.go

Lines changed: 97 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build/scripts/generate_deployment.sh

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
set -e
3232

3333
# List of environment variables that will be replaced by envsubst
34-
SUBST_VARS='$NAMESPACE $DWO_IMG $PROJECT_CLONE_IMG $ROUTING_SUFFIX $DEFAULT_ROUTING $PULL_POLICY'
34+
SUBST_VARS='$NAMESPACE $DWO_IMG $PROJECT_CLONE_IMG $PROJECT_BACKUP_IMG $ROUTING_SUFFIX $DEFAULT_ROUTING $PULL_POLICY'
3535

3636
SCRIPT_DIR=$(cd "$(dirname "$0")"; pwd)
3737
DEPLOY_DIR="$SCRIPT_DIR/../../deploy/"
@@ -58,6 +58,11 @@ Arguments:
5858
'--use-defaults' is passed; otherwise, the value of the PROJECT_CLONE_IMG
5959
environment variable is used. If unspecifed, the default value of
6060
'quay.io/devfile/project-clone:next' is used.
61+
--project-backup-image
62+
Image to use for the project backup workspace. Used only when
63+
'--use-defaults' is passed; otherwise, the value of the PROJECT_BACKUP_IMG
64+
environment variable is used. If unspecifed, the default value of
65+
'quay.io/devfile/project-backup:next' is used.
6166
--split-yaml
6267
Parse output file combined.yaml into a yaml file for each record
6368
in combined yaml. Files are output to the 'objects' subdirectory
@@ -96,6 +101,10 @@ while [[ "$#" -gt 0 ]]; do
96101
PROJECT_CLONE_IMG=$2
97102
shift
98103
;;
104+
--project-backup-image)
105+
PROJECT_BACKUP_IMG=$2
106+
shift
107+
;;
99108
--split-yamls)
100109
SPLIT_YAMLS=true
101110
;;
@@ -118,6 +127,7 @@ if $USE_DEFAULT_ENV; then
118127
export NAMESPACE=devworkspace-controller
119128
export DWO_IMG=${DEFAULT_DWO_IMG:-"quay.io/devfile/devworkspace-controller:next"}
120129
export PROJECT_CLONE_IMG=${PROJECT_CLONE_IMG:-"quay.io/devfile/project-clone:next"}
130+
export PROJECT_BACKUP_IMG=${PROJECT_BACKUP_IMG:-"quay.io/devfile/project-backup:next"}
121131
export PULL_POLICY=Always
122132
export DEFAULT_ROUTING=basic
123133
export DEVWORKSPACE_API_VERSION=a6ec0a38307b63a29fad2eea945cc69bee97a683

0 commit comments

Comments
 (0)