Esempio n. 1
0
func assertUnitState(name string, js job.JobState, out io.Writer) (ret bool) {
	u, err := cAPI.Unit(name)
	if err != nil {
		log.Warningf("Error retrieving Unit(%s) from Registry: %v", name, err)
		return
	}
	if u == nil {
		log.Warningf("Unit %s not found", name)
		return
	}
	if job.JobState(u.CurrentState) != js {
		log.Debugf("Waiting for Unit(%s) state(%s) to be %s", name, job.JobState(u.CurrentState), js)
		return
	}

	ret = true
	msg := fmt.Sprintf("Unit %s %s", name, u.CurrentState)

	if u.MachineID != "" {
		ms := cachedMachineState(u.MachineID)
		if ms != nil {
			msg = fmt.Sprintf("%s on %s", msg, machineFullLegend(*ms, false))
		}
	}

	fmt.Fprintln(out, msg)
	return
}
Esempio n. 2
0
func runRestartUnit(cCmd *cobra.Command, args []string) (exit int) {
	if len(args) == 0 {
		stderr("No units given")
		return 0
	}
	units, err := findUnits(args)
	if err != nil {
		stderr("%v", err)
		return 1
	}

	if err := lazyCreateUnits(cCmd, args); err != nil {
		stderr("Error creating units: %v", err)
		return 1
	}

	globalUnits := make([]schema.Unit, 0)
	for _, unit := range units {
		if suToGlobal(unit) {
			globalUnits = append(globalUnits, unit)
			continue
		}
		if job.JobState(unit.CurrentState) == job.JobStateInactive {
			stderr("Unable to restart unit %s in state %s", unit.Name, job.JobStateInactive)
			continue
		} else if job.JobState(unit.CurrentState) == job.JobStateLoaded {
			log.Infof("Unit(%s) already %s, starting.", unit.Name, job.JobStateLoaded)

			exit = setUnitStateAndWait(unit, job.JobStateLaunched, getBlockAttempts(cCmd))
			if exit == 1 {
				return exit
			}
			continue
		} else {
			//stop and start it
			exit = setUnitStateAndWait(unit, job.JobStateLoaded, getBlockAttempts(cCmd))
			if exit == 1 {
				return exit
			}
			exit = setUnitStateAndWait(unit, job.JobStateLaunched, getBlockAttempts(cCmd))
			if exit == 1 {
				return exit
			}
		}
		log.Infof("Unit(%s) was restarted.", unit.Name)
	}

	if err := cmdGlobalMachineState(cCmd, globalUnits); err != nil {
		stderr("Error restarting global units %v err:%v", globalUnits, err)
		return 1
	}

	return
}
Esempio n. 3
0
func runJournal(args []string) (exit int) {
	if len(args) != 1 {
		stderr("One unit file must be provided.")
		return 1
	}
	name := unitNameMangle(args[0])

	u, err := cAPI.Unit(name)
	if err != nil {
		stderr("Error retrieving unit %s: %v", name, err)
		return 1
	} else if u == nil {
		stderr("Unit %s does not exist.", name)
		return 1
	} else if suToGlobal(*u) {
		stderr("Unable to retrieve journal of global unit %s.", name)
		return 1
	} else if job.JobState(u.CurrentState) == job.JobStateInactive {
		stderr("Unit %s does not appear to be running.", name)
		return 1
	}

	cmd := []string{"journalctl", "--unit", name, "--no-pager", "-n", strconv.Itoa(flagLines)}

	if flagSudo {
		cmd = append([]string{"sudo"}, cmd...)
	}

	if flagFollow {
		cmd = append(cmd, "-f")
	}

	return runCommand(u.MachineID, cmd[0], cmd[1:]...)
}
Esempio n. 4
0
func runJournal(args []string) (exit int) {
	if len(args) != 1 {
		fmt.Fprintln(os.Stderr, "One unit file must be provided.")
		return 1
	}
	name := unitNameMangle(args[0])

	u, err := cAPI.Unit(name)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error retrieving unit %s: %v", name, err)
		return 1
	}
	if u == nil {
		fmt.Fprintf(os.Stderr, "Unit %s does not exist.\n", name)
		return 1
	} else if job.JobState(u.CurrentState) == job.JobStateInactive {
		fmt.Fprintf(os.Stderr, "Unit %s does not appear to be running.\n", name)
		return 1
	}

	command := fmt.Sprintf("journalctl --unit %s --no-pager -n %d", name, flagLines)
	if flagFollow {
		command += " -f"
	}

	return runCommand(command, u.MachineID)
}
Esempio n. 5
0
File: fleetctl.go Progetto: pulcy/j2
// checkReplaceUnitState checks if the unit should be replaced.
// It takes a Unit object as a parameter.
// It returns 0 on success and if the unit should be replaced, 1 if the
// unit should not be replaced; and any error encountered.
func checkReplaceUnitState(unit *schema.Unit) (int, error) {
	// We replace units only for 'submit', 'load' and
	// 'start' commands.
	allowedReplace := map[string][]job.JobState{
		"submit": []job.JobState{
			job.JobStateInactive,
		},
		"load": []job.JobState{
			job.JobStateInactive,
			job.JobStateLoaded,
		},
		"start": []job.JobState{
			job.JobStateInactive,
			job.JobStateLoaded,
			job.JobStateLaunched,
		},
	}

	if allowedJobs, ok := allowedReplace[currentCommand]; ok {
		for _, j := range allowedJobs {
			if job.JobState(unit.DesiredState) == j {
				return 0, nil
			}
		}
		// Report back to caller that we are not allowed to
		// cross unit transition states
		stderr("Warning: can not replace Unit(%s) in state '%s', use the appropriate command", unit.Name, unit.DesiredState)
	} else {
		// This function should only be called from 'submit',
		// 'load' and 'start' upper paths.
		return 1, fmt.Errorf("error: replacing units is not supported in this context")
	}

	return 1, nil
}
Esempio n. 6
0
File: status.go Progetto: pulcy/j2
func runStatusUnit(cCmd *cobra.Command, args []string) (exit int) {
	for i, arg := range args {
		name := unitNameMangle(arg)
		unit, err := cAPI.Unit(name)
		if err != nil {
			stderr("Error retrieving unit: %v", err)
			return 1
		}

		if unit == nil {
			stderr("Unit %s does not exist.", name)
			return 1
		} else if suToGlobal(*unit) {
			stderr("Unable to determine status of global unit %s.", unit.Name)
			return 1
		} else if job.JobState(unit.CurrentState) == job.JobStateInactive {
			stderr("Unit %s does not appear to be loaded.", unit.Name)
			return 1
		}

		// This extra newline is here to match systemctl status output
		if i != 0 {
			fmt.Printf("\n")
		}

		if exitVal := runCommand(cCmd, unit.MachineID, "systemctl", "status", "-l", unit.Name); exitVal != 0 {
			exit = exitVal
			break
		}
	}

	return
}
Esempio n. 7
0
func runUnloadUnit(args []string) (exit int) {
	units, err := findUnits(args)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%v\n", err)
		return 1
	}

	wait := make([]string, 0)
	for _, s := range units {
		if job.JobState(s.CurrentState) == job.JobStateInactive {
			log.V(1).Infof("Unit(%s) already %s, skipping.", s.Name, job.JobStateInactive)
			continue
		}

		log.V(1).Infof("Setting target state of Unit(%s) to %s", s.Name, job.JobStateInactive)
		cAPI.SetUnitTargetState(s.Name, string(job.JobStateInactive))
		wait = append(wait, s.Name)
	}

	if !sharedFlags.NoBlock {
		errchan := waitForUnitStates(wait, job.JobStateInactive, sharedFlags.BlockAttempts, os.Stdout)
		for err := range errchan {
			fmt.Fprintf(os.Stderr, "%v\n", err)
			exit = 1
		}
	}

	return
}
Esempio n. 8
0
func runUnloadUnit(args []string) (exit int) {
	if len(args) == 0 {
		stderr("No units given")
		return 0
	}

	units, err := findUnits(args)
	if err != nil {
		stderr("%v", err)
		return 1
	}

	wait := make([]string, 0)
	for _, s := range units {
		if !suToGlobal(s) {
			if job.JobState(s.CurrentState) == job.JobStateInactive {
				log.Debugf("Target state of Unit(%s) already %s, skipping.", s.Name, job.JobStateInactive)
				continue
			}
		}

		log.Debugf("Setting target state of Unit(%s) to %s", s.Name, job.JobStateInactive)
		cAPI.SetUnitTargetState(s.Name, string(job.JobStateInactive))
		if suToGlobal(s) {
			stdout("Triggered global unit %s unload", s.Name)
		} else {
			wait = append(wait, s.Name)
		}
	}

	exit = tryWaitForUnitStates(wait, "unload", job.JobStateInactive, getBlockAttempts(), os.Stdout)

	return
}
Esempio n. 9
0
func runJournal(args []string) (exit int) {
	if len(args) != 1 {
		stderr("One unit file must be provided.")
		return 1
	}
	name := unitNameMangle(args[0])

	u, err := cAPI.Unit(name)
	if err != nil {
		stderr("Error retrieving unit %s: %v", name, err)
		return 1
	} else if u == nil {
		stderr("Unit %s does not exist.", name)
		return 1
	} else if suToGlobal(*u) {
		stderr("Unable to retrieve journal of global unit %s.", name)
		return 1
	} else if job.JobState(u.CurrentState) == job.JobStateInactive {
		stderr("Unit %s does not appear to be running.", name)
		return 1
	}

	command := fmt.Sprintf("journalctl --unit %s --no-pager -n %d", name, flagLines)

	if flagSudo {
		command = "sudo " + command
	}

	if flagFollow {
		command += " -f"
	}

	return runCommand(command, u.MachineID)
}
Esempio n. 10
0
func mapUnitToJob(entity *schema.Unit, mm map[string]*machine.MachineState) (*job.Job, error) {
	contents, err := base64.StdEncoding.DecodeString(entity.FileContents)
	if err != nil {
		return nil, err
	}
	u, err := unit.NewUnit(string(contents))
	if err != nil {
		return nil, err
	}

	js := job.JobState(entity.CurrentState)
	j := job.Job{
		Name:  entity.Name,
		State: &js,
		Unit:  *u,
	}

	// populate a UnitState object only if the entity
	// is actually reporting relevant data
	if entity.Systemd != nil {
		j.UnitState = &unit.UnitState{
			LoadState:   entity.Systemd.LoadState,
			ActiveState: entity.Systemd.ActiveState,
			SubState:    entity.Systemd.SubState,
		}
		if len(entity.Systemd.MachineID) > 0 {
			j.UnitState.MachineID = entity.Systemd.MachineID
		}
	}

	return &j, nil
}
Esempio n. 11
0
func runStopUnit(cCmd *cobra.Command, args []string) (exit int) {
	if len(args) == 0 {
		stderr("No units given")
		return 0
	}

	units, err := findUnits(args)
	if err != nil {
		stderr("%v", err)
		return 1
	}

	if len(units) == 0 {
		stderr("Units not found in registry")
		return 0
	}

	stopping := make([]string, 0)
	for _, u := range units {
		if !suToGlobal(u) {
			if job.JobState(u.CurrentState) == job.JobStateInactive {
				stderr("Unable to stop unit %s in state %s", u.Name, job.JobStateInactive)
				return 1
			} else if job.JobState(u.CurrentState) == job.JobStateLoaded {
				log.Debugf("Unit(%s) already %s, skipping.", u.Name, job.JobStateLoaded)
				continue
			}
		}

		log.Debugf("Setting target state of Unit(%s) to %s", u.Name, job.JobStateLoaded)
		cAPI.SetUnitTargetState(u.Name, string(job.JobStateLoaded))
		if suToGlobal(u) {
			stdout("Triggered global unit %s stop", u.Name)
		} else {
			stopping = append(stopping, u.Name)
		}
	}

	exit = tryWaitForUnitStates(stopping, "stop", job.JobStateLoaded, getBlockAttempts(cCmd), os.Stdout)
	if exit == 0 {
		stderr("Successfully stopped units %v.", stopping)
	} else {
		stderr("Failed to stop units %v. exit == %d.", stopping, exit)
	}

	return
}
Esempio n. 12
0
func (ur *unitsResource) set(rw http.ResponseWriter, req *http.Request, item string) {
	if err := validateContentType(req); err != nil {
		sendError(rw, http.StatusUnsupportedMediaType, err)
		return
	}

	var su schema.Unit
	dec := json.NewDecoder(req.Body)
	err := dec.Decode(&su)
	if err != nil {
		sendError(rw, http.StatusBadRequest, fmt.Errorf("unable to decode body: %v", err))
		return
	}
	if su.Name == "" {
		su.Name = item
	}
	if item != su.Name {
		sendError(rw, http.StatusBadRequest, fmt.Errorf("name in URL %q differs from unit name in request body %q", item, su.Name))
		return
	}
	if err := ValidateName(su.Name); err != nil {
		sendError(rw, http.StatusBadRequest, err)
		return
	}

	eu, err := ur.cAPI.Unit(su.Name)
	if err != nil {
		log.Errorf("Failed fetching Unit(%s) from Registry: %v", su.Name, err)
		sendError(rw, http.StatusInternalServerError, nil)
		return
	}

	if eu == nil {
		if len(su.Options) == 0 {
			err := errors.New("unit does not exist and options field empty")
			sendError(rw, http.StatusConflict, err)
		} else if err := ValidateOptions(su.Options); err != nil {
			sendError(rw, http.StatusBadRequest, err)
		} else {
			ur.create(rw, su.Name, &su)
		}
		return
	}

	if len(su.DesiredState) == 0 {
		err := errors.New("must provide DesiredState to update existing unit")
		sendError(rw, http.StatusConflict, err)
		return
	}

	un := unit.NewUnitNameInfo(su.Name)
	if un.IsTemplate() && job.JobState(su.DesiredState) != job.JobStateInactive {
		err := fmt.Errorf("cannot activate template %q", su.Name)
		sendError(rw, http.StatusBadRequest, err)
		return
	}

	ur.update(rw, su.Name, su.DesiredState)
}
Esempio n. 13
0
func TestAgentLoadUnloadJob(t *testing.T) {
	uManager := unit.NewFakeUnitManager()
	usGenerator := unit.NewUnitStateGenerator(uManager)
	fReg := registry.NewFakeRegistry()
	mach := &machine.FakeMachine{machine.MachineState{ID: "XXX"}}
	a, err := New(uManager, usGenerator, fReg, mach, DefaultTTL)
	if err != nil {
		t.Fatalf("Failed creating Agent: %v", err)
	}

	j := newTestJobFromUnitContents(t, "foo.service", "")
	err = a.loadJob(j)
	if err != nil {
		t.Fatalf("Failed calling Agent.loadJob: %v", err)
	}

	jobs, err := a.jobs()
	if err != nil {
		t.Fatalf("Failed calling Agent.jobs: %v", err)
	}

	jsLoaded := job.JobStateLoaded
	expectJobs := map[string]*job.Job{
		"foo.service": &job.Job{
			Name: "foo.service",
			UnitState: &unit.UnitState{
				LoadState:   "loaded",
				ActiveState: "active",
				SubState:    "running",
				MachineID:   "",
			},
			State: &jsLoaded,

			Unit:            unit.Unit{},
			TargetState:     job.JobState(""),
			TargetMachineID: "",
		},
	}

	if !reflect.DeepEqual(expectJobs, jobs) {
		t.Fatalf("Received unexpected collection of Jobs: %#v\nExpected: %#v", jobs, expectJobs)
	}

	a.unloadJob("foo.service")

	// This sucks, but we have to do it if Agent.unloadJob is going to spin
	// off the real work that matters in a goroutine
	time.Sleep(200)

	jobs, err = a.jobs()
	if err != nil {
		t.Fatalf("Failed calling Agent.jobs: %v", err)
	}

	expectJobs = map[string]*job.Job{}
	if !reflect.DeepEqual(expectJobs, jobs) {
		t.Fatalf("Received unexpected collection of Jobs: %#v\nExpected: %#v", jobs, expectJobs)
	}
}
Esempio n. 14
0
func MapSchemaUnitToScheduledUnit(entity *Unit) *job.ScheduledUnit {
	cs := job.JobState(entity.CurrentState)
	return &job.ScheduledUnit{
		Name:            entity.Name,
		State:           &cs,
		TargetMachineID: entity.MachineID,
	}
}
Esempio n. 15
0
func runStopUnit(args []string) (exit int) {
	units, err := findUnits(args)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%v\n", err)
		return 1
	}

	stopping := make([]string, 0)
	for _, u := range units {
		if !suToGlobal(u) {
			if job.JobState(u.CurrentState) == job.JobStateInactive {
				fmt.Fprintf(os.Stderr, "Unable to stop unit %s in state %s\n", u.Name, job.JobStateInactive)
				return 1
			} else if job.JobState(u.CurrentState) == job.JobStateLoaded {
				log.V(1).Infof("Unit(%s) already %s, skipping.", u.Name, job.JobStateLoaded)
				continue
			}
		}

		log.V(1).Infof("Setting target state of Unit(%s) to %s", u.Name, job.JobStateLoaded)
		cAPI.SetUnitTargetState(u.Name, string(job.JobStateLoaded))
		if suToGlobal(u) {
			fmt.Printf("Triggered global unit %s stop\n", u.Name)
		} else {
			stopping = append(stopping, u.Name)
		}
	}

	if !sharedFlags.NoBlock {
		errchan := waitForUnitStates(stopping, job.JobStateLoaded, sharedFlags.BlockAttempts, os.Stdout)
		for err := range errchan {
			fmt.Fprintf(os.Stderr, "Error waiting for units: %v\n", err)
			exit = 1
		}
	} else {
		for _, name := range stopping {
			fmt.Printf("Triggered unit %s stop\n", name)
		}
	}

	return
}
Esempio n. 16
0
func assertUnitState(name string, js job.JobState, out io.Writer) bool {
	fetchUnitState := func() error {
		var state string

		u, err := cAPI.Unit(name)
		if err != nil {
			return fmt.Errorf("Error retrieving Unit(%s) from Registry: %v", name, err)
		}
		if u == nil {
			return fmt.Errorf("Unit %s not found", name)
		}

		// If this is a global unit, CurrentState will never be set. Instead, wait for DesiredState.
		if suToGlobal(*u) {
			state = u.DesiredState
		} else {
			state = u.CurrentState
		}

		if job.JobState(state) != js {
			return fmt.Errorf("Waiting for Unit(%s) state(%s) to be %s", name, job.JobState(state), js)
		}

		msg := fmt.Sprintf("Unit %s %s", name, u.CurrentState)

		if u.MachineID != "" {
			ms := cachedMachineState(u.MachineID)
			if ms != nil {
				msg = fmt.Sprintf("%s on %s", msg, machineFullLegend(*ms, false))
			}
		}

		fmt.Fprintln(out, msg)
		return nil
	}
	_, err := waitForState(fetchUnitState)
	if err != nil {
		return false
	}

	return true
}
Esempio n. 17
0
func checkLoadUnitState(unit schema.Unit, loadRet int, errchan chan error) {
	if loadRet == 0 {
		if job.JobState(unit.DesiredState) != job.JobStateLoaded {
			errchan <- fmt.Errorf("Error: unit %s was not loaded as requested", unit.Name)
		}
	} else if unit.DesiredState != "" {
		// if the whole load operation failed, then no unit
		// should have a DesiredState set
		errchan <- fmt.Errorf("Error: Unit(%s) DesiredState was set to (%s)", unit.Name, unit.DesiredState)
	}
}
Esempio n. 18
0
func (f *FleetTunnel) Stop(events chan Event, unitNames ...string) (StopStats, error) {
	log.Debugf("stopping %v", unitNames)

	units, err := f.findUnits(unitNames)
	if err != nil {
		return StopStats{}, maskAny(err)
	}

	stopping := make([]string, 0)
	stats := StopStats{}
	for _, u := range units {
		if !suToGlobal(u) {
			if job.JobState(u.CurrentState) == job.JobStateInactive {
				return StopStats{}, maskAny(fmt.Errorf("Unable to stop unit %s in state %s", u.Name, job.JobStateInactive))
			} else if job.JobState(u.CurrentState) == job.JobStateLoaded {
				log.Debugf("Unit(%s) already %s, skipping.", u.Name, job.JobStateLoaded)
				continue
			}
		}

		log.Debugf("Setting target state of Unit(%s) to %s", u.Name, job.JobStateLoaded)
		if err := f.setUnitTargetStateWithRetry(u.Name, string(job.JobStateLoaded)); err != nil {
			return StopStats{}, maskAny(err)
		}
		if suToGlobal(u) {
			stats.StoppedGlobalUnits++
			events <- newEvent(u.Name, "triggered global unit stop")
		} else {
			stats.StoppedUnits++
			events <- newEvent(u.Name, "triggered unit stop")
			stopping = append(stopping, u.Name)
		}
	}

	if err := f.tryWaitForUnitStates(stopping, "stop", job.JobStateLoaded, f.BlockAttempts, events); err != nil {
		return StopStats{}, maskAny(err)
	}

	return stats, nil
}
Esempio n. 19
0
File: fleet.go Progetto: pulcy/j2
func (f *FleetTunnel) assertUnitState(name string, js job.JobState, events chan Event) (ret bool) {
	var state string

	u, err := f.unitWithRetry(name)
	if err != nil {
		log.Warningf("Error retrieving Unit(%s) from Registry: %v", name, err)
		return
	}
	if u == nil {
		events <- newEvent(name, "unit not found")
		log.Warningf("Unit %s not found", name)
		return
	}

	// If this is a global unit, CurrentState will never be set. Instead, wait for DesiredState.
	if suToGlobal(*u) {
		state = u.DesiredState
	} else {
		state = u.CurrentState
	}

	if job.JobState(state) != js {
		log.Debugf("Waiting for Unit(%s) state(%s) to be %s", name, job.JobState(state), js)
		return
	}

	ret = true
	msg := u.CurrentState

	if u.MachineID != "" {
		ms := f.cachedMachineState(u.MachineID)
		if ms != nil {
			msg = fmt.Sprintf("%s on %s", msg, machineFullLegend(*ms, false))
		}
	}

	events <- newEvent(name, msg)
	return
}
Esempio n. 20
0
// jobs returns a collection of all Jobs that the Agent has either loaded
// or launched. The Unit, TargetState and TargetMachineID fields of the
// returned *job.Job objects are not properly hydrated.
func (a *Agent) jobs() (map[string]*job.Job, error) {
	launched := pkg.NewUnsafeSet()
	for _, jName := range a.cache.launchedJobs() {
		launched.Add(jName)
	}

	loaded := pkg.NewUnsafeSet()
	for _, jName := range a.cache.loadedJobs() {
		loaded.Add(jName)
	}

	units, err := a.um.Units()
	if err != nil {
		return nil, fmt.Errorf("failed fetching loaded units from UnitManager: %v", err)
	}

	filter := pkg.NewUnsafeSet()
	for _, u := range units {
		filter.Add(u)
	}
	states, err := a.um.GetUnitStates(filter)
	if err != nil {
		return nil, fmt.Errorf("failed fetching unit states: %v", err)
	}

	jobs := make(map[string]*job.Job)
	for _, uName := range units {
		jobs[uName] = &job.Job{
			Name:      uName,
			UnitState: states[uName],
			State:     nil,

			// The following fields are not properly populated
			// and should not be used in the calling code
			Unit:            unit.Unit{},
			TargetState:     job.JobState(""),
			TargetMachineID: "",
		}

		js := job.JobStateInactive
		if loaded.Contains(uName) {
			js = job.JobStateLoaded
		} else if launched.Contains(uName) {
			js = job.JobStateLaunched
		}
		jobs[uName].State = &js
	}

	return jobs, nil
}
Esempio n. 21
0
func printUnitStatus(name string) int {
	u, err := cAPI.Unit(name)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error retrieving unit %s: %v", name, err)
		return 1
	}
	if u == nil {
		fmt.Fprintf(os.Stderr, "Unit %s does not exist.\n", name)
		return 1
	} else if job.JobState(u.CurrentState) == job.JobStateInactive {
		fmt.Fprintf(os.Stderr, "Unit %s does not appear to be running.\n", name)
		return 1
	}

	cmd := fmt.Sprintf("systemctl status -l %s", name)
	return runCommand(cmd, u.MachineID)
}
Esempio n. 22
0
func TestAgentLoadUnloadJob(t *testing.T) {
	uManager := unit.NewFakeUnitManager()
	usGenerator := unit.NewUnitStateGenerator(uManager)
	fReg := registry.NewFakeRegistry()
	mach := &machine.FakeMachine{machine.MachineState{ID: "XXX"}}
	a := New(uManager, usGenerator, fReg, mach, time.Second)

	j := newTestJobFromUnitContents(t, "foo.service", "")
	err := a.loadJob(j)
	if err != nil {
		t.Fatalf("Failed calling Agent.loadJob: %v", err)
	}

	jobs, err := a.jobs()
	if err != nil {
		t.Fatalf("Failed calling Agent.jobs: %v", err)
	}

	jsLoaded := job.JobStateLoaded
	expectJobs := map[string]*job.Job{
		"foo.service": &job.Job{
			Name:  "foo.service",
			State: &jsLoaded,

			Unit:            unit.UnitFile{},
			TargetState:     job.JobState(""),
			TargetMachineID: "",
		},
	}

	if !reflect.DeepEqual(expectJobs, jobs) {
		t.Fatalf("Received unexpected collection of Jobs: %#v\nExpected: %#v", jobs, expectJobs)
	}

	a.unloadJob("foo.service")

	jobs, err = a.jobs()
	if err != nil {
		t.Fatalf("Failed calling Agent.jobs: %v", err)
	}

	expectJobs = map[string]*job.Job{}
	if !reflect.DeepEqual(expectJobs, jobs) {
		t.Fatalf("Received unexpected collection of Jobs: %#v\nExpected: %#v", jobs, expectJobs)
	}
}
Esempio n. 23
0
func runStatusUnits(args []string) (exit int) {
	units, err := cAPI.Units()
	if err != nil {
		stderr("Error retrieving unit: %v", err)
		return 1
	}

	uMap := make(map[string]*schema.Unit, len(args))
	for _, u := range units {
		if u != nil {
			u := u
			uMap[u.Name] = u
		}
	}

	names := make([]string, len(args))
	for i, arg := range args {
		name := unitNameMangle(arg)
		names[i] = name

		u, ok := uMap[name]
		if !ok {
			stderr("Unit %s does not exist.", name)
			return 1
		} else if suToGlobal(*u) {
			stderr("Unable to determine status of global unit %s.", name)
			return 1
		} else if job.JobState(u.CurrentState) == job.JobStateInactive {
			stderr("Unit %s does not appear to be loaded.", name)
			return 1
		}
	}

	for i, name := range names {
		// This extra newline is here to match systemctl status output
		if i != 0 {
			fmt.Printf("\n")
		}

		cmd := fmt.Sprintf("systemctl status -l %s", name)
		if exit = runCommand(cmd, uMap[name].MachineID); exit != 0 {
			break
		}
	}
	return
}
Esempio n. 24
0
func runUnloadUnit(cCmd *cobra.Command, args []string) (exit int) {
	if len(args) == 0 {
		stderr("No units given")
		return 0
	}

	units, err := findUnits(args)
	if err != nil {
		stderr("%v", err)
		return 1
	}

	if len(units) == 0 {
		stderr("Units not found in registry")
		return 0
	}

	wait := make([]string, 0)
	for _, s := range units {
		if !suToGlobal(s) {
			if job.JobState(s.CurrentState) == job.JobStateInactive {
				log.Debugf("Target state of Unit(%s) already %s, skipping.", s.Name, job.JobStateInactive)
				continue
			}
		}

		log.Debugf("Setting target state of Unit(%s) to %s", s.Name, job.JobStateInactive)
		cAPI.SetUnitTargetState(s.Name, string(job.JobStateInactive))
		if suToGlobal(s) {
			stdout("Triggered global unit %s unload", s.Name)
		} else {
			wait = append(wait, s.Name)
		}
	}

	exit = tryWaitForUnitStates(wait, "unload", job.JobStateInactive, getBlockAttempts(cCmd), os.Stdout)
	if exit == 0 {
		stderr("Successfully unloaded units %v.", wait)
	} else {
		stderr("Failed to unload units %v. exit == %d.", wait, exit)
	}

	return
}
Esempio n. 25
0
func doUnloadUnits(r commandTestResults, errchan chan error) {
	exit := runUnloadUnit(r.units)
	if exit != r.expectedExit {
		errchan <- fmt.Errorf("%s: expected exit code %d but received %d", r.description, r.expectedExit, exit)
		return
	}

	real_units, err := findUnits(r.units)
	if err != nil {
		errchan <- err
		return
	}

	// We assume that we reached the desired state
	for _, v := range real_units {
		if job.JobState(v.DesiredState) != job.JobStateInactive {
			errchan <- fmt.Errorf("Error: unit %s was not unloaded as requested", v.Name)
		}
	}
}
Esempio n. 26
0
// setTargetStateOfUnits ensures that the target state for the given Units is set
// to the given state in the Registry.
// On success, a slice of the Units for which a state change was made is returned.
// Any error encountered is immediately returned (i.e. this is not a transaction).
func setTargetStateOfUnits(units []string, state job.JobState) ([]*schema.Unit, error) {
	triggered := make([]*schema.Unit, 0)
	for _, name := range units {
		u, err := cAPI.Unit(name)
		if err != nil {
			return nil, fmt.Errorf("error retrieving unit %s from registry: %v", name, err)
		} else if u == nil {
			return nil, fmt.Errorf("unable to find unit %s", name)
		} else if job.JobState(u.DesiredState) == state {
			log.V(1).Infof("Unit(%s) already %s, skipping.", u.Name, u.DesiredState)
			continue
		}

		log.V(1).Infof("Setting Unit(%s) target state to %s", u.Name, state)
		cAPI.SetUnitTargetState(u.Name, string(state))
		triggered = append(triggered, u)
	}

	return triggered, nil
}
Esempio n. 27
0
func (ur *unitsResource) set(rw http.ResponseWriter, req *http.Request, item string) {
	if validateContentType(req) != nil {
		sendError(rw, http.StatusNotAcceptable, errors.New("application/json is only supported Content-Type"))
		return
	}

	var dus schema.DesiredUnitState
	dec := json.NewDecoder(req.Body)
	err := dec.Decode(&dus)
	if err != nil {
		sendError(rw, http.StatusBadRequest, fmt.Errorf("unable to decode body: %v", err))
		return
	}

	j, err := ur.reg.Job(item)
	if err != nil {
		log.Errorf("Failed fetching Job(%s) from Registry: %v", item, err)
		sendError(rw, http.StatusInternalServerError, nil)
		return
	}

	var u *unit.Unit
	if len(dus.FileContents) > 0 {
		u, err = decodeUnitContents(dus.FileContents)
		if err != nil {
			sendError(rw, http.StatusBadRequest, fmt.Errorf("invalid fileContents: %v", err))
			return
		}
	}

	// TODO(bcwaldon): Assert value of DesiredState is launched, loaded or inactive
	ds := job.JobState(dus.DesiredState)

	if j != nil {
		ur.update(rw, j, ds, u)
	} else if u != nil {
		ur.create(rw, item, ds, u)
	} else {
		sendError(rw, http.StatusConflict, errors.New("unit does not exist and no fileContents provided"))
	}
}
Esempio n. 28
0
func doStopUnits(t *testing.T, r commandTestResults, errchan chan error) {
	sharedFlags.NoBlock = true
	exit := runStopUnit(cmdStop, r.units)
	if exit != r.expectedExit {
		errchan <- fmt.Errorf("%s: expected exit code %d but received %d", r.description, r.expectedExit, exit)
		return
	}

	real_units, err := findUnits(r.units)
	if err != nil {
		errchan <- err
		return
	}

	// We assume that we reached the desired state
	for _, v := range real_units {
		if job.JobState(v.DesiredState) != job.JobStateLoaded {
			errchan <- fmt.Errorf("Error: unit %s was not stopped as requested", v.Name)
		}
	}
}
Esempio n. 29
0
File: fleet.go Progetto: pulcy/j2
// setTargetStateOfUnits ensures that the target state for the given Units is set
// to the given state in the Registry.
// On success, a slice of the Units for which a state change was made is returned.
// Any error encountered is immediately returned (i.e. this is not a transaction).
func (f *FleetTunnel) setTargetStateOfUnits(units []string, state job.JobState) ([]*schema.Unit, error) {
	var triggered []*schema.Unit
	for _, name := range units {
		u, err := f.cAPI.Unit(name)
		if err != nil {
			return nil, maskAny(fmt.Errorf("error retrieving unit %s from registry: %v", name, err))
		} else if u == nil {
			return nil, maskAny(fmt.Errorf("unable to find unit %s", name))
		} else if job.JobState(u.DesiredState) == state {
			log.Debugf("Unit(%s) already %s, skipping.", u.Name, u.DesiredState)
			continue
		}

		log.Debugf("Setting Unit(%s) target state to %s", u.Name, state)
		if err := f.setUnitTargetStateWithRetry(u.Name, string(state)); err != nil {
			return nil, maskAny(err)
		}
		triggered = append(triggered, u)
	}

	return triggered, nil
}
Esempio n. 30
0
func runUnloadUnit(args []string) (exit int) {
	units, err := findUnits(args)
	if err != nil {
		stderr("%v", err)
		return 1
	}

	wait := make([]string, 0)
	for _, s := range units {
		if !suToGlobal(s) {
			if job.JobState(s.CurrentState) == job.JobStateInactive {
				log.Debugf("Target state of Unit(%s) already %s, skipping.", s.Name, job.JobStateInactive)
				continue
			}
		}

		log.Debugf("Setting target state of Unit(%s) to %s", s.Name, job.JobStateInactive)
		cAPI.SetUnitTargetState(s.Name, string(job.JobStateInactive))
		if suToGlobal(s) {
			stdout("Triggered global unit %s unload", s.Name)
		} else {
			wait = append(wait, s.Name)
		}
	}

	if !sharedFlags.NoBlock {
		errchan := waitForUnitStates(wait, job.JobStateInactive, sharedFlags.BlockAttempts, os.Stdout)
		for err := range errchan {
			stderr("Error waiting for units: %v", err)
			exit = 1
		}
	} else {
		for _, name := range wait {
			stdout("Triggered unit %s unload", name)
		}
	}

	return
}