// SetUpAt creates new directory. func (ed *emptyDir) SetUpAt(dir string, fsGroup *int64) error { notMnt, err := ed.mounter.IsLikelyNotMountPoint(dir) // Getting an os.IsNotExist err from is a contingency; the directory // may not exist yet, in which case, setup should run. if err != nil && !os.IsNotExist(err) { return err } // If the plugin readiness file is present for this volume, and the // storage medium is the default, then the volume is ready. If the // medium is memory, and a mountpoint is present, then the volume is // ready. if volumeutil.IsReady(ed.getMetaDir()) { if ed.medium == api.StorageMediumMemory && !notMnt { return nil } else if ed.medium == api.StorageMediumDefault { return nil } } // Determine the effective SELinuxOptions to use for this volume. securityContext := "" if selinuxEnabled() { securityContext = ed.rootContext } switch ed.medium { case api.StorageMediumDefault: err = ed.setupDir(dir) case api.StorageMediumMemory: err = ed.setupTmpfs(dir, securityContext) default: err = fmt.Errorf("unknown storage medium %q", ed.medium) } volume.SetVolumeOwnership(ed, fsGroup) if err == nil { volumeutil.SetReady(ed.getMetaDir()) } return err }
// doTestPlugin sets up a volume and tears it back down. func doTestPlugin(t *testing.T, config pluginTestConfig) { basePath, err := utiltesting.MkTmpdir("emptydir_volume_test") if err != nil { t.Fatalf("can't make a temp rootdir: %v", err) } defer os.RemoveAll(basePath) var ( volumePath = path.Join(basePath, "pods/poduid/volumes/kubernetes.io~empty-dir/test-volume") metadataDir = path.Join(basePath, "pods/poduid/plugins/kubernetes.io~empty-dir/test-volume") plug = makePluginUnderTest(t, "kubernetes.io/empty-dir", basePath, config.rootContext) volumeName = "test-volume" spec = &api.Volume{ Name: volumeName, VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{Medium: config.medium}}, } physicalMounter = mount.FakeMounter{} mountDetector = fakeMountDetector{} pod = &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} ) // Set up the SELinux options on the pod if config.SELinuxOptions != nil { pod.Spec = api.PodSpec{ Containers: []api.Container{ { SecurityContext: &api.SecurityContext{ SELinuxOptions: config.SELinuxOptions, }, VolumeMounts: []api.VolumeMount{ { Name: volumeName, }, }, }, }, } } if config.idempotent { physicalMounter.MountPoints = []mount.MountPoint{ { Path: volumePath, }, } util.SetReady(metadataDir) } mounter, err := plug.(*emptyDirPlugin).newMounterInternal(volume.NewSpecFromVolume(spec), pod, &physicalMounter, &mountDetector, volume.VolumeOptions{}) if err != nil { t.Errorf("Failed to make a new Mounter: %v", err) } if mounter == nil { t.Errorf("Got a nil Mounter") } volPath := mounter.GetPath() if volPath != volumePath { t.Errorf("Got unexpected path: %s", volPath) } if err := mounter.SetUp(nil); err != nil { t.Errorf("Expected success, got: %v", err) } // Stat the directory and check the permission bits fileinfo, err := os.Stat(volPath) if !config.idempotent { if err != nil { if os.IsNotExist(err) { t.Errorf("SetUp() failed, volume path not created: %s", volPath) } else { t.Errorf("SetUp() failed: %v", err) } } if e, a := perm, fileinfo.Mode().Perm(); e != a { t.Errorf("Unexpected file mode for %v: expected: %v, got: %v", volPath, e, a) } } else if err == nil { // If this test is for idempotency and we were able // to stat the volume path, it's an error. t.Errorf("Volume directory was created unexpectedly") } // Check the number of mounts performed during setup if e, a := config.expectedSetupMounts, len(physicalMounter.Log); e != a { t.Errorf("Expected %v physicalMounter calls during setup, got %v", e, a) } else if config.expectedSetupMounts == 1 && (physicalMounter.Log[0].Action != mount.FakeActionMount || physicalMounter.Log[0].FSType != "tmpfs") { t.Errorf("Unexpected physicalMounter action during setup: %#v", physicalMounter.Log[0]) } physicalMounter.ResetLog() // Make a unmounter for the volume teardownMedium := mediumUnknown if config.medium == api.StorageMediumMemory { teardownMedium = mediumMemory } unmounterMountDetector := &fakeMountDetector{medium: teardownMedium, isMount: config.shouldBeMountedBeforeTeardown} unmounter, err := plug.(*emptyDirPlugin).newUnmounterInternal(volumeName, types.UID("poduid"), &physicalMounter, unmounterMountDetector) if err != nil { t.Errorf("Failed to make a new Unmounter: %v", err) } if unmounter == nil { t.Errorf("Got a nil Unmounter") } // Tear down the volume if err := unmounter.TearDown(); err != nil { t.Errorf("Expected success, got: %v", err) } if _, err := os.Stat(volPath); err == nil { t.Errorf("TearDown() failed, volume path still exists: %s", volPath) } else if !os.IsNotExist(err) { t.Errorf("SetUp() failed: %v", err) } // Check the number of physicalMounter calls during tardown if e, a := config.expectedTeardownMounts, len(physicalMounter.Log); e != a { t.Errorf("Expected %v physicalMounter calls during teardown, got %v", e, a) } else if config.expectedTeardownMounts == 1 && physicalMounter.Log[0].Action != mount.FakeActionUnmount { t.Errorf("Unexpected physicalMounter action during teardown: %#v", physicalMounter.Log[0]) } physicalMounter.ResetLog() }