Beispiel #1
0
func main() {
	var bootId string

	f := flag.NewFlagSet(os.Args[0], 1)
	f.StringVar(&bootId, "bootid", "", "Provide a user-generated boot ID. This will override the actual boot ID of the machine.")
	f.Parse(os.Args[1:])

	if bootId == "" {
		bootId = machine.ReadLocalBootId()
	}

	m := machine.New(bootId)
	r := registry.New()
	a := agent.New(r, m, "")

	// Push the initial state to the registry
	a.UpdateJobs()
	a.UpdateMachine()

	// Kick off the heartbeating process
	go a.DoHeartbeat()

	s := scheduler.New(r, m)
	s.DoSchedule()
}
Beispiel #2
0
func TestNewJob(t *testing.T) {
	mach := machine.New("XXX")
	js1 := NewJobState("loaded", "inactive", "running", []string{}, mach)
	jp1 := &JobPayload{"echo.service", "Echo"}

	j1, _ := NewJob("pong.service", js1, jp1)
	j2 := Job{"pong.service", "systemd-service", js1, jp1}

	if *j1 != j2 {
		t.Error("job.NewJob factory failed to produce appropriate job.Job")
	}

	if j1.Name != "pong.service" {
		t.Fatal("job.Job.Name != 'pong.service'")
	}

	if j1.Type != "systemd-service" {
		t.Fatal("job.Job.Name != 'systemd-service'")
	}

	if j1.State != js1 {
		t.Fatal("job.Job.State does not match expected value")
	}

	if j1.Payload != jp1 {
		t.Fatal("job.Job.Payload does not match expected value")
	}

}
Beispiel #3
0
func filterEventJobCreated(resp *etcd.Response) *Event {
	if resp.Action != "set" || resp.Node.PrevValue != "" {
		return nil
	}

	dir, jobName := path.Split(resp.Node.Key)
	dir = strings.TrimSuffix(dir, "/")
	dir, prefix := path.Split(dir)
	if prefix != strings.Trim(schedulePrefix, "/") {
		return nil
	}

	var jp job.JobPayload
	err := unmarshal(resp.Node.Value, &jp)
	if err != nil {
		log.V(1).Infof("Failed to deserialize JobPayload: %s", err)
		return nil
	}

	j, _ := job.NewJob(jobName, nil, &jp)

	dir = strings.TrimSuffix(dir, "/")
	dir, machName := path.Split(dir)
	m := machine.New(machName)

	return &Event{"EventJobCreated", *j, m}
}
Beispiel #4
0
func (self *Server) Configure(cfg *config.Config) {
	if cfg.BootId != self.machine.BootId {
		self.machine = machine.New(cfg.BootId)
		self.agent.Stop()
		self.agent = agent.New(self.registry, self.events, self.machine, "")
		go self.agent.Run()
	}
}
Beispiel #5
0
func (self *Server) Configure(cfg *config.Config) {
	if cfg.BootId != self.machine.BootId {
		self.machine = machine.New(cfg.BootId, cfg.PublicIP, cfg.Metadata())
		self.agent.Stop()
		self.agent = agent.New(self.registry, self.events, self.machine, "", cfg.UnitPrefix)
		go self.agent.Run()
	}
}
Beispiel #6
0
func (r *Registry) GetJobTarget(jobName string) *machine.Machine {
	// Figure out to which Machine this Job is scheduled
	key := path.Join(keyPrefix, jobPrefix, jobName, "target")
	resp, err := r.etcd.Get(key, false, true)
	if err != nil {
		return nil
	}

	return machine.New(resp.Node.Value, "", make(map[string]string, 0))
}
Beispiel #7
0
func New(cfg config.Config) *Server {
	m := machine.New(cfg.BootId)
	r := registry.New()
	es := registry.NewEventStream()

	a := agent.New(r, es, m, "")
	e := engine.New(r, es, m)

	srv := Server{a, e, m, r, es}
	srv.Configure(&cfg)

	return &srv
}
Beispiel #8
0
func filterEventMachineDeleted(resp *etcd.Response) *Event {
	if base := path.Base(resp.Node.Key); base != "addrs" {
		return nil
	}

	if resp.Action != "expire" && resp.Action != "delete" {
		return nil
	}

	name := path.Base(path.Dir(resp.Node.Key))
	m := machine.New(name)
	return &Event{"EventMachineDeleted", *m, nil}
}
Beispiel #9
0
func filterEventMachineUpdated(resp *etcd.Response) *Event {
	if base := path.Base(resp.Node.Key); base != "addrs" {
		return nil
	}

	if resp.Action != "set" || resp.Node.PrevValue == "" {
		return nil
	}

	name := path.Base(path.Dir(resp.Node.Key))
	m := machine.New(name)
	return &Event{"EventMachineUpdated", *m, nil}
}
Beispiel #10
0
func filterEventJobScheduled(resp *etcd.Response) *Event {
	if resp.Action != "set" {
		return nil
	}

	dir, baseName := path.Split(resp.Node.Key)
	if baseName != "target" {
		return nil
	}

	mach := machine.New(resp.Node.Value, "", make(map[string]string, 0))
	jobName := path.Base(strings.TrimSuffix(dir, "/"))

	return &Event{"EventJobScheduled", jobName, mach}
}
Beispiel #11
0
func New(cfg config.Config) *Server {
	m := machine.New(cfg.BootId, cfg.PublicIP, cfg.Metadata())

	regClient := etcd.NewClient(cfg.EtcdServers)
	regClient.SetConsistency(etcd.WEAK_CONSISTENCY)
	r := registry.New(regClient)

	eventClient := etcd.NewClient(cfg.EtcdServers)
	eventClient.SetConsistency(etcd.WEAK_CONSISTENCY)
	es := registry.NewEventStream(eventClient, r)
	es.Open()

	a := agent.New(r, es, m, "", cfg.UnitPrefix)
	e := engine.New(r, es, m)

	return &Server{a, e, m, r, es}
}
Beispiel #12
0
func TestNewJob(t *testing.T) {
	mach := machine.New("XXX", "", make(map[string]string, 0))
	js1 := NewJobState("loaded", "inactive", "running", []string{}, mach)
	jp1, _ := NewJobPayload("echo.service", "Echo", map[string][]string{})

	j1 := NewJob("pong.service", js1, jp1)

	if j1.Name != "pong.service" {
		t.Fatal("job.Job.Name != 'pong.service'")
	}

	if j1.State != js1 {
		t.Fatal("job.Job.State does not match expected value")
	}

	if j1.Payload.Name != jp1.Name {
		t.Fatal("job.Job.Payload does not match expected value")
	}
}
Beispiel #13
0
// Describe all active Machines
func (r *Registry) GetActiveMachines() []machine.Machine {
	key := path.Join(keyPrefix, machinePrefix)
	resp, err := r.etcd.Get(key, false, true)

	// Assume the error was KeyNotFound and return an empty data structure
	if err != nil {
		return make([]machine.Machine, 0)
	}

	machines := make([]machine.Machine, 0)
	for _, kv := range resp.Node.Nodes {
		_, bootId := path.Split(kv.Key)
		machine := machine.New(bootId)

		// This is a hacky way of telling if a Machine is reporting state
		addrs := r.getMachineAddrs(machine)
		if len(addrs) > 0 {
			machines = append(machines, *machine)
		}
	}

	return machines
}
Beispiel #14
0
// Describe the list of all known Machines
func (r *Registry) GetActiveMachines() map[string]machine.Machine {
	key := path.Join(keyPrefix, machinePrefix)
	resp, err := r.Etcd.Get(key, false)

	// Assume the error was KeyNotFound and return an empty data structure
	if err != nil {
		return make(map[string]machine.Machine, 0)
	}

	machines := make(map[string]machine.Machine, len(resp.Kvs))
	for _, kv := range resp.Kvs {
		_, bootId := path.Split(kv.Key)
		machine := machine.New(bootId)

		// This is a hacky way of telling if a Machine is reporting state
		addrs := r.GetMachineAddrs(machine)
		if len(addrs) > 0 {
			machines[machine.BootId] = *machine
		}
	}

	return machines
}
Beispiel #15
0
func TestJobState(t *testing.T) {
	mach := machine.New("XXX", "", make(map[string]string, 0))
	js1 := NewJobState("loaded", "inactive", "dead", []string{}, mach)

	if js1.LoadState != "loaded" {
		t.Fatal("job.JobState.LoadState != 'loaded'")
	}

	if js1.ActiveState != "inactive" {
		t.Fatal("job.JobState.ActiveState != 'inactive'")
	}

	if js1.SubState != "dead" {
		t.Fatal("job.JobState.SubState != 'dead'")
	}

	if len(js1.Sockets) != 0 {
		t.Fatal("job.JobState.Sockets does not match expected length")
	}

	if js1.Machine != mach {
		t.Fatal("job.JobState.Machine does not match expected value")
	}
}