diff --git a/images/virtualization-artifact/cmd/virtualization-controller/main.go b/images/virtualization-artifact/cmd/virtualization-controller/main.go index 4943bf258..5606b2398 100644 --- a/images/virtualization-artifact/cmd/virtualization-controller/main.go +++ b/images/virtualization-artifact/cmd/virtualization-controller/main.go @@ -37,7 +37,6 @@ import ( metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" "github.com/deckhouse/deckhouse/pkg/log" - "github.com/deckhouse/virtualization-controller/pkg/common" appconfig "github.com/deckhouse/virtualization-controller/pkg/config" "github.com/deckhouse/virtualization-controller/pkg/controller/cvi" "github.com/deckhouse/virtualization-controller/pkg/controller/indexer" @@ -58,13 +57,17 @@ import ( ) const ( - metricsBindAddrEnv = "METRICS_BIND_ADDRESS" - pprofBindAddrEnv = "PPROF_BIND_ADDRESS" - logLevelEnv = "LOG_LEVEL" - logDebugVerbosityEnv = "LOG_DEBUG_VERBOSITY" logDebugControllerListEnv = "LOG_DEBUG_CONTROLLER_LIST" + logDebugVerbosityEnv = "LOG_DEBUG_VERBOSITY" logFormatEnv = "LOG_FORMAT" + logLevelEnv = "LOG_LEVEL" logOutputEnv = "LOG_OUTPUT" + + metricsBindAddrEnv = "METRICS_BIND_ADDRESS" + podNamespaceEnv = "POD_NAMESPACE" + pprofBindAddrEnv = "PPROF_BIND_ADDRESS" + virtualMachineCIDRsEnv = "VIRTUAL_MACHINE_CIDRS" + virtualMachineIPLeasesRetentionDurationEnv = "VIRTUAL_MACHINE_IP_LEASES_RETENTION_DURATION" ) func main() { @@ -109,7 +112,7 @@ func main() { printVersion(log) - controllerNamespace, err := appconfig.GetRequiredEnvVar(common.PodNamespaceVar) + controllerNamespace, err := appconfig.GetRequiredEnvVar(podNamespaceEnv) if err != nil { log.Error(err.Error()) os.Exit(1) @@ -147,7 +150,7 @@ func main() { cfg.ContentType = apiruntime.ContentTypeJSON cfg.NegotiatedSerializer = clientgoscheme.Codecs.WithoutConversion() - leaderElectionNS := os.Getenv(common.PodNamespaceVar) + leaderElectionNS := os.Getenv(podNamespaceEnv) if leaderElectionNS == "" { leaderElectionNS = "default" } @@ -185,14 +188,14 @@ func main() { managerOpts.PprofBindAddress = pprofBindAddr } - vmCIDRsRaw := os.Getenv(common.VirtualMachineCIDRs) + vmCIDRsRaw := os.Getenv(virtualMachineCIDRsEnv) if vmCIDRsRaw == "" { log.Error("Failed to get virtualMachineCIDRs: virtualMachineCIDRs not found, but required") os.Exit(1) } virtualMachineCIDRs := strings.Split(vmCIDRsRaw, ",") - virtualMachineIPLeasesRetentionDuration := os.Getenv(common.VirtualMachineIPLeasesRetentionDuration) + virtualMachineIPLeasesRetentionDuration := os.Getenv(virtualMachineIPLeasesRetentionDurationEnv) if virtualMachineIPLeasesRetentionDuration == "" { log.Info("virtualMachineIPLeasesRetentionDuration not found -> set default value '10m'") virtualMachineIPLeasesRetentionDuration = "10m" diff --git a/images/virtualization-artifact/pkg/common/common.go b/images/virtualization-artifact/pkg/common/common.go index 3e2a01c03..3bfbfe8a5 100644 --- a/images/virtualization-artifact/pkg/common/common.go +++ b/images/virtualization-artifact/pkg/common/common.go @@ -17,19 +17,11 @@ limitations under the License. package common const ( - // PodNamespaceVar is a name of variable with the namespace of the Pod (e.g. Pod with virtualization-controller). - PodNamespaceVar = "POD_NAMESPACE" - // FilesystemOverheadVar provides a constant to capture our env variable "FILESYSTEM_OVERHEAD" FilesystemOverheadVar = "FILESYSTEM_OVERHEAD" // OwnerUID provides the UID of the owner entity (either PVC or DV) OwnerUID = "OWNER_UID" - // KeyAccess provides a constant to the accessKeyId label using in controller pkg and transport_test.go - KeyAccess = "accessKeyId" - // KeySecret provides a constant to the secretKey label using in controller pkg and transport_test.go - KeySecret = "secretKey" - // ImporterContainerName provides a constant to use as a name for importer Container ImporterContainerName = "importer" // UploaderContainerName provides a constant to use as a name for uploader Container @@ -38,14 +30,6 @@ const ( UploaderPortName = "uploader" // UploaderPort provides a constant to use as a port for uploader Service UploaderPort = 80 - // UploaderIngressHostVar is a env variable - UploaderIngressHostVar = "UPLOADER_INGRESS_HOST" - // UploaderIngressTLSSecretVar is a env variable - UploaderIngressTLSSecretVar = "UPLOADER_INGRESS_TLS_SECRET" - // UploaderIngressClassVar is a env variable - UploaderIngressClassVar = "UPLOADER_INGRESS_CLASS" - // UploaderIngressTLSSecretNS is a env variable - UploaderIngressTLSSecretNS = "UPLOADER_INGRESS_TLS_SECRET_NAMESPACE" // ImporterPodImageNameVar is a name of variable with the image name for the importer Pod ImporterPodImageNameVar = "IMPORTER_IMAGE" // UploaderPodImageNameVar is a name of variable with the image name for the uploader Pod @@ -55,20 +39,6 @@ const ( // ImporterProxyCertDir is where the configmap containing proxy certs will be mounted ImporterProxyCertDir = "/proxycerts/" - // QemuSubGid is the gid used as the qemu group in fsGroup - QemuSubGid = int64(107) - - // AppKubernetesPartOfLabel is the Kubernetes recommended part-of label - AppKubernetesPartOfLabel = "app.kubernetes.io/part-of" - // AppKubernetesVersionLabel is the Kubernetes recommended version label - AppKubernetesVersionLabel = "app.kubernetes.io/version" - // AppKubernetesManagedByLabel is the Kubernetes recommended managed-by label - AppKubernetesManagedByLabel = "app.kubernetes.io/managed-by" - // AppKubernetesComponentLabel is the Kubernetes recommended component label - AppKubernetesComponentLabel = "app.kubernetes.io/component" - - // PullPolicy provides a constant to capture our env variable "PULL_POLICY" (only used by cmd/cdi-controller/controller.go) - PullPolicy = "PULL_POLICY" // ImporterSource provides a constant to capture our env variable "IMPORTER_SOURCE" ImporterSource = "IMPORTER_SOURCE" // ImporterContentType provides a constant to capture our env variable "IMPORTER_CONTENTTYPE" @@ -85,10 +55,6 @@ const ( ImporterCertDirVar = "IMPORTER_CERT_DIR" // InsecureTLSVar provides a constant to capture our env variable "INSECURE_TLS" InsecureTLSVar = "INSECURE_TLS" - // CiphersTLSVar provides a constant to capture our env variable "TLS_CIPHERS" - CiphersTLSVar = "TLS_CIPHERS" - // MinVersionTLSVar provides a constant to capture our env variable "TLS_MIN_VERSION" - MinVersionTLSVar = "TLS_MIN_VERSION" // ImporterDiskID provides a constant to capture our env variable "IMPORTER_DISK_ID" ImporterDiskID = "IMPORTER_DISK_ID" // ImporterUUID provides a constant to capture our env variable "IMPORTER_UUID" @@ -101,14 +67,6 @@ const ( ImporterBackingFile = "IMPORTER_BACKING_FILE" // ImporterThumbprint provides a constant to capture our env variable "IMPORTER_THUMBPRINT" ImporterThumbprint = "IMPORTER_THUMBPRINT" - // ImporterCurrentCheckpoint provides a constant to capture our env variable "IMPORTER_CURRENT_CHECKPOINT" - ImporterCurrentCheckpoint = "IMPORTER_CURRENT_CHECKPOINT" - // ImporterPreviousCheckpoint provides a constant to capture our env variable "IMPORTER_PREVIOUS_CHECKPOINT" - ImporterPreviousCheckpoint = "IMPORTER_PREVIOUS_CHECKPOINT" - // ImporterFinalCheckpoint provides a constant to capture our env variable "IMPORTER_FINAL_CHECKPOINT" - ImporterFinalCheckpoint = "IMPORTER_FINAL_CHECKPOINT" - // Preallocation provides a constant to capture out env variable "PREALLOCATION" - Preallocation = "PREALLOCATION" // ImportProxyHTTP provides a constant to capture our env variable "http_proxy" ImportProxyHTTP = "http_proxy" // ImportProxyHTTPS provides a constant to capture our env variable "https_proxy" @@ -117,28 +75,11 @@ const ( ImportProxyNoProxy = "no_proxy" // ImporterProxyCertDirVar provides a constant to capture our env variable "IMPORTER_PROXY_CERT_DIR" ImporterProxyCertDirVar = "IMPORTER_PROXY_CERT_DIR" - // InstallerPartOfLabel provides a constant to capture our env variable "INSTALLER_PART_OF_LABEL" - InstallerPartOfLabel = "INSTALLER_PART_OF_LABEL" - // InstallerVersionLabel provides a constant to capture our env variable "INSTALLER_VERSION_LABEL" - InstallerVersionLabel = "INSTALLER_VERSION_LABEL" // ImporterExtraHeader provides a constant to include extra HTTP headers, as the prefix to a format string ImporterExtraHeader = "IMPORTER_EXTRA_HEADER_" // ImporterSecretExtraHeadersDir is where the secrets containing extra HTTP headers will be mounted ImporterSecretExtraHeadersDir = "/extraheaders" - // DVCRAddressVar is an env variable holds address to DVCR registry. - DVCRRegistryURLVar = "DVCR_REGISTRY_URL" - // DVCRAuthSecretVar is an env variable holds the name of the Secret with DVCR auth credentials. - DVCRAuthSecretVar = "DVCR_AUTH_SECRET" - // DVCRAuthSecretNSVar is an env variable holds the namespace for the Secret with DVCR auth credentials. - DVCRAuthSecretNSVar = "DVCR_AUTH_SECRET_NAMESPACE" - // DVCRCertsSecretVar is an env variable holds the name of the Secret with DVCR certificates. - DVCRCertsSecretVar = "DVCR_CERTS_SECRET" - // DVCRCertsSecretNSVar is an env variable holds the namespace for the Secret with DVCR certificates. - DVCRCertsSecretNSVar = "DVCR_CERTS_SECRET_NAMESPACE" - // DVCRInsecureTLSVar is an env variable holds the flag whether DVCR is insecure. - DVCRInsecureTLSVar = "DVCR_INSECURE_TLS" - // ImporterDestinationAuthConfigDir is a mount directory for auth Secret. ImporterDestinationAuthConfigDir = "/dvcr-auth" // ImporterDestinationAuthConfigVar is an environment variable with auth config file for Importer Pod. @@ -161,49 +102,8 @@ const ( UploaderDestinationAuthConfigFile = "/dvcr-auth/.dockerconfigjson" UploaderSecretExtraHeadersDir = "/extraheaders" - // ImporterGoogleCredentialFileVar provides a constant to capture our env variable "GOOGLE_APPLICATION_CREDENTIALS" - ImporterGoogleCredentialFileVar = "GOOGLE_APPLICATION_CREDENTIALS" - // ImporterGoogleCredentialDir provides a constant to capture our secret mount Dir - ImporterGoogleCredentialDir = "/google" - // ImporterGoogleCredentialFile provides a constant to capture our credentials.json file - ImporterGoogleCredentialFile = "/google/credentials.json" - - // ClonerSourcePodNameSuffix (controller pkg only) - ClonerSourcePodNameSuffix = "-source-pod" - - // VirtualMachineCIDRs is a list of CIDRs used to allocate static IP addresses for Virtual Machines. - VirtualMachineCIDRs = "VIRTUAL_MACHINE_CIDRS" - - // VirtualMachineIPLeasesRetentionDuration is a parameter for configuring the Virtual Machine IP address lease lifetime - VirtualMachineIPLeasesRetentionDuration = "VIRTUAL_MACHINE_IP_LEASES_RETENTION_DURATION" - - // VirtualImageStorageClass is a parameter for configuring the storage class for Virtual Image on PVC. - VirtualImageStorageClass = "VIRTUAL_IMAGE_STORAGE_CLASS" - // VirtualImageDefaultStorageClass specifies the default storage class for virtual images on PVC when none is specified. - VirtualImageDefaultStorageClass = "VIRTUAL_IMAGE_DEFAULT_STORAGE_CLASS" - // VirtualImageAllowedStorageClasses is a parameter that lists all allowed storage classes for virtual images on PVC. - VirtualImageAllowedStorageClasses = "VIRTUAL_IMAGE_ALLOWED_STORAGE_CLASSES" - // VirtualDiskDefaultStorageClass specifies the default storage class for virtual disks when none is specified. - VirtualDiskDefaultStorageClass = "VIRTUAL_DISK_DEFAULT_STORAGE_CLASS" - // VirtualDiskAllowedStorageClasses is a parameter that lists all allowed storage classes for virtual disks. - VirtualDiskAllowedStorageClasses = "VIRTUAL_DISK_ALLOWED_STORAGE_CLASSES" - DockerRegistrySchemePrefix = "docker://" - KubevirtAPIServerEndpointVar = "KUBEVIRT_APISERVER_ENDPOINT" - KubevirtAPIServerCABundlePathVar = "KUBEVIRT_APISERVER_CABUNDLE" - - ProvisioningPodLimitsVar = "PROVISIONING_POD_LIMITS" - ProvisioningPodRequestsVar = "PROVISIONING_POD_REQUESTS" - - VirtualizationApiAuthServiceAccountNameVar = "VIRTUALIZATION_API_AUTH_SERVICE_ACCOUNT_NAME" - VirtualizationApiAuthServiceAccountNamespaceVar = "VIRTUALIZATION_API_AUTH_SERVICE_ACCOUNT_NAMESPACE" - - GcVmopTtlVar = "GC_VMOP_TTL" - GcVmopScheduleVar = "GC_VMOP_SCHEDULE" - GcVMIMigrationTtlVar = "GC_VMI_MIGRATION_TTL" - GcVMIMigrationScheduleVar = "GC_VMI_MIGRATION_SCHEDULE" - VmBlockDeviceAttachedLimit = 16 CmpLesser = -1 diff --git a/images/virtualization-artifact/pkg/config/load_dvcr_settings.go b/images/virtualization-artifact/pkg/config/load_dvcr_settings.go index 18d51a08b..98c20b3ed 100644 --- a/images/virtualization-artifact/pkg/config/load_dvcr_settings.go +++ b/images/virtualization-artifact/pkg/config/load_dvcr_settings.go @@ -20,37 +20,60 @@ import ( "fmt" "os" - "github.com/deckhouse/virtualization-controller/pkg/common" "github.com/deckhouse/virtualization-controller/pkg/dvcr" ) +const ( + // DVCRAddressVar is an env variable holds address to DVCR registry. + DVCRRegistryURLVar = "DVCR_REGISTRY_URL" + // DVCRAuthSecretVar is an env variable holds the name of the Secret with DVCR auth credentials. + DVCRAuthSecretVar = "DVCR_AUTH_SECRET" + // DVCRAuthSecretNSVar is an env variable holds the namespace for the Secret with DVCR auth credentials. + DVCRAuthSecretNSVar = "DVCR_AUTH_SECRET_NAMESPACE" + // DVCRCertsSecretVar is an env variable holds the name of the Secret with DVCR certificates. + DVCRCertsSecretVar = "DVCR_CERTS_SECRET" + // DVCRCertsSecretNSVar is an env variable holds the namespace for the Secret with DVCR certificates. + DVCRCertsSecretNSVar = "DVCR_CERTS_SECRET_NAMESPACE" + // DVCRInsecureTLSVar is an env variable holds the flag whether DVCR is insecure. + DVCRInsecureTLSVar = "DVCR_INSECURE_TLS" + + // UploaderIngressHostVar is a env variable + UploaderIngressHostVar = "UPLOADER_INGRESS_HOST" + // UploaderIngressTLSSecretVar is a env variable + UploaderIngressTLSSecretVar = "UPLOADER_INGRESS_TLS_SECRET" + // UploaderIngressClassVar is a env variable + UploaderIngressClassVar = "UPLOADER_INGRESS_CLASS" + // UploaderIngressTLSSecretNS is a env variable + UploaderIngressTLSSecretNS = "UPLOADER_INGRESS_TLS_SECRET_NAMESPACE" +) + func LoadDVCRSettingsFromEnvs(controllerNamespace string) (*dvcr.Settings, error) { dvcrSettings := &dvcr.Settings{ - AuthSecret: os.Getenv(common.DVCRAuthSecretVar), - AuthSecretNamespace: os.Getenv(common.DVCRAuthSecretNSVar), - CertsSecret: os.Getenv(common.DVCRCertsSecretVar), - CertsSecretNamespace: os.Getenv(common.DVCRCertsSecretNSVar), - RegistryURL: os.Getenv(common.DVCRRegistryURLVar), - InsecureTLS: os.Getenv(common.DVCRInsecureTLSVar), + AuthSecret: os.Getenv(DVCRAuthSecretVar), + AuthSecretNamespace: os.Getenv(DVCRAuthSecretNSVar), + CertsSecret: os.Getenv(DVCRCertsSecretVar), + CertsSecretNamespace: os.Getenv(DVCRCertsSecretNSVar), + RegistryURL: os.Getenv(DVCRRegistryURLVar), + InsecureTLS: os.Getenv(DVCRInsecureTLSVar), UploaderIngressSettings: dvcr.UploaderIngressSettings{ - Host: os.Getenv(common.UploaderIngressHostVar), - TLSSecret: os.Getenv(common.UploaderIngressTLSSecretVar), - TLSSecretNamespace: os.Getenv(common.UploaderIngressTLSSecretNS), - Class: os.Getenv(common.UploaderIngressClassVar), + Host: os.Getenv(UploaderIngressHostVar), + TLSSecret: os.Getenv(UploaderIngressTLSSecretVar), + TLSSecretNamespace: os.Getenv(UploaderIngressTLSSecretNS), + Class: os.Getenv(UploaderIngressClassVar), }, } if dvcrSettings.RegistryURL == "" { - return nil, fmt.Errorf("environment variable %q undefined, specify DVCR settings", common.DVCRRegistryURLVar) + return nil, fmt.Errorf("environment variable %q undefined, specify DVCR settings", DVCRRegistryURLVar) } if dvcrSettings.UploaderIngressSettings.Host == "" { - return nil, fmt.Errorf("environment variable %q undefined, specify DVCR settings", common.UploaderIngressHostVar) + return nil, fmt.Errorf("environment variable %q undefined, specify DVCR settings", UploaderIngressHostVar) } if dvcrSettings.UploaderIngressSettings.TLSSecret == "" { - return nil, fmt.Errorf("environment variable %q undefined, specify DVCR settings", common.UploaderIngressTLSSecretVar) + return nil, fmt.Errorf("environment variable %q undefined, specify DVCR settings", UploaderIngressTLSSecretVar) } if dvcrSettings.UploaderIngressSettings.Class == "" { - return nil, fmt.Errorf("environment variable %q undefined, specify DVCR settings", common.UploaderIngressClassVar) + return nil, fmt.Errorf("environment variable %q undefined, specify DVCR settings", UploaderIngressClassVar) } if dvcrSettings.AuthSecret != "" && dvcrSettings.AuthSecretNamespace == "" { diff --git a/images/virtualization-artifact/pkg/config/load_gc_settings.go b/images/virtualization-artifact/pkg/config/load_gc_settings.go index 5e81acc76..aaafdfd04 100644 --- a/images/virtualization-artifact/pkg/config/load_gc_settings.go +++ b/images/virtualization-artifact/pkg/config/load_gc_settings.go @@ -22,8 +22,13 @@ import ( "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) - "github.com/deckhouse/virtualization-controller/pkg/common" +const ( + GcVmopTtlVar = "GC_VMOP_TTL" + GcVmopScheduleVar = "GC_VMOP_SCHEDULE" + GcVMIMigrationTtlVar = "GC_VMI_MIGRATION_TTL" + GcVMIMigrationScheduleVar = "GC_VMI_MIGRATION_SCHEDULE" ) type GCSettings struct { @@ -38,13 +43,13 @@ type BaseGcSettings struct { func LoadGcSettings() (GCSettings, error) { var gcSettings GCSettings - base, err := GetBaseGCSettingsFromEnv(common.GcVmopScheduleVar, common.GcVmopTtlVar) + base, err := GetBaseGCSettingsFromEnv(GcVmopScheduleVar, GcVmopTtlVar) if err != nil { return gcSettings, err } gcSettings.VMOP = base - base, err = GetBaseGCSettingsFromEnv(common.GcVMIMigrationScheduleVar, common.GcVMIMigrationTtlVar) + base, err = GetBaseGCSettingsFromEnv(GcVMIMigrationScheduleVar, GcVMIMigrationTtlVar) if err != nil { return gcSettings, err } diff --git a/images/virtualization-artifact/pkg/config/load_import_settings.go b/images/virtualization-artifact/pkg/config/load_import_settings.go index 79c117567..c3cdc7cc6 100644 --- a/images/virtualization-artifact/pkg/config/load_import_settings.go +++ b/images/virtualization-artifact/pkg/config/load_import_settings.go @@ -26,6 +26,11 @@ import ( "github.com/deckhouse/virtualization-controller/pkg/common" ) +const ( + ProvisioningPodLimitsVar = "PROVISIONING_POD_LIMITS" + ProvisioningPodRequestsVar = "PROVISIONING_POD_REQUESTS" +) + type ImportSettings struct { ImporterImage string UploaderImage string @@ -45,14 +50,14 @@ func LoadImportSettingsFromEnv() (ImportSettings, error) { return ImportSettings{}, err } - limits := os.Getenv(common.ProvisioningPodLimitsVar) + limits := os.Getenv(ProvisioningPodLimitsVar) if limits != "" { err = json.Unmarshal([]byte(limits), &settings.Requirements.Limits) if err != nil { return ImportSettings{}, err } } - requests := os.Getenv(common.ProvisioningPodRequestsVar) + requests := os.Getenv(ProvisioningPodRequestsVar) if requests != "" { err = json.Unmarshal([]byte(requests), &settings.Requirements.Requests) if err != nil { diff --git a/images/virtualization-artifact/pkg/config/load_kubevirt_apiserver_settings.go b/images/virtualization-artifact/pkg/config/load_kubevirt_apiserver_settings.go index c1eac286e..fe5ebb9cc 100644 --- a/images/virtualization-artifact/pkg/config/load_kubevirt_apiserver_settings.go +++ b/images/virtualization-artifact/pkg/config/load_kubevirt_apiserver_settings.go @@ -20,14 +20,20 @@ import ( "os" "github.com/deckhouse/virtualization-controller/pkg/apiserver/registry/vm/rest" - "github.com/deckhouse/virtualization-controller/pkg/common" +) + +const ( + KubevirtAPIServerEndpointVar = "KUBEVIRT_APISERVER_ENDPOINT" + KubevirtAPIServerCABundlePathVar = "KUBEVIRT_APISERVER_CABUNDLE" + VirtualizationApiAuthServiceAccountNameVar = "VIRTUALIZATION_API_AUTH_SERVICE_ACCOUNT_NAME" + VirtualizationApiAuthServiceAccountNamespaceVar = "VIRTUALIZATION_API_AUTH_SERVICE_ACCOUNT_NAMESPACE" ) func LoadKubevirtAPIServerFromEnv() rest.KubevirtApiServerConfig { conf := rest.KubevirtApiServerConfig{} - conf.Endpoint = os.Getenv(common.KubevirtAPIServerEndpointVar) - conf.CaBundlePath = os.Getenv(common.KubevirtAPIServerCABundlePathVar) - conf.ServiceAccount.Name = os.Getenv(common.VirtualizationApiAuthServiceAccountNameVar) - conf.ServiceAccount.Namespace = os.Getenv(common.VirtualizationApiAuthServiceAccountNamespaceVar) + conf.Endpoint = os.Getenv(KubevirtAPIServerEndpointVar) + conf.CaBundlePath = os.Getenv(KubevirtAPIServerCABundlePathVar) + conf.ServiceAccount.Name = os.Getenv(VirtualizationApiAuthServiceAccountNameVar) + conf.ServiceAccount.Namespace = os.Getenv(VirtualizationApiAuthServiceAccountNamespaceVar) return conf } diff --git a/images/virtualization-artifact/pkg/config/load_vd_storage_class_settings.go b/images/virtualization-artifact/pkg/config/load_vd_storage_class_settings.go index 7f7d61079..b6d769195 100644 --- a/images/virtualization-artifact/pkg/config/load_vd_storage_class_settings.go +++ b/images/virtualization-artifact/pkg/config/load_vd_storage_class_settings.go @@ -19,8 +19,13 @@ package config import ( "os" "strings" +) - "github.com/deckhouse/virtualization-controller/pkg/common" +const ( + // VirtualDiskDefaultStorageClass specifies the default storage class for virtual disks when none is specified. + VirtualDiskDefaultStorageClass = "VIRTUAL_DISK_DEFAULT_STORAGE_CLASS" + // VirtualDiskAllowedStorageClasses is a parameter that lists all allowed storage classes for virtual disks. + VirtualDiskAllowedStorageClasses = "VIRTUAL_DISK_ALLOWED_STORAGE_CLASSES" ) type VirtualDiskStorageClassSettings struct { @@ -30,13 +35,13 @@ type VirtualDiskStorageClassSettings struct { func LoadVirtualDiskStorageClassSettings() VirtualDiskStorageClassSettings { var allowedStorageClassNames []string - allowedStorageClassNamesRaw := os.Getenv(common.VirtualDiskAllowedStorageClasses) + allowedStorageClassNamesRaw := os.Getenv(VirtualDiskAllowedStorageClasses) if allowedStorageClassNamesRaw != "" { allowedStorageClassNames = strings.Split(allowedStorageClassNamesRaw, ",") } return VirtualDiskStorageClassSettings{ AllowedStorageClassNames: allowedStorageClassNames, - DefaultStorageClassName: os.Getenv(common.VirtualDiskDefaultStorageClass), + DefaultStorageClassName: os.Getenv(VirtualDiskDefaultStorageClass), } } diff --git a/images/virtualization-artifact/pkg/config/load_vi_storage_class_settings.go b/images/virtualization-artifact/pkg/config/load_vi_storage_class_settings.go index d9d3cd6cc..d8fed5ea5 100644 --- a/images/virtualization-artifact/pkg/config/load_vi_storage_class_settings.go +++ b/images/virtualization-artifact/pkg/config/load_vi_storage_class_settings.go @@ -19,8 +19,15 @@ package config import ( "os" "strings" +) - "github.com/deckhouse/virtualization-controller/pkg/common" +const ( + // VirtualImageStorageClass is a parameter for configuring the storage class for Virtual Image on PVC. + VirtualImageStorageClass = "VIRTUAL_IMAGE_STORAGE_CLASS" + // VirtualImageDefaultStorageClass specifies the default storage class for virtual images on PVC when none is specified. + VirtualImageDefaultStorageClass = "VIRTUAL_IMAGE_DEFAULT_STORAGE_CLASS" + // VirtualImageAllowedStorageClasses is a parameter that lists all allowed storage classes for virtual images on PVC. + VirtualImageAllowedStorageClasses = "VIRTUAL_IMAGE_ALLOWED_STORAGE_CLASSES" ) type VirtualImageStorageClassSettings struct { @@ -31,14 +38,14 @@ type VirtualImageStorageClassSettings struct { func LoadVirtualImageStorageClassSettings() VirtualImageStorageClassSettings { var allowedStorageClassNames []string - allowedStorageClassNamesRaw := os.Getenv(common.VirtualImageAllowedStorageClasses) + allowedStorageClassNamesRaw := os.Getenv(VirtualImageAllowedStorageClasses) if allowedStorageClassNamesRaw != "" { allowedStorageClassNames = strings.Split(allowedStorageClassNamesRaw, ",") } return VirtualImageStorageClassSettings{ AllowedStorageClassNames: allowedStorageClassNames, - DefaultStorageClassName: os.Getenv(common.VirtualImageDefaultStorageClass), - StorageClassName: os.Getenv(common.VirtualImageStorageClass), + DefaultStorageClassName: os.Getenv(VirtualImageDefaultStorageClass), + StorageClassName: os.Getenv(VirtualImageStorageClass), } } diff --git a/images/virtualization-artifact/pkg/controller/common/util.go b/images/virtualization-artifact/pkg/controller/common/util.go index 0025c379c..6e3b73426 100644 --- a/images/virtualization-artifact/pkg/controller/common/util.go +++ b/images/virtualization-artifact/pkg/controller/common/util.go @@ -17,23 +17,14 @@ limitations under the License. package common import ( - "context" - "crypto/rand" - "crypto/rsa" "errors" - "fmt" "reflect" "slices" "strings" - "sync" - "time" corev1 "k8s.io/api/core/v1" - storagev1 "k8s.io/api/storage/v1" - "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/tools/record" "k8s.io/utils/ptr" cdiv1 "kubevirt.io/containerized-data-importer-api/pkg/apis/core/v1beta1" "sigs.k8s.io/controller-runtime/pkg/client" @@ -51,145 +42,22 @@ const ( // AnnCreatedBy is a pod annotation indicating if the pod was created by the PVC AnnCreatedBy = AnnAPIGroup + "/storage.createdByController" - // AnnPodPhase is a PVC annotation indicating the related pod progress (phase) - AnnPodPhase = AnnAPIGroup + "/storage.pod.phase" - // AnnPodReady tells whether the pod is ready - AnnPodReady = AnnAPIGroup + "/storage.pod.ready" - // AnnPodRestarts is a PVC annotation that tells how many times a related pod was restarted - AnnPodRestarts = AnnAPIGroup + "/storage.pod.restarts" - // AnnPopulatedFor is a PVC annotation telling the datavolume controller that the PVC is already populated - AnnPopulatedFor = AnnAPIGroup + "/storage.populatedFor" - // AnnPrePopulated is a PVC annotation telling the datavolume controller that the PVC is already populated - AnnPrePopulated = AnnAPIGroup + "/storage.prePopulated" - // AnnPriorityClassName is PVC annotation to indicate the priority class name for importer, cloner and uploader pod - AnnPriorityClassName = AnnAPIGroup + "/storage.pod.priorityclassname" - // AnnExternalPopulation annotation marks a PVC as "externally populated", allowing the import-controller to skip it - AnnExternalPopulation = AnnAPIGroup + "/externalPopulation" - - // AnnDeleteAfterCompletion is PVC annotation for deleting DV after completion - AnnDeleteAfterCompletion = AnnAPIGroup + "/storage.deleteAfterCompletion" + // AnnPodRetainAfterCompletion is PVC annotation for retaining transfer pods after completion AnnPodRetainAfterCompletion = AnnAPIGroup + "/storage.pod.retainAfterCompletion" - // AnnPreviousCheckpoint provides a const to indicate the previous snapshot for a multistage import - AnnPreviousCheckpoint = AnnAPIGroup + "/storage.checkpoint.previous" - // AnnCurrentCheckpoint provides a const to indicate the current snapshot for a multistage import - AnnCurrentCheckpoint = AnnAPIGroup + "/storage.checkpoint.current" - // AnnFinalCheckpoint provides a const to indicate whether the current checkpoint is the last one - AnnFinalCheckpoint = AnnAPIGroup + "/storage.checkpoint.final" - // AnnCheckpointsCopied is a prefix for recording which checkpoints have already been copied - AnnCheckpointsCopied = AnnAPIGroup + "/storage.checkpoint.copied" - - // AnnCurrentPodID keeps track of the latest pod servicing this PVC - AnnCurrentPodID = AnnAPIGroup + "/storage.checkpoint.pod.id" - - // AnnRunningCondition provides a const for the running condition - AnnRunningCondition = AnnAPIGroup + "/storage.condition.running" - // AnnRunningConditionMessage provides a const for the running condition - AnnRunningConditionMessage = AnnAPIGroup + "/storage.condition.running.message" - // AnnRunningConditionReason provides a const for the running condition - AnnRunningConditionReason = AnnAPIGroup + "/storage.condition.running.reason" - - // AnnSourceRunningCondition provides a const for the running condition - AnnSourceRunningCondition = AnnAPIGroup + "/storage.condition.source.running" - // AnnSourceRunningConditionMessage provides a const for the running condition - AnnSourceRunningConditionMessage = AnnAPIGroup + "/storage.condition.source.running.message" - // AnnSourceRunningConditionReason provides a const for the running condition - AnnSourceRunningConditionReason = AnnAPIGroup + "/storage.condition.source.running.reason" - - // AnnSource provide a const for our PVC import source annotation - AnnSource = AnnAPIGroup + "/storage.import.source" - // AnnEndpoint provides a const for our PVC endpoint annotation - AnnEndpoint = AnnAPIGroup + "/storage.import.endpoint" - - // AnnRegistryImportMethod provides a const for registry import method annotation - AnnRegistryImportMethod = AnnAPIGroup + "/storage.import.registryImportMethod" - // AnnRegistryImageStream provides a const for registry image stream annotation - AnnRegistryImageStream = AnnAPIGroup + "/storage.import.registryImageStream" // AnnUploadURL provides a const for CVMI/VMI/VMD uploadURL annotation AnnUploadURL = AnnAPIGroup + "/upload.url" - // AnnDiskID provides a const for our PVC diskId annotation - AnnDiskID = AnnAPIGroup + "/storage.import.diskId" - // AnnUUID provides a const for our PVC uuid annotation - AnnUUID = AnnAPIGroup + "/storage.import.uuid" - // AnnBackingFile provides a const for our PVC backing file annotation - AnnBackingFile = AnnAPIGroup + "/storage.import.backingFile" - // AnnThumbprint provides a const for our PVC backing thumbprint annotation - AnnThumbprint = AnnAPIGroup + "/storage.import.vddk.thumbprint" - // AnnExtraHeaders provides a const for our PVC extraHeaders annotation - AnnExtraHeaders = AnnAPIGroup + "/storage.import.extraHeaders" - // AnnSecretExtraHeaders provides a const for our PVC secretExtraHeaders annotation - AnnSecretExtraHeaders = AnnAPIGroup + "/storage.import.secretExtraHeaders" - AnnCreatedByImporter = AnnAPIGroup + "/storage.createdByImporter" - - AnnImportAvgSpeedBytes = AnnAPIGroup + "/storage.import.speed.avg" - AnnImportCurrentSpeedBytes = AnnAPIGroup + "/storage.import.speed.current" - AnnImportStoredSizeBytes = AnnAPIGroup + "/storage.import.size.stored" - AnnImportUnpackedSizeBytes = AnnAPIGroup + "/storage.import.size.unpacked" - - // AnnCloneToken is the annotation containing the clone token - AnnCloneToken = AnnAPIGroup + "/storage.clone.token" - // AnnExtendedCloneToken is the annotation containing the long term clone token - AnnExtendedCloneToken = AnnAPIGroup + "/storage.extended.clone.token" - // AnnPermissiveClone annotation allows the clone-controller to skip the clone size validation - AnnPermissiveClone = AnnAPIGroup + "/permissiveClone" - // AnnOwnerUID annotation has the owner UID - AnnOwnerUID = AnnAPIGroup + "/ownerUID" - // AnnCloneType is the comuuted/requested clone type - AnnCloneType = AnnAPIGroup + "/cloneType" - // AnnCloneSourcePod name of the source clone pod - AnnCloneSourcePod = "cdi.kubevirt.io/storage.sourceClonePodName" - - // AnnUploadRequest marks that a PVC should be made available for upload - AnnUploadRequest = AnnAPIGroup + "/storage.upload.target" - - // AnnCheckStaticVolume checks if a statically allocated PV exists before creating the target PVC. - // If so, PVC is still created but population is skipped - AnnCheckStaticVolume = AnnAPIGroup + "/storage.checkStaticVolume" - - // AnnPersistentVolumeList is an annotation storing a list of PV names - AnnPersistentVolumeList = AnnAPIGroup + "/storage.persistentVolumeList" - - // AnnPopulatorKind annotation is added to a PVC' to specify the population kind, so it's later - // checked by the common populator watches. - AnnPopulatorKind = AnnAPIGroup + "/storage.populator.kind" // AnnDefaultStorageClass is the annotation indicating that a storage class is the default one. AnnDefaultStorageClass = "storageclass.kubernetes.io/is-default-class" - // AnnOpenShiftImageLookup is the annotation for OpenShift image stream lookup - AnnOpenShiftImageLookup = "alpha.image.policy.openshift.io/resolve-names" - - // AnnCloneRequest sets our expected annotation for a CloneRequest - AnnCloneRequest = "k8s.io/CloneRequest" - // AnnCloneOf is used to indicate that cloning was complete - AnnCloneOf = "k8s.io/CloneOf" - - // AnnPodNetwork is used for specifying Pod Network - AnnPodNetwork = "k8s.v1.cni.cncf.io/networks" - // AnnPodMultusDefaultNetwork is used for specifying default Pod Network - AnnPodMultusDefaultNetwork = "v1.multus-cni.io/default-network" - // AnnPodSidecarInjection is used for enabling/disabling Pod istio/AspenMesh sidecar injection - AnnPodSidecarInjection = "sidecar.istio.io/inject" - // AnnPodSidecarInjectionDefault is the default value passed for AnnPodSidecarInjection - AnnPodSidecarInjectionDefault = "false" - - // AnnImmediateBinding provides a const to indicate whether immediate binding should be performed on the PV (overrides global config) - AnnImmediateBinding = AnnAPIGroup + "/storage.bind.immediate.requested" - AnnAPIGroupV = "virtualization.deckhouse.io" AnnVirtualDisk = "virtualdisk." + AnnAPIGroupV AnnVirtualDiskVolumeMode = AnnVirtualDisk + "/volume-mode" AnnVirtualDiskAccessMode = AnnVirtualDisk + "/access-mode" AnnVirtualDiskBindingMode = AnnVirtualDisk + "/binding-mode" - // AnnSelectedNode annotation is added to a PVC that has been triggered by scheduler to - // be dynamically provisioned. Its value is the name of the selected node. - AnnSelectedNode = "volume.kubernetes.io/selected-node" - - // AnnBoundVirtualMachineName is an ip address annotation with value of bound vm name. - AnnBoundVirtualMachineName = AnnAPIGroup + "/bound-virtual-machine-name" - // AnnVMLastAppliedSpec is an annotation on KVVM. It contains a JSON with VM spec. AnnVMLastAppliedSpec = AnnAPIGroup + "/vm.last-applied-spec" @@ -198,83 +66,30 @@ const ( // LastPropagatedVMLabelsAnnotation is a marshalled map of previously applied virtual machine labels. LastPropagatedVMLabelsAnnotation = AnnAPIGroup + "/last-propagated-vm-labels" - // ErrStartingPod provides a const to indicate that a pod wasn't able to start without providing sensitive information (reason) - ErrStartingPod = "ErrStartingPod" - // MessageErrStartingPod provides a const to indicate that a pod wasn't able to start without providing sensitive information (message) - MessageErrStartingPod = "Error starting pod '%s': For more information, request access to cdi-deploy logs from your sysadmin" - // ErrClaimNotValid provides a const to indicate a claim is not valid - ErrClaimNotValid = "ErrClaimNotValid" - // ErrExceededQuota provides a const to indicate the claim has exceeded the quota - ErrExceededQuota = "ErrExceededQuota" - // ErrIncompatiblePVC provides a const to indicate a clone is not possible due to an incompatible PVC - ErrIncompatiblePVC = "ErrIncompatiblePVC" - - // SourceHTTP is the source type HTTP, if unspecified or invalid, it defaults to SourceHTTP - SourceHTTP = "http" - // SourceS3 is the source type S3 - SourceS3 = "s3" - // SourceGCS is the source type GCS - SourceGCS = "gcs" - // SourceGlance is the source type of glance - SourceGlance = "glance" - // SourceNone means there is no source. - SourceNone = "none" - // SourceRegistry is the source type of Registry - SourceRegistry = "registry" - // SourceImageio is the source type ovirt-imageio - SourceImageio = "imageio" - // SourceVDDK is the source type of VDDK - SourceVDDK = "vddk" - // SourceDVCR is the source type of dvcr - SourceDVCR = "dvcr" - // SourceBlockDevice is the source type of block device - SourceBlockDevice = "blockDevice" - // ClaimLost reason const - ClaimLost = "ClaimLost" - // NotFound reason const - NotFound = "NotFound" - - // LabelDefaultInstancetype provides a default VirtualMachine{ClusterInstancetype,Instancetype} that can be used by a VirtualMachine booting from a given PVC - LabelDefaultInstancetype = "instancetype.kubevirt.io/default-instancetype" - // LabelDefaultInstancetypeKind provides a default kind of either VirtualMachineClusterInstancetype or VirtualMachineInstancetype - LabelDefaultInstancetypeKind = "instancetype.kubevirt.io/default-instancetype-kind" - // LabelDefaultPreference provides a default VirtualMachine{ClusterPreference,Preference} that can be used by a VirtualMachine booting from a given PVC - LabelDefaultPreference = "instancetype.kubevirt.io/default-preference" - // LabelDefaultPreferenceKind provides a default kind of either VirtualMachineClusterPreference or VirtualMachinePreference - LabelDefaultPreferenceKind = "instancetype.kubevirt.io/default-preference-kind" - // LabelsPrefix is a prefix for virtualization-controller labels. LabelsPrefix = "virtualization.deckhouse.io" - // LabelVirtualMachineName is a label to link VirtualMachineOperation to VirtualMachine. - LabelVirtualMachineName = LabelsPrefix + "/virtual-machine-name" - // LabelVirtualMachineUID is a label to link VirtualMachineIPAddress to VirtualMachine. LabelVirtualMachineUID = LabelsPrefix + "/virtual-machine-uid" UploaderServiceLabel = "service" - // ProgressDone this means we are DONE - ProgressDone = "100.0%" - // UploaderWaitDuration is upload waiting timeout - UploaderWaitDuration = 15 * time.Minute + + // AppKubernetesManagedByLabel is the Kubernetes recommended managed-by label + AppKubernetesManagedByLabel = "app.kubernetes.io/managed-by" + // AppKubernetesComponentLabel is the Kubernetes recommended component label + AppKubernetesComponentLabel = "app.kubernetes.io/component" + + // QemuSubGid is the gid used as the qemu group in fsGroup + QemuSubGid = int64(107) ) var ( - apiServerKeyOnce sync.Once - apiServerKey *rsa.PrivateKey - // ErrUnknownValue is a variable of type `error` that represents an error message indicating an unknown value. ErrUnknownValue = errors.New("unknown value") // ErrUnknownType is a variable of type `error` that represents an error message indicating an unknown type. ErrUnknownType = errors.New("unknown type") ) -// GetPriorityClass gets PVC priority class -func GetPriorityClass(pvc *corev1.PersistentVolumeClaim) string { - anno := pvc.GetAnnotations() - return anno[AnnPriorityClassName] -} - // ShouldCleanupSubResources returns whether sub resources should be deleted: // - CVMI, VMI has no annotation to retain pod after import // - CVMI, VMI is deleted @@ -282,48 +97,6 @@ func ShouldCleanupSubResources(obj metav1.Object) bool { return obj.GetAnnotations()[AnnPodRetainAfterCompletion] != "true" || obj.GetDeletionTimestamp() != nil } -func ShouldDeletePod(obj metav1.Object) bool { - if len(obj.GetAnnotations()) == 0 { - return false - } - return ShouldCleanupSubResources(obj) -} - -// AddFinalizer adds a finalizer to a resource -func AddFinalizer(obj metav1.Object, name string) { - if HasFinalizer(obj, name) { - return - } - - obj.SetFinalizers(append(obj.GetFinalizers(), name)) -} - -// RemoveFinalizer removes a finalizer from a resource -func RemoveFinalizer(obj metav1.Object, name string) { - if !HasFinalizer(obj, name) { - return - } - - var finalizers []string - for _, f := range obj.GetFinalizers() { - if f != name { - finalizers = append(finalizers, f) - } - } - - obj.SetFinalizers(finalizers) -} - -// HasFinalizer returns true if a resource has a specific finalizer -func HasFinalizer(object metav1.Object, value string) bool { - for _, f := range object.GetFinalizers() { - if f == value { - return true - } - } - return false -} - // AddAnnotation adds an annotation to an object func AddAnnotation(obj metav1.Object, key, value string) { if obj.GetAnnotations() == nil { @@ -340,43 +113,10 @@ func AddLabel(obj metav1.Object, key, value string) { obj.GetLabels()[key] = value } -// PublishPodErr handles pod-creation errors and updates the CVMI without providing sensitive information. -// TODO make work with VirtualImage object. -func PublishPodErr(err error, podName string, obj client.Object, recorder record.EventRecorder, apiClient client.Client) error { - // Generic reason and msg to avoid providing sensitive information - reason := ErrStartingPod - msg := fmt.Sprintf(MessageErrStartingPod, podName) + ": " + err.Error() - - // Error handling to fine-tune the event with pertinent info - if ErrQuotaExceeded(err) { - reason = ErrExceededQuota - } - - recorder.Event(obj, corev1.EventTypeWarning, reason, msg) - - if isCloneSourcePod := CreateCloneSourcePodName(obj) == podName; isCloneSourcePod { - AddAnnotation(obj, AnnSourceRunningCondition, "false") - AddAnnotation(obj, AnnSourceRunningConditionReason, reason) - AddAnnotation(obj, AnnSourceRunningConditionMessage, msg) - } else { - AddAnnotation(obj, AnnRunningCondition, "false") - AddAnnotation(obj, AnnRunningConditionReason, reason) - AddAnnotation(obj, AnnRunningConditionMessage, msg) - } - - AddAnnotation(obj, AnnPodPhase, string(corev1.PodFailed)) - return apiClient.Update(context.TODO(), obj) -} - type UIDable interface { GetUID() types.UID } -// CreateCloneSourcePodName creates clone source pod name -func CreateCloneSourcePodName(obj UIDable) string { - return string(obj.GetUID()) + common.ClonerSourcePodNameSuffix -} - // IsPodRunning returns true if a Pod is in 'Running' phase, false if not. func IsPodRunning(pod *corev1.Pod) bool { return pod != nil && pod.Status.Phase == corev1.PodRunning @@ -445,7 +185,7 @@ func SetRestrictedSecurityContext(podSpec *corev1.PodSpec) { } container.SecurityContext.AllowPrivilegeEscalation = ptr.To(false) container.SecurityContext.RunAsNonRoot = ptr.To(true) - container.SecurityContext.RunAsUser = ptr.To(common.QemuSubGid) + container.SecurityContext.RunAsUser = ptr.To(QemuSubGid) if len(container.VolumeMounts) > 0 { hasVolumeMounts = true } @@ -456,78 +196,7 @@ func SetRestrictedSecurityContext(podSpec *corev1.PodSpec) { if podSpec.SecurityContext == nil { podSpec.SecurityContext = &corev1.PodSecurityContext{} } - podSpec.SecurityContext.FSGroup = ptr.To(common.QemuSubGid) - } -} - -// SetNodeNameIfPopulator sets NodeName in a pod spec when the PVC is being handled by a CDI volume populator -func SetNodeNameIfPopulator(pvc *corev1.PersistentVolumeClaim, podSpec *corev1.PodSpec) { - _, isPopulator := pvc.Annotations[AnnPopulatorKind] - nodeName := pvc.Annotations[AnnSelectedNode] - if isPopulator && nodeName != "" { - podSpec.NodeName = nodeName - } -} - -// CreatePvc creates PVC -func CreatePvc(name, ns string, annotations, labels map[string]string) *corev1.PersistentVolumeClaim { - return CreatePvcInStorageClass(name, ns, nil, annotations, labels, corev1.ClaimBound) -} - -// CreatePvcInStorageClass creates PVC with storgae class -func CreatePvcInStorageClass(name, ns string, storageClassName *string, annotations, labels map[string]string, phase corev1.PersistentVolumeClaimPhase) *corev1.PersistentVolumeClaim { - pvc := &corev1.PersistentVolumeClaim{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: ns, - Annotations: annotations, - Labels: labels, - UID: types.UID(ns + "-" + name), - }, - Spec: corev1.PersistentVolumeClaimSpec{ - AccessModes: []corev1.PersistentVolumeAccessMode{corev1.ReadOnlyMany, corev1.ReadWriteOnce}, - Resources: corev1.VolumeResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceStorage: resource.MustParse("1G"), - }, - }, - StorageClassName: storageClassName, - }, - Status: corev1.PersistentVolumeClaimStatus{ - Phase: phase, - }, - } - pvc.Status.Capacity = pvc.Spec.Resources.Requests.DeepCopy() - return pvc -} - -// GetAPIServerKey returns API server RSA key -func GetAPIServerKey() *rsa.PrivateKey { - apiServerKeyOnce.Do(func() { - apiServerKey, _ = rsa.GenerateKey(rand.Reader, 2048) - }) - return apiServerKey -} - -// CreateStorageClass creates storage class CR -func CreateStorageClass(name string, annotations map[string]string) *storagev1.StorageClass { - return &storagev1.StorageClass{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Annotations: annotations, - }, - } -} - -// CreateStorageClassWithProvisioner creates CR of storage class with provisioner -func CreateStorageClassWithProvisioner(name string, annotations, labels map[string]string, provisioner string) *storagev1.StorageClass { - return &storagev1.StorageClass{ - Provisioner: provisioner, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Annotations: annotations, - Labels: labels, - }, + podSpec.SecurityContext.FSGroup = ptr.To(QemuSubGid) } } @@ -536,46 +205,12 @@ func ErrQuotaExceeded(err error) bool { return strings.Contains(err.Error(), "exceeded quota:") } -// GetNamespace returns the given namespace if not empty, otherwise the default namespace -func GetNamespace(namespace, defaultNamespace string) string { - if namespace == "" { - return defaultNamespace - } - return namespace -} - // IsBound returns if the pvc is bound -func IsBound(pvc *corev1.PersistentVolumeClaim) bool { - return pvc.Spec.VolumeName != "" -} - -// IsUnbound returns if the pvc is not bound yet -func IsUnbound(pvc *corev1.PersistentVolumeClaim) bool { - return !IsBound(pvc) -} - -// IsImageStream returns true if registry source is ImageStream -func IsImageStream(pvc *corev1.PersistentVolumeClaim) bool { - return pvc.Annotations[AnnRegistryImageStream] == "true" -} - -// ShouldIgnorePod checks if a pod should be ignored. -// If this is a completed pod that was used for one checkpoint of a multi-stage import, it -// should be ignored by pod lookups as long as the retainAfterCompletion annotation is set. -func ShouldIgnorePod(pod *corev1.Pod, pvc *corev1.PersistentVolumeClaim) bool { - retain := pvc.ObjectMeta.Annotations[AnnPodRetainAfterCompletion] - checkpoint := pvc.ObjectMeta.Annotations[AnnCurrentCheckpoint] - if checkpoint != "" && pod.Status.Phase == corev1.PodSucceeded { - return retain == "true" - } - return false -} - // SetRecommendedLabels sets the recommended labels on CDI resources (does not get rid of existing ones) func SetRecommendedLabels(obj metav1.Object, installerLabels map[string]string, controllerName string) { staticLabels := map[string]string{ - common.AppKubernetesManagedByLabel: controllerName, - common.AppKubernetesComponentLabel: "storage", + AppKubernetesManagedByLabel: controllerName, + AppKubernetesComponentLabel: "storage", } // Merge existing labels with static labels and add installer dynamic labels as well (/version, /part-of). @@ -588,10 +223,6 @@ func NamespacedName(obj client.Object) types.NamespacedName { return types.NamespacedName{Name: obj.GetName(), Namespace: obj.GetNamespace()} } -func MatchLabelSelector(labels map[string]string, selector metav1.LabelSelector) bool { - return MatchLabels(labels, selector.MatchLabels) && MatchExpressions(labels, selector.MatchExpressions) -} - func MatchLabels(labels, matchLabels map[string]string) bool { for key, value := range matchLabels { if labels[key] != value { diff --git a/images/virtualization-artifact/pkg/controller/importer/importer_pod.go b/images/virtualization-artifact/pkg/controller/importer/importer_pod.go index 18e3fa9e4..635b6ec68 100644 --- a/images/virtualization-artifact/pkg/controller/importer/importer_pod.go +++ b/images/virtualization-artifact/pkg/controller/importer/importer_pod.go @@ -57,6 +57,12 @@ const ( // sourceRegistryAuthVol is the name of the volume containing source registry docker auth config. sourceRegistryAuthVol = "source-registry-secret-vol" + + // KeyAccess provides a constant to the accessKeyId label using in controller pkg and transport_test.go + KeyAccess = "accessKeyId" + + // KeySecret provides a constant to the secretKey label using in controller pkg and transport_test.go + KeySecret = "secretKey" ) type Importer struct { @@ -298,7 +304,7 @@ func (imp *Importer) makeImporterContainerEnv() []corev1.EnvVar { LocalObjectReference: corev1.LocalObjectReference{ Name: imp.EnvSettings.SecretName, }, - Key: common.KeyAccess, + Key: KeyAccess, }, }, }, corev1.EnvVar{ @@ -308,7 +314,7 @@ func (imp *Importer) makeImporterContainerEnv() []corev1.EnvVar { LocalObjectReference: corev1.LocalObjectReference{ Name: imp.EnvSettings.SecretName, }, - Key: common.KeySecret, + Key: KeySecret, }, }, }) diff --git a/images/virtualization-artifact/pkg/controller/importer/settings.go b/images/virtualization-artifact/pkg/controller/importer/settings.go index bcedfdb40..25e93e391 100644 --- a/images/virtualization-artifact/pkg/controller/importer/settings.go +++ b/images/virtualization-artifact/pkg/controller/importer/settings.go @@ -19,13 +19,22 @@ package importer import ( "github.com/deckhouse/virtualization-controller/pkg/common" "github.com/deckhouse/virtualization-controller/pkg/common/datasource" - dsutil "github.com/deckhouse/virtualization-controller/pkg/common/datasource" - cc "github.com/deckhouse/virtualization-controller/pkg/controller/common" "github.com/deckhouse/virtualization-controller/pkg/controller/supplements" "github.com/deckhouse/virtualization-controller/pkg/dvcr" virtv2alpha1 "github.com/deckhouse/virtualization/api/core/v1alpha2" ) +const ( + // SourceHTTP is the source type HTTP, if unspecified or invalid, it defaults to SourceHTTP + SourceHTTP = "http" + // SourceRegistry is the source type of Registry + SourceRegistry = "registry" + // SourceDVCR is the source type of dvcr + SourceDVCR = "dvcr" + // SourceBlockDevice is the source type of block device + SourceBlockDevice = "blockDevice" +) + // Settings stores all possible settings for dvcr-importer binary. // Fields from this struct are passed via environment variables. type Settings struct { @@ -70,7 +79,7 @@ func ApplyDVCRDestinationSettings(podEnvVars *Settings, dvcrSettings *dvcr.Setti // ApplyHTTPSourceSettings updates importer Pod settings to use http source. func ApplyHTTPSourceSettings(podEnvVars *Settings, http *virtv2alpha1.DataSourceHTTP, supGen *supplements.Generator) { - podEnvVars.Source = cc.SourceHTTP + podEnvVars.Source = SourceHTTP podEnvVars.Endpoint = http.URL if http.Checksum != nil { @@ -92,13 +101,13 @@ func ApplyHTTPSourceSettings(podEnvVars *Settings, http *virtv2alpha1.DataSource // ApplyRegistrySourceSettings updates importer Pod settings to use registry source. func ApplyRegistrySourceSettings(podEnvVars *Settings, ctrImg *datasource.ContainerRegistry, supGen *supplements.Generator) { - podEnvVars.Source = cc.SourceRegistry + podEnvVars.Source = SourceRegistry podEnvVars.Endpoint = common.DockerRegistrySchemePrefix + ctrImg.Image // Optional auth secret from imagePullSecret. if secretName := ctrImg.ImagePullSecret.Name; secretName != "" { // Copy imagePullSecret if resides in a different namespace. - if dsutil.ShouldCopyImagePullSecret(ctrImg, supGen.Namespace) { + if datasource.ShouldCopyImagePullSecret(ctrImg, supGen.Namespace) { imgPull := supGen.ImagePullSecret() podEnvVars.AuthSecret = imgPull.Name } else { @@ -116,11 +125,11 @@ func ApplyRegistrySourceSettings(podEnvVars *Settings, ctrImg *datasource.Contai // ApplyDVCRSourceSettings updates importer Pod settings to use dvcr registry source. // NOTE: no auth secret required, it will be taken from DVCR destination settings. func ApplyDVCRSourceSettings(podEnvVars *Settings, dvcrImageName string) { - podEnvVars.Source = cc.SourceDVCR + podEnvVars.Source = SourceDVCR podEnvVars.Endpoint = dvcrImageName } // ApplyBlockDeviceSourceSettings updates importer Pod settings to use BlockDevice as source. func ApplyBlockDeviceSourceSettings(podEnvVars *Settings) { - podEnvVars.Source = cc.SourceBlockDevice + podEnvVars.Source = SourceBlockDevice } diff --git a/images/virtualization-artifact/pkg/controller/service/importer_service.go b/images/virtualization-artifact/pkg/controller/service/importer_service.go index a97e3c148..854836ccd 100644 --- a/images/virtualization-artifact/pkg/controller/service/importer_service.go +++ b/images/virtualization-artifact/pkg/controller/service/importer_service.go @@ -25,8 +25,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/deckhouse/virtualization-controller/pkg/common" "github.com/deckhouse/virtualization-controller/pkg/common/datasource" + "github.com/deckhouse/virtualization-controller/pkg/controller/common" "github.com/deckhouse/virtualization-controller/pkg/controller/importer" "github.com/deckhouse/virtualization-controller/pkg/controller/supplements" "github.com/deckhouse/virtualization-controller/pkg/dvcr"