Ejemplo n.º 1
0
func New(cfg config.Config) (*Server, error) {
	mach, err := newMachineFromConfig(cfg)
	if err != nil {
		return nil, err
	}

	mgr, err := systemd.NewSystemdUnitManager(systemd.DefaultUnitsDirectory)
	if err != nil {
		return nil, err
	}

	eClient, err := etcd.NewClient(cfg.EtcdServers, http.Transport{})
	if err != nil {
		return nil, err
	}

	reg := registry.New(eClient, cfg.EtcdKeyPrefix)

	a, err := newAgentFromConfig(mach, reg, cfg, mgr)
	if err != nil {
		return nil, err
	}

	e := engine.New(reg, mach)

	sStream := systemd.NewEventStream(mgr)

	rStream, err := registry.NewEventStream(eClient, reg)
	if err != nil {
		return nil, err
	}

	aHandler := agent.NewEventHandler(a)
	eHandler := engine.NewEventHandler(e)

	eBus := event.NewEventBus()
	eBus.AddListener("engine", eHandler)
	eBus.AddListener("agent", aHandler)

	listeners, err := activation.Listeners(false)
	if err != nil {
		return nil, err
	}

	mux := api.NewServeMux(reg)
	for _, f := range listeners {
		go http.Serve(f, mux)
	}

	return &Server{a, e, rStream, sStream, eBus, mach, nil}, nil
}
Ejemplo n.º 2
0
func New(cfg config.Config) (*Server, error) {
	mach, err := newMachineFromConfig(cfg)
	if err != nil {
		return nil, err
	}

	mgr, err := systemd.NewSystemdUnitManager(systemd.DefaultUnitsDirectory)
	if err != nil {
		return nil, err
	}

	eClient := etcd.NewClient(cfg.EtcdServers)

	reg := registry.New(eClient, cfg.EtcdKeyPrefix)

	a, err := newAgentFromConfig(mach, reg, cfg, mgr)
	if err != nil {
		return nil, err
	}

	e := engine.New(reg, mach)

	sStream := systemd.NewEventStream(mgr)

	rStream, err := registry.NewEventStream(eClient, reg)
	if err != nil {
		return nil, err
	}

	aHandler := agent.NewEventHandler(a)
	eHandler := engine.NewEventHandler(e)

	eBus := event.NewEventBus()
	eBus.AddListener("engine", eHandler)
	eBus.AddListener("agent", aHandler)

	return &Server{a, e, rStream, sStream, eBus, mach, nil}, nil
}
Ejemplo n.º 3
0
func New(cfg config.Config) (*Server, error) {
	mach, err := newMachineFromConfig(cfg)
	if err != nil {
		return nil, err
	}

	mgr, err := systemd.NewSystemdUnitManager(systemd.DefaultUnitsDirectory)
	if err != nil {
		return nil, err
	}

	a, err := newAgentFromConfig(mach, cfg, mgr)
	if err != nil {
		return nil, err
	}

	e, err := newEngineFromConfig(mach, cfg)
	if err != nil {
		return nil, err
	}

	sStream := systemd.NewEventStream(mgr)

	rStream, err := newRegistryEventStreamFromConfig(cfg)
	if err != nil {
		return nil, err
	}

	aHandler := agent.NewEventHandler(a)
	eHandler := engine.NewEventHandler(e)

	eBus := event.NewEventBus()
	eBus.AddListener("engine", eHandler)
	eBus.AddListener("agent", aHandler)

	return &Server{a, e, rStream, sStream, eBus, mach, nil}, nil
}
Ejemplo n.º 4
0
func New(cfg config.Config) (*Server, error) {
	agentTTL, err := time.ParseDuration(cfg.AgentTTL)
	if err != nil {
		return nil, err
	}

	mgr, err := systemd.NewSystemdUnitManager(systemd.DefaultUnitsDirectory)
	if err != nil {
		return nil, err
	}

	mach, err := newMachineFromConfig(cfg, mgr)
	if err != nil {
		return nil, err
	}

	tlsConfig, err := pkg.ReadTLSConfigFiles(cfg.EtcdCAFile, cfg.EtcdCertFile, cfg.EtcdKeyFile)
	if err != nil {
		return nil, err
	}

	eCfg := etcd.Config{
		Transport: &http.Transport{TLSClientConfig: tlsConfig},
		Endpoints: cfg.EtcdServers,
	}
	eClient, err := etcd.New(eCfg)
	if err != nil {
		return nil, err
	}

	etcdRequestTimeout := time.Duration(cfg.EtcdRequestTimeout*1000) * time.Millisecond
	kAPI := etcd.NewKeysAPI(eClient)
	reg := registry.NewEtcdRegistry(kAPI, cfg.EtcdKeyPrefix, etcdRequestTimeout)

	pub := agent.NewUnitStatePublisher(reg, mach, agentTTL)
	gen := unit.NewUnitStateGenerator(mgr)

	a := agent.New(mgr, gen, reg, mach, agentTTL)

	var rStream pkg.EventStream
	if !cfg.DisableWatches {
		rStream = registry.NewEtcdEventStream(kAPI, cfg.EtcdKeyPrefix)
	}
	lManager := lease.NewEtcdLeaseManager(kAPI, cfg.EtcdKeyPrefix, etcdRequestTimeout)

	ar := agent.NewReconciler(reg, rStream)

	e := engine.New(reg, lManager, rStream, mach)

	listeners, err := activation.Listeners(false)
	if err != nil {
		return nil, err
	}

	hrt := heart.New(reg, mach)
	mon := heart.NewMonitor(agentTTL)

	apiServer := api.NewServer(listeners, api.NewServeMux(reg, cfg.TokenLimit))
	apiServer.Serve()

	eIval := time.Duration(cfg.EngineReconcileInterval*1000) * time.Millisecond

	srv := Server{
		agent:       a,
		aReconciler: ar,
		usGen:       gen,
		usPub:       pub,
		engine:      e,
		mach:        mach,
		hrt:         hrt,
		mon:         mon,
		api:         apiServer,
		stop:        nil,
		engineReconcileInterval: eIval,
		disableEngine:           cfg.DisableEngine,
	}

	return &srv, nil
}
Ejemplo n.º 5
0
func New(cfg config.Config) (*Server, error) {
	mgr, err := systemd.NewSystemdUnitManager(systemd.DefaultUnitsDirectory)
	if err != nil {
		return nil, err
	}

	mach, err := newMachineFromConfig(cfg, mgr)
	if err != nil {
		return nil, err
	}

	tlsConfig, err := etcd.ReadTLSConfigFiles(cfg.EtcdCAFile, cfg.EtcdCertFile, cfg.EtcdKeyFile)
	if err != nil {
		return nil, err
	}

	eTrans := http.Transport{TLSClientConfig: tlsConfig}
	timeout := time.Duration(cfg.EtcdRequestTimeout*1000) * time.Millisecond
	eClient, err := etcd.NewClient(cfg.EtcdServers, eTrans, timeout)
	if err != nil {
		return nil, err
	}

	reg := registry.New(eClient, cfg.EtcdKeyPrefix)

	pub := agent.NewUnitStatePublisher(mgr, reg, mach)
	gen := unit.NewUnitStateGenerator(mgr)

	a, err := newAgentFromConfig(mach, reg, cfg, mgr, gen)
	if err != nil {
		return nil, err
	}

	ar, err := newAgentReconcilerFromConfig(reg, eClient, cfg)
	if err != nil {
		return nil, err
	}

	e, err := newEngineFromConfig(reg, eClient, mach, cfg)
	if err != nil {
		return nil, err
	}

	listeners, err := activation.Listeners(false)
	if err != nil {
		return nil, err
	}

	hrt, mon, err := newHeartMonitorFromConfig(mach, reg, cfg)
	if err != nil {
		return nil, err
	}

	apiServer := api.NewServer(listeners, api.NewServeMux(reg))
	apiServer.Serve()

	eIval := time.Duration(cfg.EngineReconcileInterval*1000) * time.Millisecond

	srv := Server{
		agent:       a,
		aReconciler: ar,
		usGen:       gen,
		usPub:       pub,
		engine:      e,
		mach:        mach,
		hrt:         hrt,
		mon:         mon,
		api:         apiServer,
		stop:        nil,
		engineReconcileInterval: eIval,
	}

	return &srv, nil
}
Ejemplo n.º 6
0
func TestSystemdUnitFlow(t *testing.T) {
	uDir, err := ioutil.TempDir("", "fleet-")
	if err != nil {
		t.Fatalf("Failed creating tempdir: %v", err)
	}
	defer os.RemoveAll(uDir)

	mgr, err := systemd.NewSystemdUnitManager(uDir, false)
	if err != nil {
		t.Fatalf("Failed initializing SystemdUnitManager: %v", err)
	}

	units, err := mgr.Units()
	if err != nil {
		t.Fatalf("Failed calling Units(): %v", err)
	}

	if len(units) > 0 {
		t.Fatalf("Expected no units to be returned, got %v", units)
	}

	contents := `[Service]
ExecStart=/usr/bin/sleep 3000
`
	name := fmt.Sprintf("fleet-unit-%d.service", rand.Int63())
	uf, err := unit.NewUnitFile(contents)
	if err != nil {
		t.Fatalf("Invalid unit file: %v", err)
	}
	hash := uf.Hash().String()
	j := job.NewJob(name, *uf)

	if err := mgr.Load(j.Name, j.Unit); err != nil {
		t.Fatalf("Failed loading job: %v", err)
	}

	units, err = mgr.Units()
	if err != nil {
		t.Fatalf("Failed calling Units(): %v", err)
	}

	if !reflect.DeepEqual([]string{name}, units) {
		t.Fatalf("Expected [hello.service], got %v", units)
	}

	err = waitForUnitState(mgr, name, unit.UnitState{"loaded", "inactive", "dead", "", hash, ""})
	if err != nil {
		t.Error(err.Error())
	}

	mgr.TriggerStart(name)

	err = waitForUnitState(mgr, name, unit.UnitState{"loaded", "active", "running", "", hash, ""})
	if err != nil {
		t.Error(err.Error())
	}

	mgr.TriggerStop(name)

	mgr.Unload(name)

	units, err = mgr.Units()
	if err != nil {
		t.Fatalf("Failed calling Units(): %v", err)
	}

	if len(units) > 0 {
		t.Fatalf("Expected no units to be returned, got %v", units)
	}
}
Ejemplo n.º 7
0
func New(cfg config.Config, listeners []net.Listener) (*Server, error) {
	agentTTL, err := time.ParseDuration(cfg.AgentTTL)
	if err != nil {
		return nil, err
	}

	mgr, err := systemd.NewSystemdUnitManager(cfg.UnitsDirectory, cfg.SystemdUser)
	if err != nil {
		return nil, err
	}

	mach, err := newMachineFromConfig(cfg, mgr)
	if err != nil {
		return nil, err
	}

	tlsConfig, err := pkg.ReadTLSConfigFiles(cfg.EtcdCAFile, cfg.EtcdCertFile, cfg.EtcdKeyFile)
	if err != nil {
		return nil, err
	}

	eCfg := etcd.Config{
		Transport:               &http.Transport{TLSClientConfig: tlsConfig},
		Endpoints:               cfg.EtcdServers,
		HeaderTimeoutPerRequest: (time.Duration(cfg.EtcdRequestTimeout*1000) * time.Millisecond),
		Username:                cfg.EtcdUsername,
		Password:                cfg.EtcdPassword,
	}

	eClient, err := etcd.New(eCfg)
	if err != nil {
		return nil, err
	}

	kAPI := etcd.NewKeysAPI(eClient)

	var (
		reg        engine.CompleteRegistry
		genericReg interface{}
	)
	lManager := lease.NewEtcdLeaseManager(kAPI, cfg.EtcdKeyPrefix)

	if !cfg.EnableGRPC {
		genericReg = registry.NewEtcdRegistry(kAPI, cfg.EtcdKeyPrefix)
		if obj, ok := genericReg.(engine.CompleteRegistry); ok {
			reg = obj
		}
	} else {
		etcdReg := registry.NewEtcdRegistry(kAPI, cfg.EtcdKeyPrefix)
		genericReg = rpc.NewRegistryMux(etcdReg, mach, lManager)
		if obj, ok := genericReg.(engine.CompleteRegistry); ok {
			reg = obj
		}
	}

	pub := agent.NewUnitStatePublisher(reg, mach, agentTTL)
	gen := unit.NewUnitStateGenerator(mgr)

	a := agent.New(mgr, gen, reg, mach, agentTTL)

	var rStream pkg.EventStream
	if !cfg.DisableWatches {
		rStream = registry.NewEtcdEventStream(kAPI, cfg.EtcdKeyPrefix)
	}

	ar := agent.NewReconciler(reg, rStream)

	var e *engine.Engine
	if !cfg.EnableGRPC {
		e = engine.New(reg, lManager, rStream, mach, nil)
	} else {
		regMux := genericReg.(*rpc.RegistryMux)
		e = engine.New(reg, lManager, rStream, mach, regMux.EngineChanged)
		if cfg.DisableEngine {
			go regMux.ConnectToRegistry(e)
		}
	}

	if len(listeners) == 0 {
		listeners, err = activation.Listeners(false)
		if err != nil {
			return nil, err
		}
	}

	hrt := heart.New(reg, mach)
	mon := NewMonitor(agentTTL)

	apiServer := api.NewServer(listeners, api.NewServeMux(reg, cfg.TokenLimit))
	apiServer.Serve()

	eIval := time.Duration(cfg.EngineReconcileInterval*1000) * time.Millisecond

	srv := Server{
		agent:       a,
		aReconciler: ar,
		usGen:       gen,
		usPub:       pub,
		engine:      e,
		mach:        mach,
		hrt:         hrt,
		mon:         mon,
		api:         apiServer,
		killc:       make(chan struct{}),
		stopc:       nil,
		engineReconcileInterval: eIval,
		disableEngine:           cfg.DisableEngine,
		reconfigServer:          false,
		restartServer:           false,
	}

	return &srv, nil
}
Ejemplo n.º 8
0
func New(cfg config.Config) (*Server, error) {
	agentTTL, err := time.ParseDuration(cfg.AgentTTL)
	if err != nil {
		return nil, err
	}

	mgr, err := systemd.NewSystemdUnitManager(systemd.DefaultUnitsDirectory)
	if err != nil {
		return nil, err
	}

	mach, err := newMachineFromConfig(cfg, mgr)
	if err != nil {
		return nil, err
	}

	tlsConfig, err := pkg.ReadTLSConfigFiles(cfg.EtcdCAFile, cfg.EtcdCertFile, cfg.EtcdKeyFile)
	if err != nil {
		return nil, err
	}
	etcdRequestTimeout := time.Duration(cfg.EtcdRequestTimeout*1000) * time.Millisecond
	// set a per server request timeout that is the global request timeout divided by the number of quorum nodes (i.e. 3 out of 5)
	// this ensures that the the retry logic in etcd can try at least 3 servers before the global timeout fires and cancels the entire request
	quorumCount := (len(cfg.EtcdServers) / 2) + 1
	etcdRequestPerServerTimeout := etcdRequestTimeout
	if quorumCount > 1 {
		etcdRequestPerServerTimeout = time.Duration(int64(etcdRequestTimeout) / int64(quorumCount))
	}
	log.Infof("Etcd endpoints: %v", strings.Join(cfg.EtcdServers, ","))
	log.Infof("Setting global request timeout of %v and per server request timeout of %v using a quorum count of %v", etcdRequestTimeout, etcdRequestPerServerTimeout, quorumCount)

	eCfg := etcd.Config{
		Transport:               &http.Transport{TLSClientConfig: tlsConfig},
		Endpoints:               cfg.EtcdServers,
		HeaderTimeoutPerRequest: etcdRequestPerServerTimeout,
	}
	eClient, err := etcd.New(eCfg)
	if err != nil {
		return nil, err
	}

	kAPI := etcd.NewKeysAPI(eClient)
	reg := registry.NewEtcdRegistry(kAPI, cfg.EtcdKeyPrefix, etcdRequestTimeout)

	pub := agent.NewUnitStatePublisher(reg, mach, agentTTL)
	gen := unit.NewUnitStateGenerator(mgr)

	a := agent.New(mgr, gen, reg, mach, agentTTL)

	rStream := registry.NewEtcdEventStream(kAPI, cfg.EtcdKeyPrefix)
	lManager := lease.NewEtcdLeaseManager(kAPI, cfg.EtcdKeyPrefix, etcdRequestTimeout)

	ar := agent.NewReconciler(reg, rStream)

	e := engine.New(reg, lManager, rStream, mach)

	listeners, err := activation.Listeners(false)
	if err != nil {
		return nil, err
	}

	hrt := heart.New(reg, mach)
	mon := heart.NewMonitor(agentTTL)

	apiServer := api.NewServer(listeners, api.NewServeMux(reg))
	apiServer.Serve()

	eIval := time.Duration(cfg.EngineReconcileInterval*1000) * time.Millisecond

	srv := Server{
		agent:       a,
		aReconciler: ar,
		usGen:       gen,
		usPub:       pub,
		engine:      e,
		mach:        mach,
		hrt:         hrt,
		mon:         mon,
		api:         apiServer,
		stop:        nil,
		engineReconcileInterval: eIval,
	}

	return &srv, nil
}
Ejemplo n.º 9
0
func TestSystemdUnitFlow(t *testing.T) {
	uDir, err := ioutil.TempDir("", "fleet-")
	if err != nil {
		t.Fatalf("Failed creating tempdir: %v", err)
	}
	defer os.RemoveAll(uDir)

	mgr, err := systemd.NewSystemdUnitManager(uDir)
	if err != nil {
		t.Fatalf("Failed initializing SystemdUnitManager: %v", err)
	}

	units, err := mgr.Units()
	if err != nil {
		t.Fatalf("Failed calling Units(): %v", err)
	}

	if len(units) > 0 {
		t.Fatalf("Expected no units to be returned, got %v", units)
	}

	name := fmt.Sprintf("fleet-unit-%d.service", rand.Int63())
	uf := unit.NewUnit(`[Service]
ExecStart=/usr/bin/sleep 3000
`)
	j := job.NewJob(name, *uf)

	if err := mgr.Load(j.Name, j.Unit); err != nil {
		t.Fatalf("Failed loading job: %v", err)
	}

	units, err = mgr.Units()
	if err != nil {
		t.Fatalf("Failed calling Units(): %v", err)
	}

	if !reflect.DeepEqual([]string{name}, units) {
		t.Fatalf("Expected [hello.service], got %v", units)
	}

	us, err := mgr.GetUnitState(name)
	if err == nil {
		expect := unit.UnitState{"loaded", "inactive", "dead", nil}
		if !reflect.DeepEqual(expect, *us) {
			t.Errorf("Expected UnitState %v, got %v", expect, *us)
		}
	} else {
		t.Errorf("Failed determining unit state: %v", err)
	}

	mgr.Start(name)

	us, err = mgr.GetUnitState(name)
	if err == nil {
		expect := unit.UnitState{"loaded", "active", "running", nil}
		if !reflect.DeepEqual(expect, *us) {
			t.Errorf("Expected UnitState %v, got %v", expect, *us)
		}
	} else {
		t.Errorf("Failed determining unit state: %v", err)
	}

	mgr.Stop(name)

	us, err = mgr.GetUnitState(name)
	if err == nil {
		expect := unit.UnitState{"loaded", "inactive", "dead", nil}
		if !reflect.DeepEqual(expect, *us) {
			t.Errorf("Expected UnitState %v, got %v", expect, *us)
		}
	} else {
		t.Errorf("Failed determining unit state: %v", err)
	}

	mgr.Unload(name)

	units, err = mgr.Units()
	if err != nil {
		t.Fatalf("Failed calling Units(): %v", err)
	}

	if len(units) > 0 {
		t.Fatalf("Expected no units to be returned, got %v", units)
	}
}
Ejemplo n.º 10
0
func New(cfg config.Config) (*Server, error) {
	etcdRequestTimeout := time.Duration(cfg.EtcdRequestTimeout*1000) * time.Millisecond
	agentTTL, err := time.ParseDuration(cfg.AgentTTL)
	if err != nil {
		return nil, err
	}

	mgr, err := systemd.NewSystemdUnitManager(systemd.DefaultUnitsDirectory)
	if err != nil {
		return nil, err
	}

	mach, err := newMachineFromConfig(cfg, mgr)
	if err != nil {
		return nil, err
	}

	tlsConfig, err := pkg.ReadTLSConfigFiles(cfg.EtcdCAFile, cfg.EtcdCertFile, cfg.EtcdKeyFile)
	if err != nil {
		return nil, err
	}

	eTrans := &http.Transport{TLSClientConfig: tlsConfig}
	eClient, err := etcd.NewClient(cfg.EtcdServers, eTrans, etcdRequestTimeout)
	if err != nil {
		return nil, err
	}

	reg := registry.NewEtcdRegistry(eClient, cfg.EtcdKeyPrefix)

	pub := agent.NewUnitStatePublisher(reg, mach, agentTTL)
	gen := unit.NewUnitStateGenerator(mgr)

	a := agent.New(mgr, gen, reg, mach, agentTTL)

	rStream := registry.NewEtcdEventStream(eClient, cfg.EtcdKeyPrefix)

	ar := agent.NewReconciler(reg, rStream)

	e := engine.New(reg, rStream, mach)

	listeners, err := activation.Listeners(false)
	if err != nil {
		return nil, err
	}

	hrt := heart.New(reg, mach)
	mon := heart.NewMonitor(agentTTL)

	apiServer := api.NewServer(listeners, api.NewServeMux(reg))
	apiServer.Serve()

	eIval := time.Duration(cfg.EngineReconcileInterval*1000) * time.Millisecond

	srv := Server{
		agent:       a,
		aReconciler: ar,
		usGen:       gen,
		usPub:       pub,
		engine:      e,
		mach:        mach,
		hrt:         hrt,
		mon:         mon,
		api:         apiServer,
		stop:        nil,
		engineReconcileInterval: eIval,
	}

	return &srv, nil
}
Ejemplo n.º 11
0
func New(cfg config.Config) (*Server, error) {
	mgr, err := systemd.NewSystemdUnitManager(systemd.DefaultUnitsDirectory)
	if err != nil {
		return nil, err
	}

	mach, err := newMachineFromConfig(cfg, mgr)
	if err != nil {
		return nil, err
	}

	tlsConfig, err := etcd.TLSClientConfig(cfg.EtcdCAFile, cfg.EtcdCertFile, cfg.EtcdKeyFile)
	if err != nil {
		return nil, err
	}

	eClient, err := etcd.NewClient(cfg.EtcdServers, http.Transport{TLSClientConfig: tlsConfig})
	if err != nil {
		return nil, err
	}

	reg := registry.New(eClient, cfg.EtcdKeyPrefix)

	pub := agent.NewUnitStatePublisher(mgr, reg, mach)
	gen := unit.NewUnitStateGenerator(mgr)

	a, err := newAgentFromConfig(mach, reg, cfg, mgr, gen)
	if err != nil {
		return nil, err
	}

	ar, err := newAgentReconcilerFromConfig(reg, cfg)
	if err != nil {
		return nil, err
	}

	e := engine.New(reg, mach)

	rStream, err := registry.NewEventStream(eClient, reg)
	if err != nil {
		return nil, err
	}

	eBus := event.NewEventBus()
	eBus.AddListener(event.JobEvent, ar.Trigger)
	eBus.AddListener(event.GlobalEvent, e.Trigger)

	listeners, err := activation.Listeners(false)
	if err != nil {
		return nil, err
	}

	hrt, mon, err := newHeartMonitorFromConfig(mach, reg, cfg)
	if err != nil {
		return nil, err
	}

	apiServer := api.NewServer(listeners, api.NewServeMux(reg))
	apiServer.Serve()

	srv := Server{
		agent:       a,
		aReconciler: ar,
		usGen:       gen,
		usPub:       pub,
		engine:      e,
		rStream:     rStream,
		eBus:        eBus,
		mach:        mach,
		hrt:         hrt,
		mon:         mon,
		api:         apiServer,
		stop:        nil,
	}

	return &srv, nil
}