diff --git a/cmd/virtlet/virtlet.go b/cmd/virtlet/virtlet.go index e39cbb0d7..a5b6b1bbe 100644 --- a/cmd/virtlet/virtlet.go +++ b/cmd/virtlet/virtlet.go @@ -86,7 +86,7 @@ func runTapManager(config *v1.VirtletConfig) { glog.Errorf("FD server returned error: %v", err) os.Exit(1) } - if err := libvirttools.ChownForEmulator(*config.FDServerSocketPath); err != nil { + if err := libvirttools.ChownForEmulator(*config.FDServerSocketPath, false); err != nil { glog.Warningf("Couldn't set tapmanager socket permissions: %v", err) } for { diff --git a/deploy/data/virtlet-ds.yaml b/deploy/data/virtlet-ds.yaml index 1da988355..20eb1004d 100644 --- a/deploy/data/virtlet-ds.yaml +++ b/deploy/data/virtlet-ds.yaml @@ -185,6 +185,7 @@ spec: mountPath: /dev - mountPath: /var/lib/virtlet name: virtlet + mountPropagation: Bidirectional - mountPath: /var/lib/libvirt name: libvirt - mountPath: /var/run/libvirt @@ -222,10 +223,14 @@ spec: volumeMounts: - mountPath: /var/lib/virtlet name: virtlet + mountPropagation: HostToContainer - mountPath: /var/lib/libvirt name: libvirt - name: vms-log mountPath: /var/log/vms + - mountPath: /var/lib/kubelet/pods + name: k8s-pods-dir + mountPropagation: HostToContainer - name: dev mountPath: /dev - name: modules diff --git a/pkg/flexvolume/flexvolume.go b/pkg/flexvolume/flexvolume.go index ff4387a21..3196b94a8 100644 --- a/pkg/flexvolume/flexvolume.go +++ b/pkg/flexvolume/flexvolume.go @@ -269,6 +269,10 @@ func formatResult(fields map[string]interface{}, err error) string { // means that no partition number was specified. func GetFlexvolumeInfo(dir string) (string, int, error) { dataFile := filepath.Join(dir, flexvolumeDataFile) + if _, err := os.Stat(dataFile); os.IsNotExist(err) { + return "", 0, err + } + var opts map[string]interface{} if err := utils.ReadJSON(dataFile, &opts); err != nil { return "", 0, fmt.Errorf("can't read flexvolume data file %q: %v", dataFile, err) diff --git a/pkg/libvirttools/TestContainerLifecycle.out.yaml b/pkg/libvirttools/TestContainerLifecycle.out.yaml index 31d1b1587..349234816 100755 --- a/pkg/libvirttools/TestContainerLifecycle.out.yaml +++ b/pkg/libvirttools/TestContainerLifecycle.out.yaml @@ -122,6 +122,7 @@ UserDataOverwrite: false UserDataScript: "" VCPUCount: 1 + VirtletChown9pfsMounts: false PodAnnotations: hello: world virt: let @@ -176,6 +177,7 @@ UserDataOverwrite: false UserDataScript: "" VCPUCount: 1 + VirtletChown9pfsMounts: false PodAnnotations: hello: world virt: let @@ -225,6 +227,7 @@ UserDataOverwrite: false UserDataScript: "" VCPUCount: 1 + VirtletChown9pfsMounts: false PodAnnotations: hello: world virt: let diff --git a/pkg/libvirttools/TestDomainForcedShutdown.out.yaml b/pkg/libvirttools/TestDomainForcedShutdown.out.yaml index 1724e3bfe..b1068d6b3 100755 --- a/pkg/libvirttools/TestDomainForcedShutdown.out.yaml +++ b/pkg/libvirttools/TestDomainForcedShutdown.out.yaml @@ -138,6 +138,7 @@ UserDataOverwrite: false UserDataScript: "" VCPUCount: 1 + VirtletChown9pfsMounts: false PodAnnotations: hello: world virt: let diff --git a/pkg/libvirttools/ceph_flexvolume.go b/pkg/libvirttools/ceph_flexvolume.go index 4c6a06cb4..40f6a49e6 100644 --- a/pkg/libvirttools/ceph_flexvolume.go +++ b/pkg/libvirttools/ceph_flexvolume.go @@ -93,24 +93,24 @@ func (v *cephVolume) UUID() string { return v.opts.UUID } -func (v *cephVolume) Setup() (*libvirtxml.DomainDisk, error) { +func (v *cephVolume) Setup() (*libvirtxml.DomainDisk, *libvirtxml.DomainFilesystem, error) { ipPortPair := strings.Split(v.opts.Monitor, ":") if len(ipPortPair) != 2 { - return nil, fmt.Errorf("invalid format of ceph monitor setting: %s. Expected ip:port", v.opts.Monitor) + return nil, nil, fmt.Errorf("invalid format of ceph monitor setting: %s. Expected ip:port", v.opts.Monitor) } secret, err := v.owner.DomainConnection().DefineSecret(v.secretDef()) if err != nil { - return nil, fmt.Errorf("error defining ceph secret: %v", err) + return nil, nil, fmt.Errorf("error defining ceph secret: %v", err) } key, err := base64.StdEncoding.DecodeString(v.opts.Secret) if err != nil { - return nil, fmt.Errorf("error decoding ceph secret: %v", err) + return nil, nil, fmt.Errorf("error decoding ceph secret: %v", err) } if err := secret.SetValue([]byte(key)); err != nil { - return nil, fmt.Errorf("error setting value of secret %q: %v", v.secretUsageName(), err) + return nil, nil, fmt.Errorf("error setting value of secret %q: %v", v.secretUsageName(), err) } return &libvirtxml.DomainDisk{ @@ -135,7 +135,7 @@ func (v *cephVolume) Setup() (*libvirtxml.DomainDisk, error) { }, }, }, - }, nil + }, nil, nil } func (v *cephVolume) Teardown() error { diff --git a/pkg/libvirttools/cloudinit.go b/pkg/libvirttools/cloudinit.go index f211d03a3..4613a167e 100644 --- a/pkg/libvirttools/cloudinit.go +++ b/pkg/libvirttools/cloudinit.go @@ -467,36 +467,31 @@ func (g *CloudInitGenerator) generateMounts(volumeMap diskPathMap) ([]interface{ var mountScriptLines []string for _, m := range g.config.Mounts { // Skip file based mounts (including secrets and config maps). - if isRegularFile(m.HostPath) { + if isRegularFile(m.HostPath) || + strings.Contains(m.HostPath, "kubernetes.io~secret") || + strings.Contains(m.HostPath, "kubernetes.io~configmap") { continue } - uuid, part, err := flexvolume.GetFlexvolumeInfo(m.HostPath) + mountInfo, mountScriptLine, err := generateFlexvolumeMounts(volumeMap, m) if err != nil { - glog.Errorf("Can't mount directory %q to %q inside the VM: can't get flexvolume uuid: %v", m.HostPath, m.ContainerPath, err) - continue - } - dpath, found := volumeMap[uuid] - if !found { - glog.Errorf("Can't mount directory %q to %q inside the VM: no device found for flexvolume uuid %q", m.HostPath, m.ContainerPath, uuid) - continue - } - if part < 0 { - part = 1 - } - devPath := dpath.devPath - mountDevSuffix := "" - if part != 0 { - devPath += fmt.Sprintf("-part%d", part) - mountDevSuffix += strconv.Itoa(part) + if !os.IsNotExist(err) { + glog.Errorf("Can't mount directory %q to %q inside the VM: %v", m.HostPath, m.ContainerPath, err) + continue + } + + // Fs based volume + mountInfo, mountScriptLine, err = generateFsBasedVolumeMounts(m) + if err != nil { + glog.Errorf("Can't mount directory %q to %q inside the VM: %v", m.HostPath, m.ContainerPath, err) + continue + } } - r = append(r, []interface{}{devPath, m.ContainerPath}) - mountScriptLines = append( - mountScriptLines, - // TODO: do better job at escaping m.ContainerPath - fmt.Sprintf("if ! mountpoint '%s'; then mkdir -p '%s' && mount /dev/`ls %s`%s '%s'; fi", - m.ContainerPath, m.ContainerPath, dpath.sysfsPath, mountDevSuffix, m.ContainerPath)) + + r = append(r, mountInfo) + mountScriptLines = append(mountScriptLines, mountScriptLine) } + mountScript := "" if len(mountScriptLines) != 0 { mountScript = fmt.Sprintf("#!/bin/sh\n%s\n", strings.Join(mountScriptLines, "\n")) @@ -504,6 +499,44 @@ func (g *CloudInitGenerator) generateMounts(volumeMap diskPathMap) ([]interface{ return r, mountScript } +func generateFlexvolumeMounts(volumeMap diskPathMap, mount types.VMMount) ([]interface{}, string, error) { + uuid, part, err := flexvolume.GetFlexvolumeInfo(mount.HostPath) + if err != nil { + // If the error is NotExist, return the original error + if os.IsNotExist(err) { + return nil, "", err + } + err = fmt.Errorf("can't get flexvolume uuid: %v", err) + return nil, "", err + } + dpath, found := volumeMap[uuid] + if !found { + err = fmt.Errorf("no device found for flexvolume uuid %q", uuid) + return nil, "", err + } + if part < 0 { + part = 1 + } + devPath := dpath.devPath + mountDevSuffix := "" + if part != 0 { + devPath += fmt.Sprintf("-part%d", part) + mountDevSuffix += strconv.Itoa(part) + } + // TODO: do better job at escaping mount.ContainerPath + mountScriptLine := fmt.Sprintf("if ! mountpoint '%s'; then mkdir -p '%s' && mount /dev/`ls %s`%s '%s'; fi", + mount.ContainerPath, mount.ContainerPath, dpath.sysfsPath, mountDevSuffix, mount.ContainerPath) + return []interface{}{devPath, mount.ContainerPath}, mountScriptLine, nil +} + +func generateFsBasedVolumeMounts(mount types.VMMount) ([]interface{}, string, error) { + mountTag := path.Base(mount.ContainerPath) + fsMountScript := fmt.Sprintf("if ! mountpoint '%s'; then mkdir -p '%s' && mount -t 9p -o trans=virtio %s '%s'; fi", + mount.ContainerPath, mount.ContainerPath, mountTag, mount.ContainerPath) + r := []interface{}{mountTag, mount.ContainerPath, "9p", "trans=virtio"} + return r, fsMountScript, nil +} + type writeFilesUpdater struct { entries []interface{} mounts []types.VMMount diff --git a/pkg/libvirttools/config_volumesource.go b/pkg/libvirttools/config_volumesource.go index 8523cbb27..1f1d528ab 100644 --- a/pkg/libvirttools/config_volumesource.go +++ b/pkg/libvirttools/config_volumesource.go @@ -51,8 +51,8 @@ func (v *configVolume) cloudInitGenerator() *CloudInitGenerator { return NewCloudInitGenerator(v.config, configIsoDir) } -func (v *configVolume) Setup() (*libvirtxml.DomainDisk, error) { - return v.cloudInitGenerator().DiskDef(), nil +func (v *configVolume) Setup() (*libvirtxml.DomainDisk, *libvirtxml.DomainFilesystem, error) { + return v.cloudInitGenerator().DiskDef(), nil, nil } func (v *configVolume) WriteImage(volumeMap diskPathMap) error { diff --git a/pkg/libvirttools/defaultvolumesrc.go b/pkg/libvirttools/defaultvolumesrc.go index b56a99a1f..028771ff6 100644 --- a/pkg/libvirttools/defaultvolumesrc.go +++ b/pkg/libvirttools/defaultvolumesrc.go @@ -22,6 +22,7 @@ func GetDefaultVolumeSource() VMVolumeSource { return CombineVMVolumeSources( GetRootVolume, ScanFlexVolumes, + GetFileSystemVolumes, // XXX: GetConfigVolume must go last because it // doesn't produce correct name for cdrom devices GetConfigVolume) diff --git a/pkg/libvirttools/disklist.go b/pkg/libvirttools/disklist.go index f83b06902..a0733aa05 100644 --- a/pkg/libvirttools/disklist.go +++ b/pkg/libvirttools/disklist.go @@ -32,14 +32,16 @@ type diskItem struct { volume VMVolume } -func (di *diskItem) setup(config *types.VMConfig) (*libvirtxml.DomainDisk, error) { - diskDef, err := di.volume.Setup() +func (di *diskItem) setup(config *types.VMConfig) (*libvirtxml.DomainDisk, *libvirtxml.DomainFilesystem, error) { + diskDef, fsDef, err := di.volume.Setup() if err != nil { - return nil, err + return nil, nil, err + } + if diskDef != nil { + diskDef.Target = di.driver.target() + diskDef.Address = di.driver.address() } - diskDef.Target = di.driver.target() - diskDef.Address = di.driver.address() - return diskDef, nil + return diskDef, fsDef, nil } type diskList struct { @@ -72,11 +74,12 @@ func newDiskList(config *types.VMConfig, source VMVolumeSource, owner volumeOwne } // setup performs the setup procedure on each volume in the diskList -// and returns a list of libvirtxml DomainDisk structs -func (dl *diskList) setup() ([]libvirtxml.DomainDisk, error) { +// and returns a list of libvirtxml DomainDisk and domainFileSystems structs +func (dl *diskList) setup() ([]libvirtxml.DomainDisk, []libvirtxml.DomainFilesystem, error) { var domainDisks []libvirtxml.DomainDisk + var domainFileSystems []libvirtxml.DomainFilesystem for n, item := range dl.items { - diskDef, err := item.setup(dl.config) + diskDef, fsDef, err := item.setup(dl.config) if err != nil { // try to tear down volumes that were already set up for _, item := range dl.items[:n] { @@ -84,11 +87,16 @@ func (dl *diskList) setup() ([]libvirtxml.DomainDisk, error) { glog.Warningf("Failed to tear down a volume on error: %v", err) } } - return nil, err + return nil, nil, err + } + if diskDef != nil { + domainDisks = append(domainDisks, *diskDef) + } + if fsDef != nil { + domainFileSystems = append(domainFileSystems, *fsDef) } - domainDisks = append(domainDisks, *diskDef) } - return domainDisks, nil + return domainDisks, domainFileSystems, nil } // writeImages writes images for volumes that are based on generated diff --git a/pkg/libvirttools/fileownership.go b/pkg/libvirttools/fileownership.go index 267655f15..ad7df740d 100644 --- a/pkg/libvirttools/fileownership.go +++ b/pkg/libvirttools/fileownership.go @@ -20,8 +20,11 @@ import ( "fmt" "os" "os/user" + "path/filepath" "strconv" "sync" + + "github.com/golang/glog" ) const ( @@ -35,7 +38,7 @@ var emulatorUser struct { } // ChownForEmulator makes a file or directory owned by the emulator user. -func ChownForEmulator(filePath string) error { +func ChownForEmulator(filePath string, recursive bool) error { emulatorUser.Lock() defer emulatorUser.Unlock() if !emulatorUser.initialized { @@ -52,8 +55,26 @@ func ChownForEmulator(filePath string) error { return fmt.Errorf("bad gid %q for user %q: %v", u.Gid, emulatorUserName, err) } } - if err := os.Chown(filePath, emulatorUser.uid, emulatorUser.gid); err != nil { - return fmt.Errorf("can't set the owner of tapmanager socket: %v", err) + + chown := os.Chown + if recursive { + chown = ChownR + } + if err := chown(filePath, emulatorUser.uid, emulatorUser.gid); err != nil { + return fmt.Errorf("can't set the owner of %q: %v", filePath, err) } return nil } + +// ChownR makes a file or directory owned by the emulator user recursively. +func ChownR(path string, uid, gid int) error { + return filepath.Walk(path, func(name string, info os.FileInfo, err error) error { + if err == nil { + err = os.Chown(name, uid, gid) + if err != nil { + glog.Warningf("Failed to change the owner of %q: %v", name, err) + } + } + return err + }) +} diff --git a/pkg/libvirttools/filesystem_volumesource.go b/pkg/libvirttools/filesystem_volumesource.go new file mode 100644 index 000000000..fb3902b28 --- /dev/null +++ b/pkg/libvirttools/filesystem_volumesource.go @@ -0,0 +1,52 @@ +/* +Copyright 2018 Mirantis + +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 libvirttools + +import ( + "fmt" + "os" + "path" + "strings" + + "github.com/Mirantis/virtlet/pkg/metadata/types" +) + +// GetFileSystemVolumes using prepared by kubelet volumes and contained in pod sandbox +// annotations prepares volumes to be passed to libvirt as a DomainFileSystem definitions. +func GetFileSystemVolumes(config *types.VMConfig, owner volumeOwner) ([]VMVolume, error) { + volumePoolPath := supportedStoragePools[owner.VolumePoolName()] + if _, err := os.Stat(volumePoolPath); err != nil { + return nil, err + } + + var fsVolumes []VMVolume + for index, mount := range config.Mounts { + if isRegularFile(mount.HostPath) || + strings.Contains(mount.HostPath, flexvolumeSubdir) || + strings.Contains(mount.HostPath, "kubernetes.io~secret") || + strings.Contains(mount.HostPath, "kubernetes.io~configmap") { + continue + } + + // `Index` is used to avoid causing conflicts as multiple host paths can have the same `path.Base` + volumeDirName := fmt.Sprintf("virtlet_%s_%s_%d", config.DomainUUID, path.Base(mount.HostPath), index) + volumeMountPoint := path.Join(volumePoolPath, volumeDirName) + fsVolumes = append(fsVolumes, &filesystemVolume{mount: mount, volumeMountPoint: volumeMountPoint}) + } + + return fsVolumes, nil +} diff --git a/pkg/libvirttools/filesystemvolume.go b/pkg/libvirttools/filesystemvolume.go new file mode 100644 index 000000000..f2a9c5535 --- /dev/null +++ b/pkg/libvirttools/filesystemvolume.go @@ -0,0 +1,80 @@ +/* +Copyright 2018 Mirantis + +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 libvirttools + +import ( + "fmt" + "os" + "path" + + libvirtxml "github.com/libvirt/libvirt-go-xml" + + "github.com/Mirantis/virtlet/pkg/metadata/types" + "github.com/Mirantis/virtlet/pkg/utils" +) + +// rootVolume denotes the root disk of the VM +type filesystemVolume struct { + volumeBase + mount types.VMMount + volumeMountPoint string + chownRecursively bool +} + +var _ VMVolume = &filesystemVolume{} + +var mounter = utils.NewMounter() + +func (v *filesystemVolume) UUID() string { return "" } + +func (v *filesystemVolume) Setup() (*libvirtxml.DomainDisk, *libvirtxml.DomainFilesystem, error) { + err := os.MkdirAll(v.volumeMountPoint, 0777) + if err == nil { + err = ChownForEmulator(v.volumeMountPoint, false) + } + if err == nil && v.chownRecursively { + err = mounter.Mount(v.mount.HostPath, v.volumeMountPoint, "bind") + } + if err == nil { + err = ChownForEmulator(v.volumeMountPoint, true) + } + if err != nil { + return nil, nil, fmt.Errorf("failed to create vm pod path: %v", err) + } + + fsDef := &libvirtxml.DomainFilesystem{ + AccessMode: "squash", + Source: &libvirtxml.DomainFilesystemSource{Mount: &libvirtxml.DomainFilesystemSourceMount{Dir: v.volumeMountPoint}}, + Target: &libvirtxml.DomainFilesystemTarget{Dir: path.Base(v.mount.ContainerPath)}, + } + + return nil, fsDef, nil +} + +func (v *filesystemVolume) Teardown() error { + var err error + if _, err = os.Stat(v.volumeMountPoint); err == nil { + err = mounter.Unmount(v.volumeMountPoint) + } + if err == nil { + err = os.Remove(v.volumeMountPoint) + } + if err != nil { + return fmt.Errorf("failed to tear down fs volume mountpoint '%s': %v", v.volumeMountPoint, err) + } + return nil +} diff --git a/pkg/libvirttools/flexvolume_volumesource.go b/pkg/libvirttools/flexvolume_volumesource.go index b23fae9ec..22fc07bb1 100644 --- a/pkg/libvirttools/flexvolume_volumesource.go +++ b/pkg/libvirttools/flexvolume_volumesource.go @@ -67,6 +67,9 @@ func ScanFlexVolumes(config *types.VMConfig, owner volumeOwner) ([]VMVolume, err dataFilePath := filepath.Join(dir, fi.Name(), flexvolumeDataFile) content, err := ioutil.ReadFile(dataFilePath) if err != nil { + if os.IsNotExist(err) { + continue + } return nil, fmt.Errorf("error reading flexvolume config %q: %v", dataFilePath, err) } var msi map[string]interface{} diff --git a/pkg/libvirttools/qcow2_flexvolume.go b/pkg/libvirttools/qcow2_flexvolume.go index 998ac890a..705d31b0b 100644 --- a/pkg/libvirttools/qcow2_flexvolume.go +++ b/pkg/libvirttools/qcow2_flexvolume.go @@ -97,27 +97,27 @@ func (v *qcow2Volume) UUID() string { return v.uuid } -func (v *qcow2Volume) Setup() (*libvirtxml.DomainDisk, error) { +func (v *qcow2Volume) Setup() (*libvirtxml.DomainDisk, *libvirtxml.DomainFilesystem, error) { vol, err := v.createQCOW2Volume(uint64(v.capacity), v.capacityUnit) if err != nil { - return nil, fmt.Errorf("error during creation of volume '%s' with virtlet description %s: %v", v.volumeName(), v.name, err) + return nil, nil, fmt.Errorf("error during creation of volume '%s' with virtlet description %s: %v", v.volumeName(), v.name, err) } path, err := vol.Path() if err != nil { - return nil, err + return nil, nil, err } err = vol.Format() if err != nil { - return nil, err + return nil, nil, err } return &libvirtxml.DomainDisk{ Device: "disk", Source: &libvirtxml.DomainDiskSource{File: &libvirtxml.DomainDiskSourceFile{File: path}}, Driver: &libvirtxml.DomainDiskDriver{Name: "qemu", Type: "qcow2"}, - }, nil + }, nil, nil } func (v *qcow2Volume) Teardown() error { diff --git a/pkg/libvirttools/qcow2_flexvolume_test.go b/pkg/libvirttools/qcow2_flexvolume_test.go index 02f67bbff..413411d8d 100644 --- a/pkg/libvirttools/qcow2_flexvolume_test.go +++ b/pkg/libvirttools/qcow2_flexvolume_test.go @@ -91,7 +91,7 @@ func TestQCOW2VolumeLifeCycle(t *testing.T) { t.Fatalf("newQCOW2Volume returned an error: %v", err) } - vol, err := volume.Setup() + vol, _, err := volume.Setup() if err != nil { t.Errorf("Setup returned an error: %v", err) } diff --git a/pkg/libvirttools/raw_flexvolume.go b/pkg/libvirttools/raw_flexvolume.go index 60681fb05..6c418e866 100644 --- a/pkg/libvirttools/raw_flexvolume.go +++ b/pkg/libvirttools/raw_flexvolume.go @@ -78,19 +78,19 @@ func (v *rawDeviceVolume) UUID() string { return v.opts.UUID } -func (v *rawDeviceVolume) Setup() (*libvirtxml.DomainDisk, error) { +func (v *rawDeviceVolume) Setup() (*libvirtxml.DomainDisk, *libvirtxml.DomainFilesystem, error) { if err := v.verifyRawDeviceWhitelisted(v.opts.Path); err != nil { - return nil, err + return nil, nil, err } if err := verifyRawDeviceAccess(v.opts.Path); err != nil { - return nil, err + return nil, nil, err } return &libvirtxml.DomainDisk{ Device: "disk", Source: &libvirtxml.DomainDiskSource{Block: &libvirtxml.DomainDiskSourceBlock{Dev: v.opts.Path}}, Driver: &libvirtxml.DomainDiskDriver{Name: "qemu", Type: "raw"}, - }, nil + }, nil, nil } func init() { diff --git a/pkg/libvirttools/root_volumesource.go b/pkg/libvirttools/root_volumesource.go index 66a7f6173..99a55b370 100644 --- a/pkg/libvirttools/root_volumesource.go +++ b/pkg/libvirttools/root_volumesource.go @@ -83,21 +83,21 @@ func (v *rootVolume) createVolume() (virt.StorageVolume, error) { func (v *rootVolume) UUID() string { return "" } -func (v *rootVolume) Setup() (*libvirtxml.DomainDisk, error) { +func (v *rootVolume) Setup() (*libvirtxml.DomainDisk, *libvirtxml.DomainFilesystem, error) { vol, err := v.createVolume() if err != nil { - return nil, err + return nil, nil, err } volPath, err := vol.Path() if err != nil { - return nil, fmt.Errorf("error getting root volume path: %v", err) + return nil, nil, fmt.Errorf("error getting root volume path: %v", err) } return &libvirtxml.DomainDisk{ Device: "disk", Driver: &libvirtxml.DomainDiskDriver{Name: "qemu", Type: "qcow2"}, Source: &libvirtxml.DomainDiskSource{File: &libvirtxml.DomainDiskSourceFile{File: volPath}}, - }, nil + }, nil, nil } func (v *rootVolume) Teardown() error { diff --git a/pkg/libvirttools/root_volumesource_test.go b/pkg/libvirttools/root_volumesource_test.go index 99d477287..d619b815e 100644 --- a/pkg/libvirttools/root_volumesource_test.go +++ b/pkg/libvirttools/root_volumesource_test.go @@ -129,7 +129,7 @@ func TestRootVolumeSize(t *testing.T) { }, }) - _, err := rootVol.Setup() + _, _, err := rootVol.Setup() if err != nil { t.Fatalf("Setup returned an error: %v", err) } @@ -159,7 +159,7 @@ func TestRootVolumeLifeCycle(t *testing.T) { Image: "rootfs image name", }) - vol, err := rootVol.Setup() + vol, _, err := rootVol.Setup() if err != nil { t.Fatalf("Setup returned an error: %v", err) } @@ -218,3 +218,5 @@ func (vo fakeVolumeOwner) ImageManager() ImageManager { func (vo fakeVolumeOwner) RawDevices() []string { return nil } func (vo fakeVolumeOwner) KubeletRootDir() string { return "" } + +func (vo fakeVolumeOwner) VolumePoolName() string { return "" } diff --git a/pkg/libvirttools/virtualization.go b/pkg/libvirttools/virtualization.go index 71e702d8b..d26b1a198 100644 --- a/pkg/libvirttools/virtualization.go +++ b/pkg/libvirttools/virtualization.go @@ -330,12 +330,11 @@ func (v *VirtualizationTool) CreateContainer(config *types.VMConfig, netFdKey st } domainDef := settings.createDomain(config) - diskList, err := newDiskList(config, v.volumeSource, v) if err != nil { return "", err } - domainDef.Devices.Disks, err = diskList.setup() + domainDef.Devices.Disks, domainDef.Devices.Filesystems, err = diskList.setup() if err != nil { return "", err } @@ -564,10 +563,10 @@ func (v *VirtualizationTool) cleanupVolumes(containerID string) error { err = diskList.teardown() } + var errs []string if err != nil { glog.Errorf("Volume teardown failed for domain %q: %v", containerID, err) - return err - + errs = append(errs, err.Error()) } return nil @@ -833,6 +832,9 @@ func (v *VirtualizationTool) RawDevices() []string { return v.config.RawDevices // KubeletRootDir implements volumeOwner KubeletRootDir method func (v *VirtualizationTool) KubeletRootDir() string { return v.config.KubeletRootDir } +// KubeletRootDir implements volumeOwner VolumePoolName method +func (v *VirtualizationTool) VolumePoolName() string { return v.config.VolumePoolName } + func filterContainer(containerInfo *types.ContainerInfo, filter types.ContainerFilter) bool { if filter.Id != "" && containerInfo.Id != filter.Id { return false diff --git a/pkg/libvirttools/volumes.go b/pkg/libvirttools/volumes.go index 799624a64..764096c4c 100644 --- a/pkg/libvirttools/volumes.go +++ b/pkg/libvirttools/volumes.go @@ -34,6 +34,7 @@ type volumeOwner interface { ImageManager() ImageManager RawDevices() []string KubeletRootDir() string + VolumePoolName() string } // VMVolumeSource is a function that provides `VMVolume`s for VMs @@ -42,7 +43,7 @@ type VMVolumeSource func(config *types.VMConfig, owner volumeOwner) ([]VMVolume, // VMVolume describes a volume provider. type VMVolume interface { UUID() string - Setup() (*libvirtxml.DomainDisk, error) + Setup() (*libvirtxml.DomainDisk, *libvirtxml.DomainFilesystem, error) WriteImage(diskPathMap) error Teardown() error } diff --git a/pkg/metadata/types/annotations.go b/pkg/metadata/types/annotations.go index d7b9017ed..dc1aff941 100644 --- a/pkg/metadata/types/annotations.go +++ b/pkg/metadata/types/annotations.go @@ -41,6 +41,7 @@ const ( rootVolumeSizeKeyName = "VirtletRootVolumeSize" libvirtCPUSetting = "VirtletLibvirtCPUSetting" sshKeysKeyName = "VirtletSSHKeys" + chown9pfsMountsKeyName = "VirtletChown9pfsMounts" // CloudInitUserDataSourceKeyName is the name of user data source key in the pod annotations. CloudInitUserDataSourceKeyName = "VirtletCloudInitUserDataSource" // SSHKeySourceKeyName is the name of ssh key source key in the pod annotations. @@ -100,6 +101,8 @@ type VirtletAnnotations struct { // size of the QCOW2 image, the size of the QCOW2 image is // used instead. RootVolumeSize int64 + // VirtletChown9pfsMounts indicates if chown is enabled for 9pfs mounts. + VirtletChown9pfsMounts bool } // ExternalDataLoader is a function that loads external data that's specified @@ -240,5 +243,9 @@ func (va *VirtletAnnotations) parsePodAnnotations(ns string, podAnnotations map[ } } + if podAnnotations[chown9pfsMountsKeyName] == "true" { + va.VirtletChown9pfsMounts = true + } + return nil } diff --git a/pkg/tools/TestGenCommand__compat.out.yaml b/pkg/tools/TestGenCommand__compat.out.yaml index 44515d093..ee63a41b0 100755 --- a/pkg/tools/TestGenCommand__compat.out.yaml +++ b/pkg/tools/TestGenCommand__compat.out.yaml @@ -87,6 +87,7 @@ spec: - mountPath: /dev name: dev - mountPath: /var/lib/virtlet + mountPropagation: Bidirectional name: virtlet - mountPath: /var/lib/libvirt name: libvirt @@ -115,11 +116,14 @@ spec: resources: {} volumeMounts: - mountPath: /var/lib/virtlet + mountPropagation: HostToContainer name: virtlet - mountPath: /var/lib/libvirt name: libvirt - mountPath: /var/log/vms name: vms-log + - mountPath: /var/lib/kubelet/pods:shared + name: k8s-pods-dir - mountPath: /dev name: dev - mountPath: /lib/modules diff --git a/pkg/tools/TestGenCommand__compat_dev.out.yaml b/pkg/tools/TestGenCommand__compat_dev.out.yaml index e5f67b012..765155390 100755 --- a/pkg/tools/TestGenCommand__compat_dev.out.yaml +++ b/pkg/tools/TestGenCommand__compat_dev.out.yaml @@ -89,6 +89,7 @@ spec: - mountPath: /dev name: dev - mountPath: /var/lib/virtlet + mountPropagation: Bidirectional name: virtlet - mountPath: /var/lib/libvirt name: libvirt @@ -119,11 +120,14 @@ spec: resources: {} volumeMounts: - mountPath: /var/lib/virtlet + mountPropagation: HostToContainer name: virtlet - mountPath: /var/lib/libvirt name: libvirt - mountPath: /var/log/vms name: vms-log + - mountPath: /var/lib/kubelet/pods:shared + name: k8s-pods-dir - mountPath: /dev name: dev - mountPath: /lib/modules diff --git a/pkg/tools/TestGenCommand__dev.out.yaml b/pkg/tools/TestGenCommand__dev.out.yaml index 3f054f2a6..15ec17cd1 100755 --- a/pkg/tools/TestGenCommand__dev.out.yaml +++ b/pkg/tools/TestGenCommand__dev.out.yaml @@ -89,6 +89,7 @@ spec: - mountPath: /dev name: dev - mountPath: /var/lib/virtlet + mountPropagation: Bidirectional name: virtlet - mountPath: /var/lib/libvirt name: libvirt @@ -120,11 +121,15 @@ spec: resources: {} volumeMounts: - mountPath: /var/lib/virtlet + mountPropagation: HostToContainer name: virtlet - mountPath: /var/lib/libvirt name: libvirt - mountPath: /var/log/vms name: vms-log + - mountPath: /var/lib/kubelet/pods + mountPropagation: HostToContainer + name: k8s-pods-dir - mountPath: /dev name: dev - mountPath: /lib/modules diff --git a/pkg/tools/TestGenCommand__plain.out.yaml b/pkg/tools/TestGenCommand__plain.out.yaml index 1dc306eb9..c9e93be73 100755 --- a/pkg/tools/TestGenCommand__plain.out.yaml +++ b/pkg/tools/TestGenCommand__plain.out.yaml @@ -87,6 +87,7 @@ spec: - mountPath: /dev name: dev - mountPath: /var/lib/virtlet + mountPropagation: Bidirectional name: virtlet - mountPath: /var/lib/libvirt name: libvirt @@ -116,11 +117,15 @@ spec: resources: {} volumeMounts: - mountPath: /var/lib/virtlet + mountPropagation: HostToContainer name: virtlet - mountPath: /var/lib/libvirt name: libvirt - mountPath: /var/log/vms name: vms-log + - mountPath: /var/lib/kubelet/pods + mountPropagation: HostToContainer + name: k8s-pods-dir - mountPath: /dev name: dev - mountPath: /lib/modules diff --git a/pkg/tools/TestGenCommand__tag.out.yaml b/pkg/tools/TestGenCommand__tag.out.yaml index bb5a6d67c..4f8a13e53 100755 --- a/pkg/tools/TestGenCommand__tag.out.yaml +++ b/pkg/tools/TestGenCommand__tag.out.yaml @@ -87,6 +87,7 @@ spec: - mountPath: /dev name: dev - mountPath: /var/lib/virtlet + mountPropagation: Bidirectional name: virtlet - mountPath: /var/lib/libvirt name: libvirt @@ -116,11 +117,15 @@ spec: resources: {} volumeMounts: - mountPath: /var/lib/virtlet + mountPropagation: HostToContainer name: virtlet - mountPath: /var/lib/libvirt name: libvirt - mountPath: /var/log/vms name: vms-log + - mountPath: /var/lib/kubelet/pods + mountPropagation: HostToContainer + name: k8s-pods-dir - mountPath: /dev name: dev - mountPath: /lib/modules diff --git a/pkg/tools/bindata.go b/pkg/tools/bindata.go index c6e764d83..a8a6b6dce 100644 --- a/pkg/tools/bindata.go +++ b/pkg/tools/bindata.go @@ -66,7 +66,7 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } -var _deployDataVirtletDsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xd4\x5a\x5b\x6f\xdb\x38\xf6\x7f\xcf\xa7\x38\x68\x80\x7f\x67\x80\xbf\xe2\xa4\xd8\xd9\x76\x8c\xdd\x87\x34\xf6\x64\x8d\x26\xb6\xe1\x5c\x3a\x6f\x06\x4d\x1d\xcb\x5c\x53\xa4\x96\xa4\x94\x78\x3f\xfd\x82\xa4\xa4\xe8\x66\xc7\x49\x13\xa3\x93\x97\xba\xbc\x1c\x9e\xfb\xf9\x1d\x8a\x41\x10\x1c\x91\x84\xdd\xa3\xd2\x4c\x8a\x3e\x90\x24\xd1\xbd\xec\xec\x68\xcd\x44\xd8\x87\x01\xc1\x58\x8a\x1b\x34\x47\x31\x1a\x12\x12\x43\xfa\x47\x00\x82\xc4\xd8\x87\x8c\x29\xc3\xd1\xe4\xff\xd7\x09\xa1\xd8\x87\x75\xba\xc0\x40\x6f\xb4\xc1\xf8\x48\x27\x48\xed\x72\x8d\x1c\xa9\x91\xca\xfe\x06\x88\x89\xa1\xab\x2b\xb2\x40\xae\xfd\x00\x80\x4a\x85\x61\x75\x92\x06\xe3\x84\x13\x83\xf9\x9e\xca\xe1\xf6\xaf\xc9\x80\xfd\xe3\x35\x92\x9d\x44\x01\x0a\x96\xec\xdf\x4a\x6a\x33\x46\xf3\x20\xd5\xba\x0f\x46\xa5\x98\x8f\x87\x42\x4f\x25\x67\x74\xd3\x87\x0b\x9e\x6a\x83\xea\x0f\xa6\xb4\xf9\xce\xcc\xea\x5f\x7e\x4b\xbe\xf0\xd8\x91\x98\x8e\x06\xc0\xb4\x23\x00\x46\xc2\x2f\x67\xbf\x02\x0a\xb2\xe0\x08\xf7\xd7\xda\x8e\xe8\x54\x65\x2c\xc3\x82\x0f\xa0\x52\x18\xc2\x04\x2a\x50\xa8\x0d\x51\x4f\xe4\x7e\x31\x12\x16\x08\x74\x85\x74\x8d\xe1\xaf\x40\x44\x08\xbf\x7c\xfa\xd5\x12\xc9\x49\x9a\x15\x42\xaa\x11\xe4\x12\x84\x46\x61\x50\x01\x13\xc0\x04\xab\x90\xad\x88\x37\x1d\x0d\x6a\xa2\x1d\xc3\x42\x4a\xa3\x8d\x22\x09\x24\x4a\x52\x0c\x53\x85\x20\x10\x43\xc7\x29\x55\x48\x0c\x02\xb1\xb4\x96\x2c\x8a\x49\x62\xa9\x57\x4c\xfa\x64\xe9\x9c\xa0\x46\x95\x31\x8a\xe7\x94\xca\x54\x98\x71\xcd\x2c\xe5\x99\x52\xf0\x8d\x35\x07\xdc\xe7\x1a\x48\x64\xa8\x41\x0a\x27\x8d\x90\x21\x6a\x78\x60\x66\x05\xf8\x68\x14\x99\x79\xb3\xfd\xb3\xd0\x96\x33\x6b\x4e\x8a\x2c\x97\x56\xd4\xcd\x93\x91\xed\xee\xf3\xd6\x28\x80\xc2\xff\xa4\x4c\x61\x38\x48\x15\x13\xd1\x0d\x5d\x61\x98\x72\x26\xa2\x51\x24\x64\x39\x3c\x7c\x44\x9a\x1a\xeb\xf5\x95\x9d\x9e\xe6\x4d\xee\xb2\xb7\xa8\x62\x5d\x9f\x0e\xbc\x07\x0f\x1f\x13\x85\xda\xc6\x4c\x63\xde\xae\x58\xe3\xa6\x5f\x13\xa7\xb1\x02\x40\x26\xa8\x88\x8d\x09\x18\x89\xd6\x64\x46\x78\x8a\x2d\xb2\x96\x70\x43\xb7\x56\xee\x8b\xc2\xee\xe5\x86\x63\xb8\x5d\x61\xc3\x29\x80\xca\x84\xa1\x2e\x08\x7c\xd4\xb0\xe4\xf8\x98\x49\x9e\xc6\x08\xa1\x62\x59\xe9\x37\xc7\xd6\x13\xac\x65\x42\x5c\x92\x94\x1b\x67\x7f\x67\x35\x9e\x46\x4c\x40\xc8\x94\x73\x4c\x14\x3a\x55\xa8\xc1\xac\xc8\x93\x07\xbb\x7d\x4c\x39\xdd\xd9\xe3\xac\x6b\x61\x08\x8b\x0d\x70\xb6\xb0\x67\xc3\xff\x95\x71\x80\x8f\x4c\x9b\xc2\x0d\xac\xb7\x1e\x15\x52\xfa\xf0\x4e\x14\x26\x44\x61\x60\xed\x51\xaa\x82\xc5\x24\xc2\x3e\xc4\x4c\x11\x61\x98\xee\xd5\x73\x40\x3e\x3f\x4d\x39\x2f\x42\x78\xb4\x1c\x4b\x33\x55\x68\xa3\xa5\x5c\x45\x65\x1c\x13\x11\x3e\x69\x38\x80\x5e\xf5\xb8\x13\xbd\x2a\xa7\xbc\x8e\xae\xad\x7f\xeb\xea\x06\xcf\xe4\xfa\x8b\x0e\x9e\x34\x19\x78\x1d\xe9\x20\x64\xaa\x62\xbd\xd8\x6e\x9e\x12\xb3\xea\x43\x2f\xd7\x66\x50\xdf\xd0\xa2\xab\xd2\xaa\x5b\x1c\xc3\x40\x8a\x8f\x06\x48\x18\xc2\x07\x4f\x4d\xc9\x84\x44\xc4\x79\x2f\x7c\x65\x5e\xe7\x4c\x0a\xc2\x3f\xfc\x3f\x30\x03\x0f\x8c\x73\xe0\x84\xae\xfd\xe1\x80\xc2\xa8\xcd\x16\x96\xaa\x67\x15\xe7\x87\x92\xae\x51\x69\x49\xd7\x5b\x36\x65\x44\xd9\x8d\x3d\xbf\xf0\xa4\xb6\xb2\x20\xc2\x65\xb4\x65\xb7\x35\x77\x75\xf6\x18\x96\x52\x79\x97\x62\x22\x72\x3e\xe5\x8f\xe0\x6c\xd1\xcb\x5d\xa7\xe7\x6c\xab\xbd\xdf\xb8\xfc\x51\xf3\x8c\xe2\xd0\x8c\xa8\x80\xb3\xc5\x8e\x83\x83\xe6\x92\x52\x68\xcc\xb6\x6c\xab\xce\x04\x2d\x3d\x58\x26\x9b\x8e\xd8\x5d\xa4\x6c\xc6\xa4\xa9\x62\x66\x63\xc3\x16\x1f\x4d\x35\xc8\x13\xc5\x32\xc6\x31\xc2\xb0\x96\xb4\x01\x50\x64\x6d\xcf\xfb\x76\xf7\x75\x38\x1f\x4f\x06\xc3\xf9\xf8\xfc\x7a\x58\x21\xe3\xb2\xc7\x1f\x4a\xc6\xf5\x04\xb2\x64\xc8\xc3\x19\x2e\x9b\x69\xa5\x5a\xfc\xb3\xb3\xc6\xa4\xdb\xe4\x25\xb5\xa5\xf3\xc4\x6a\xdc\x66\xf9\x16\x37\xf7\xa3\xd9\xed\xd5\xf0\x76\x3e\x18\xdd\x9c\x7f\xbd\x1a\xce\xbf\xdd\x5f\x3f\xcf\x92\x2f\x33\xd7\x24\xf9\x86\x9b\x0e\xce\x6a\x0a\x0c\xfc\xe2\xc6\x12\x97\x68\x43\xa6\x6d\x71\x9c\xaf\xb3\xb8\x31\x2d\x13\x1f\x13\x0d\x7d\x36\x99\xbe\x99\x8d\x26\xf7\xf3\x9b\xbb\xe9\x74\x32\xbb\x3d\x18\xdb\x5a\x31\x99\xcd\x75\x9a\x24\x52\x99\xd7\x31\x3e\x98\x7c\x1f\x5f\x4d\xce\x07\xf3\xe9\x6c\x72\x3b\xb9\x98\x5c\x1d\x4e\xe7\xf2\x41\x70\x49\xc2\x79\xa2\xa4\x91\x54\xf2\xd7\x09\x70\x35\xb9\xbc\x1a\xde\x0f\x0f\xc7\x37\x97\x11\xc7\x0c\x5f\xc9\xee\xc5\xf9\xd5\xe8\x62\x32\xbf\xb9\xfb\x3a\x1e\x1e\xce\x51\x28\xe1\x8c\xca\x40\xa7\x0b\x81\x2f\x74\x94\xd1\xf5\xf9\xe5\x70\x3e\x1b\x5e\x0e\xff\x9c\xce\x6f\x67\xe7\xe3\x9b\xab\xf3\xdb\xd1\x64\x7c\x30\xde\x5d\xce\x9e\x2b\x8c\xf0\x31\x99\x1b\x45\x84\xe6\xae\x68\xbd\x4e\xff\xb3\xf3\xef\xf3\xc1\xf0\x7e\x74\x31\xbc\x39\x98\x04\x8a\x3c\xcc\x43\xb4\x28\x57\xbf\x32\x48\xf3\x94\x78\x35\xb9\xbc\x1c\x8d\x2f\x0f\x9e\x16\xb9\x8c\x22\x26\x9a\x4b\xf6\xf5\xf8\xe9\xdd\xfc\x7a\x32\x38\x60\x84\xd2\x24\x0d\x62\x19\xbe\x36\x44\xbd\xc7\x57\x5c\xfd\x66\x3e\x18\xcd\x9a\xdc\xf7\xa1\x87\x86\x16\x45\x3b\x47\x16\x05\xaa\xa6\x2d\x44\x5d\x02\x1a\x8f\x44\xf6\x46\xa3\xc7\x30\x12\x40\x89\x46\x78\xb0\x80\xfc\xdf\x48\x0d\x70\x49\x09\x2f\x41\xb0\xa3\x60\x67\x1f\x88\x30\x16\x79\xdb\xee\x8e\x19\x10\xd2\x80\x5c\x2e\x19\x65\x84\xf3\x0d\x90\x8c\x30\xee\x3a\x40\x29\xf0\x0d\xc0\x6e\x2e\xc8\x3e\x38\xb7\x0a\x76\xf4\x46\xf7\x96\xba\x47\x23\x25\xd3\xa4\x05\x75\x1a\xc3\xf5\xad\x16\x23\xc5\x32\x4c\x79\x2d\x8c\xfc\xc6\xf6\xb8\x42\x12\x4e\x04\xdf\xb4\x8c\x5d\x25\x69\x7b\xd9\x16\xad\xc6\xe0\x5e\x84\xde\x1b\x6c\xb7\x21\xfd\x8f\x61\xc8\xee\xdd\x4d\xe7\x84\x2d\x4e\xdb\xde\x6d\x71\xfc\x33\xbb\x03\x0b\xf0\xd1\xe8\x8a\x6b\xdb\xb6\x8d\xcb\xc8\x35\x84\xac\x6c\xf5\x56\xa8\x10\x16\x48\x89\xbb\xa6\x30\x2b\x54\x0f\x4c\x63\xd9\xfe\x39\x55\x25\x4a\x86\x29\x45\x40\xa5\xa4\xaa\x92\xe4\x6c\x8d\x60\x56\xac\xe2\x80\xc7\x70\x97\x5f\x7d\x48\xdb\x11\x06\xf9\x1d\x05\x5d\x11\x15\x62\x06\x4b\xc6\x11\x3e\x7a\x1d\xc8\xa8\x97\xc5\xba\x47\x96\xe1\xe7\xdf\x16\x8b\x45\xf0\x05\x7f\xff\x1c\x9c\x9d\xe1\xe7\xe0\xf7\xdf\xfe\x7e\x16\x9c\x7e\xfa\xdb\xa7\x53\x42\x4f\x4f\x4f\x4f\x3f\xf5\x28\x53\x4a\xea\x20\x8b\xe7\xa7\x27\x5c\x46\x1f\xfb\x30\x96\xa0\x53\xba\xf2\x14\xa5\x2a\xdb\xd8\x4d\xbb\xc3\x88\x75\xb0\xbd\xb5\xa9\xb0\xd2\x6e\x88\x72\x65\x3e\xbf\xbb\x6d\xb4\x97\xb4\x28\xaf\x69\x32\x6c\xa4\x30\x81\x5a\x4f\x95\x5c\x60\x75\x0b\x3e\x3e\x5d\x9a\xf9\xbf\x56\x4a\xf1\x2c\xf6\x16\x4c\xf4\x2a\x29\xc5\x8f\x06\xb4\x31\xa0\x25\x25\x06\x02\xb8\x1b\x8f\xfe\xec\x37\x1d\xb0\x57\x75\xb8\x40\x49\xf8\x87\x95\xac\x27\x52\xce\x1b\xc9\xb8\xb3\xf5\xff\xd9\x93\xf1\x3e\x59\xf6\xf0\xe9\xe8\xd8\x27\x53\x77\xaf\x53\xcd\xd4\x40\x14\x96\x77\x69\xb0\xd8\x80\x4e\x13\x54\x31\xdb\x96\xc8\x7e\xb6\x24\x7f\xb8\xb6\xfe\x67\x48\xc9\x75\x2a\xa9\x76\x3c\xd8\xe0\x75\x97\x4e\x4a\xa0\x41\x5d\xde\x3f\xe5\x17\x4f\x3d\xef\x90\x3d\xbb\xac\x75\xd0\x1e\x97\x5b\xdd\x72\xe7\x87\xf4\x12\x19\xb6\x1d\xc1\x52\xb5\x13\x9d\x97\x64\x5b\x5d\xfb\x4d\xb2\x70\x75\x45\x07\xfe\x6b\x72\xea\x86\x03\xfb\x3b\xa8\xb4\x2e\xed\xb4\xee\xa4\x79\x9e\x97\x9a\x36\x8e\x8b\x82\xb9\x74\xb5\x86\x44\x42\x6a\xc3\x28\x24\xa9\x4a\xa4\xc6\xf7\xa8\x1d\x02\xcd\xce\xab\xc9\xc2\xef\xdc\xba\x57\x58\xe6\xaf\x54\x75\xac\x9c\xb9\xf5\xdd\xdd\xe5\x8e\x32\x53\xf1\xa0\xf7\xbb\x7d\xce\x62\xfd\x52\x30\x7e\xe8\x14\xf5\xa3\xe0\x67\xdf\x34\xbc\xad\x5c\xec\x2e\x34\x5e\x63\x95\x6f\x20\x96\x6a\x05\x97\xda\x30\x5b\x49\x6d\x6c\x3f\x0f\xbe\x9f\x07\x42\x29\x6a\x5d\xda\xdb\x7d\x31\xb3\xf4\xab\x8e\xdb\xe6\xb0\x29\xcd\xce\x8d\xdd\x1d\x53\x47\xbf\xb4\x93\x4a\x57\x5d\xed\x52\xd3\x4e\x22\xb5\xa2\xd9\xaa\xa3\x3b\xb7\x56\xb1\x42\x13\x3d\x1c\xc3\xed\x64\x30\xe9\x43\xe8\x50\x8a\x85\xe5\x54\x86\x98\x7f\x40\x00\x5f\xa3\x1c\xce\xb2\xd9\xc2\xb5\x07\x4f\x1b\x57\x4c\x7b\xb4\x92\x63\x0c\xb8\x98\x8d\x6c\x77\xf0\xb8\x01\x26\xb4\x21\xdc\x67\x5c\x0b\xc5\xaa\x07\x32\xe1\x4d\xe9\xe1\x4d\xf9\x4d\xf2\x64\x1f\x51\x76\x7d\xb7\xd8\xf2\xe9\xe3\x59\x7a\x5d\x51\xd8\x15\x83\x7b\x11\x6a\x06\x5e\x57\x38\x3e\x4f\xa8\x12\xa1\xcd\x6f\x31\x3b\x37\xff\x00\x6a\xd8\x13\x33\xec\xa5\x84\x4e\x00\xb1\x15\x3e\xec\x43\xb2\x69\x98\xda\x27\xa0\x7d\xf4\x59\x82\x85\x6a\x6e\xeb\xca\x89\x7b\x11\xdb\x69\xe5\x97\x10\xeb\x02\x8a\xbb\x60\xe2\x5e\xdc\x75\xa8\xbd\x81\x71\xf6\xe2\xab\x0e\x24\xba\x41\x48\xf0\x74\x6f\xd8\xdf\x56\xc2\x02\x0f\xc4\x3a\x31\xd8\x6e\xa4\xd6\x7c\xdd\xa2\x16\x84\x9e\x90\xd4\xac\xa4\x62\xff\x75\x6b\x4e\xd6\x5f\xf4\x09\x93\xbd\xec\x6c\x81\x86\x14\xef\x5e\xf2\x87\x1f\x33\xc9\xf1\x2b\x13\x21\x13\xd1\x8e\x07\x30\x4a\x72\xcc\x2f\x3c\x49\xc2\x2e\x6d\x52\xdf\x71\xd2\x11\x40\xeb\x8c\x16\x49\x9d\x2e\x6c\x7f\xaa\xfb\x47\x41\xbe\xfa\xa6\xf6\xd2\x62\xff\x47\x38\x56\x03\xed\xf3\x5e\xa6\x93\x57\xbc\xfd\x51\xb6\x2a\xd9\xf5\x41\xa9\x93\xbc\x36\x07\xf0\xe1\x83\xfb\xa1\x50\xcb\x54\x51\x2c\xc7\xcb\x57\x27\x3a\x1f\x70\x6f\x43\xdc\xef\x0c\xd5\xe2\x69\x9d\xbb\x02\xca\xff\x13\xa1\x79\x0b\x2b\x77\xc8\x58\xb2\x13\x58\x90\x8a\xaa\x90\xa9\x21\x51\x2e\x4f\x4d\x9a\x86\x2c\x25\xf7\x9e\x5d\xfb\x2f\x67\xda\xff\x78\x20\x86\xae\xde\x49\x82\x22\x7c\x52\x8d\xca\xce\xfc\xb0\x20\x81\xc5\xf8\xca\x27\x93\x86\x50\xef\x1a\x69\x45\xf9\xb1\x0e\x11\x2c\xf2\x65\x6f\x18\x76\x2d\x53\x57\xe3\xef\x25\xc4\x2f\x73\x44\xe7\xc9\xfa\x58\xe8\x7b\x37\x7e\xdf\x54\x14\x3f\x19\xf9\x1d\xf4\xb3\xcd\x91\xfe\x22\x69\x2a\xa0\x2a\xdc\xee\xf4\x24\x61\xf8\x68\x50\xb8\xb7\x5c\x39\xcd\xae\x40\x48\xb5\x91\x71\x31\x18\xa2\x7b\x74\x96\x97\xa2\x4a\x2c\xe4\xc9\xa9\x7d\x4c\xd1\x6d\xae\xbf\xe8\x0e\xea\xf9\xac\xab\x63\x31\x49\x12\x26\x22\x5d\x9d\x28\x3d\xb4\x98\xa9\x1c\x59\xe6\x92\x77\x8f\xc3\x9a\x3e\xdf\xde\xbd\x2c\xd9\xb7\x75\xa9\xc6\xe3\x96\x4e\x82\xaf\xa8\x6e\xff\x0b\x00\x00\xff\xff\xb6\xc9\xb3\x09\x35\x2b\x00\x00") +var _deployDataVirtletDsYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xd4\x5a\x5b\x6f\xdb\x38\x16\x7e\xcf\xaf\x38\x68\x80\xed\x0c\xb0\x8a\x93\x62\x67\xa7\x63\xec\x3e\xa4\xb1\x27\x63\x34\xb1\x0d\xe7\xd2\x79\x33\x68\xea\x58\xe6\x9a\x22\xb5\x24\xa5\xc4\xfb\xeb\x17\x24\x25\x45\x37\x3b\x8e\x9b\x04\x9d\xbc\xd4\xe5\xe5\xe3\xb9\x5f\x28\x06\x41\x70\x44\x12\x76\x8f\x4a\x33\x29\xfa\x40\x92\x44\xf7\xb2\xb3\xa3\x35\x13\x61\x1f\x06\x04\x63\x29\x6e\xd0\x1c\xc5\x68\x48\x48\x0c\xe9\x1f\x01\x08\x12\x63\x1f\x32\xa6\x0c\x47\x93\xff\x5f\x27\x84\x62\x1f\xd6\xe9\x02\x03\xbd\xd1\x06\xe3\x23\x9d\x20\xb5\xcb\x35\x72\xa4\x46\x2a\xfb\x1b\x20\x26\x86\xae\xae\xc8\x02\xb9\xf6\x03\x00\x2a\x15\x86\xd5\x21\x0d\xc6\x09\x27\x06\xf3\x3d\x95\xc3\xed\x5f\x93\x00\xfb\xc7\x6b\x90\x9d\xa0\x00\x05\x49\xf6\x6f\x25\xb5\x19\xa3\x79\x90\x6a\xdd\x07\xa3\x52\xcc\xc7\x43\xa1\xa7\x92\x33\xba\xe9\xc3\x05\x4f\xb5\x41\xf5\x3b\x53\xda\x7c\x63\x66\xf5\x87\xdf\x92\x2f\x3c\x76\x10\xd3\xd1\x00\x98\x76\x00\x60\x24\xfc\x74\xf6\x33\xa0\x20\x0b\x8e\x70\x7f\xad\xed\x88\x4e\x55\xc6\x32\x2c\xe8\x00\x2a\x85\x21\x4c\xa0\x02\x85\xda\x10\xf5\x04\xf7\x93\x91\xb0\x40\xa0\x2b\xa4\x6b\x0c\x7f\x06\x22\x42\xf8\xe9\xd3\xcf\x16\x24\x87\x34\x2b\x84\x54\x23\xc8\x25\x08\x8d\xc2\xa0\x02\x26\x80\x09\x56\x81\xad\xb0\x37\x1d\x0d\x6a\xac\x1d\xc3\x42\x4a\xa3\x8d\x22\x09\x24\x4a\x52\x0c\x53\x85\x20\x10\x43\x47\x29\x55\x48\x0c\x02\xb1\x58\x4b\x16\xc5\x24\xb1\xe8\x15\x95\x3e\x69\x3a\x07\xd4\xa8\x32\x46\xf1\x9c\x52\x99\x0a\x33\xae\xa9\xa5\x3c\x53\x0a\xbe\xb1\xea\x80\xfb\x5c\x02\x89\x0c\x35\x48\xe1\xb8\x11\x32\x44\x0d\x0f\xcc\xac\x00\x1f\x8d\x22\x33\xaf\xb6\x7f\x17\xd2\x72\x6a\xcd\xa1\xc8\x72\x69\x59\xdd\x3c\x29\xd9\xee\x3e\x6f\x8d\x02\x28\xfc\x6f\xca\x14\x86\x83\x54\x31\x11\xdd\xd0\x15\x86\x29\x67\x22\x1a\x45\x42\x96\xc3\xc3\x47\xa4\xa9\xb1\x56\x5f\xd9\xe9\x31\x6f\x72\x93\xbd\x45\x15\xeb\xfa\x74\xe0\x2d\x78\xf8\x98\x28\xd4\xd6\x67\x1a\xf3\x76\xc5\x1a\x37\xfd\x1a\x3b\x8d\x15\x00\x32\x41\x45\xac\x4f\xc0\x48\xb4\x26\x33\xc2\x53\x6c\xc1\x5a\xe0\x86\x6c\x2d\xdf\x17\x85\xde\xcb\x0d\xc7\x70\xbb\xc2\x86\x51\x00\x95\x09\x43\x5d\x00\x7c\xd4\xb0\xe4\xf8\x98\x49\x9e\xc6\x08\xa1\x62\x59\x69\x37\xc7\xd6\x12\xac\x66\x42\x5c\x92\x94\x1b\xa7\x7f\xa7\x35\x9e\x46\x4c\x40\xc8\x94\x33\x4c\x14\x3a\x55\xa8\xc1\xac\xc8\x93\x05\xbb\x7d\x4c\x39\xd9\xd9\xe3\xac\x69\x61\x08\x8b\x0d\x70\xb6\xb0\x67\xc3\xdf\x4a\x3f\xc0\x47\xa6\x4d\x61\x06\xd6\x5a\x8f\x0a\x2e\xbd\x7b\x27\x0a\x13\xa2\x30\xb0\xfa\x28\x45\xc1\x62\x12\x61\x1f\x62\xa6\x88\x30\x4c\xf7\xea\x31\x20\x9f\x9f\xa6\x9c\x17\x2e\x3c\x5a\x8e\xa5\x99\x2a\xb4\xde\x52\xae\xa2\x32\x8e\x89\x08\x9f\x24\x1c\x40\xaf\x7a\xdc\x89\x5e\x95\x53\x5e\x46\xd7\xd6\xbe\x75\x75\x83\x27\x72\xfd\x59\x07\x4f\x92\x0c\xbc\x8c\x74\x10\x32\x55\xd1\x5e\x6c\x37\x4f\x89\x59\xf5\xa1\x97\x4b\x33\xa8\x6f\x68\xe1\xaa\xb4\x6a\x16\xc7\x30\x90\xe2\xa3\x01\x12\x86\xf0\xc1\xa3\x29\x99\x90\x88\x38\xeb\x85\x2f\xcc\xcb\x9c\x49\x41\xf8\x87\xbf\x03\x33\xf0\xc0\x38\x07\x4e\xe8\xda\x1f\x0e\x28\x8c\xda\x6c\x21\xa9\x7a\x56\x71\x7e\x28\xe9\x1a\x95\x96\x74\xbd\x65\x53\x46\x94\xdd\xd8\xf3\x0b\x4f\x6a\x2b\x0b\x10\x2e\xa3\x2d\xbb\xad\xba\xab\xb3\xc7\xb0\x94\xca\x9b\x14\x13\x91\xb3\x29\x7f\x04\x67\x8b\x5e\x6e\x3a\x3d\xa7\x5b\xed\xed\xc6\xc5\x8f\x9a\x65\x14\x87\x66\x44\x05\x9c\x2d\x76\x1c\x1c\x34\x97\x94\x4c\x63\xb6\x65\x5b\x75\x26\x68\xc9\xc1\x12\xd9\x34\xc4\xee\x24\x65\x23\x26\x4d\x15\x33\x1b\xeb\xb6\xf8\x68\xaa\x4e\x9e\x28\x96\x31\x8e\x11\x86\xb5\xa0\x0d\x80\x22\x6b\x5b\xde\xd7\xbb\x2f\xc3\xf9\x78\x32\x18\xce\xc7\xe7\xd7\xc3\x0a\x8c\x8b\x1e\xbf\x2b\x19\xd7\x03\xc8\x92\x21\x0f\x67\xb8\x6c\x86\x95\x6a\xf2\xcf\xce\x1a\x93\x6e\x93\xe7\xd4\xa6\xce\x13\x2b\x71\x1b\xe5\x5b\xd4\xdc\x8f\x66\xb7\x57\xc3\xdb\xf9\x60\x74\x73\xfe\xe5\x6a\x38\xff\x7a\x7f\xfd\x3c\x49\x3e\xcd\x5c\x93\xe4\x2b\x6e\x3a\x28\xab\x09\x30\xf0\x8b\x1b\x4b\x5c\xa0\x0d\x99\xb6\xc9\x71\xbe\xce\xe2\xc6\xb4\x4c\xbc\x4f\x34\xe4\xd9\x24\xfa\x66\x36\x9a\xdc\xcf\x6f\xee\xa6\xd3\xc9\xec\xf6\xdd\xc8\xd6\x8a\xc9\x6c\xae\xd3\x24\x91\xca\x1c\x46\xf8\x60\xf2\x6d\x7c\x35\x39\x1f\xcc\xa7\xb3\xc9\xed\xe4\x62\x72\xf5\x7e\x32\x97\x0f\x82\x4b\x12\xce\x13\x25\x8d\xa4\x92\x1f\xc6\xc0\xd5\xe4\xf2\x6a\x78\x3f\x7c\x3f\xba\xb9\x8c\x38\x66\x78\x20\xb9\x17\xe7\x57\xa3\x8b\xc9\xfc\xe6\xee\xcb\x78\xf8\x7e\x86\x42\x09\x67\x54\x06\x3a\x5d\x08\x7c\xa1\xa1\x8c\xae\xcf\x2f\x87\xf3\xd9\xf0\x72\xf8\xe7\x74\x7e\x3b\x3b\x1f\xdf\x5c\x9d\xdf\x8e\x26\xe3\x77\xa3\xdd\xc5\xec\xb9\xc2\x08\x1f\x93\xb9\x51\x44\x68\xee\x92\xd6\x61\xf2\x9f\x9d\x7f\x9b\x0f\x86\xf7\xa3\x8b\xe1\xcd\xbb\x71\xa0\xc8\xc3\x3c\x44\x5b\xe5\xea\x03\x9d\x34\x0f\x89\x57\x93\xcb\xcb\xd1\xf8\xf2\xdd\xc3\x22\x97\x51\xc4\x44\x73\xc9\xbe\x16\x3f\xbd\x9b\x5f\x4f\x06\xef\xe8\xa1\x34\x49\x83\x58\x86\x87\xba\xa8\xb7\xf8\x8a\xa9\xdf\xcc\x07\xa3\x59\x93\xfa\x3e\xf4\xd0\xd0\x22\x69\xe7\x95\x45\x51\x55\xd3\x56\x45\x5d\x16\x34\xbe\x12\xd9\xbb\x1a\x3d\x86\x91\x00\x4a\x34\xc2\x83\x2d\xc8\xff\x83\xd4\x00\x97\x94\xf0\xb2\x08\x76\x08\x76\xf6\x81\x08\x63\x2b\x6f\xdb\xdd\x31\x03\x42\x1a\x90\xcb\x25\xa3\x8c\x70\xbe\x01\x92\x11\xc6\x5d\x07\x28\x05\xbe\x42\xb1\x9b\x33\xb2\x4f\x9d\x5b\x2d\x76\xf4\x46\xf7\x96\xba\x47\x23\x25\xd3\xa4\x55\xea\x34\x86\xeb\x5b\x6d\x8d\x14\xcb\x30\xe5\x35\x37\xf2\x1b\xdb\xe3\x0a\x49\x38\x11\x7c\xd3\x52\x76\x15\xd2\xf6\xb2\x2d\xac\xc6\xe0\x5e\x40\x6f\x5d\x6c\xb7\x4b\xfa\xef\xab\x21\xbb\x77\x37\x8d\x13\xb6\x18\x6d\x7b\xb7\xad\xe3\x9f\xd9\x1d\xd8\x02\x1f\x8d\xae\x98\xb6\x6d\xdb\xb8\x8c\x5c\x43\xc8\xca\x56\x6f\x85\x0a\x61\x81\x94\xb8\x6b\x0a\xb3\x42\xf5\xc0\x34\x96\xed\x9f\x13\x55\xa2\x64\x98\x52\x04\x54\x4a\xaa\x2a\x24\x67\x6b\x04\xb3\x62\x15\x03\x3c\x86\xbb\xfc\xea\x43\xda\x8e\x30\xc8\xef\x28\xe8\x8a\xa8\x10\x33\x58\x32\x8e\xf0\xd1\xcb\x40\x46\xbd\x2c\xd6\x3d\xb2\x0c\x7f\xfd\x65\xb1\x58\x04\x9f\xf1\xb7\x5f\x83\xb3\x33\xfc\x35\xf8\xed\x97\x7f\x9e\x05\xa7\x9f\xfe\xf1\xe9\x94\xd0\xd3\xd3\xd3\xd3\x4f\x3d\xca\x94\x92\x3a\xc8\xe2\xf9\xe9\x09\x97\xd1\xc7\x3e\x8c\x25\xe8\x94\xae\x3c\xa2\x54\x65\x1b\xbb\x69\x77\x18\xb1\x0e\xb6\xb7\x36\x15\x52\xda\x0d\x51\x2e\xcc\xe7\x77\xb7\x95\xf6\x92\x16\xe5\x90\x26\xc3\x7a\x0a\x13\xa8\xf5\x54\xc9\x05\x56\xb7\xe0\xe3\xd3\xa5\x99\xff\x6b\x85\x14\x4f\x62\x6f\xc1\x44\xaf\x12\x52\xfc\x68\x40\x1b\x03\x5a\x52\x62\x20\x80\xbb\xf1\xe8\xcf\x7e\xd3\x00\x7b\x55\x83\x0b\x94\x84\x7f\x59\xce\x7a\x22\xe5\xbc\x11\x8c\x3b\x5b\xff\x1f\x3d\x18\xef\x13\x65\xdf\x3f\x1c\x1d\xfb\x60\xea\xee\x75\xaa\x91\x1a\x88\xc2\xf2\x2e\x0d\x16\x1b\xd0\x69\x82\x2a\x66\xdb\x02\xd9\x8f\x16\xe4\xdf\xaf\xad\x2f\x70\xb7\xaa\xe6\x87\x0a\xde\x75\x94\x54\x3b\x1a\xac\x9b\xbb\xeb\x29\x25\xd0\xa0\x2e\x6f\xaa\xf2\x2b\xaa\x9e\x37\xdd\x9e\x5d\xd6\x3a\x68\x8f\x6b\xb0\x6e\xbe\xf3\x43\x7a\x89\x0c\xdb\x26\x63\x51\xed\x44\xe7\x75\xda\x3e\x92\x3e\x3c\x5e\x57\x57\x74\x54\x8a\x4d\x4a\xdd\x70\x60\x7f\x07\x95\x26\xa7\x9d\x00\x1c\x37\xcf\xd3\x52\x93\xc6\x71\x91\x5a\x97\x2e\x2b\x91\x48\x48\x6d\x18\x85\x24\x55\x89\xd4\xf8\x16\x59\x46\xa0\xd9\x79\x89\x59\xd8\x9d\x5b\x77\x80\x66\xfe\x4a\xf9\xc9\xf2\x99\x6b\xdf\xdd\x72\xee\x48\x48\x15\x0b\x7a\xbb\x7b\xea\x2c\xd6\x2f\x2d\xdb\x5f\x23\x98\xfd\x21\xb5\xb9\x95\x17\x8d\x8f\x4c\xdf\x1f\xce\x5e\xc7\x45\x5f\x37\x9c\x6c\xe7\xf5\x65\x09\x65\x5b\xe2\xdb\x9d\x32\xbd\x46\x2b\x5f\x73\x2c\x6a\xa5\xc2\xb6\x61\x60\x25\xb5\x01\x45\x1e\xc0\xdf\x4c\x00\xa1\x14\xb5\x2e\xed\xd1\x7d\xfb\xb3\xf8\x55\xc7\x6a\x53\xd8\xe4\x66\xe7\xc6\xee\xde\xaf\xa3\xf3\xdb\x89\xd2\x55\x21\x74\x89\x69\x27\x48\x2d\xfd\xb7\x2a\x82\x9d\x5b\xab\x55\x4f\xb3\x0e\x3a\x86\xdb\xc9\x60\xd2\x87\xd0\xd5\x5b\xb6\xc1\xa0\x32\xc4\xfc\x53\x08\xf8\x1c\xea\x2a\x46\x6b\x25\xae\xd1\x79\xda\xb8\x62\xda\xd7\x5d\x79\xb5\x04\x17\xb3\x91\xed\x73\x1e\x37\xc0\x84\x36\x84\xfb\x8c\x60\x8b\xca\xea\x81\x4c\x78\x55\xfa\x42\xad\xfc\xba\x7a\xb2\x0f\x2b\xbb\xbe\xc0\x6c\xf9\x88\xf3\x2c\x5e\x57\x94\xe8\x8a\x11\x7b\x01\x35\x9d\xbd\x2b\x04\x3c\x0f\x54\x89\x0a\xcd\xaf\x4a\x3b\x37\x7f\x47\x55\xb3\x67\x4d\xb3\x97\x10\x3a\x23\xd2\xd6\x78\xb4\x0f\x64\x53\x31\xb5\x8f\x59\xfb\xc8\xb3\x2c\x66\xaa\xf1\xb4\x2b\x0e\xef\x05\xb6\x53\xcb\x2f\x01\xeb\x2a\x64\x77\x95\xb1\x7b\x51\xd7\x21\xf6\x46\x0d\xb6\x17\x5d\xf5\x42\xa7\xbb\x48\x0a\x9e\x6e\x40\xfb\xdb\x52\x6c\xe0\x0b\xc5\xce\x1a\x71\x77\x25\xd9\x7c\xa7\xa3\x16\x84\x9e\x90\xd4\xac\xa4\x62\xff\x73\x6b\x4e\xd6\x9f\xf5\x09\x93\xbd\xec\x6c\x81\x86\x14\x2f\x78\xf2\x27\x2c\x33\xc9\xf1\x0b\x13\x21\x13\xd1\x8e\xa7\x3c\x4a\x72\xcc\xaf\x6e\x49\xc2\x2e\x6d\x50\xdf\x71\xd2\x11\x40\xeb\x8c\x16\xa4\x4e\x17\xb6\xd3\xd6\xfd\xa3\x20\x5f\x7d\x53\x7b\x33\xb2\xff\x73\x22\x2b\x81\xf6\x79\x2f\x93\xc9\x01\xaf\x98\x94\xcd\x4a\x76\x7d\x50\xca\x24\xcf\xcd\x01\x7c\xf8\xe0\x7e\x28\xd4\x32\x55\x14\xcb\xf1\xf2\xfd\x8c\xce\x07\xdc\x2b\x17\xf7\x3b\x43\xb5\x78\x5a\xe7\x2e\xb3\xf2\xff\x44\x68\x5e\x43\xcb\x1d\x3c\x96\xe4\x04\xb6\x88\x46\x55\xf0\xd4\xe0\x28\xe7\xa7\xc6\x4d\x83\x97\x92\x7a\x4f\xae\xfd\x97\x33\xed\x7f\x3c\x10\x43\x57\x6f\xc4\x41\xe1\x3e\xa9\x46\x65\x67\xbe\x9b\x91\xc0\xf6\x20\xca\x07\x93\x06\x53\x6f\xea\x69\x45\xfa\xb1\x06\x11\x2c\xf2\x65\xaf\xe8\x76\x2d\x55\x57\xfd\xef\x25\xe0\x97\x79\x45\xe7\x61\xbd\x2f\xf4\xbd\x19\xbf\x6d\x28\x8a\x9f\x94\xfc\x06\xf2\xd9\x66\x48\x7f\x91\x30\x15\x50\x15\x6e\x37\x7a\x92\x30\x7c\x34\x28\xdc\xab\xb4\x1c\xb3\xcb\x11\x52\x6d\x64\x5c\x0c\x86\xe8\x9e\xcf\xe5\xa9\xa8\xe2\x0b\x79\x70\x6a\x1f\x53\x74\xc3\xeb\xcf\xba\x03\x3d\x9f\x75\x79\x2c\x26\x49\xc2\x44\xa4\xab\x13\xa5\x85\x16\x33\x95\x23\xcb\x58\xf2\xe6\x7e\x58\x93\xe7\xeb\x9b\x97\x85\x7d\x5d\x93\x6a\x3c\xd3\xe9\x04\x3c\x20\xbb\xfd\x3f\x00\x00\xff\xff\x01\xb8\xb7\x74\xff\x2b\x00\x00") func deployDataVirtletDsYamlBytes() ([]byte, error) { return bindataRead( @@ -81,7 +81,7 @@ func deployDataVirtletDsYaml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "deploy/data/virtlet-ds.yaml", size: 11061, mode: os.FileMode(420), modTime: time.Unix(1522279343, 0)} + info := bindataFileInfo{name: "deploy/data/virtlet-ds.yaml", size: 11263, mode: os.FileMode(420), modTime: time.Unix(1522279343, 0)} a := &asset{bytes: bytes, info: info} return a, nil } diff --git a/pkg/utils/mounter_linux.go b/pkg/utils/mounter_linux.go index b81e11a58..82aaa7737 100644 --- a/pkg/utils/mounter_linux.go +++ b/pkg/utils/mounter_linux.go @@ -33,5 +33,5 @@ func (mounter *mounter) Mount(source string, target string, fstype string) error } func (mounter *mounter) Unmount(target string) error { - return syscall.Unmount(target, 0) + return syscall.Unmount(target, syscall.MS_REC) }