Exemple #1
0
func (client *cinderClient) terminateConnection(id string, copts *volumeactions.ConnectorOpts) error {
	terminateResult := volumeactions.TerminateConnection(client.cinder, id, copts)
	if terminateResult.Err != nil && terminateResult.Err.Error() != "EOF" {
		glog.Warningf("Terminate cinder volume %s failed: %v", id, terminateResult.Err)
	}

	return nil
}
func TestVolumeConns(t *testing.T) {
	client, err := newClient(t)
	th.AssertNoErr(t, err)

	t.Logf("Creating volume")
	cv, err := volumes.Create(client, &volumes.CreateOpts{
		Size: 1,
		Name: "blockv2-volume",
	}).Extract()
	th.AssertNoErr(t, err)

	defer func() {
		err = volumes.WaitForStatus(client, cv.ID, "available", 60)
		th.AssertNoErr(t, err)

		t.Logf("Deleting volume")
		err = volumes.Delete(client, cv.ID).ExtractErr()
		th.AssertNoErr(t, err)
	}()

	err = volumes.WaitForStatus(client, cv.ID, "available", 60)
	th.AssertNoErr(t, err)

	connOpts := &volumeactions.ConnectorOpts{
		IP:        "127.0.0.1",
		Host:      "stack",
		Initiator: "iqn.1994-05.com.redhat:17cf566367d2",
		Multipath: false,
		Platform:  "x86_64",
		OSType:    "linux2",
	}

	t.Logf("Initializing connection")
	_, err = volumeactions.InitializeConnection(client, cv.ID, connOpts).Extract()
	th.AssertNoErr(t, err)

	t.Logf("Terminating connection")
	err = volumeactions.TerminateConnection(client, cv.ID, connOpts).ExtractErr()
	th.AssertNoErr(t, err)
}
func (d CinderDriver) Unmount(r volume.Request) volume.Response {
	log.Infof("Unmounting volume: %+v", r)
	d.Mutex.Lock()
	defer d.Mutex.Unlock()
	vol, err := d.getByName(r.Name)
	if vol.ID == "" {
		log.Errorf("Request to Unmount failed because volume `%s` could not be found", r.Name)
		err := errors.New("Volume Not Found")
		return volume.Response{Err: err.Error()}
	}

	if err != nil {
		log.Errorf("Failed to retrieve volume named: `", r.Name, "` during Unmount operation", err)
		return volume.Response{Err: err.Error()}
	}

	if umountErr := Umount(d.Conf.MountPoint + "/" + r.Name); umountErr != nil {
		if umountErr.Error() == "Volume is not mounted" {
			log.Warning("Request to unmount volume, but it's not mounted")
			return volume.Response{}
		} else {
			return volume.Response{Err: umountErr.Error()}
		}
	}
	// NOTE(jdg): So there's a couple issues with how Docker works here.  If
	// you are trying to attach and it fails, it kindly goes through and does
	// an Unmount to clean up anything that went bad, BUT that creates a
	// problem here.  Say for example you try to attach an in-use volume, we
	// don't want to rip that out from under wherever it's currently being used

	// NOTE(jdg): Don't rely on things like `df --output=source mounpoint`
	// that's no good for error situations.

	tgt, portal := getTgtInfo(vol)
	iscsiDetachVolume(tgt, portal)
	log.Debug("Terminate Connection")
	iface := d.Conf.InitiatorIFace
	netDev, _ := net.InterfaceByName(iface)
	IPs, _ := net.InterfaceAddrs()
	log.Debugf("iface: %+v\n Addrs: %+v", netDev, IPs)
	initiators, err := GetInitiatorIqns()
	if err != nil {
		log.Error("Failed to retrieve Initiator name!")
		return volume.Response{Err: err.Error()}
	}
	hostname, _ := os.Hostname()
	// TODO(ebalduf): Change assumption that we have only one Initiator defined
	// TODO(jdg): For now we're only supporting linux, but in the future we'll
	// need to get rid of the hard coded Platform/OSType and fix this up for
	// things like say Windows
	log.Debugf("IPs=%+v\n", IPs)
	connectorOpts := volumeactions.ConnectorOpts{
		IP:        d.Conf.InitiatorIP,
		Host:      hostname,
		Initiator: initiators[0],
		Wwpns:     []string{},
		Wwnns:     "",
		Multipath: false,
		Platform:  "x86",
		OSType:    "linux",
	}
	log.Debugf("Unreserve volume: %s", vol.ID)
	volumeactions.Unreserve(d.Client, vol.ID)
	log.Debugf("Terminate connection for volume: %s", vol.ID)
	volumeactions.TerminateConnection(d.Client, vol.ID, &connectorOpts)
	log.Debugf("Detach volume: %s", vol.ID)
	volumeactions.Detach(d.Client, vol.ID)
	return volume.Response{}
}