diff --git a/images/dvcr-artifact/pkg/datasource/filesystem-datasource.go b/images/dvcr-artifact/pkg/datasource/filesystem-datasource.go new file mode 100644 index 0000000000..2a997499e7 --- /dev/null +++ b/images/dvcr-artifact/pkg/datasource/filesystem-datasource.go @@ -0,0 +1,76 @@ +/* +Copyright 2025 Flant JSC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package datasource + +import ( + "context" + "fmt" + "io" + "os" + + "github.com/google/uuid" +) + +type FilesystemDataSource struct { + readCloser io.ReadCloser + sourceImageSize int64 + sourceImageFilename string +} + +func NewFilesystemDataSource(ctx context.Context) (*FilesystemDataSource, error) { + filesystemImagePath := "/tmp/fs/disk.img" + + file, err := os.Open(filesystemImagePath) + if err != nil { + return nil, fmt.Errorf("can not get open image %s: %w", filesystemImagePath, err) + } + + sourceImageSize, err := file.Seek(0, io.SeekEnd) + if err != nil { + return nil, fmt.Errorf("error seeking to end: %w", err) + } + + _, err = file.Seek(0, io.SeekStart) + if err != nil { + return nil, fmt.Errorf("error seeking to start: %w", err) + } + + uuid, _ := uuid.NewUUID() + sourceImageFilename := uuid.String() + ".img" + + return &FilesystemDataSource{ + readCloser: file, + sourceImageSize: int64(sourceImageSize), + sourceImageFilename: sourceImageFilename, + }, nil +} + +func (ds *FilesystemDataSource) ReadCloser() (io.ReadCloser, error) { + return ds.readCloser, nil +} + +func (ds *FilesystemDataSource) Length() (int, error) { + return int(ds.sourceImageSize), nil +} + +func (ds *FilesystemDataSource) Filename() (string, error) { + return ds.sourceImageFilename, nil +} + +func (ds *FilesystemDataSource) Close() error { + return ds.readCloser.Close() +} diff --git a/images/dvcr-artifact/pkg/importer/importer.go b/images/dvcr-artifact/pkg/importer/importer.go index a544a77f4e..1c6534cb6b 100644 --- a/images/dvcr-artifact/pkg/importer/importer.go +++ b/images/dvcr-artifact/pkg/importer/importer.go @@ -49,6 +49,7 @@ const ( DockerRegistrySchemePrefix = "docker://" DVCRSource = "dvcr" BlockDeviceSource = "blockDevice" + FilesystemSource = "filesystem" ) func New() *Importer { @@ -180,7 +181,7 @@ func (i *Importer) runForDataSource(ctx context.Context) error { return monitoring.WriteImportCompleteMessage(res.SourceImageSize, res.VirtualSize, res.AvgSpeed, res.Format, durCollector.Collect()) } -func (i *Importer) newDataSource(_ context.Context) (datasource.DataSourceInterface, error) { +func (i *Importer) newDataSource(ctx context.Context) (datasource.DataSourceInterface, error) { var result datasource.DataSourceInterface switch i.srcType { case cc.SourceHTTP: @@ -201,6 +202,12 @@ func (i *Importer) newDataSource(_ context.Context) (datasource.DataSourceInterf if err != nil { return nil, fmt.Errorf("error creating block device data source: %w", err) } + case FilesystemSource: + var err error + result, err = datasource.NewFilesystemDataSource(ctx) + if err != nil { + return nil, fmt.Errorf("error creating filesystem data source: %w", err) + } default: return nil, fmt.Errorf("unknown source type: %s", i.srcType) } diff --git a/images/virtualization-artifact/pkg/common/consts.go b/images/virtualization-artifact/pkg/common/consts.go index 1a78a19bf3..41ddc972c7 100644 --- a/images/virtualization-artifact/pkg/common/consts.go +++ b/images/virtualization-artifact/pkg/common/consts.go @@ -79,6 +79,12 @@ const ( ImportProxyNoProxy = "no_proxy" // ImporterProxyCertDirVar provides a constant to capture our env variable "IMPORTER_PROXY_CERT_DIR" ImporterProxyCertDirVar = "IMPORTER_PROXY_CERT_DIR" + // ImporterFilesystemVar provides a constant to capture our env variable "IMPORTER_FILESYSTEM" + ImporterFilesystemVar = "IMPORTER_FILESYSTEM" + // ImporterFilesystemDir provides a constant to capture our env variable "IMPORTER_FILESYSTEM_DIR" + ImporterFilesystemDir = "/tmp/fs" + // ImporterBlockDeviceDir provides a constant to capture our directory for block device + ImporterBlockDeviceDir = "/dev/xvda" // ImporterDestinationAuthConfigDir is a mount directory for auth Secret. ImporterDestinationAuthConfigDir = "/dvcr-auth" diff --git a/images/virtualization-artifact/pkg/controller/bounder/bounder.go b/images/virtualization-artifact/pkg/controller/bounder/bounder.go index ed361e6a0d..4dffbcf623 100644 --- a/images/virtualization-artifact/pkg/controller/bounder/bounder.go +++ b/images/virtualization-artifact/pkg/controller/bounder/bounder.go @@ -112,13 +112,13 @@ func (imp *Bounder) makeBounderPodSpec() (*corev1.Pod, error) { } } - annotations.SetRecommendedLabels(&pod, imp.PodSettings.InstallerLabels, imp.PodSettings.ControllerName) - podutil.SetRestrictedSecurityContext(&pod.Spec) - container := imp.makeBounderContainerSpec() imp.addVolumes(&pod, container) pod.Spec.Containers = append(pod.Spec.Containers, *container) + annotations.SetRecommendedLabels(&pod, imp.PodSettings.InstallerLabels, imp.PodSettings.ControllerName) + podutil.SetRestrictedSecurityContext(&pod.Spec) + return &pod, nil } @@ -155,7 +155,7 @@ func (imp *Bounder) addVolumes(pod *corev1.Pod, container *corev1.Container) { }, corev1.VolumeDevice{ Name: "volume", - DevicePath: "/dev/xvda", + DevicePath: common.ImporterBlockDeviceDir, }, ) } diff --git a/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vd.go b/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vd.go index 8faf025d12..25ba137f87 100644 --- a/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vd.go +++ b/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vd.go @@ -111,8 +111,13 @@ func (ds ObjectRefVirtualDisk) Sync(ctx context.Context, cvi *v1alpha2.ClusterVi cvi.Status.Progress = ds.statService.GetProgress(cvi.GetUID(), pod, cvi.Status.Progress) cvi.Status.Target.RegistryURL = ds.statService.GetDVCRImageName(pod) - envSettings := ds.getEnvSettings(cvi, supgen) + pvc := &corev1.PersistentVolumeClaim{} + err := ds.client.Get(ctx, types.NamespacedName{Name: vdRef.Status.Target.PersistentVolumeClaim, Namespace: vdRef.Namespace}, pvc) + if err != nil { + return reconcile.Result{}, err + } + envSettings := ds.getEnvSettings(cvi, supgen, pvc.Spec.VolumeMode) ownerRef := metav1.NewControllerRef(cvi, cvi.GroupVersionKind()) podSettings := ds.importerService.GetPodSettingsWithPVC(ownerRef, supgen, vdRef.Status.Target.PersistentVolumeClaim, vdRef.Namespace) err = ds.importerService.StartWithPodSetting(ctx, envSettings, supgen, datasource.NewCABundleForCVMI(cvi.Spec.DataSource), podSettings) @@ -216,9 +221,15 @@ func (ds ObjectRefVirtualDisk) CleanUp(ctx context.Context, cvi *v1alpha2.Cluste return ds.importerService.DeletePod(ctx, cvi, controllerName, supgen) } -func (ds ObjectRefVirtualDisk) getEnvSettings(cvi *v1alpha2.ClusterVirtualImage, sup supplements.Generator) *importer.Settings { +func (ds ObjectRefVirtualDisk) getEnvSettings(cvi *v1alpha2.ClusterVirtualImage, sup supplements.Generator, volumeMode *corev1.PersistentVolumeMode) *importer.Settings { var settings importer.Settings - importer.ApplyBlockDeviceSourceSettings(&settings) + + if volumeMode != nil && *volumeMode == corev1.PersistentVolumeBlock { + importer.ApplyBlockDeviceSourceSettings(&settings) + } else { + importer.ApplyFilesystemSourceSettings(&settings) + } + importer.ApplyDVCRDestinationSettings( &settings, ds.dvcrSettings, diff --git a/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vdsnapshot.go b/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vdsnapshot.go index 4064d59a5e..9bef91ea9c 100644 --- a/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vdsnapshot.go +++ b/images/virtualization-artifact/pkg/controller/cvi/internal/source/object_ref_vdsnapshot.go @@ -207,7 +207,7 @@ func (ds ObjectRefVirtualDiskSnapshot) Sync(ctx context.Context, cvi *v1alpha2.C cvi.Status.Progress = ds.statService.GetProgress(cvi.GetUID(), pod, cvi.Status.Progress) cvi.Status.Target.RegistryURL = ds.statService.GetDVCRImageName(pod) - envSettings := ds.getEnvSettings(cvi, supgen) + envSettings := ds.getEnvSettings(cvi, supgen, pvc.Spec.VolumeMode) ownerRef := metav1.NewControllerRef(cvi, cvi.GroupVersionKind()) podSettings := ds.importerService.GetPodSettingsWithPVC(ownerRef, supgen, pvc.Name, pvc.Namespace) @@ -358,9 +358,15 @@ func (ds ObjectRefVirtualDiskSnapshot) CleanUp(ctx context.Context, cvi *v1alpha return importerRequeue || diskRequeue, nil } -func (ds ObjectRefVirtualDiskSnapshot) getEnvSettings(cvi *v1alpha2.ClusterVirtualImage, sup supplements.Generator) *importer.Settings { +func (ds ObjectRefVirtualDiskSnapshot) getEnvSettings(cvi *v1alpha2.ClusterVirtualImage, sup supplements.Generator, volumeMode *corev1.PersistentVolumeMode) *importer.Settings { var settings importer.Settings - importer.ApplyBlockDeviceSourceSettings(&settings) + + if volumeMode != nil && *volumeMode == corev1.PersistentVolumeBlock { + importer.ApplyBlockDeviceSourceSettings(&settings) + } else { + importer.ApplyFilesystemSourceSettings(&settings) + } + importer.ApplyDVCRDestinationSettings( &settings, ds.dvcrSettings, diff --git a/images/virtualization-artifact/pkg/controller/importer/importer_pod.go b/images/virtualization-artifact/pkg/controller/importer/importer_pod.go index 44d2ac912a..15949abb71 100644 --- a/images/virtualization-artifact/pkg/controller/importer/importer_pod.go +++ b/images/virtualization-artifact/pkg/controller/importer/importer_pod.go @@ -153,13 +153,13 @@ func (imp *Importer) makeImporterPodSpec() (*corev1.Pod, error) { } } - annotations.SetRecommendedLabels(&pod, imp.PodSettings.InstallerLabels, imp.PodSettings.ControllerName) - podutil.SetRestrictedSecurityContext(&pod.Spec) - container := imp.makeImporterContainerSpec() imp.addVolumes(&pod, container) pod.Spec.Containers = append(pod.Spec.Containers, *container) + annotations.SetRecommendedLabels(&pod, imp.PodSettings.InstallerLabels, imp.PodSettings.ControllerName) + podutil.SetRestrictedSecurityContext(&pod.Spec) + return &pod, nil } @@ -365,21 +365,19 @@ func (imp *Importer) addVolumes(pod *corev1.Pod, container *corev1.Container) { } if imp.PodSettings.PVCName != "" { - podutil.AddVolumeDevice( - pod, - container, - corev1.Volume{ - Name: "volume", - VolumeSource: corev1.VolumeSource{ - PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ - ClaimName: imp.PodSettings.PVCName, - }, + volume := corev1.Volume{ + Name: "volume", + VolumeSource: corev1.VolumeSource{ + PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ + ClaimName: imp.PodSettings.PVCName, }, }, - corev1.VolumeDevice{ - Name: "volume", - DevicePath: "/dev/xvda", - }, - ) + } + + if imp.EnvSettings.Source == SourceFilesystem { + podutil.AddVolume(pod, container, volume, corev1.VolumeMount{Name: "volume", MountPath: common.ImporterFilesystemDir}, corev1.EnvVar{Name: common.ImporterFilesystemVar, Value: common.ImporterFilesystemDir}) + } else { + podutil.AddVolumeDevice(pod, container, volume, corev1.VolumeDevice{Name: "volume", DevicePath: common.ImporterBlockDeviceDir}) + } } } diff --git a/images/virtualization-artifact/pkg/controller/importer/settings.go b/images/virtualization-artifact/pkg/controller/importer/settings.go index 8a312f65b7..3560c7884e 100644 --- a/images/virtualization-artifact/pkg/controller/importer/settings.go +++ b/images/virtualization-artifact/pkg/controller/importer/settings.go @@ -33,6 +33,8 @@ const ( SourceDVCR = "dvcr" // SourceBlockDevice is the source type of block device SourceBlockDevice = "blockDevice" + // SourceFilesystem is the source type of filesystem + SourceFilesystem = "filesystem" ) // Settings stores all possible settings for dvcr-importer binary. @@ -132,3 +134,8 @@ func ApplyDVCRSourceSettings(podEnvVars *Settings, dvcrImageName string) { func ApplyBlockDeviceSourceSettings(podEnvVars *Settings) { podEnvVars.Source = SourceBlockDevice } + +// ApplyFilesystemSourceSettings updates importer Pod settings to use filesystem as source. +func ApplyFilesystemSourceSettings(podEnvVars *Settings) { + podEnvVars.Source = SourceFilesystem +} diff --git a/images/virtualization-artifact/pkg/controller/uploader/uploader_pod.go b/images/virtualization-artifact/pkg/controller/uploader/uploader_pod.go index 813e6d86f0..4db1e97049 100644 --- a/images/virtualization-artifact/pkg/controller/uploader/uploader_pod.go +++ b/images/virtualization-artifact/pkg/controller/uploader/uploader_pod.go @@ -121,13 +121,13 @@ func (p *Pod) makeSpec() (*corev1.Pod, error) { } } - annotations.SetRecommendedLabels(&pod, p.PodSettings.InstallerLabels, p.PodSettings.ControllerName) - podutil.SetRestrictedSecurityContext(&pod.Spec) - container := p.makeUploaderContainerSpec() p.addVolumes(&pod, container) pod.Spec.Containers = append(pod.Spec.Containers, *container) + annotations.SetRecommendedLabels(&pod, p.PodSettings.InstallerLabels, p.PodSettings.ControllerName) + podutil.SetRestrictedSecurityContext(&pod.Spec) + return &pod, nil } diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vd.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vd.go index 344f45924a..b3ccea6390 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vd.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vd.go @@ -113,8 +113,13 @@ func (ds ObjectRefVirtualDisk) StoreToDVCR(ctx context.Context, vi *v1alpha2.Vir vi.Status.Progress = ds.statService.GetProgress(vi.GetUID(), pod, vi.Status.Progress) vi.Status.Target.RegistryURL = ds.statService.GetDVCRImageName(pod) - envSettings := ds.getEnvSettings(vi, supgen) + pvc := &corev1.PersistentVolumeClaim{} + err := ds.client.Get(ctx, types.NamespacedName{Name: vdRef.Status.Target.PersistentVolumeClaim, Namespace: vdRef.Namespace}, pvc) + if err != nil { + return reconcile.Result{}, err + } + envSettings := ds.getEnvSettings(vi, supgen, pvc.Spec.VolumeMode) ownerRef := metav1.NewControllerRef(vi, vi.GroupVersionKind()) podSettings := ds.importerService.GetPodSettingsWithPVC(ownerRef, supgen, vdRef.Status.Target.PersistentVolumeClaim, vdRef.Namespace) err = ds.importerService.StartWithPodSetting(ctx, envSettings, supgen, datasource.NewCABundleForVMI(vi.GetNamespace(), vi.Spec.DataSource), podSettings) @@ -411,9 +416,15 @@ func (ds ObjectRefVirtualDisk) CleanUp(ctx context.Context, vi *v1alpha2.Virtual return importerRequeue || diskRequeue, nil } -func (ds ObjectRefVirtualDisk) getEnvSettings(vi *v1alpha2.VirtualImage, sup supplements.Generator) *importer.Settings { +func (ds ObjectRefVirtualDisk) getEnvSettings(vi *v1alpha2.VirtualImage, sup supplements.Generator, volumeMode *corev1.PersistentVolumeMode) *importer.Settings { var settings importer.Settings - importer.ApplyBlockDeviceSourceSettings(&settings) + + if volumeMode != nil && *volumeMode == corev1.PersistentVolumeBlock { + importer.ApplyBlockDeviceSourceSettings(&settings) + } else { + importer.ApplyFilesystemSourceSettings(&settings) + } + importer.ApplyDVCRDestinationSettings( &settings, ds.dvcrSettings, diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vdsnapshot_cr.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vdsnapshot_cr.go index 9478c42aee..176269f2c6 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vdsnapshot_cr.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vdsnapshot_cr.go @@ -89,7 +89,7 @@ func (ds ObjectRefVirtualDiskSnapshotCR) Sync(ctx context.Context, vi *v1alpha2. step.NewReadyContainerRegistryStep(pod, ds.importer, ds.diskService, ds.stat, ds.recorder, cb), step.NewTerminatingStep(pvc), step.NewCreatePersistentVolumeClaimStep(pvc, ds.recorder, ds.client, cb), - step.NewCreatePodStep(pod, ds.dvcrSettings, ds.recorder, ds.importer, ds.stat, cb), + step.NewCreatePodStep(pod, ds.client, ds.dvcrSettings, ds.recorder, ds.importer, ds.stat, cb), step.NewWaitForPodStep(pod, pvc, ds.stat, cb), ).Run(ctx, vi) } diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vdsnapshot_cr_test.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vdsnapshot_cr_test.go index 33c5db4a06..da64fd1a44 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vdsnapshot_cr_test.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/object_ref_vdsnapshot_cr_test.go @@ -57,6 +57,7 @@ var _ = Describe("ObjectRef VirtualImageSnapshot ContainerRegistry", func() { ctx context.Context scheme *runtime.Scheme vi *v1alpha2.VirtualImage + vd *v1alpha2.VirtualDisk vs *vsv1.VolumeSnapshot sc *storagev1.StorageClass vdSnapshot *v1alpha2.VirtualDiskSnapshot @@ -142,7 +143,7 @@ var _ = Describe("ObjectRef VirtualImageSnapshot ContainerRegistry", func() { Name: "vd-snapshot", UID: "11111111-1111-1111-1111-111111111111", }, - Spec: v1alpha2.VirtualDiskSnapshotSpec{}, + Spec: v1alpha2.VirtualDiskSnapshotSpec{VirtualDiskName: "vd"}, Status: v1alpha2.VirtualDiskSnapshotStatus{ Phase: v1alpha2.VirtualDiskSnapshotPhaseReady, VolumeSnapshotName: vs.Name, @@ -185,6 +186,18 @@ var _ = Describe("ObjectRef VirtualImageSnapshot ContainerRegistry", func() { Name: supgen.ImporterPod().Name, }, } + + vd = &v1alpha2.VirtualDisk{ + ObjectMeta: metav1.ObjectMeta{ + Name: "vd", + UID: "11111111-1111-1111-1111-111111111111", + }, + Status: v1alpha2.VirtualDiskStatus{ + Target: v1alpha2.DiskTarget{ + PersistentVolumeClaim: pvc.Name, + }, + }, + } }) Context("VirtualImage has just been created", func() { @@ -208,7 +221,7 @@ var _ = Describe("ObjectRef VirtualImageSnapshot ContainerRegistry", func() { } vi.Status = v1alpha2.VirtualImageStatus{} - client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(vdSnapshot, vs). + client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(vdSnapshot, vs, vd, pvc). WithInterceptorFuncs(interceptor.Funcs{ Create: func(_ context.Context, _ client.WithWatch, obj client.Object, _ ...client.CreateOption) error { switch obj.(type) { diff --git a/images/virtualization-artifact/pkg/controller/vi/internal/source/step/create_pod_step.go b/images/virtualization-artifact/pkg/controller/vi/internal/source/step/create_pod_step.go index 9b28b8558e..2509ebbeb9 100644 --- a/images/virtualization-artifact/pkg/controller/vi/internal/source/step/create_pod_step.go +++ b/images/virtualization-artifact/pkg/controller/vi/internal/source/step/create_pod_step.go @@ -23,6 +23,8 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/reconcile" "github.com/deckhouse/virtualization-controller/pkg/common" @@ -54,6 +56,7 @@ type CreatePodStepStat interface { type CreatePodStep struct { pod *corev1.Pod dvcrSettings *dvcr.Settings + client client.Client recorder eventrecord.EventRecorderLogger importer CreatePodStepImporter stat CreatePodStepStat @@ -62,6 +65,7 @@ type CreatePodStep struct { func NewCreatePodStep( pod *corev1.Pod, + client client.Client, dvcrSettings *dvcr.Settings, recorder eventrecord.EventRecorderLogger, importer CreatePodStepImporter, @@ -70,6 +74,7 @@ func NewCreatePodStep( ) *CreatePodStep { return &CreatePodStep{ pod: pod, + client: client, dvcrSettings: dvcrSettings, recorder: recorder, importer: importer, @@ -88,9 +93,26 @@ func (s CreatePodStep) Take(ctx context.Context, vi *v1alpha2.VirtualImage) (*re pvcKey := supgen.PersistentVolumeClaim() podSettings := s.importer.GetPodSettingsWithPVC(ownerRef, supgen, pvcKey.Name, pvcKey.Namespace) - envSettings := s.getEnvSettings(vi, supgen) + vds := &v1alpha2.VirtualDiskSnapshot{} + err := s.client.Get(ctx, types.NamespacedName{Name: vi.Spec.DataSource.ObjectRef.Name, Namespace: vi.Namespace}, vds) + if err != nil { + return &reconcile.Result{}, err + } + + vd := &v1alpha2.VirtualDisk{} + err = s.client.Get(ctx, types.NamespacedName{Name: vds.Spec.VirtualDiskName, Namespace: vds.Namespace}, vd) + if err != nil { + return &reconcile.Result{}, err + } + + pvc := &corev1.PersistentVolumeClaim{} + err = s.client.Get(ctx, types.NamespacedName{Name: vd.Status.Target.PersistentVolumeClaim, Namespace: vd.Namespace}, pvc) + if err != nil { + return &reconcile.Result{}, err + } - err := s.importer.StartWithPodSetting(ctx, envSettings, supgen, datasource.NewCABundleForVMI(vi.GetNamespace(), vi.Spec.DataSource), podSettings) + envSettings := s.getEnvSettings(vi, supgen, pvc.Spec.VolumeMode) + err = s.importer.StartWithPodSetting(ctx, envSettings, supgen, datasource.NewCABundleForVMI(vi.GetNamespace(), vi.Spec.DataSource), podSettings) switch { case err == nil: // OK. @@ -111,9 +133,15 @@ func (s CreatePodStep) Take(ctx context.Context, vi *v1alpha2.VirtualImage) (*re return nil, nil } -func (s CreatePodStep) getEnvSettings(vi *v1alpha2.VirtualImage, sup supplements.Generator) *importer.Settings { +func (s CreatePodStep) getEnvSettings(vi *v1alpha2.VirtualImage, sup supplements.Generator, volumeMode *corev1.PersistentVolumeMode) *importer.Settings { var settings importer.Settings - importer.ApplyBlockDeviceSourceSettings(&settings) + + if volumeMode != nil && *volumeMode == corev1.PersistentVolumeBlock { + importer.ApplyBlockDeviceSourceSettings(&settings) + } else { + importer.ApplyFilesystemSourceSettings(&settings) + } + importer.ApplyDVCRDestinationSettings( &settings, s.dvcrSettings,