// Start starts the daemon. func Start( ctx apitypes.Context, config gofig.Config, host string, stop <-chan os.Signal) (<-chan error, error) { var ( err error errs = make(chan error) daemonErrChan <-chan error ) if daemonErrChan, err = start(ctx, config, host, stop); err != nil { ctx.WithError(err).Error("daemon failed to initialize") return nil, err } ctx.Info("service successfully initialized, waiting on stop signal") go func() { sig := <-stop ctx.WithField("signal", sig).Info("service received stop signal") util.WaitUntilLibStorageStopped(ctx, daemonErrChan) close(errs) }() return errs, nil }
func (c *client) withAllLocalDevices(ctx types.Context) (types.Context, error) { if c.isController() { return ctx, nil } ldm := types.LocalDevicesMap{} hit := map[string]bool{} for _, service := range c.serviceCache.Keys() { si := c.serviceCache.GetServiceInfo(service) dn := strings.ToLower(si.Driver.Name) if _, ok := hit[dn]; ok { continue } ctx := ctx.WithValue(context.ServiceKey, service) ld, err := c.LocalDevices(ctx, &types.LocalDevicesOpts{}) if err != nil { if err == errExecutorNotSupported || err == types.ErrNotImplemented { ctx.WithError(err).Warn("cannot get local deviecs") continue } return nil, err } hit[dn] = true ldm[dn] = ld } return ctx.WithValue(context.AllLocalDevicesKey, ldm), nil }
func waitUntilLibStorageStopped(ctx apitypes.Context, errs <-chan error) { ctx.Debug("waiting until libStorage is stopped") // if there is no err channel then do not wait until libStorage is stopped // as the absence of the err channel means libStorage was not started in // embedded mode if errs == nil { ctx.Debug("done waiting on err chan; err chan is nil") return } // in a goroutine, range over the apiserver.Close channel until it's closed for range apiserver.Close() { } ctx.Debug("done sending close signals to libStorage") // block until the err channel is closed for err := range errs { if err == nil { continue } ctx.WithError(err).Error("error on closing libStorage server") } ctx.Debug("done waiting on err chan") }
func (c *client) dial(ctx types.Context) error { ctx.WithField("path", lsxMutex).Info("lsx lock file path") svcInfos, err := c.Services(ctx) if err != nil { return err } // controller clients do not have any additional dialer logic if c.isController() { return nil } store := utils.NewStore() c.ctx = c.ctx.WithValue(context.ServerKey, c.ServerName()) if !c.config.GetBool(types.ConfigExecutorNoDownload) { ctx.Info("initializing executors cache") if _, err := c.Executors(ctx); err != nil { return err } if err := c.updateExecutor(ctx); err != nil { return err } } for service, _ := range svcInfos { ctx := c.ctx.WithValue(context.ServiceKey, service) ctx.Info("initializing supported cache") supported, err := c.Supported(ctx, store) if err != nil { return goof.WithError("error initializing supported cache", err) } if !supported { ctx.Warn("executor not supported") continue } ctx.Info("initializing instance ID cache") if _, err := c.InstanceID(ctx, store); err != nil { if err == types.ErrNotImplemented { ctx.WithError(err).Warn("cannot get instance ID") continue } return goof.WithError("error initializing instance ID cache", err) } } return nil }
func start( ctx apitypes.Context, config gofig.Config, host string, stop <-chan os.Signal) (<-chan error, error) { ctx, _, errs, err := util.ActivateLibStorage(ctx, config) if err != nil { ctx.WithError(err).Error( "error activing libStorage in server-only mode") return nil, err } return errs, nil }
func start( ctx apitypes.Context, config gofig.Config, host string, stop <-chan os.Signal) (<-chan error, error) { moduleErrChan, err := module.InitializeDefaultModules(ctx, config) if err != nil { ctx.WithError(err).Error("default module(s) failed to initialize") return nil, err } if err = module.StartDefaultModules(ctx, config); err != nil { ctx.WithError(err).Error("default module(s) failed to start") return nil, err } return moduleErrChan, nil }
func activateLibStorage( ctx apitypes.Context, config gofig.Config) (apitypes.Context, gofig.Config, <-chan error, error) { apiserver.DisableStartupInfo = true var ( host string err error isRunning bool errs chan error serverErrChan <-chan error server apitypes.Server ) if host = config.GetString(apitypes.ConfigHost); host != "" { if !config.GetBool(apitypes.ConfigEmbedded) { ctx.WithField( "host", host, ).Debug("not starting embedded server; embedded mode disabled") return ctx, config, nil, nil } } if host, isRunning = IsLocalServerActive(ctx, config); isRunning { ctx = setHost(ctx, config, host) ctx.WithField("host", host).Debug( "not starting embedded server; already running") return ctx, config, nil, nil } // if no host was specified then see if a set of default services need to // be initialized if host == "" { ctx.Debug("host is empty; initiliazing default services") if err = initDefaultLibStorageServices(ctx, config); err != nil { ctx.WithError(err).Error("error initializing default services") return ctx, config, nil, err } } ctx.Debug("starting embedded libStorage server") if server, serverErrChan, err = apiserver.Serve(ctx, config); err != nil { ctx.WithError(err).Error("error starting libStorage server") return ctx, config, nil, err } if host == "" { host = server.Addrs()[0] ctx.WithField("host", host).Debug("got host from new server address") } ctx = setHost(ctx, config, host) errs = make(chan error) go func() { for err := range serverErrChan { if err != nil { errs <- err } } if err := os.RemoveAll(SpecFilePath()); err == nil { logHostSpec(ctx, host, "removed spec file") } close(errs) }() // write the host to the spec file so that other rex-ray invocations can // find it, even if running as an embedded libStorage server if err := WriteSpecFile(host); err != nil { specFile := SpecFilePath() if os.IsPermission(err) { ctx.WithError(err).Errorf( "user does not have write permissions for %s", specFile) } else { ctx.WithError(err).Errorf( "error writing spec file at %s", specFile) } //WaitUntilLibStorageStopped(ctx, serverErrChan) return ctx, config, errs, err } logHostSpec(ctx, host, "created spec file") return ctx, config, errs, nil }