diff --git a/api/unversioned/config/config.go b/api/unversioned/config/config.go index 2ddad4b85c..acaa34ff50 100644 --- a/api/unversioned/config/config.go +++ b/api/unversioned/config/config.go @@ -5,9 +5,11 @@ import ( "sync" "time" + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + "github.com/eraser-dev/eraser/api/unversioned" "github.com/eraser-dev/eraser/version" - "k8s.io/apimachinery/pkg/api/resource" ) var defaultScannerConfig = ` @@ -142,7 +144,8 @@ func Default() *unversioned.EraserConfig { Mem: resource.MustParse("2Gi"), CPU: resource.MustParse("1500m"), }, - Config: &defaultScannerConfig, + Config: &defaultScannerConfig, + Volumes: []v1.Volume{}, }, }, Remover: unversioned.ContainerConfig{ diff --git a/api/unversioned/eraserconfig_types.go b/api/unversioned/eraserconfig_types.go index 6f0bc5db80..970ce92dda 100644 --- a/api/unversioned/eraserconfig_types.go +++ b/api/unversioned/eraserconfig_types.go @@ -22,6 +22,7 @@ import ( "net/url" "time" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -153,6 +154,7 @@ type ContainerConfig struct { Request ResourceRequirements `json:"request,omitempty"` Limit ResourceRequirements `json:"limit,omitempty"` Config *string `json:"config,omitempty"` + Volumes []corev1.Volume `json:"volumes,omitempty"` } type ManagerConfig struct { diff --git a/api/unversioned/zz_generated.deepcopy.go b/api/unversioned/zz_generated.deepcopy.go index 1e4a4f2d1c..a66a7291d6 100644 --- a/api/unversioned/zz_generated.deepcopy.go +++ b/api/unversioned/zz_generated.deepcopy.go @@ -21,6 +21,7 @@ limitations under the License. package unversioned import ( + "k8s.io/api/core/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -53,6 +54,13 @@ func (in *ContainerConfig) DeepCopyInto(out *ContainerConfig) { *out = new(string) **out = **in } + if in.Volumes != nil { + in, out := &in.Volumes, &out.Volumes + *out = make([]v1.Volume, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerConfig. diff --git a/api/v1alpha1/eraserconfig_types.go b/api/v1alpha1/eraserconfig_types.go index c27bde1fb0..e34f9ca4a2 100644 --- a/api/v1alpha1/eraserconfig_types.go +++ b/api/v1alpha1/eraserconfig_types.go @@ -22,6 +22,7 @@ import ( "time" "github.com/eraser-dev/eraser/api/unversioned" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/conversion" @@ -88,6 +89,7 @@ type ContainerConfig struct { Request ResourceRequirements `json:"request,omitempty"` Limit ResourceRequirements `json:"limit,omitempty"` Config *string `json:"config,omitempty"` + Volumes []corev1.Volume `json:"volumes,omitempty"` } type ManagerConfig struct { diff --git a/api/v1alpha1/zz_generated.conversion.go b/api/v1alpha1/zz_generated.conversion.go index 98f62f724c..39dc6b622d 100644 --- a/api/v1alpha1/zz_generated.conversion.go +++ b/api/v1alpha1/zz_generated.conversion.go @@ -24,7 +24,8 @@ import ( unsafe "unsafe" unversioned "github.com/eraser-dev/eraser/api/unversioned" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" conversion "k8s.io/apimachinery/pkg/conversion" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -282,6 +283,7 @@ func autoConvert_v1alpha1_ContainerConfig_To_unversioned_ContainerConfig(in *Con return err } out.Config = (*string)(unsafe.Pointer(in.Config)) + out.Volumes = *(*[]v1.Volume)(unsafe.Pointer(&in.Volumes)) return nil } @@ -301,6 +303,7 @@ func autoConvert_unversioned_ContainerConfig_To_v1alpha1_ContainerConfig(in *unv return err } out.Config = (*string)(unsafe.Pointer(in.Config)) + out.Volumes = *(*[]v1.Volume)(unsafe.Pointer(&in.Volumes)) return nil } @@ -465,7 +468,7 @@ func autoConvert_v1alpha1_ImageJobStatus_To_unversioned_ImageJobStatus(in *Image out.Desired = in.Desired out.Skipped = in.Skipped out.Phase = unversioned.JobPhase(in.Phase) - out.DeleteAfter = (*v1.Time)(unsafe.Pointer(in.DeleteAfter)) + out.DeleteAfter = (*metav1.Time)(unsafe.Pointer(in.DeleteAfter)) return nil } @@ -480,7 +483,7 @@ func autoConvert_unversioned_ImageJobStatus_To_v1alpha1_ImageJobStatus(in *unver out.Desired = in.Desired out.Skipped = in.Skipped out.Phase = JobPhase(in.Phase) - out.DeleteAfter = (*v1.Time)(unsafe.Pointer(in.DeleteAfter)) + out.DeleteAfter = (*metav1.Time)(unsafe.Pointer(in.DeleteAfter)) return nil } @@ -564,7 +567,7 @@ func Convert_unversioned_ImageListSpec_To_v1alpha1_ImageListSpec(in *unversioned } func autoConvert_v1alpha1_ImageListStatus_To_unversioned_ImageListStatus(in *ImageListStatus, out *unversioned.ImageListStatus, s conversion.Scope) error { - out.Timestamp = (*v1.Time)(unsafe.Pointer(in.Timestamp)) + out.Timestamp = (*metav1.Time)(unsafe.Pointer(in.Timestamp)) out.Success = in.Success out.Failed = in.Failed out.Skipped = in.Skipped @@ -577,7 +580,7 @@ func Convert_v1alpha1_ImageListStatus_To_unversioned_ImageListStatus(in *ImageLi } func autoConvert_unversioned_ImageListStatus_To_v1alpha1_ImageListStatus(in *unversioned.ImageListStatus, out *ImageListStatus, s conversion.Scope) error { - out.Timestamp = (*v1.Time)(unsafe.Pointer(in.Timestamp)) + out.Timestamp = (*metav1.Time)(unsafe.Pointer(in.Timestamp)) out.Success = in.Success out.Failed = in.Failed out.Skipped = in.Skipped diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 31a79f5fa1..e0809bb7b7 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -21,6 +21,7 @@ limitations under the License. package v1alpha1 import ( + "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" ) @@ -53,6 +54,13 @@ func (in *ContainerConfig) DeepCopyInto(out *ContainerConfig) { *out = new(string) **out = **in } + if in.Volumes != nil { + in, out := &in.Volumes, &out.Volumes + *out = make([]v1.Volume, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerConfig. diff --git a/api/v1alpha2/eraserconfig_types.go b/api/v1alpha2/eraserconfig_types.go index f6f8ee8e39..c299ef948c 100644 --- a/api/v1alpha2/eraserconfig_types.go +++ b/api/v1alpha2/eraserconfig_types.go @@ -21,6 +21,7 @@ import ( "fmt" "time" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -86,6 +87,7 @@ type ContainerConfig struct { Request ResourceRequirements `json:"request,omitempty"` Limit ResourceRequirements `json:"limit,omitempty"` Config *string `json:"config,omitempty"` + Volumes []corev1.Volume `json:"volumes,omitempty"` } type ManagerConfig struct { diff --git a/api/v1alpha2/zz_generated.conversion.go b/api/v1alpha2/zz_generated.conversion.go index b7e282cf68..151e42ca17 100644 --- a/api/v1alpha2/zz_generated.conversion.go +++ b/api/v1alpha2/zz_generated.conversion.go @@ -24,6 +24,7 @@ import ( unsafe "unsafe" unversioned "github.com/eraser-dev/eraser/api/unversioned" + v1 "k8s.io/api/core/v1" conversion "k8s.io/apimachinery/pkg/conversion" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -215,6 +216,7 @@ func autoConvert_v1alpha2_ContainerConfig_To_unversioned_ContainerConfig(in *Con return err } out.Config = (*string)(unsafe.Pointer(in.Config)) + out.Volumes = *(*[]v1.Volume)(unsafe.Pointer(&in.Volumes)) return nil } @@ -234,6 +236,7 @@ func autoConvert_unversioned_ContainerConfig_To_v1alpha2_ContainerConfig(in *unv return err } out.Config = (*string)(unsafe.Pointer(in.Config)) + out.Volumes = *(*[]v1.Volume)(unsafe.Pointer(&in.Volumes)) return nil } diff --git a/api/v1alpha2/zz_generated.deepcopy.go b/api/v1alpha2/zz_generated.deepcopy.go index 54c04dcef7..86a7bfdc9a 100644 --- a/api/v1alpha2/zz_generated.deepcopy.go +++ b/api/v1alpha2/zz_generated.deepcopy.go @@ -21,6 +21,7 @@ limitations under the License. package v1alpha2 import ( + "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" ) @@ -53,6 +54,13 @@ func (in *ContainerConfig) DeepCopyInto(out *ContainerConfig) { *out = new(string) **out = **in } + if in.Volumes != nil { + in, out := &in.Volumes, &out.Volumes + *out = make([]v1.Volume, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerConfig. diff --git a/api/v1alpha3/eraserconfig_types.go b/api/v1alpha3/eraserconfig_types.go index 6f7ef2e434..48ac242bef 100644 --- a/api/v1alpha3/eraserconfig_types.go +++ b/api/v1alpha3/eraserconfig_types.go @@ -22,6 +22,7 @@ import ( "net/url" "time" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -153,6 +154,7 @@ type ContainerConfig struct { Request ResourceRequirements `json:"request,omitempty"` Limit ResourceRequirements `json:"limit,omitempty"` Config *string `json:"config,omitempty"` + Volumes []corev1.Volume `json:"volumes,omitempty"` } type ManagerConfig struct { diff --git a/api/v1alpha3/zz_generated.conversion.go b/api/v1alpha3/zz_generated.conversion.go index b40453f670..0a5888b970 100644 --- a/api/v1alpha3/zz_generated.conversion.go +++ b/api/v1alpha3/zz_generated.conversion.go @@ -24,6 +24,7 @@ import ( unsafe "unsafe" unversioned "github.com/eraser-dev/eraser/api/unversioned" + v1 "k8s.io/api/core/v1" conversion "k8s.io/apimachinery/pkg/conversion" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -215,6 +216,7 @@ func autoConvert_v1alpha3_ContainerConfig_To_unversioned_ContainerConfig(in *Con return err } out.Config = (*string)(unsafe.Pointer(in.Config)) + out.Volumes = *(*[]v1.Volume)(unsafe.Pointer(&in.Volumes)) return nil } @@ -234,6 +236,7 @@ func autoConvert_unversioned_ContainerConfig_To_v1alpha3_ContainerConfig(in *unv return err } out.Config = (*string)(unsafe.Pointer(in.Config)) + out.Volumes = *(*[]v1.Volume)(unsafe.Pointer(&in.Volumes)) return nil } diff --git a/api/v1alpha3/zz_generated.deepcopy.go b/api/v1alpha3/zz_generated.deepcopy.go index 689915b1dd..7d086d01b2 100644 --- a/api/v1alpha3/zz_generated.deepcopy.go +++ b/api/v1alpha3/zz_generated.deepcopy.go @@ -21,6 +21,7 @@ limitations under the License. package v1alpha3 import ( + "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" ) @@ -53,6 +54,13 @@ func (in *ContainerConfig) DeepCopyInto(out *ContainerConfig) { *out = new(string) **out = **in } + if in.Volumes != nil { + in, out := &in.Volumes, &out.Volumes + *out = make([]v1.Volume, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerConfig. diff --git a/config/manager/controller_manager_config.yaml b/config/manager/controller_manager_config.yaml index b13aba7b1e..710abff064 100644 --- a/config/manager/controller_manager_config.yaml +++ b/config/manager/controller_manager_config.yaml @@ -76,6 +76,7 @@ components: timeout: total: 23h perImage: 1h + volumes: [] remover: image: repo: REMOVER_REPO diff --git a/controllers/imagecollector/imagecollector_controller.go b/controllers/imagecollector/imagecollector_controller.go index 400ba36f46..8755177679 100644 --- a/controllers/imagecollector/imagecollector_controller.go +++ b/controllers/imagecollector/imagecollector_controller.go @@ -448,6 +448,27 @@ func (r *Reconciler) createImageJob(ctx context.Context) (ctrl.Result, error) { }, }, } + + log.Info("extra mount for scanner starts") + scannerVolumes := compCfg.Scanner.Volumes + if len(scannerVolumes) != 0 { + jobTemplate.Spec.Volumes = append(jobTemplate.Spec.Volumes, scannerVolumes...) + scannerVolumeMounts := []corev1.VolumeMount{} + for idx := range scannerVolumes { + volume := scannerVolumes[idx] + if volume.HostPath == nil { + log.Error(fmt.Errorf("volume hostPath is nil"), "invalid volume", "volumeName", volume.Name) + continue + } + scannerVolumeMounts = append(scannerVolumeMounts, corev1.VolumeMount{ + Name: volume.Name, + MountPath: volume.HostPath.Path, + ReadOnly: true, + }) + } + scannerContainer.VolumeMounts = append(scannerContainer.VolumeMounts, scannerVolumeMounts...) + } + jobTemplate.Spec.Containers = append(jobTemplate.Spec.Containers, scannerContainer) } diff --git a/docs/docs/customization.md b/docs/docs/customization.md index b89706e46b..4b562eb50c 100644 --- a/docs/docs/customization.md +++ b/docs/docs/customization.md @@ -105,6 +105,8 @@ manager: pullSecrets: [] # image pull secrets for collector/scanner/remover priorityClassName: "" # priority class name for collector/scanner/remover additionalPodLabels: {} + extraScannerVolumes: {} + extraScannerVolumeMounts: {} nodeFilter: type: exclude # must be either exclude|include selectors: @@ -228,6 +230,7 @@ timeout: | components.scanner.limit.mem | The maximum amount of memory the scanner container is allowed to use. | 2Gi | | components.scanner.limit.cpu | The maximum amount of CPU the scanner container is allowed to use. | 0 | | components.scanner.config | The configuration to pass to the scanner container, as a YAML string. | See YAML below | +| components.scanner.volumes | Extra volumes for scanner. | `{}` | | components.remover.image.repo | The repository containing the remover image. | ghcr.io/eraser-dev/remover | | components.remover.image.tag | The tag of the remover image. | v1.0.0 | | components.remover.request.mem | The amount of memory to request for the remover container. | 25Mi | diff --git a/manifest_staging/deploy/eraser.yaml b/manifest_staging/deploy/eraser.yaml index 172ad94172..30dd590783 100644 --- a/manifest_staging/deploy/eraser.yaml +++ b/manifest_staging/deploy/eraser.yaml @@ -489,6 +489,7 @@ data: timeout: total: 23h perImage: 1h + volumes: [] remover: image: repo: ghcr.io/eraser-dev/remover