func main() { // XXX Uncomment the following line to run the profiler //runProfiler(5 * time.Minute) log.Info("Minion Start") log.SetFormatter(util.Formatter{}) conn := db.New() dk := docker.New("unix:///var/run/docker.sock") go minionServerRun(conn) go supervisor.Run(conn, dk) go scheduler.Run(conn) go network.Run(conn, dk) go etcd.Run(conn) for range conn.Trigger(db.MinionTable).C { conn.Transact(func(view db.Database) error { minion, err := view.MinionSelf() if err != nil { return err } updatePolicy(view, minion.Role, minion.Spec) return nil }) } }
// Run blocks implementing the scheduler module. func Run(conn db.Conn) { var sched scheduler for range conn.TriggerTick(30, db.MinionTable, db.EtcdTable, db.ContainerTable, db.PlacementTable).C { minion, err := conn.MinionSelf() if err != nil || !conn.EtcdLeader() || minion.Role != db.Master || minion.PrivateIP == "" { sched = nil continue } if sched == nil { ip := minion.PrivateIP sched = newSwarm(docker.New(fmt.Sprintf("tcp://%s:2377", ip))) time.Sleep(60 * time.Second) } placements := conn.SelectFromPlacement(nil) connections := conn.SelectFromConnection(nil) // Each time we run through this loop, we may boot or terminate // containers. These modification should, in turn, be reflected in the // database themselves. For this reason, we attempt to sync until no // database modifications happen (up to an arbitrary limit of three // tries). for i := 0; i < 3; i++ { dkc, err := sched.list() if err != nil { log.WithError(err).Warning("Failed to get containers.") break } var boot []db.Container var term []string conn.Transact(func(view db.Database) error { term, boot = syncDB(view, dkc) return nil }) if len(term) == 0 && len(boot) == 0 { break } sched.terminate(term) sched.boot(boot, placements, connections) } } }
// Run blocks executing the minion. func Run() { // XXX Uncomment the following line to run the profiler //runProfiler(5 * time.Minute) log.Info("Minion Start") conn := db.New() dk := docker.New("unix:///var/run/docker.sock") // Not in a goroutine, want the plugin to start before the scheduler plugin.Run() go minionServerRun(conn) go supervisor.Run(conn, dk) go scheduler.Run(conn, dk) go network.Run(conn, dk) go etcd.Run(conn) go syncAuthorizedKeys(conn) go apiServer.Run(conn, fmt.Sprintf("tcp://0.0.0.0:%d", api.DefaultRemotePort)) loopLog := util.NewEventTimer("Minion-Update") for range conn.Trigger(db.MinionTable).C { loopLog.LogStart() conn.Transact(func(view db.Database) error { minion, err := view.MinionSelf() if err != nil { return err } updatePolicy(view, minion.Role, minion.Spec) return nil }) loopLog.LogEnd() } }