func driverConfig(fwinfo *mesos.FrameworkInfo) sched.DriverConfig { // build command executor exec := prepareExecutorInfo() publishedAddress := parseIP(config.Runonce.Address) dConfig := sched.DriverConfig{ Scheduler: newMesosRunonceScheduler(exec), Framework: fwinfo, Master: config.Runonce.Master, Credential: cred(fwinfo), PublishedAddress: publishedAddress, WithAuthContext: func(ctx context.Context) context.Context { ctx = auth.WithLoginProvider(ctx, config.Runonce.AuthProvider) ctx = sasl.WithBindingAddress(ctx, publishedAddress) return ctx }, } // Allow listening port to be configurable so we can run this inside of // mesos if desired. // NOTE only affects main PID, meaning the authentication step uses // another PID which picks a random (32K range) port :(. Opened // https://github.com/mesos/mesos-go/issues/229 to discuss. if config.Runonce.BindingPort != 0 { dConfig.BindingPort = uint16(config.Runonce.BindingPort) } return dConfig }
// NewScheduler for Scheduler mesos driver creation func NewScheduler(config mesosscheduler.DriverConfig, cluster *Cluster, sched *scheduler.Scheduler) (*Scheduler, error) { scheduler := Scheduler{ Scheduler: *sched, cluster: cluster, } config.Scheduler = &scheduler driver, err := mesosscheduler.NewMesosSchedulerDriver(config) if err != nil { return nil, err } scheduler.driver = driver return &scheduler, nil }
// NewCluster for mesos Cluster creation func NewCluster(scheduler *scheduler.Scheduler, store *state.Store, TLSConfig *tls.Config, master string, options cluster.DriverOpts) (cluster.Cluster, error) { log.WithFields(log.Fields{"name": "mesos"}).Debug("Initializing cluster") cluster := &Cluster{ dockerEnginePort: defaultDockerEnginePort, master: master, slaves: make(map[string]*slave), scheduler: scheduler, store: store, TLSConfig: TLSConfig, options: &options, offerTimeout: defaultOfferTimeout, taskCreationTimeout: defaultTaskCreationTimeout, } cluster.pendingTasks = queue.NewQueue() // Empty string is accepted by the scheduler. user, _ := options.String("mesos.user", "SWARM_MESOS_USER") // Override the hostname here because mesos-go will try // to shell out to the hostname binary and it won't work with our official image. // Do not check error here, so mesos-go can still try. hostname, _ := os.Hostname() driverConfig := mesosscheduler.DriverConfig{ Scheduler: cluster, Framework: &mesosproto.FrameworkInfo{Name: proto.String(frameworkName), User: &user}, Master: cluster.master, HostnameOverride: hostname, } if taskCreationTimeout, ok := options.String("mesos.tasktimeout", "SWARM_MESOS_TASK_TIMEOUT"); ok { d, err := time.ParseDuration(taskCreationTimeout) if err != nil { return nil, err } cluster.taskCreationTimeout = d } // Changing port for https if cluster.TLSConfig != nil { cluster.dockerEnginePort = defaultDockerEngineTLSPort } if bindingPort, ok := options.Uint("mesos.port", "SWARM_MESOS_PORT"); ok { driverConfig.BindingPort = uint16(bindingPort) } if bindingAddress, ok := options.IP("mesos.address", "SWARM_MESOS_ADDRESS"); ok { if bindingAddress == nil { return nil, fmt.Errorf("invalid address %s", bindingAddress) } driverConfig.BindingAddress = bindingAddress } if offerTimeout, ok := options.String("mesos.offertimeout", "SWARM_MESOS_OFFER_TIMEOUT"); ok { d, err := time.ParseDuration(offerTimeout) if err != nil { return nil, err } cluster.offerTimeout = d } driver, err := mesosscheduler.NewMesosSchedulerDriver(driverConfig) if err != nil { return nil, err } cluster.driver = driver status, err := driver.Start() if err != nil { log.Debugf("Mesos driver started, status/err %v: %v", status, err) return nil, err } log.Debugf("Mesos driver started, status %v", status) return cluster, nil }
// NewCluster for mesos Cluster creation func NewCluster(scheduler *scheduler.Scheduler, TLSConfig *tls.Config, master string, options cluster.DriverOpts, engineOptions *cluster.EngineOpts) (cluster.Cluster, error) { log.WithFields(log.Fields{"name": "mesos"}).Debug("Initializing cluster") // Enabling mesos-go glog logging if log.GetLevel() == log.DebugLevel { flag.Lookup("logtostderr").Value.Set("true") } cluster := &Cluster{ dockerEnginePort: defaultDockerEnginePort, eventHandlers: cluster.NewEventHandlers(), master: master, agents: make(map[string]*agent), TLSConfig: TLSConfig, options: &options, offerTimeout: defaultOfferTimeout, taskCreationTimeout: defaultTaskCreationTimeout, engineOpts: engineOptions, refuseTimeout: defaultRefuseTimeout, } cluster.pendingTasks = task.NewTasks(cluster) // Empty string is accepted by the scheduler. user, _ := options.String("mesos.user", "SWARM_MESOS_USER") // Override the hostname here because mesos-go will try // to shell out to the hostname binary and it won't work with our official image. // Do not check error here, so mesos-go can still try. hostname, _ := os.Hostname() driverConfig := mesosscheduler.DriverConfig{ Framework: &mesosproto.FrameworkInfo{Name: proto.String(frameworkName), User: &user}, Master: cluster.master, HostnameOverride: hostname, } if taskCreationTimeout, ok := options.String("mesos.tasktimeout", "SWARM_MESOS_TASK_TIMEOUT"); ok { d, err := time.ParseDuration(taskCreationTimeout) if err != nil { return nil, err } cluster.taskCreationTimeout = d } // Changing port for https if cluster.TLSConfig != nil { cluster.dockerEnginePort = defaultDockerEngineTLSPort } if bindingPort, ok := options.Uint("mesos.port", "SWARM_MESOS_PORT"); ok { driverConfig.BindingPort = uint16(bindingPort) } if bindingAddress, ok := options.IP("mesos.address", "SWARM_MESOS_ADDRESS"); ok { if bindingAddress == nil { value, _ := options.String("mesos.address", "SWARM_MESOS_ADDRESS") return nil, fmt.Errorf( "invalid IP address for cluster-opt mesos.address: \"%s\"", value) } driverConfig.BindingAddress = bindingAddress } if checkpointFailover, ok := options.Bool("mesos.checkpointfailover", "SWARM_MESOS_CHECKPOINT_FAILOVER"); ok { driverConfig.Framework.Checkpoint = &checkpointFailover } if offerTimeout, ok := options.String("mesos.offertimeout", "SWARM_MESOS_OFFER_TIMEOUT"); ok { d, err := time.ParseDuration(offerTimeout) if err != nil { return nil, err } cluster.offerTimeout = d } if refuseTimeout, ok := options.String("mesos.offerrefusetimeout", "SWARM_MESOS_OFFER_REFUSE_TIMEOUT"); ok { d, err := time.ParseDuration(refuseTimeout) if err != nil { return nil, err } cluster.refuseTimeout = d } sched, err := NewScheduler(driverConfig, cluster, scheduler) if err != nil { return nil, err } cluster.scheduler = sched status, err := sched.driver.Start() if err != nil { log.Debugf("Mesos driver started, status/err %v: %v", status, err) return nil, err } log.Debugf("Mesos driver started, status %v", status) go func() { status, err := sched.driver.Join() log.Debugf("Mesos driver stopped unexpectedly, status/err %v: %v", status, err) }() return cluster, nil }
func (sc *SchedulerCore) Run(mesosMaster string) { sc.schedulerState.MesosMaster = mesosMaster var frameworkId *mesos.FrameworkID if sc.schedulerState.FrameworkID == nil { frameworkId = nil } else { frameworkId = &mesos.FrameworkID{ Value: sc.schedulerState.FrameworkID, } } fwinfo := &mesos.FrameworkInfo{ Name: proto.String(sc.frameworkName), Id: frameworkId, FailoverTimeout: proto.Float64(86400), WebuiUrl: proto.String(sc.schedulerHTTPServer.GetURI()), Checkpoint: proto.Bool(true), Role: proto.String(sc.frameworkRole), } if sc.user != "" { fwinfo.User = proto.String(sc.user) } else { guestUser := "******" fwinfo.User = &guestUser } cred := (*mesos.Credential)(nil) if sc.mesosAuthPrincipal != "" { fwinfo.Principal = proto.String(sc.mesosAuthPrincipal) } if sc.mesosAuthSecretFile != "" && sc.mesosAuthPrincipal != "" { secret, err := ioutil.ReadFile(sc.mesosAuthSecretFile) if err != nil { log.Fatal(err) } cred = &mesos.Credential{ Principal: proto.String(sc.mesosAuthPrincipal), Secret: secret, } } hostname, err := os.Hostname() if err != nil { log.Fatal(err) } config := sched.DriverConfig{ Scheduler: sc, Framework: fwinfo, Master: mesosMaster, Credential: cred, HostnameOverride: hostname, } if sc.schedulerIPAddr != "" { config.BindingAddress = parseIP(sc.schedulerIPAddr) } if sc.authProvider != "" && sc.mesosAuthPrincipal != "" { config.WithAuthContext = func(ctx context.Context) context.Context { ctx = auth.WithLoginProvider(ctx, sc.authProvider) if sc.schedulerIPAddr != "" { ctx = sasl.WithBindingAddress(ctx, parseIP(sc.schedulerIPAddr)) } return ctx } } log.Infof("Running scheduler with FrameworkInfo: %v and DriverConfig: %v", fwinfo, config) driver, err := sched.NewMesosSchedulerDriver(config) if err != nil { log.Error("Unable to create a SchedulerDriver ", err.Error()) } sc.rServer = newReconciliationServer(driver, sc) sc.mgr.SetupFramework(sc.schedulerHTTPServer.URI) if stat, err := driver.Run(); err != nil { log.Infof("Framework stopped with status %s and error: %s\n", stat.String(), err.Error()) } }