예제 #1
0
파일: voldriver.go 프로젝트: Oskoss/rexray
func Init(id int32, cfg *module.ModuleConfig) (module.Module, error) {

	osdm, osdmErr := osm.NewOSDriverManager(cfg.Config)
	if osdmErr != nil {
		return nil, osdmErr
	}
	if len(osdm.Drivers) == 0 {
		return nil, errors.New("no os drivers initialized")
	}

	sdm, sdmErr := storage.NewStorageDriverManager(cfg.Config)
	if sdmErr != nil {
		return nil, sdmErr
	}
	if len(sdm.Drivers) == 0 {
		return nil, errors.New("no storage drivers initialized")
	}

	vdm, vdmErr := volume.NewVolumeDriverManager(cfg.Config, osdm, sdm)
	if vdmErr != nil {
		return nil, vdmErr
	}
	if len(vdm.Drivers) == 0 {
		return nil, errors.New("no volume drivers initialized")
	}

	return &Module{
		id:   id,
		vdm:  vdm,
		name: MOD_NAME,
		desc: MOD_DESC,
		addr: cfg.Address,
	}, nil
}
예제 #2
0
파일: volume.go 프로젝트: Oskoss/rexray
// NetworkName will return relevant information about how a volume can be discovered on an OS
func (driver *Driver) NetworkName(volumeName, instanceID string) (string, error) {
	log.WithFields(log.Fields{
		"volumeName": volumeName,
		"instanceID": instanceID,
		"driverName": driver.Name()}).Info("returning network name")

	volumes, err := driver.sdm.GetVolume("", volumeName)
	if err != nil {
		return "", err
	}

	switch {
	case len(volumes) == 0:
		return "", errors.New("No volumes returned by name")
	case len(volumes) > 1:
		return "", errors.New("Multiple volumes returned by name")
	}

	volumeAttachment, err := driver.sdm.GetVolumeAttach(
		volumes[0].VolumeID, instanceID)
	if err != nil {
		return "", err
	}

	if len(volumeAttachment) == 0 {
		return "", errors.New("Volume not attached")
	}

	volumes, err = driver.sdm.GetVolume("", volumeName)
	if err != nil {
		return "", err
	}

	return volumes[0].NetworkName, nil
}
예제 #3
0
파일: volume.go 프로젝트: Oskoss/rexray
// Path returns the mounted path of the volume
func (driver *Driver) Path(volumeName, volumeID string) (string, error) {
	log.WithFields(log.Fields{
		"volumeName": volumeName,
		"volumeID":   volumeID,
		"driverName": driver.Name()}).Info("getting path to volume")
	if volumeName == "" && volumeID == "" {
		return "", errors.New("Missing volume name or ID")
	}

	instances, err := driver.sdm.GetInstance()
	if err != nil {
		return "", err
	}

	switch {
	case len(instances) == 0:
		return "", errors.New("No instances")
	case len(instances) > 1:
		return "", errors.New("Too many instances returned, limit the storagedrivers")
	}

	volumes, err := driver.sdm.GetVolume(volumeID, volumeName)
	if err != nil {
		return "", err
	}

	switch {
	case len(volumes) == 0:
		return "", errors.New("No volumes returned by name")
	case len(volumes) > 1:
		return "", errors.New("Multiple volumes returned by name")
	}

	volumeAttachment, err := driver.sdm.GetVolumeAttach(volumes[0].VolumeID, instances[0].InstanceID)
	if err != nil {
		return "", err
	}

	if len(volumeAttachment) == 0 {
		return "", nil
	}

	mounts, err := driver.osdm.GetMounts(volumeAttachment[0].DeviceName, "")
	if err != nil {
		return "", err
	}

	if len(mounts) == 0 {
		return "", nil
	}

	return mounts[0].Mountpoint, nil
}
예제 #4
0
파일: storage.go 프로젝트: robnolen/rexray
func (driver *Driver) getLunMaps(initiatorName, volumeID string) (xtio.Refs, error) {
	if initiatorName == "" {
		return nil, errors.New("Missing initiatorName")
	}

	initiatorGroup, err := driver.Client.GetInitiatorGroup("", initiatorName)
	if err != nil {
		return nil, err
	}

	lunMaps, err := driver.Client.GetLunMaps()
	if err != nil {
		return nil, err
	}

	var refs xtio.Refs
	for _, ref := range lunMaps {

		idents := strings.Split(ref.Name, "_")
		if len(idents) < 3 {
			continue
		} else if strconv.Itoa(initiatorGroup.Index) == idents[1] && volumeID == idents[0] {
			refs = append(refs, ref)
		}
	}

	return refs, nil
}
예제 #5
0
파일: volume.go 프로젝트: Oskoss/rexray
func getVolumeMountPath(name string) (string, error) {
	if name == "" {
		return "", errors.New("Missing volume name")
	}

	return fmt.Sprintf("%s/%s", mountDirectoryPath, name), nil
}
예제 #6
0
파일: volume.go 프로젝트: Oskoss/rexray
// Remove will remove a remote volume
func (driver *Driver) Remove(volumeName string) error {
	log.WithFields(log.Fields{
		"volumeName": volumeName,
		"driverName": driver.Name()}).Info("removing volume")

	if volumeName == "" {
		return errors.New("Missing volume name")
	}

	instances, err := driver.sdm.GetInstance()
	if err != nil {
		return err
	}

	switch {
	case len(instances) == 0:
		return errors.New("No instances")
	case len(instances) > 1:
		return errors.New("Too many instances returned, limit the storagedrivers")
	}

	volumes, err := driver.sdm.GetVolume("", volumeName)
	if err != nil {
		return err
	}

	switch {
	case len(volumes) == 0:
		return errors.New("No volumes returned by name")
	case len(volumes) > 1:
		return errors.New("Multiple volumes returned by name")
	}

	err = driver.Unmount("", volumes[0].VolumeID)
	if err != nil {
		return err
	}

	err = driver.sdm.RemoveVolume(volumes[0].VolumeID)
	if err != nil {
		return err
	}

	return nil
}
예제 #7
0
파일: os.go 프로젝트: Oskoss/rexray
func (osdm *OSDriverManager) Unmount(mountPoint string) error {
	for _, driver := range osdm.Drivers {
		log.WithFields(log.Fields{
			"mountPoint": mountPoint,
			"driverName": driver.Name()}).Info("unmounting filesystem")
		return driver.Unmount(mountPoint)
	}
	return errors.New("No OS detected")
}
예제 #8
0
파일: os.go 프로젝트: Oskoss/rexray
func (osdm *OSDriverManager) Mounted(mountPoint string) (bool, error) {
	for _, driver := range osdm.Drivers {
		log.WithFields(log.Fields{
			"mountPoint": mountPoint,
			"driverName": driver.Name()}).Info("checking filesystem mount")
		return driver.Mounted(mountPoint)
	}
	return false, errors.New("No OS detected")
}
예제 #9
0
파일: os.go 프로젝트: Oskoss/rexray
func (osdm *OSDriverManager) Format(deviceName, fsType string, overwriteFs bool) error {
	for _, driver := range osdm.Drivers {
		log.WithFields(log.Fields{
			"deviceName":  deviceName,
			"fsType":      fsType,
			"overwriteFs": overwriteFs,
			"driverName":  driver.Name()}).Info("formatting if blank or overwriteFs specified")
		return driver.Format(deviceName, fsType, overwriteFs)
	}
	return errors.New("No OS detected")
}
예제 #10
0
파일: os.go 프로젝트: Oskoss/rexray
func (osdm *OSDriverManager) Mount(device, target, mountOptions, mountLabel string) error {
	for _, driver := range osdm.Drivers {
		log.WithFields(log.Fields{
			"device":       device,
			"target":       target,
			"mountOptions": mountOptions,
			"mountLabel":   mountLabel,
			"driverName":   driver.Name()}).Info("mounting filesystem")
		return driver.Mount(device, target, mountOptions, mountLabel)
	}
	return errors.New("No OS detected")
}
예제 #11
0
파일: os.go 프로젝트: robnolen/rexray
func (osdm *OSDriverManager) GetMounts(deviceName, mountPoint string) ([]*mount.Info, error) {

	for _, driver := range osdm.Drivers {
		mounts, err := driver.GetMounts(deviceName, mountPoint)
		if err != nil {
			return nil, err
		}
		return mounts, nil
	}

	return nil, errors.New("No OS detected")
}
예제 #12
0
파일: os.go 프로젝트: Oskoss/rexray
func NewOSDriverManager(conf *config.Config) (*OSDriverManager, error) {

	drivers, err := getDrivers(conf)
	if err != nil {
		return nil, err
	}

	if len(drivers) == 0 {
		return nil, errors.New("no os drivers initialized")
	}

	return &OSDriverManager{drivers, conf}, nil
}
예제 #13
0
파일: os.go 프로젝트: Oskoss/rexray
func (osdm *OSDriverManager) GetMounts(deviceName, mountPoint string) ([]*mount.Info, error) {

	for _, driver := range osdm.Drivers {
		log.WithFields(log.Fields{
			"deviceName": deviceName,
			"mountPoint": mountPoint,
			"driverName": driver.Name()}).Info("getting mounts")
		mounts, err := driver.GetMounts(deviceName, mountPoint)
		if err != nil {
			return nil, err
		}
		return mounts, nil
	}

	return nil, errors.New("No OS detected")
}
예제 #14
0
파일: storage.go 프로젝트: robnolen/rexray
func NewStorageDriverManager(conf *config.Config) (*StorageDriverManager, error) {

	sd, sdErr := getDrivers(conf)
	if sdErr != nil {
		return nil, sdErr
	}

	if len(sd) == 0 {
		return nil, errors.New("no storage drivers initialized")
	}

	return &StorageDriverManager{
		Drivers: sd,
		Config:  conf,
	}, nil
}
예제 #15
0
파일: storage.go 프로젝트: robnolen/rexray
func getIQN() (string, error) {
	data, err := ioutil.ReadFile("/etc/iscsi/initiatorname.iscsi")
	if err != nil {
		return "", err
	}

	result := string(data)
	lines := strings.Split(result, "\n")

	for _, line := range lines {
		split := strings.Split(line, "=")
		if split[0] == "InitiatorName" {
			return split[1], nil
		}
	}
	return "", errors.New("IQN not found")
}
예제 #16
0
파일: volume.go 프로젝트: robnolen/rexray
func NewVolumeDriverManager(
	conf *config.Config,
	osDriverManager *osm.OSDriverManager,
	storageDriverManager *storage.StorageDriverManager) (*VolumeDriverManager, error) {

	vd, vdErr := getDrivers(conf, osDriverManager, storageDriverManager)
	if vdErr != nil {
		return nil, vdErr
	}

	if len(vd) == 0 {
		return nil, errors.New("no volume drivers initialized")
	}

	return &VolumeDriverManager{
		Drivers: vd,
	}, nil
}
예제 #17
0
파일: storage.go 프로젝트: robnolen/rexray
func getLocalDevices() (deviceNames []string, err error) {
	file := "/proc/partitions"
	contentBytes, err := ioutil.ReadFile(file)
	if err != nil {
		return []string{}, errors.New(fmt.Sprintf("Couldn't read %s: %v", file, err))
	}

	content := string(contentBytes)

	lines := strings.Split(content, "\n")
	for _, line := range lines[2:] {
		fields := strings.Fields(line)
		if len(fields) == 4 {
			deviceNames = append(deviceNames, fields[3])
		}
	}

	return deviceNames, nil
}
예제 #18
0
파일: storage.go 프로젝트: robnolen/rexray
func (driver *Driver) GetDeviceNextAvailable() (string, error) {
	letters := []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"}
	blockDeviceNames := make(map[string]bool)

	blockDeviceMapping, err := driver.GetVolumeMapping()
	if err != nil {
		return "", err
	}

	for _, blockDevice := range blockDeviceMapping {
		re, _ := regexp.Compile(`^/dev/xvd([a-z])`)
		res := re.FindStringSubmatch(blockDevice.DeviceName)
		if len(res) > 0 {
			blockDeviceNames[res[1]] = true
		}
	}

	localDevices, err := getLocalDevices()
	if err != nil {
		return "", err
	}

	for _, localDevice := range localDevices {
		re, _ := regexp.Compile(`^xvd([a-z])`)
		res := re.FindStringSubmatch(localDevice)
		if len(res) > 0 {
			blockDeviceNames[res[1]] = true
		}
	}

	for _, letter := range letters {
		if !blockDeviceNames[letter] {
			nextDeviceName := "/dev/xvd" + letter
			log.Println("Got next device name: " + nextDeviceName)
			return nextDeviceName, nil
		}
	}
	return "", errors.New("No available device")
}
예제 #19
0
파일: storage.go 프로젝트: robnolen/rexray
func (driver *Driver) CopySnapshot(runAsync bool, volumeID, snapshotID, snapshotName, destinationSnapshotName, destinationRegion string) (*storage.Snapshot, error) {
	return nil, errors.New("This driver does not implement CopySnapshot")
}
예제 #20
0
파일: storage.go 프로젝트: robnolen/rexray
func (driver *Driver) CopySnapshot(runAsync bool, volumeID, snapshotID, snapshotName, destinationSnapshotName, destinationRegion string) (*storage.Snapshot, error) {
	if volumeID == "" && snapshotID == "" && snapshotName == "" {
		return nil, errors.New("Missing volumeID, snapshotID, or snapshotName")
	}

	snapshots, err := driver.getSnapshot(volumeID, snapshotID, snapshotName)
	if err != nil {
		return nil, err
	}

	if len(snapshots) > 1 {
		return nil, ErrMultipleVolumesReturned
	} else if len(snapshots) == 0 {
		return nil, ErrNoVolumesReturned
	}

	snapshotID = snapshots[0].Id

	options := &ec2.CopySnapshot{
		SourceRegion:      driver.EC2Instance.Region.Name,
		DestinationRegion: destinationRegion,
		SourceSnapshotId:  snapshotID,
		Description:       fmt.Sprintf("[Copied %s from %s]", snapshotID, driver.EC2Instance.Region.Name),
	}
	resp := &ec2.CopySnapshotResp{}

	auth := aws.Auth{
		AccessKey: driver.Config.AwsAccessKey,
		SecretKey: driver.Config.AwsSecretKey}
	destEC2Instance := ec2.New(
		auth,
		aws.Regions[destinationRegion],
	)

	origEC2Instance := driver.EC2Instance
	driver.EC2Instance = destEC2Instance
	defer func() { driver.EC2Instance = origEC2Instance }()

	resp, err = driver.EC2Instance.CopySnapshot(options)
	if err != nil {
		return nil, err
	}

	if destinationSnapshotName != "" {
		_, err := driver.EC2Instance.CreateTags([]string{resp.SnapshotId}, []ec2.Tag{{"Name", destinationSnapshotName}})
		if err != nil {
			return nil, err
		}
	}

	if !runAsync {
		log.Println("Waiting for snapshot copy to complete")
		err = driver.waitSnapshotComplete(resp.SnapshotId)
		if err != nil {
			return nil, err
		}
	}

	snapshot, err := driver.GetSnapshot("", resp.SnapshotId, "")
	if err != nil {
		return nil, err
	}

	return snapshot[0], nil
}
예제 #21
0
파일: voldriver.go 프로젝트: Oskoss/rexray
		return nil, errors.New("no volume drivers initialized")
	}

	return &Module{
		id:   id,
		vdm:  vdm,
		name: MOD_NAME,
		desc: MOD_DESC,
		addr: cfg.Address,
	}, nil
}

const driverName = "dockervolumedriver"

var (
	ErrMissingHost      = errors.New("Missing host parameter")
	ErrBadHostSpecified = errors.New("Bad host specified, ie. unix:///run/docker/plugins/rexray.sock or tcp://127.0.0.1:8080")
	ErrBadProtocol      = errors.New("Bad protocol specified with host, ie. unix:// or tcp://")
)

type pluginRequest struct {
	Name string            `json:"Name,omitempty"`
	Opts volume.VolumeOpts `json:"Opts,omitempty"`
}

func (mod *Module) Start() error {

	proto, addr, parseAddrErr := util.ParseAddress(mod.Address())
	if parseAddrErr != nil {
		return parseAddrErr
	}
예제 #22
0
파일: voldriver.go 프로젝트: Oskoss/rexray
func (mod *Module) Start() error {

	proto, addr, parseAddrErr := util.ParseAddress(mod.Address())
	if parseAddrErr != nil {
		return parseAddrErr
	}

	const validProtoPatt = "(?i)^unix|tcp$"
	isProtoValid, matchProtoErr := regexp.MatchString(validProtoPatt, proto)
	if matchProtoErr != nil {
		return errors.New(fmt.Sprintf(
			"Error matching protocol %s with pattern '%s' ERR: %v",
			proto, validProtoPatt, matchProtoErr))
	}
	if !isProtoValid {
		return errors.New(fmt.Sprintf("Invalid protocol %s", proto))
	}

	if err := os.MkdirAll("/etc/docker/plugins", 0755); err != nil {
		return err
	}

	var specPath string
	var startFunc func() error

	mux := mod.buildMux()

	if proto == "unix" {
		sockFile := addr
		sockFileDir := filepath.Dir(sockFile)
		mkSockFileDirErr := os.MkdirAll(sockFileDir, 0755)
		if mkSockFileDirErr != nil {
			return mkSockFileDirErr
		}

		_ = os.RemoveAll(sockFile)

		specPath = mod.Address()
		startFunc = func() error {
			l, lErr := net.Listen("unix", sockFile)
			if lErr != nil {
				return lErr
			}
			defer l.Close()
			defer os.Remove(sockFile)

			return http.Serve(l, mux)
		}
	} else {
		specPath = addr
		startFunc = func() error {
			s := &http.Server{
				Addr:           addr,
				Handler:        mux,
				ReadTimeout:    10 * time.Second,
				WriteTimeout:   10 * time.Second,
				MaxHeaderBytes: 1 << 20,
			}
			return s.ListenAndServe()
		}
	}

	go func() {
		sErr := startFunc()
		if sErr != nil {
			panic(sErr)
		}
	}()

	writeSpecErr := ioutil.WriteFile(
		"/etc/docker/plugins/rexray.spec", []byte(specPath), 0644)
	if writeSpecErr != nil {
		return writeSpecErr
	}

	return nil
}
예제 #23
0
파일: storage.go 프로젝트: robnolen/rexray
const ProviderName = "XtremIO"

type Driver struct {
	Client          *xtio.Client
	Initiator       xtio.Initiator
	VolumesSig      string
	LunMapsSig      string
	VolumesByNAA    map[string]xtio.Volume
	UseDeviceMapper bool
	UseMultipath    bool
	Config          *config.Config
}

var (
	ErrMissingVolumeID         = errors.New("Missing VolumeID")
	ErrMultipleVolumesReturned = errors.New("Multiple Volumes returned")
	ErrNoVolumesReturned       = errors.New("No Volumes returned")
	ErrLocalVolumeMaps         = errors.New("Getting local volume mounts")
)

func ef() errors.Fields {
	return errors.Fields{
		"provider": ProviderName,
	}
}

func eff(fields errors.Fields) map[string]interface{} {
	errFields := map[string]interface{}{
		"provider": ProviderName,
	}
예제 #24
0
파일: volume.go 프로젝트: robnolen/rexray
func (vdm *VolumeDriverManager) Unmount(volumeName, volumeID string) error {
	for _, driver := range vdm.Drivers {
		return driver.Unmount(volumeName, volumeID)
	}
	return errors.New("no volume manager specified")
}
예제 #25
0
파일: volume.go 프로젝트: robnolen/rexray
func (vdm *VolumeDriverManager) Mount(volumeName, volumeID string, overwriteFs bool, newFsType string) (string, error) {
	for _, driver := range vdm.Drivers {
		return driver.Mount(volumeName, volumeID, overwriteFs, newFsType)
	}
	return "", errors.New("no volume manager specified")
}
예제 #26
0
파일: volume.go 프로젝트: robnolen/rexray
func (vdm *VolumeDriverManager) NetworkName(volumeName, instanceID string) (string, error) {
	for _, driver := range vdm.Drivers {
		return driver.NetworkName(volumeName, instanceID)
	}
	return "", errors.New("no volume manager specified")
}
예제 #27
0
파일: volume.go 프로젝트: robnolen/rexray
func (vdm *VolumeDriverManager) Detach(volumeName, instanceID string) error {
	for _, driver := range vdm.Drivers {
		return driver.Detach(volumeName, instanceID)
	}
	return errors.New("no volume manager specified")
}
예제 #28
0
파일: volume.go 프로젝트: robnolen/rexray
func (vdm *VolumeDriverManager) Remove(volumeName string) error {
	for _, driver := range vdm.Drivers {
		return driver.Remove(volumeName)
	}
	return errors.New("no volume manager specified")
}
예제 #29
0
파일: volume.go 프로젝트: robnolen/rexray
func (vdm *VolumeDriverManager) Path(volumeName, volumeID string) (string, error) {
	for _, driver := range vdm.Drivers {
		return driver.Path(volumeName, volumeID)
	}
	return "", errors.New("no volume manager specified")
}
예제 #30
0
파일: storage.go 프로젝트: robnolen/rexray
func (driver *Driver) GetDeviceNextAvailable() (string, error) {
	return "", errors.New("This driver does not implment, since it cannot determine device name when attaching")
}