Ejemplo n.º 1
0
func (d *driver) createGetSnapshot(
	volumeOpts core.VolumeOpts) (*core.Snapshot, error) {

	var optSnapshotName string
	var optSnapshotID string

	optSnapshotName, _ = volumeOpts["snapshotname"]
	optSnapshotID, _ = volumeOpts["snapshotid"]

	if optSnapshotName == "" && optSnapshotID == "" {
		return nil, nil
	}

	var err error
	var snapshots []*core.Snapshot

	if snapshots, err = d.r.Storage.GetSnapshot(
		"", optSnapshotID, optSnapshotName); err != nil {
		return nil, err
	}

	switch {
	case len(snapshots) == 0:
		return nil, goof.WithField(
			"optSnapshotName", optSnapshotName, "No snapshots returned")
	case len(snapshots) > 1:
		return nil, goof.WithField(
			"optSnapshotName", optSnapshotName, "Too many snapshots returned")
	}

	return snapshots[0], nil
}
Ejemplo n.º 2
0
func (d *driver) createInitVolume(
	volumeName string,
	volumeOpts core.VolumeOpts) (*core.Volume, error) {

	var optVolumeName string
	var optVolumeID string

	optVolumeName, _ = volumeOpts["volumename"]
	optVolumeID, _ = volumeOpts["volumeid"]

	if optVolumeName == "" && optVolumeID == "" {
		return nil, nil
	}

	var err error
	var volumes []*core.Volume
	if volumes, err = d.r.Storage.GetVolume(optVolumeID, optVolumeName); err != nil {
		return nil, err
	}

	switch {
	case len(volumes) == 0:
		return nil, goof.WithField(
			"optVolumeName", optVolumeName, "No volumes returned")
	case len(volumes) > 1:
		return nil, goof.WithField(
			"optVolumeName", optVolumeName, "Too many volumes returned")
	}

	return volumes[0], nil
}
Ejemplo n.º 3
0
// RegisterCustomKey registers a custom key with the context package.
func RegisterCustomKey(key interface{}, mask CustomKeyTypes) error {

	customKeysRWL.Lock()
	defer customKeysRWL.Unlock()

	if _, ok := customKeys[key]; ok {
		return goof.WithField("key", key, "key already registered")
	}

	newCustomKey := &customKey{
		internalID: len(customKeys) + 1,
		externalID: key,
		keyBitmask: mask,
	}

	customKeys[newCustomKey.externalID] = newCustomKey

	log.WithFields(log.Fields{
		"internalID": newCustomKey.internalID,
		"externalID": newCustomKey.externalID,
		"keyBitmask": newCustomKey.keyBitmask,
	}).Info("registered custom context key")

	return nil
}
Ejemplo n.º 4
0
// CompileFilter compiles a filter string.
func CompileFilter(s string) (*types.Filter, error) {

	es, err := url.QueryUnescape(s)
	if err != nil {
		return nil, err
	}
	s = es

	if len(s) == 0 || s[0] != '(' {
		return nil, errCharZeroNotLParen
	}

	f, pos, err := compileFilter(s, 1)
	if err != nil {
		return nil, err
	}

	if pos != len(s) {
		return nil, goof.WithField(
			"extra", s[pos:],
			"finished compiling filter with extra at end")
	}

	return f, nil
}
Ejemplo n.º 5
0
func (d *driver) CreateVolume(
	runAsync bool, volumeName, volumeID, snapshotID, volumeType string,
	IOPS, size int64, availabilityZone string) (*core.Volume, error) {

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

	if len(volumes) > 0 {
		return nil, goof.WithField("volumeName", volumeName, "volume name already exists")
	}

	resp, err := d.createVolume(
		runAsync, volumeName, volumeID, snapshotID, volumeType,
		IOPS, size, availabilityZone)

	if err != nil {
		return nil, err
	}

	volumes, err = d.GetVolume(resp.VolumeId, "")
	if err != nil {
		return nil, err
	}

	// log.Println(fmt.Sprintf("Created volume: %+v", volumes[0]))
	return volumes[0], nil

}
Ejemplo n.º 6
0
func (c *client) getServiceInfo(service string) (*types.ServiceInfo, error) {

	if si := c.serviceCache.GetServiceInfo(service); si != nil {
		return si, nil
	}
	return nil, goof.WithField("name", service, "unknown service")
}
Ejemplo n.º 7
0
func (s *storageService) initStorageDriver(ctx types.Context) error {
	driverName := s.config.GetString("driver")
	if driverName == "" {
		driverName = s.config.GetString("libstorage.driver")
		if driverName == "" {
			driverName = s.config.GetString("libstorage.storage.driver")
			if driverName == "" {
				return goof.WithField(
					"service", s.name, "error getting driver name")
			}
		}
	}

	ctx.WithField("driverName", driverName).Debug("got driver name")
	driver, err := registry.NewStorageDriver(driverName)
	if err != nil {
		return err
	}

	ctx = ctx.WithValue(context.DriverKey, driver)

	if err := driver.Init(ctx, s.config); err != nil {
		return err
	}

	s.driver = driver
	return nil
}
Ejemplo n.º 8
0
// GetModuleInstance gets the module instance with the provided instance ID.
func GetModuleInstance(modInstID int32) (*Instance, error) {
	modInstancesRwl.RLock()
	defer modInstancesRwl.RUnlock()

	mod, modExists := modInstances[modInstID]

	if !modExists {
		return nil,
			goof.WithField("id", modInstID, "unknown module instance")
	}

	return mod, nil
}
Ejemplo n.º 9
0
// GetModuleInstance gets the module instance with the provided name.
func GetModuleInstance(name string) (*Instance, error) {
	modInstancesRwl.RLock()
	defer modInstancesRwl.RUnlock()

	name = strings.ToLower(name)
	mod, modExists := modInstances[name]

	if !modExists {
		return nil,
			goof.WithField("name", name, "unknown module instance")
	}

	return mod, nil
}
Ejemplo n.º 10
0
func (c *client) updateExecutor(ctx types.Context) error {

	if c.isController() {
		return utils.NewUnsupportedForClientTypeError(
			c.clientType, "updateExecutor")
	}

	ctx.Debug("updating executor")

	lsxi := c.lsxCache.GetExecutorInfo(types.LSX.Name())
	if lsxi == nil {
		return goof.WithField("lsx", types.LSX, "unknown executor")
	}

	ctx.Debug("waiting on executor lock")
	if err := c.lsxMutexWait(); err != nil {
		return err
	}
	defer func() {
		ctx.Debug("signalling executor lock")
		if err := c.lsxMutexSignal(); err != nil {
			panic(err)
		}
	}()

	if !types.LSX.Exists() {
		ctx.Debug("executor does not exist, download executor")
		return c.downloadExecutor(ctx)
	}

	ctx.Debug("executor exists, getting local checksum")

	checksum, err := c.getExecutorChecksum(ctx)
	if err != nil {
		return err
	}

	if lsxi.MD5Checksum != checksum {
		ctx.WithFields(log.Fields{
			"remoteChecksum": lsxi.MD5Checksum,
			"localChecksum":  checksum,
		}).Debug("executor checksums do not match, download executor")
		return c.downloadExecutor(ctx)
	}

	return nil
}
Ejemplo n.º 11
0
// UnmarshalText unmarshals the Transaction from a string.
func (t *Transaction) UnmarshalText(text []byte) error {

	m := txRX.FindSubmatch(text)
	if len(m) == 0 {
		return goof.WithField("value", string(text), "invalid transaction")
	}

	t.ID = &UUID{}
	if err := t.ID.UnmarshalText(m[1]); err != nil {
		return err
	}

	if err := (&t.Created).UnmarshalText(m[2]); err != nil {
		return err
	}

	return nil
}
Ejemplo n.º 12
0
func probeFsType(device string) (string, error) {
	probes := []probeData{
		{"btrfs", "_BHRfS_M", 0x10040},
		{"ext4", "\123\357", 0x438},
		{"xfs", "XFSB", 0},
	}

	maxLen := uint64(0)
	for _, p := range probes {
		l := p.offset + uint64(len(p.magic))
		if l > maxLen {
			maxLen = l
		}
	}

	file, err := os.Open(device)
	if err != nil {
		return "", err
	}
	defer file.Close()

	buffer := make([]byte, maxLen)
	l, err := file.Read(buffer)
	if err != nil {
		return "", err
	}

	if uint64(l) != maxLen {
		return "", goof.WithField(
			"device", device, "error detecting filesystem")
	}

	for _, p := range probes {
		if bytes.Equal(
			[]byte(p.magic), buffer[p.offset:p.offset+uint64(len(p.magic))]) {
			return p.fsName, nil
		}
	}

	return "", errUnknownFileSystem
}
Ejemplo n.º 13
0
func (d *driver) createGetVolumes(
	volumeName string,
	volumeOpts core.VolumeOpts) ([]*core.Volume, bool, error) {
	var err error
	var volumes []*core.Volume

	if volumes, err = d.r.Storage.GetVolume("", volumeName); err != nil {
		return nil, false, err
	}

	overwriteFs, _ := strconv.ParseBool(volumeOpts["overwritefs"])

	switch {
	case len(volumes) == 1 && !overwriteFs:
		return volumes, overwriteFs, nil
	case len(volumes) > 1:
		return nil, overwriteFs, goof.WithField(
			"volumeName", volumeName, "Too many volumes returned")
	}

	return volumes, overwriteFs, nil
}
Ejemplo n.º 14
0
func (d *driver) CreateVolume(
	notUsed bool,
	volumeName, volumeID, snapshotID, NUvolumeType string,
	NUIOPS, size int64, NUavailabilityZone string) (*core.Volume, error) {

	fields := eff(map[string]interface{}{
		"volumeID":   volumeID,
		"volumeName": volumeName,
		"snapshotID": snapshotID,
		"size":       size,
	})

	size = size * 1024 * 1024 * 1024

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

	if len(volumes) > 0 {
		return nil, goof.WithField(volumeName, "volumeName", "volume exists already")
	}

	volume, err := d.createVolume(volumeName, size)
	if err != nil {
		return nil, goof.WithFieldsE(fields, "error creating new volume", err)
	}

	volumes, err = d.GetVolume(volume.ID, "")
	if err != nil {
		return nil, err
	}

	if len(volumes) == 0 {
		return nil, goof.New("failed to get new volume")
	}

	return volumes[0], nil
}
Ejemplo n.º 15
0
// UnmarshalText unmarshals the data into a an InstanceID provided the data
// adheres to the format described in the MarshalText function.
func (l *LocalDevices) UnmarshalText(value []byte) error {

	m := ldRX.FindSubmatch(value)
	lm := len(m)

	if lm < 3 {
		return goof.WithField("value", string(value), "invalid LocalDevices")
	}

	l.Driver = string(m[1])
	l.DeviceMap = map[string]string{}

	for _, p := range bytes.Split(m[2], commaByteSep) {
		pp := bytes.Split(p, colonByteSep)
		if len(pp) < 2 {
			continue
		}
		l.DeviceMap[string(pp[0])] = string(pp[1])
	}

	return nil
}
Ejemplo n.º 16
0
func (d *driver) CreateVolume(
	notUsed bool,
	volumeName, volumeID, snapshotID, volumeType string,
	IOPS, size int64, availabilityZone string) (*core.Volume, error) {

	if volumeName == "" {
		return nil, goof.New("no volume name specified")
	}

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

	if len(volumes) > 0 {
		return nil, goof.WithField("volumeName", volumeName, "volume name already exists")
	}

	resp, err := d.createVolume(
		notUsed, volumeName, volumeID, snapshotID,
		volumeType, IOPS, size, availabilityZone)

	if err != nil {
		return nil, err
	}

	volumes, err = d.GetVolume(resp.ID, "")
	if err != nil {
		return nil, err
	}

	log.WithFields(log.Fields{
		"provider": providerName,
		"volume":   volumes[0],
	}).Debug("created volume")
	return volumes[0], nil

}
Ejemplo n.º 17
0
// UnmarshalText unmarshals the data into a an InstanceID provided the data
// adheres to the format described in the MarshalText function.
func (i *InstanceID) UnmarshalText(value []byte) error {

	m := iidRX.FindSubmatch(value)
	lm := len(m)

	if lm < 3 {
		return goof.WithField("value", string(value), "invalid InstanceID")
	}

	i.Driver = string(m[1])
	i.ID = string(m[2])

	if lm > 3 && len(m[3]) > 0 {
		qs, err := url.ParseQuery(string(m[3]))
		if err != nil {
			return err
		}
		i.Fields = map[string]string{}
		for k := range qs {
			i.Fields[k] = qs.Get(k)
		}
	}

	if lm > 4 && len(m[4]) > 0 {
		enc := m[4]
		dec := b64.NewDecoder(b64.StdEncoding, bytes.NewReader(enc))
		i.metadata = make([]byte, b64.StdEncoding.DecodedLen(len(enc)))
		n, err := dec.Read(i.metadata)
		if err != nil {
			return err
		}
		i.metadata = i.metadata[:n]
	}

	return nil
}
Ejemplo n.º 18
0
func (m *mod) Start() error {

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

	const validProtoPatt = "(?i)^unix|tcp$"
	isProtoValid, matchProtoErr := regexp.MatchString(validProtoPatt, proto)
	if matchProtoErr != nil {
		return goof.WithFieldsE(goof.Fields{
			"protocol":       proto,
			"validProtoPatt": validProtoPatt,
		}, "error matching protocol", matchProtoErr)
	}
	if !isProtoValid {
		return goof.WithField("protocol", proto, "invalid protocol")
	}

	if err := m.r.InitDrivers(); err != nil {
		return goof.WithFieldsE(goof.Fields{
			"m":   m,
			"m.r": m.r,
		}, "error initializing drivers", err)
	}

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

	var specPath string
	var startFunc func() error

	mux := m.buildMux()

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

		_ = os.RemoveAll(sockFile)

		specPath = m.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
}
Ejemplo n.º 19
0
// ParseTLSConfig returns a new TLS configuration.
func ParseTLSConfig(
	config gofig.Config,
	fields log.Fields,
	roots ...string) (*tls.Config, error) {

	f := func(k string, v interface{}) {
		if fields == nil {
			return
		}
		fields[k] = v
	}

	if !isSet(config, types.ConfigTLS, roots...) {
		return nil, nil
	}

	if isSet(config, types.ConfigTLSDisabled, roots...) {
		tlsDisabled := getBool(config, types.ConfigTLSDisabled, roots...)
		if tlsDisabled {
			f(types.ConfigTLSDisabled, true)
			return nil, nil
		}
	}

	if !isSet(config, types.ConfigTLSKeyFile, roots...) {
		return nil, goof.New("keyFile required")
	}
	keyFile := getString(config, types.ConfigTLSKeyFile, roots...)
	if !gotil.FileExists(keyFile) {
		return nil, goof.WithField("path", keyFile, "invalid key file")
	}
	f(types.ConfigTLSKeyFile, keyFile)

	if !isSet(config, types.ConfigTLSCertFile, roots...) {
		return nil, goof.New("certFile required")
	}
	certFile := getString(config, types.ConfigTLSCertFile, roots...)
	if !gotil.FileExists(certFile) {
		return nil, goof.WithField("path", certFile, "invalid cert file")
	}
	f(types.ConfigTLSCertFile, certFile)

	cer, err := tls.LoadX509KeyPair(certFile, keyFile)
	if err != nil {
		return nil, err
	}

	tlsConfig := &tls.Config{Certificates: []tls.Certificate{cer}}

	if isSet(config, types.ConfigTLSServerName, roots...) {
		serverName := getString(config, types.ConfigTLSServerName, roots...)
		tlsConfig.ServerName = serverName
		f(types.ConfigTLSServerName, serverName)
	}

	if isSet(config, types.ConfigTLSClientCertRequired, roots...) {
		clientCertRequired := getBool(
			config, types.ConfigTLSClientCertRequired, roots...)
		if clientCertRequired {
			tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
		}
		f(types.ConfigTLSClientCertRequired, clientCertRequired)
	}

	if isSet(config, types.ConfigTLSTrustedCertsFile, roots...) {
		trustedCertsFile := getString(
			config, types.ConfigTLSTrustedCertsFile, roots...)

		if !gotil.FileExists(trustedCertsFile) {
			return nil, goof.WithField(
				"path", trustedCertsFile, "invalid trust file")
		}

		f(types.ConfigTLSTrustedCertsFile, trustedCertsFile)

		buf, err := func() ([]byte, error) {
			f, err := os.Open(trustedCertsFile)
			if err != nil {
				return nil, err
			}
			defer f.Close()
			buf, err := ioutil.ReadAll(f)
			if err != nil {
				return nil, err
			}
			return buf, nil
		}()
		if err != nil {
			return nil, err
		}

		certPool := x509.NewCertPool()
		certPool.AppendCertsFromPEM(buf)
		tlsConfig.RootCAs = certPool
		tlsConfig.ClientCAs = certPool
	}

	return tlsConfig, nil
}
Ejemplo n.º 20
0
func (s *server) initEndpoints(ctx types.Context) error {

	endpointsObj := s.config.Get(types.ConfigEndpoints)
	if endpointsObj == nil {
		if err := s.initDefaultEndpoint(); err != nil {
			return goof.WithError("no endpoints defined", err)
		}
		endpointsObj = s.config.Get(types.ConfigEndpoints)
	}

	endpoints, ok := endpointsObj.(map[string]interface{})
	if !ok {
		return goof.New("endpoints invalid type")
	}

	if len(endpoints) == 0 {
		if err := s.initDefaultEndpoint(); err != nil {
			return err
		}
	}

	for endpointName := range endpoints {

		endpoint := fmt.Sprintf("%s.%s", types.ConfigEndpoints, endpointName)
		address := fmt.Sprintf("%s.address", endpoint)
		laddr := s.config.GetString(address)
		if laddr == "" {
			return goof.WithField("endpoint", endpoint, "missing address")
		}

		laddrET := types.ParseEndpointType(laddr)
		switch laddrET {

		case types.TCPEndpoint:

			var tcpPort int
			func() {
				tcpPortLock.Lock()
				defer tcpPortLock.Unlock()
				tcpPort = gotil.RandomTCPPort()
			}()

			laddr = fmt.Sprintf("tcp://127.0.0.1:%d", tcpPort)
			s.ctx.WithField("endpoint", endpoint).Info(
				"initializing auto tcp endpoint")

		case types.UnixEndpoint:

			laddr = fmt.Sprintf("unix://%s", utils.GetTempSockFile())
			s.ctx.WithField("endpoint", endpoint).Info(
				"initializing auto unix endpoint")

		}

		s.ctx.WithFields(log.Fields{
			"endpoint": endpoint, "address": laddr}).Debug("endpoint info")

		s.addrs = append(s.addrs, laddr)

		proto, addr, err := gotil.ParseAddress(laddr)
		if err != nil {
			return err
		}

		logFields := map[string]interface{}{
			"endpoint": endpointName,
			"address":  laddr,
		}

		tlsConfig, err :=
			utils.ParseTLSConfig(s.config.Scope(endpoint), logFields, endpoint)
		if err != nil {
			return err
		}

		ctx.WithFields(logFields).Info("configured endpoint")

		srv, err := s.newHTTPServer(proto, addr, tlsConfig)
		if err != nil {
			return err
		}

		ctx.Info("server created")
		s.servers = append(s.servers, srv)
	}

	return nil
}
Ejemplo n.º 21
0
func (c *client) httpDo(
	ctx types.Context,
	method, path string,
	payload, reply interface{}) (*http.Response, error) {

	reqBody, err := encPayload(payload)
	if err != nil {
		return nil, err
	}

	url := fmt.Sprintf("http://%s%s", c.host, path)
	req, err := http.NewRequest(method, url, reqBody)
	if err != nil {
		return nil, err
	}

	ctx = context.RequireTX(ctx)
	tx := context.MustTransaction(ctx)
	ctx = ctx.WithValue(transactionHeaderKey, tx)

	if iid, ok := context.InstanceID(ctx); ok {
		ctx = ctx.WithValue(instanceIDHeaderKey, iid)
	} else if iidMap, ok := ctx.Value(
		context.AllInstanceIDsKey).(types.InstanceIDMap); ok {
		if len(iidMap) > 0 {
			var iids []fmt.Stringer
			for _, iid := range iidMap {
				iids = append(iids, iid)
			}
			ctx = ctx.WithValue(instanceIDHeaderKey, iids)
		}
	}

	if lds, ok := context.LocalDevices(ctx); ok {
		ctx = ctx.WithValue(localDevicesHeaderKey, lds)
	} else if ldsMap, ok := ctx.Value(
		context.AllLocalDevicesKey).(types.LocalDevicesMap); ok {
		if len(ldsMap) > 0 {
			var ldsess []fmt.Stringer
			for _, lds := range ldsMap {
				ldsess = append(ldsess, lds)
			}
			ctx = ctx.WithValue(localDevicesHeaderKey, ldsess)
		}
	}

	for key := range context.CustomHeaderKeys() {

		var headerName string

		switch tk := key.(type) {
		case string:
			headerName = tk
		case fmt.Stringer:
			headerName = tk.String()
		default:
			headerName = fmt.Sprintf("%v", key)
		}

		if headerName == "" {
			continue
		}

		val := ctx.Value(key)
		switch tv := val.(type) {
		case string:
			req.Header.Add(headerName, tv)
		case fmt.Stringer:
			req.Header.Add(headerName, tv.String())
		case []string:
			for _, sv := range tv {
				req.Header.Add(headerName, sv)
			}
		case []fmt.Stringer:
			for _, sv := range tv {
				req.Header.Add(headerName, sv.String())
			}
		default:
			if val != nil {
				req.Header.Add(headerName, fmt.Sprintf("%v", val))
			}
		}
	}

	c.logRequest(req)

	res, err := ctxhttp.Do(ctx, &c.Client, req)
	if err != nil {
		return nil, err
	}
	defer c.setServerName(res)

	c.logResponse(res)

	if res.StatusCode > 299 {
		httpErr, err := goof.DecodeHTTPError(res.Body)
		if err != nil {
			return res, goof.WithField("status", res.StatusCode, "http error")
		}
		return res, httpErr
	}

	if req.Method != http.MethodHead && reply != nil {
		if err := decRes(res.Body, reply); err != nil {
			return nil, err
		}
	}

	return res, nil
}