func TestPersistentClaimReadOnlyFlag(t *testing.T) { pv := &api.PersistentVolume{ ObjectMeta: api.ObjectMeta{ Name: "pvA", }, Spec: api.PersistentVolumeSpec{ PersistentVolumeSource: api.PersistentVolumeSource{ Glusterfs: &api.GlusterfsVolumeSource{EndpointsName: "ep", Path: "vol", ReadOnly: false}, }, ClaimRef: &api.ObjectReference{ Name: "claimA", }, }, } claim := &api.PersistentVolumeClaim{ ObjectMeta: api.ObjectMeta{ Name: "claimA", Namespace: "nsA", }, Spec: api.PersistentVolumeClaimSpec{ VolumeName: "pvA", }, Status: api.PersistentVolumeClaimStatus{ Phase: api.ClaimBound, }, } ep := &api.Endpoints{ ObjectMeta: api.ObjectMeta{ Name: "ep", }, Subsets: []api.EndpointSubset{{ Addresses: []api.EndpointAddress{{IP: "127.0.0.1"}}, Ports: []api.EndpointPort{{"foo", 80, api.ProtocolTCP}}, }}, } o := testclient.NewObjects(api.Scheme, api.Scheme) o.Add(pv) o.Add(claim) o.Add(ep) client := &testclient.Fake{} client.AddReactor("*", "*", testclient.ObjectReaction(o, testapi.Default.RESTMapper())) plugMgr := volume.VolumePluginMgr{} plugMgr.InitPlugins(ProbeVolumePlugins(), volume.NewFakeVolumeHost("/tmp/fake", client, nil)) plug, _ := plugMgr.FindPluginByName(glusterfsPluginName) // readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes spec := volume.NewSpecFromPersistentVolume(pv, true) pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}) if !builder.IsReadOnly() { t.Errorf("Expected true for builder.IsReadOnly") } }
func TestPersistentClaimReadOnlyFlag(t *testing.T) { lun := 0 pv := &api.PersistentVolume{ ObjectMeta: api.ObjectMeta{ Name: "pvA", }, Spec: api.PersistentVolumeSpec{ PersistentVolumeSource: api.PersistentVolumeSource{ FC: &api.FCVolumeSource{ TargetWWNs: []string{"some_wwn"}, FSType: "ext4", Lun: &lun, }, }, ClaimRef: &api.ObjectReference{ Name: "claimA", }, }, } claim := &api.PersistentVolumeClaim{ ObjectMeta: api.ObjectMeta{ Name: "claimA", Namespace: "nsA", }, Spec: api.PersistentVolumeClaimSpec{ VolumeName: "pvA", }, Status: api.PersistentVolumeClaimStatus{ Phase: api.ClaimBound, }, } o := testclient.NewObjects(api.Scheme, api.Scheme) o.Add(pv) o.Add(claim) client := &testclient.Fake{} client.AddReactor("*", "*", testclient.ObjectReaction(o, testapi.Default.RESTMapper())) plugMgr := volume.VolumePluginMgr{} plugMgr.InitPlugins(ProbeVolumePlugins(), volume.NewFakeVolumeHost("/tmp/fake", client, nil)) plug, _ := plugMgr.FindPluginByName(fcPluginName) // readOnly bool is supplied by persistent-claim volume source when its builder creates other volumes spec := volume.NewSpecFromPersistentVolume(pv, true) pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} builder, _ := plug.NewBuilder(spec, pod, volume.VolumeOptions{}) if !builder.IsReadOnly() { t.Errorf("Expected true for builder.IsReadOnly") } }
func TestPluginPersistentVolume(t *testing.T) { vol := &api.PersistentVolume{ ObjectMeta: api.ObjectMeta{ Name: "vol1", }, Spec: api.PersistentVolumeSpec{ PersistentVolumeSource: api.PersistentVolumeSource{ Glusterfs: &api.GlusterfsVolumeSource{EndpointsName: "ep", Path: "vol", ReadOnly: false}, }, }, } doTestPlugin(t, volume.NewSpecFromPersistentVolume(vol, false)) }
func TestPluginPersistentVolume(t *testing.T) { vol := &api.PersistentVolume{ ObjectMeta: api.ObjectMeta{ Name: "vol1", }, Spec: api.PersistentVolumeSpec{ PersistentVolumeSource: api.PersistentVolumeSource{ NFS: &api.NFSVolumeSource{Server: "localhost", Path: "/tmp", ReadOnly: false}, }, }, } doTestPlugin(t, volume.NewSpecFromPersistentVolume(vol, false)) }
func TestPluginPersistentVolume(t *testing.T) { lun := 0 vol := &api.PersistentVolume{ ObjectMeta: api.ObjectMeta{ Name: "vol1", }, Spec: api.PersistentVolumeSpec{ PersistentVolumeSource: api.PersistentVolumeSource{ FC: &api.FCVolumeSource{ TargetWWNs: []string{"some_wwn"}, FSType: "ext4", Lun: &lun, }, }, }, } doTestPlugin(t, volume.NewSpecFromPersistentVolume(vol, false)) }
func TestPluginPersistentVolume(t *testing.T) { vol := &api.PersistentVolume{ ObjectMeta: api.ObjectMeta{ Name: "vol1", }, Spec: api.PersistentVolumeSpec{ PersistentVolumeSource: api.PersistentVolumeSource{ ISCSI: &api.ISCSIVolumeSource{ TargetPortal: "127.0.0.1:3260", IQN: "iqn.2014-12.server:storage.target01", FSType: "ext4", Lun: 0, }, }, }, } doTestPlugin(t, volume.NewSpecFromPersistentVolume(vol, false)) }
func TestPluginPersistentVolume(t *testing.T) { vol := &api.PersistentVolume{ ObjectMeta: api.ObjectMeta{ Name: "vol1", }, Spec: api.PersistentVolumeSpec{ PersistentVolumeSource: api.PersistentVolumeSource{ RBD: &api.RBDVolumeSource{ CephMonitors: []string{"a", "b"}, RBDImage: "bar", FSType: "ext4", }, }, }, } doTestPlugin(t, volume.NewSpecFromPersistentVolume(vol, false)) }
func (recycler *PersistentVolumeRecycler) handleDelete(pv *api.PersistentVolume) error { glog.V(5).Infof("Deleting PersistentVolume[%s]\n", pv.Name) currentPhase := pv.Status.Phase nextPhase := currentPhase spec := volume.NewSpecFromPersistentVolume(pv, false) plugin, err := recycler.pluginMgr.FindDeletablePluginBySpec(spec) if err != nil { return fmt.Errorf("Could not find deletable volume plugin for spec: %+v", err) } deleter, err := plugin.NewDeleter(spec) if err != nil { return fmt.Errorf("could not obtain Deleter for spec: %+v", err) } // blocks until completion err = deleter.Delete() if err != nil { glog.Errorf("PersistentVolume[%s] failed deletion: %+v", pv.Name, err) pv.Status.Message = fmt.Sprintf("Deletion error: %s", err) nextPhase = api.VolumeFailed } else { glog.V(5).Infof("PersistentVolume[%s] successfully deleted through plugin\n", pv.Name) // after successful deletion through the plugin, we can also remove the PV from the cluster err = recycler.client.DeletePersistentVolume(pv) if err != nil { return fmt.Errorf("error deleting persistent volume: %+v", err) } } if currentPhase != nextPhase { glog.V(5).Infof("PersistentVolume[%s] changing phase from %s to %s\n", pv.Name, currentPhase, nextPhase) pv.Status.Phase = nextPhase _, err := recycler.client.UpdatePersistentVolumeStatus(pv) if err != nil { // Rollback to previous phase pv.Status.Phase = currentPhase } } return nil }
func (recycler *PersistentVolumeRecycler) handleRecycle(pv *api.PersistentVolume) error { glog.V(5).Infof("Recycling PersistentVolume[%s]\n", pv.Name) currentPhase := pv.Status.Phase nextPhase := currentPhase spec := volume.NewSpecFromPersistentVolume(pv, false) plugin, err := recycler.pluginMgr.FindRecyclablePluginBySpec(spec) if err != nil { return fmt.Errorf("Could not find recyclable volume plugin for spec: %+v", err) } volRecycler, err := plugin.NewRecycler(spec) if err != nil { return fmt.Errorf("Could not obtain Recycler for spec: %+v", err) } // blocks until completion err = volRecycler.Recycle() if err != nil { glog.Errorf("PersistentVolume[%s] failed recycling: %+v", pv.Name, err) pv.Status.Message = fmt.Sprintf("Recycling error: %s", err) nextPhase = api.VolumeFailed } else { glog.V(5).Infof("PersistentVolume[%s] successfully recycled\n", pv.Name) nextPhase = api.VolumePending if err != nil { glog.Errorf("Error updating pv.Status: %+v", err) } } if currentPhase != nextPhase { glog.V(5).Infof("PersistentVolume[%s] changing phase from %s to %s\n", pv.Name, currentPhase, nextPhase) pv.Status.Phase = nextPhase _, err := recycler.client.UpdatePersistentVolumeStatus(pv) if err != nil { // Rollback to previous phase pv.Status.Phase = currentPhase } } return nil }