Skip to content

Commit 020af58

Browse files
committed
Use wsprovision as alias for provision/workspace throughout code
This is a really annoying change to make, since 1. VS Code will remove "unused" imports and reimport the unaliased package name on save, *even* if you use find-replace 2. Goland will let you refactor the import alias, but will basically find-replace throughout the file to do so, meaning that "workspace" gets replaced with "wsprovision" *in comments*. Signed-off-by: Angel Misevski <[email protected]>
1 parent 4f4af21 commit 020af58

13 files changed

+36
-36
lines changed

pkg/provision/config/config.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import (
2121
"sigs.k8s.io/controller-runtime/pkg/client"
2222

2323
"github.com/devfile/devworkspace-operator/pkg/constants"
24-
"github.com/devfile/devworkspace-operator/pkg/provision/workspace"
24+
wsprovision "github.com/devfile/devworkspace-operator/pkg/provision/workspace"
2525
)
2626

2727
const (
@@ -35,7 +35,7 @@ type NamespacedConfig struct {
3535
// ReadNamespacedConfig reads the per-namespace DevWorkspace configmap and returns it as a struct. If there are
3636
// no valid configmaps in the specified namespace, returns (nil, nil). If there are multiple configmaps with the
3737
// per-namespace configmap label, returns an error.
38-
func ReadNamespacedConfig(namespace string, api workspace.ClusterAPI) (*NamespacedConfig, error) {
38+
func ReadNamespacedConfig(namespace string, api wsprovision.ClusterAPI) (*NamespacedConfig, error) {
3939
cmList := &corev1.ConfigMapList{}
4040
labelSelector, err := labels.Parse(fmt.Sprintf("%s=true", constants.NamespacedConfigLabelKey))
4141
if err != nil {

pkg/provision/metadata/metadata.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import (
2828
maputils "github.com/devfile/devworkspace-operator/internal/map"
2929
"github.com/devfile/devworkspace-operator/pkg/common"
3030
"github.com/devfile/devworkspace-operator/pkg/constants"
31-
"github.com/devfile/devworkspace-operator/pkg/provision/workspace"
31+
wsprovision "github.com/devfile/devworkspace-operator/pkg/provision/workspace"
3232
)
3333

3434
const (
@@ -46,7 +46,7 @@ const (
4646
// ProvisionWorkspaceMetadata creates a configmap on the cluster that stores metadata about the workspace and configures all
4747
// workspace containers to mount that configmap at /devworkspace-metadata. Each container has the environment
4848
// variable DEVWORKSPACE_METADATA set to the mount path for the configmap
49-
func ProvisionWorkspaceMetadata(podAdditions *v1alpha1.PodAdditions, original, flattened *dw.DevWorkspace, api *workspace.ClusterAPI) error {
49+
func ProvisionWorkspaceMetadata(podAdditions *v1alpha1.PodAdditions, original, flattened *dw.DevWorkspace, api *wsprovision.ClusterAPI) error {
5050
cm, err := getSpecMetadataConfigMap(original, flattened)
5151
if err != nil {
5252
return err
@@ -79,7 +79,7 @@ func ProvisionWorkspaceMetadata(podAdditions *v1alpha1.PodAdditions, original, f
7979
return nil
8080
}
8181

82-
func syncConfigMapToCluster(specCM *corev1.ConfigMap, api *workspace.ClusterAPI) (inSync bool, err error) {
82+
func syncConfigMapToCluster(specCM *corev1.ConfigMap, api *wsprovision.ClusterAPI) (inSync bool, err error) {
8383
clusterCM := &corev1.ConfigMap{}
8484
err = api.Client.Get(context.TODO(), types.NamespacedName{Name: specCM.Name, Namespace: specCM.Namespace}, clusterCM)
8585

pkg/provision/storage/asyncStorage.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import (
2828
"github.com/devfile/devworkspace-operator/pkg/constants"
2929
devfileConstants "github.com/devfile/devworkspace-operator/pkg/library/constants"
3030
"github.com/devfile/devworkspace-operator/pkg/provision/storage/asyncstorage"
31-
"github.com/devfile/devworkspace-operator/pkg/provision/workspace"
31+
wsprovision "github.com/devfile/devworkspace-operator/pkg/provision/workspace"
3232
)
3333

3434
// The AsyncStorageProvisioner provisions one PVC per namespace and creates an ssh deployment that syncs data into that PVC.
@@ -42,7 +42,7 @@ func (*AsyncStorageProvisioner) NeedsStorage(workspace *dw.DevWorkspaceTemplateS
4242
return needsStorage(workspace)
4343
}
4444

45-
func (p *AsyncStorageProvisioner) ProvisionStorage(podAdditions *v1alpha1.PodAdditions, workspace *dw.DevWorkspace, clusterAPI workspace.ClusterAPI) error {
45+
func (p *AsyncStorageProvisioner) ProvisionStorage(podAdditions *v1alpha1.PodAdditions, workspace *dw.DevWorkspace, clusterAPI wsprovision.ClusterAPI) error {
4646
if err := checkConfigured(); err != nil {
4747
return &ProvisioningError{
4848
Message: fmt.Sprintf("%s. Contact an administrator to resolve this issue.", err.Error()),
@@ -141,7 +141,7 @@ func (p *AsyncStorageProvisioner) ProvisionStorage(podAdditions *v1alpha1.PodAdd
141141
return nil
142142
}
143143

144-
func (p *AsyncStorageProvisioner) CleanupWorkspaceStorage(workspace *dw.DevWorkspace, clusterAPI workspace.ClusterAPI) error {
144+
func (p *AsyncStorageProvisioner) CleanupWorkspaceStorage(workspace *dw.DevWorkspace, clusterAPI wsprovision.ClusterAPI) error {
145145
// TODO: This approach relies on there being a maximum of one workspace running per namespace.
146146
asyncDeploy, err := asyncstorage.GetWorkspaceSyncDeploymentCluster(workspace.Namespace, clusterAPI)
147147
if err != nil {
@@ -240,7 +240,7 @@ func (*AsyncStorageProvisioner) addVolumesForAsyncStorage(podAdditions *v1alpha1
240240
// getAsyncWorkspaceCount returns whether the async storage provider can support starting a workspace.
241241
// Due to how cleanup for the async storage PVC is implemented, only one workspace that uses the async storage
242242
// type can be running at a time.
243-
func (*AsyncStorageProvisioner) getAsyncWorkspaceCount(api workspace.ClusterAPI) (started, total int, err error) {
243+
func (*AsyncStorageProvisioner) getAsyncWorkspaceCount(api wsprovision.ClusterAPI) (started, total int, err error) {
244244
workspaces := &dw.DevWorkspaceList{}
245245
err = api.Client.List(api.Ctx, workspaces)
246246
if err != nil {

pkg/provision/storage/asyncstorage/configmap.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import (
2020
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2121
"k8s.io/apimachinery/pkg/types"
2222

23-
"github.com/devfile/devworkspace-operator/pkg/provision/workspace"
23+
wsprovision "github.com/devfile/devworkspace-operator/pkg/provision/workspace"
2424
)
2525

2626
const (
@@ -45,7 +45,7 @@ func getSSHAuthorizedKeysConfigMapSpec(namespace string, authorizedKeys []byte)
4545
return cm
4646
}
4747

48-
func getSSHAuthorizedKeysConfigMapCluster(namespace string, clusterAPI workspace.ClusterAPI) (*corev1.ConfigMap, error) {
48+
func getSSHAuthorizedKeysConfigMapCluster(namespace string, clusterAPI wsprovision.ClusterAPI) (*corev1.ConfigMap, error) {
4949
cm := &corev1.ConfigMap{}
5050
namespaceName := types.NamespacedName{
5151
Name: sshAuthorizedKeysConfigMapName,

pkg/provision/storage/asyncstorage/configuration.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import (
1818
k8sErrors "k8s.io/apimachinery/pkg/api/errors"
1919
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
2020

21-
"github.com/devfile/devworkspace-operator/pkg/provision/workspace"
21+
wsprovision "github.com/devfile/devworkspace-operator/pkg/provision/workspace"
2222
)
2323

2424
// GetOrCreateSSHConfig returns the secret and configmap used for the asynchronous deployment. The Secret is generated per-workspace
@@ -34,7 +34,7 @@ import (
3434
// In both cases, if the ConfigMap does not exist, it is created.
3535
//
3636
// Returns NotReadyError if changes were made to the cluster.
37-
func GetOrCreateSSHConfig(workspace *dw.DevWorkspace, clusterAPI workspace.ClusterAPI) (*corev1.Secret, *corev1.ConfigMap, error) {
37+
func GetOrCreateSSHConfig(workspace *dw.DevWorkspace, clusterAPI wsprovision.ClusterAPI) (*corev1.Secret, *corev1.ConfigMap, error) {
3838
var pubKey []byte
3939
clusterSecret, err := getSSHSidecarSecretCluster(workspace, clusterAPI)
4040
if err != nil {

pkg/provision/storage/asyncstorage/deployment.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ import (
2323
"sigs.k8s.io/controller-runtime/pkg/client"
2424

2525
"github.com/devfile/devworkspace-operator/internal/images"
26-
"github.com/devfile/devworkspace-operator/pkg/provision/workspace"
26+
wsprovision "github.com/devfile/devworkspace-operator/pkg/provision/workspace"
2727
)
2828

29-
func SyncWorkspaceSyncDeploymentToCluster(namespace string, sshConfigMap *corev1.ConfigMap, storage *corev1.PersistentVolumeClaim, clusterAPI workspace.ClusterAPI) (*appsv1.Deployment, error) {
29+
func SyncWorkspaceSyncDeploymentToCluster(namespace string, sshConfigMap *corev1.ConfigMap, storage *corev1.PersistentVolumeClaim, clusterAPI wsprovision.ClusterAPI) (*appsv1.Deployment, error) {
3030
specDeployment := getWorkspaceSyncDeploymentSpec(namespace, sshConfigMap, storage)
3131
clusterDeployment, err := GetWorkspaceSyncDeploymentCluster(namespace, clusterAPI)
3232
if err != nil {
@@ -139,7 +139,7 @@ func getWorkspaceSyncDeploymentSpec(namespace string, sshConfigMap *corev1.Confi
139139
},
140140
},
141141
TerminationGracePeriodSeconds: &terminationGracePeriod,
142-
SecurityContext: workspace.GetDevWorkspaceSecurityContext(),
142+
SecurityContext: wsprovision.GetDevWorkspaceSecurityContext(),
143143
AutomountServiceAccountToken: nil,
144144
},
145145
},
@@ -148,7 +148,7 @@ func getWorkspaceSyncDeploymentSpec(namespace string, sshConfigMap *corev1.Confi
148148
return deployment
149149
}
150150

151-
func GetWorkspaceSyncDeploymentCluster(namespace string, clusterAPI workspace.ClusterAPI) (*appsv1.Deployment, error) {
151+
func GetWorkspaceSyncDeploymentCluster(namespace string, clusterAPI wsprovision.ClusterAPI) (*appsv1.Deployment, error) {
152152
deploy := &appsv1.Deployment{}
153153
namespacedName := types.NamespacedName{
154154
Name: "async-storage", // TODO

pkg/provision/storage/asyncstorage/secret.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import (
2020
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2121
"k8s.io/apimachinery/pkg/types"
2222

23-
"github.com/devfile/devworkspace-operator/pkg/provision/workspace"
23+
wsprovision "github.com/devfile/devworkspace-operator/pkg/provision/workspace"
2424
)
2525

2626
const (
@@ -50,7 +50,7 @@ func getSSHSidecarSecretSpec(workspace *dw.DevWorkspace, privateKey []byte) *cor
5050
return secret
5151
}
5252

53-
func getSSHSidecarSecretCluster(workspace *dw.DevWorkspace, clusterAPI workspace.ClusterAPI) (*corev1.Secret, error) {
53+
func getSSHSidecarSecretCluster(workspace *dw.DevWorkspace, clusterAPI wsprovision.ClusterAPI) (*corev1.Secret, error) {
5454
secret := &corev1.Secret{}
5555
namespacedName := types.NamespacedName{
5656
Name: GetSSHSidecarSecretName(workspace.Status.DevWorkspaceId),

pkg/provision/storage/asyncstorage/service.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ import (
2222
"k8s.io/apimachinery/pkg/util/intstr"
2323
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
2424

25-
"github.com/devfile/devworkspace-operator/pkg/provision/workspace"
25+
wsprovision "github.com/devfile/devworkspace-operator/pkg/provision/workspace"
2626
)
2727

28-
func SyncWorkspaceSyncServiceToCluster(asyncDeploy *appsv1.Deployment, api workspace.ClusterAPI) (*corev1.Service, error) {
28+
func SyncWorkspaceSyncServiceToCluster(asyncDeploy *appsv1.Deployment, api wsprovision.ClusterAPI) (*corev1.Service, error) {
2929
specService := getWorkspaceSyncServiceSpec(asyncDeploy)
3030
err := controllerutil.SetOwnerReference(asyncDeploy, specService, api.Scheme)
3131
if err != nil {
@@ -78,7 +78,7 @@ func getWorkspaceSyncServiceSpec(asyncDeploy *appsv1.Deployment) *corev1.Service
7878
}
7979
}
8080

81-
func getWorkspaceSyncServiceCluster(namespace string, api workspace.ClusterAPI) (*corev1.Service, error) {
81+
func getWorkspaceSyncServiceCluster(namespace string, api wsprovision.ClusterAPI) (*corev1.Service, error) {
8282
service := &corev1.Service{}
8383
namespacedName := types.NamespacedName{
8484
Name: asyncServerServiceName,

pkg/provision/storage/commonStorage.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import (
2323
"github.com/devfile/devworkspace-operator/pkg/config"
2424
"github.com/devfile/devworkspace-operator/pkg/constants"
2525
devfileConstants "github.com/devfile/devworkspace-operator/pkg/library/constants"
26-
"github.com/devfile/devworkspace-operator/pkg/provision/workspace"
26+
wsprovision "github.com/devfile/devworkspace-operator/pkg/provision/workspace"
2727
)
2828

2929
// The CommonStorageProvisioner provisions one PVC per namespace and configures all volumes in a workspace
@@ -36,7 +36,7 @@ func (*CommonStorageProvisioner) NeedsStorage(workspace *dw.DevWorkspaceTemplate
3636
return needsStorage(workspace)
3737
}
3838

39-
func (p *CommonStorageProvisioner) ProvisionStorage(podAdditions *v1alpha1.PodAdditions, workspace *dw.DevWorkspace, clusterAPI workspace.ClusterAPI) error {
39+
func (p *CommonStorageProvisioner) ProvisionStorage(podAdditions *v1alpha1.PodAdditions, workspace *dw.DevWorkspace, clusterAPI wsprovision.ClusterAPI) error {
4040
// Add ephemeral volumes
4141
if err := addEphemeralVolumesFromWorkspace(workspace, podAdditions); err != nil {
4242
return err
@@ -60,7 +60,7 @@ func (p *CommonStorageProvisioner) ProvisionStorage(podAdditions *v1alpha1.PodAd
6060
return nil
6161
}
6262

63-
func (*CommonStorageProvisioner) CleanupWorkspaceStorage(workspace *dw.DevWorkspace, clusterAPI workspace.ClusterAPI) error {
63+
func (*CommonStorageProvisioner) CleanupWorkspaceStorage(workspace *dw.DevWorkspace, clusterAPI wsprovision.ClusterAPI) error {
6464
return runCommonPVCCleanupJob(workspace, clusterAPI)
6565
}
6666

pkg/provision/storage/commonStorage_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import (
3232

3333
"github.com/devfile/devworkspace-operator/apis/controller/v1alpha1"
3434
"github.com/devfile/devworkspace-operator/pkg/config"
35-
"github.com/devfile/devworkspace-operator/pkg/provision/workspace"
35+
wsprovision "github.com/devfile/devworkspace-operator/pkg/provision/workspace"
3636
)
3737

3838
var scheme = runtime.NewScheme()
@@ -106,7 +106,7 @@ func TestRewriteContainerVolumeMountsForCommonStorageClass(t *testing.T) {
106106
t.Fatalf("Failure during setup: %s", err)
107107
}
108108
commonPVC.Status.Phase = corev1.ClaimBound
109-
clusterAPI := workspace.ClusterAPI{
109+
clusterAPI := wsprovision.ClusterAPI{
110110
Client: fake.NewFakeClientWithScheme(scheme, commonPVC),
111111
Logger: zap.New(),
112112
}

pkg/provision/storage/ephemeralStorage.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import (
1717

1818
"github.com/devfile/devworkspace-operator/apis/controller/v1alpha1"
1919
"github.com/devfile/devworkspace-operator/pkg/library/container"
20-
"github.com/devfile/devworkspace-operator/pkg/provision/workspace"
20+
wsprovision "github.com/devfile/devworkspace-operator/pkg/provision/workspace"
2121
)
2222

2323
// The EphemeralStorageProvisioner provisions all workspace storage as emptyDir volumes.
@@ -32,7 +32,7 @@ func (e EphemeralStorageProvisioner) NeedsStorage(_ *dw.DevWorkspaceTemplateSpec
3232
return false
3333
}
3434

35-
func (e EphemeralStorageProvisioner) ProvisionStorage(podAdditions *v1alpha1.PodAdditions, workspace *dw.DevWorkspace, _ workspace.ClusterAPI) error {
35+
func (e EphemeralStorageProvisioner) ProvisionStorage(podAdditions *v1alpha1.PodAdditions, workspace *dw.DevWorkspace, _ wsprovision.ClusterAPI) error {
3636
persistent, ephemeral, projects := getWorkspaceVolumes(workspace)
3737
if _, err := addEphemeralVolumesToPodAdditions(podAdditions, persistent); err != nil {
3838
return err
@@ -56,6 +56,6 @@ func (e EphemeralStorageProvisioner) ProvisionStorage(podAdditions *v1alpha1.Pod
5656
return nil
5757
}
5858

59-
func (e EphemeralStorageProvisioner) CleanupWorkspaceStorage(_ *dw.DevWorkspace, _ workspace.ClusterAPI) error {
59+
func (e EphemeralStorageProvisioner) CleanupWorkspaceStorage(_ *dw.DevWorkspace, _ wsprovision.ClusterAPI) error {
6060
return nil
6161
}

pkg/provision/storage/provisioner.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import (
1717

1818
"github.com/devfile/devworkspace-operator/apis/controller/v1alpha1"
1919
"github.com/devfile/devworkspace-operator/pkg/constants"
20-
"github.com/devfile/devworkspace-operator/pkg/provision/workspace"
20+
wsprovision "github.com/devfile/devworkspace-operator/pkg/provision/workspace"
2121
)
2222

2323
// Provisioner is an interface for rewriting volumeMounts in a pod according to a storage policy (e.g. common PVC for all mounts, etc.)
@@ -26,14 +26,14 @@ type Provisioner interface {
2626
// out-of-pod required objects to the cluster.
2727
// Returns NotReadyError to signify that storage is not ready, ProvisioningError when a fatal issue is encountered,
2828
// and other error if there is an unexpected problem.
29-
ProvisionStorage(podAdditions *v1alpha1.PodAdditions, workspace *dw.DevWorkspace, clusterAPI workspace.ClusterAPI) error
29+
ProvisionStorage(podAdditions *v1alpha1.PodAdditions, workspace *dw.DevWorkspace, clusterAPI wsprovision.ClusterAPI) error
3030
// NeedsStorage returns whether the current workspace needs a PVC to be provisioned, given this storage strategy.
3131
NeedsStorage(workspace *dw.DevWorkspaceTemplateSpec) bool
3232
// CleanupWorkspaceStorage removes any objects provisioned by in the ProvisionStorage step that aren't automatically removed when a
3333
// DevWorkspace is deleted (e.g. delete subfolders in a common PVC assigned to the workspace)
3434
// Returns nil on success (DevWorkspace can be deleted), NotReadyError if additional reconciles are necessary, ProvisioningError when
3535
// a fatal issue is encountered, and any other error if an unexpected problem arises.
36-
CleanupWorkspaceStorage(workspace *dw.DevWorkspace, clusterAPI workspace.ClusterAPI) error
36+
CleanupWorkspaceStorage(workspace *dw.DevWorkspace, clusterAPI wsprovision.ClusterAPI) error
3737
}
3838

3939
// GetProvisioner returns the storage provisioner that should be used for the current workspace

pkg/provision/storage/shared.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import (
2828
devfileConstants "github.com/devfile/devworkspace-operator/pkg/library/constants"
2929
containerlib "github.com/devfile/devworkspace-operator/pkg/library/container"
3030
nsconfig "github.com/devfile/devworkspace-operator/pkg/provision/config"
31-
"github.com/devfile/devworkspace-operator/pkg/provision/workspace"
31+
wsprovision "github.com/devfile/devworkspace-operator/pkg/provision/workspace"
3232
)
3333

3434
func getCommonPVCSpec(namespace string, size string) (*corev1.PersistentVolumeClaim, error) {
@@ -79,7 +79,7 @@ func needsStorage(workspace *dw.DevWorkspaceTemplateSpec) bool {
7979
return containerlib.AnyMountSources(workspace.Components)
8080
}
8181

82-
func syncCommonPVC(namespace string, clusterAPI workspace.ClusterAPI) (*corev1.PersistentVolumeClaim, error) {
82+
func syncCommonPVC(namespace string, clusterAPI wsprovision.ClusterAPI) (*corev1.PersistentVolumeClaim, error) {
8383
namespacedConfig, err := nsconfig.ReadNamespacedConfig(namespace, clusterAPI)
8484
if err != nil {
8585
return nil, fmt.Errorf("failed to read namespace-specific configuration: %w", err)
@@ -93,7 +93,7 @@ func syncCommonPVC(namespace string, clusterAPI workspace.ClusterAPI) (*corev1.P
9393
if err != nil {
9494
return nil, err
9595
}
96-
currObject, requeue, err := workspace.SyncObject(pvc, clusterAPI.Client, clusterAPI.Logger, false)
96+
currObject, requeue, err := wsprovision.SyncObject(pvc, clusterAPI.Client, clusterAPI.Logger, false)
9797
if err != nil {
9898
return nil, err
9999
}

0 commit comments

Comments
 (0)