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 }
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 }
// 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 }
// 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 }
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 }
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") }
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 }
// 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 }
// 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 }
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 }
// 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 }
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 }
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 }
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 }
// 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 }
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 }
// 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 }
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 }
// 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 }
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 }
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 }