func TestSchedulerDriverNew(t *testing.T) { masterAddr := "localhost:5050" driver := newTestSchedulerDriver(t, NewMockScheduler(), &mesos.FrameworkInfo{}, masterAddr, nil) user, _ := user.Current() assert.Equal(t, user.Username, driver.FrameworkInfo.GetUser()) host := util.GetHostname("") assert.Equal(t, host, driver.FrameworkInfo.GetHostname()) }
// NewMesosExecutorDriver creates a new mesos executor driver. func NewMesosExecutorDriver(config DriverConfig) (*MesosExecutorDriver, error) { if config.Executor == nil { msg := "Executor callback interface cannot be nil." log.Errorln(msg) return nil, fmt.Errorf(msg) } hostname := mesosutil.GetHostname(config.HostnameOverride) newMessenger := config.NewMessenger if newMessenger == nil { newMessenger = func() (messenger.Messenger, error) { process := process.New("executor") return messenger.ForHostname(process, hostname, config.BindingAddress, config.BindingPort, config.PublishedAddress) } } driver := &MesosExecutorDriver{ status: mesosproto.Status_DRIVER_NOT_STARTED, stopCh: make(chan struct{}), updates: make(map[string]*mesosproto.StatusUpdate), tasks: make(map[string]*mesosproto.TaskInfo), workDir: ".", started: make(chan struct{}), } driver.cond = sync.NewCond(&driver.lock) // decouple serialized executor callback execution from goroutines of this driver var execLock sync.Mutex driver.withExecutor = func(f func(e Executor)) { go func() { execLock.Lock() defer execLock.Unlock() f(config.Executor) }() } var err error if driver.messenger, err = newMessenger(); err != nil { return nil, err } if err = driver.init(); err != nil { log.Errorf("failed to initialize the driver: %v", err) return nil, err } return driver, nil }
// NewMesosExecutorDriver creates a new mesos executor driver. func NewMesosExecutorDriver(config DriverConfig) (*MesosExecutorDriver, error) { if config.Executor == nil { msg := "Executor callback interface cannot be nil." log.Errorln(msg) return nil, fmt.Errorf(msg) } hostname := mesosutil.GetHostname(config.HostnameOverride) newMessenger := config.NewMessenger if newMessenger == nil { newMessenger = func() (messenger.Messenger, error) { process := process.New("executor") return messenger.ForHostname(process, hostname, config.BindingAddress, config.BindingPort) } } driver := &MesosExecutorDriver{ exec: config.Executor, status: mesosproto.Status_DRIVER_NOT_STARTED, stopCh: make(chan struct{}), destroyCh: make(chan struct{}), stopped: true, updates: make(map[string]*mesosproto.StatusUpdate), tasks: make(map[string]*mesosproto.TaskInfo), workDir: ".", } var err error if driver.messenger, err = newMessenger(); err != nil { return nil, err } if err = driver.init(); err != nil { log.Errorf("failed to initialize the driver: %v", err) return nil, err } return driver, nil }
// Create a new mesos scheduler driver with the given // scheduler, framework info, // master address, and credential(optional) func NewMesosSchedulerDriver(config DriverConfig) (initializedDriver *MesosSchedulerDriver, err error) { if config.Scheduler == nil { err = fmt.Errorf("Scheduler callbacks required.") } else if config.Master == "" { err = fmt.Errorf("Missing master location URL.") } else if config.Framework == nil { err = fmt.Errorf("FrameworkInfo must be provided.") } else if config.Credential != nil && config.WithAuthContext == nil { err = fmt.Errorf("WithAuthContext must be provided when Credential != nil") } if err != nil { return } framework := proto.Clone(config.Framework).(*mesos.FrameworkInfo) // set default userid if framework.GetUser() == "" { user, err := user.Current() if err != nil || user == nil { if err != nil { log.Warningf("Failed to obtain username: %v\n", err) } else { log.Warningln("Failed to obtain username.") } framework.User = proto.String("") } else { framework.User = proto.String(user.Username) } } // default hostname hostname := util.GetHostname(config.HostnameOverride) if framework.GetHostname() == "" { framework.Hostname = proto.String(hostname) } driver := &MesosSchedulerDriver{ frameworkInfo: framework, stopCh: make(chan struct{}), status: mesos.Status_DRIVER_NOT_STARTED, cache: newSchedCache(), credential: config.Credential, failover: framework.Id != nil && len(framework.Id.GetValue()) > 0, withAuthContext: config.WithAuthContext, started: make(chan struct{}), done: make(chan struct{}), } driver.withScheduler = driver.makeWithScheduler(config.Scheduler) if framework.FailoverTimeout != nil && *framework.FailoverTimeout > 0 { driver.failoverTimeout = *framework.FailoverTimeout * float64(time.Second) log.V(1).Infof("found failover_timeout = %v", time.Duration(driver.failoverTimeout)) } newDetector := config.NewDetector if newDetector == nil { newDetector = func() (detector.Master, error) { return detector.New(config.Master) } } newMessenger := config.NewMessenger if newMessenger == nil { newMessenger = func() (messenger.Messenger, error) { process := process.New("scheduler") return messenger.ForHostname(process, hostname, config.BindingAddress, config.BindingPort, config.PublishedAddress) } } // initialize new detector. if driver.masterDetector, err = newDetector(); err != nil { return } else if driver.messenger, err = newMessenger(); err != nil { return } else if err = driver.init(); err != nil { return } else { initializedDriver = driver } return }
// Create a new mesos scheduler driver with the given // scheduler, framework info, // master address, and credential(optional) func NewMesosSchedulerDriver(config DriverConfig) (initializedDriver *MesosSchedulerDriver, err error) { if config.Scheduler == nil { err = fmt.Errorf("Scheduler callbacks required.") } else if config.Master == "" { err = fmt.Errorf("Missing master location URL.") } else if config.Framework == nil { err = fmt.Errorf("FrameworkInfo must be provided.") } else if config.Credential != nil && config.WithAuthContext == nil { err = fmt.Errorf("WithAuthContext must be provided when Credential != nil") } if err != nil { return } framework := proto.Clone(config.Framework).(*mesos.FrameworkInfo) // set default userid if framework.GetUser() == "" { user, err := user.Current() if err != nil || user == nil { if err != nil { log.Warningf("Failed to obtain username: %v\n", err) } else { log.Warningln("Failed to obtain username.") } framework.User = proto.String("") } else { framework.User = proto.String(user.Username) } } // default hostname hostname := util.GetHostname(config.HostnameOverride) if framework.GetHostname() == "" { framework.Hostname = proto.String(hostname) } driver := &MesosSchedulerDriver{ frameworkInfo: framework, stopCh: make(chan struct{}), status: mesos.Status_DRIVER_NOT_STARTED, cache: newSchedCache(), credential: config.Credential, failover: framework.Id != nil && len(framework.Id.GetValue()) > 0, withAuthContext: config.WithAuthContext, started: make(chan struct{}), } driver.eventCond = sync.NewCond(&driver.eventLock) // mechanism that allows us to asynchronously invoke scheduler callbacks, but in a manner // such that the callback invocations are serialized. useful because this will decouple the // goroutine executing a messenger callback from the goroutine executing a scheduler callback, // while preserving the serialization semantics for each type of callback handling. // we use a chan to maintain the order of callback invocations; this is important for maintaining // the order in which status updates are processed. schedQueue := make(chan func(s Scheduler)) go func() { for { select { case f := <-schedQueue: f(config.Scheduler) case <-driver.stopCh: // check for a tie: abort() may have sent a message that we need to pass up // to the user. select { case f := <-schedQueue: f(config.Scheduler) default: } return } } }() driver.withScheduler = func(f func(s Scheduler)) { select { case schedQueue <- f: case <-driver.stopCh: } } if framework.FailoverTimeout != nil && *framework.FailoverTimeout > 0 { driver.failoverTimeout = *framework.FailoverTimeout * float64(time.Second) log.V(1).Infof("found failover_timeout = %v", time.Duration(driver.failoverTimeout)) } newMessenger := config.NewMessenger if newMessenger == nil { newMessenger = func() (messenger.Messenger, error) { process := process.New("scheduler") return messenger.ForHostname(process, hostname, config.BindingAddress, config.BindingPort, config.PublishedAddress) } } // initialize new detector. if driver.masterDetector, err = detector.New(config.Master); err != nil { return } else if driver.messenger, err = newMessenger(); err != nil { return } else if err = driver.init(); err != nil { return } else { initializedDriver = driver } return }