diff --git a/docs/additional-configuration.md b/docs/additional-configuration.md index 8953cb34a..2f983b656 100644 --- a/docs/additional-configuration.md +++ b/docs/additional-configuration.md @@ -122,6 +122,24 @@ data: Note: As for automatically mounting secrets, it is necessary to apply the `controller.devfile.io/watch-secret` label to git credentials secrets +## Applying labels and annotations to the workspace deployment +In some cases, it is useful to apply additional labels or annotations to the deployment that is created for a DevWorkspace. This is supported by setting attributes `controller.devfile.io/deployment-labels` and `controller.devfile.io/deployment-annotations` in the DevWorkspace's attributes field. The value of these attributes should be specified as a string map, as it is for regular metadata labels and annotations. For example: +``` +kind: DevWorkspace +apiVersion: workspace.devfile.io/v1alpha2 +metadata: + name: my-workspace +spec: + template: + attributes: + controller.devfile.io/deployment-labels: + my-label: foo + my-other-label: bar + controller.devfile.io/deployment-annotations: + my-attribute: foo + my-other-attribute: bar +``` + ## Debugging a failing workspace Normally, when a workspace fails to start, the deployment will be scaled down and the workspace will be stopped in a `Failed` state. This can make it difficult to debug misconfiguration errors, so the annotation `controller.devfile.io/debug-start: "true"` can be applied to DevWorkspaces to leave resources for failed workspaces on the cluster. This allows viewing logs from workspace containers. diff --git a/pkg/constants/attributes.go b/pkg/constants/attributes.go index 9ce5f65fe..42c4092a5 100644 --- a/pkg/constants/attributes.go +++ b/pkg/constants/attributes.go @@ -65,6 +65,14 @@ const ( // will not be cloned into the workspace on start. ProjectCloneAttribute = "controller.devfile.io/project-clone" + // DeployLabelsAttribute is an DevWorkspace attribute used in .spec.attributes that defines additional labels + // that should be applied to the workspace deployment. Value should be a map[string]string + DeployLabelsAttribute = "controller.devfile.io/deployment-labels" + + // DeployAnnotationsAttribute is an DevWorkspace attribute used in .spec.attributes that defines additional annotations + // that should be applied to the workspace deployment. Value should be a map[string]string + DeployAnnotationsAttribute = "controller.devfile.io/deployment-annotations" + // PluginSourceAttribute is an attribute added to components, commands, and projects in a flattened // DevWorkspace representation to signify where the respective component came from (i.e. which plugin // or parent imported it) diff --git a/pkg/provision/workspace/deployment.go b/pkg/provision/workspace/deployment.go index eaaba76e6..1b2c30cf6 100644 --- a/pkg/provision/workspace/deployment.go +++ b/pkg/provision/workspace/deployment.go @@ -235,14 +235,19 @@ func getSpecDeployment( podAdditions.InitContainers[idx].VolumeMounts = append(podAdditions.InitContainers[idx].VolumeMounts, podAdditions.VolumeMounts...) } + labels, annotations, err := getAdditionalLabelsAndAttributes(workspace) + if err != nil { + return nil, err + } + labels[constants.DevWorkspaceIDLabel] = workspace.Status.DevWorkspaceId + labels[constants.DevWorkspaceNameLabel] = workspace.Name + deployment := &appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ - Name: common.DeploymentName(workspace.Status.DevWorkspaceId), - Namespace: workspace.Namespace, - Labels: map[string]string{ - constants.DevWorkspaceIDLabel: workspace.Status.DevWorkspaceId, - constants.DevWorkspaceNameLabel: workspace.Name, - }, + Name: common.DeploymentName(workspace.Status.DevWorkspaceId), + Namespace: workspace.Namespace, + Labels: labels, + Annotations: annotations, }, Spec: appsv1.DeploymentSpec{ Replicas: &replicas, @@ -501,3 +506,22 @@ func checkIfUnrecoverableEventIgnored(reason string) (ignored bool) { } return false } + +// getAdditionalLabelsAndAttributes reads attributes on the DevWorkspace and returns the additional labels and +// attributes that should be applied to the DevWorkspace. Returns an error if attributes cannot be deserialized +// into a map[string]string. If attributes are not defined, returns an empty map. +func getAdditionalLabelsAndAttributes(workspace *dw.DevWorkspace) (labels, annotations map[string]string, err error) { + labels = map[string]string{} + annotations = map[string]string{} + if workspace.Spec.Template.Attributes.Exists(constants.DeployLabelsAttribute) { + if err := workspace.Spec.Template.Attributes.GetInto(constants.DeployLabelsAttribute, &labels); err != nil { + return nil, nil, fmt.Errorf("failed to process %s attribute: %w", constants.DeployLabelsAttribute, err) + } + } + if workspace.Spec.Template.Attributes.Exists(constants.DeployAnnotationsAttribute) { + if err := workspace.Spec.Template.Attributes.GetInto(constants.DeployAnnotationsAttribute, &annotations); err != nil { + return nil, nil, fmt.Errorf("failed to process %s attribute: %w", constants.DeployAnnotationsAttribute, err) + } + } + return labels, annotations, nil +}