Skip to content
This repository has been archived by the owner on Jan 30, 2020. It is now read-only.

Commit

Permalink
fleetctl: check systemd active state via cAPI.UnitStates()
Browse files Browse the repository at this point in the history
It's not appropriate to check systemd active states with DBUS
connection, as that will return correct states only on the same machine.
So we should introduce a check using cAPI.UnitStates(), to check states
on other machines.
  • Loading branch information
Dongsu Park committed Aug 31, 2016
1 parent 39089a5 commit 88a0a30
Showing 1 changed file with 36 additions and 25 deletions.
61 changes: 36 additions & 25 deletions fleetctl/fleetctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import (
"github.com/spf13/pflag"

etcd "github.com/coreos/etcd/client"
sd_dbus "github.com/coreos/go-systemd/dbus"

"github.com/coreos/fleet/api"
"github.com/coreos/fleet/client"
Expand Down Expand Up @@ -177,6 +176,12 @@ type Command struct {

}

type suState struct {
LoadState string
ActiveState string
SubState string
}

func getFlags(flagset *flag.FlagSet) (flags []*flag.Flag) {
flags = make([]*flag.Flag, 0)
flagset.VisitAll(func(f *flag.Flag) {
Expand Down Expand Up @@ -1082,18 +1087,8 @@ func tryWaitForSystemdActiveState(units []string, maxAttempts int) (err error) {
return nil
}

conn, err := sd_dbus.New()
if err != nil {
stderr("Failed to get systemd-dbus conn: %v", err)
return nil
}
defer conn.Close()

// Get systemd state and check the state is active & loaded.
// If any unit in []units cannot be found, then return an error.
// That should be the only case of returning 1.
for _, uName := range units {
err := waitForSystemdActiveState(conn, uName)
err := waitForSystemdActiveState(uName)
if err != nil {
stderr("cannot find an active unit: %v", err)
return err
Expand All @@ -1106,7 +1101,7 @@ func tryWaitForSystemdActiveState(units []string, maxAttempts int) (err error) {
// waitForSystemdActiveState tries to assert that the given unit becomes
// active, retrying periodically until the unit gets active. It will retry
// up to 15 seconds.
func waitForSystemdActiveState(conn *sd_dbus.Conn, unitName string) (err error) {
func waitForSystemdActiveState(unitName string) (err error) {
return func() error {
timeout := 15 * time.Second
alarm := time.After(timeout)
Expand All @@ -1116,7 +1111,7 @@ func waitForSystemdActiveState(conn *sd_dbus.Conn, unitName string) (err error)
case <-alarm:
return fmt.Errorf("Failed to reach expected state within %v.", timeout)
case <-ticker:
if errA := assertSystemdActiveState(conn, unitName); errA == nil {
if errA := assertSystemdActiveState(unitName); errA == nil {
return nil
}
}
Expand All @@ -1125,25 +1120,41 @@ func waitForSystemdActiveState(conn *sd_dbus.Conn, unitName string) (err error)
}

// assertSystemdActiveState determines if a given systemd unit is actually
// in the active state, making use of systemd's DBUS connection.
func assertSystemdActiveState(conn *sd_dbus.Conn, unitName string) (err error) {
listUnits, err := conn.ListUnits()
// in the active state, making use of cAPI
func assertSystemdActiveState(unitName string) (err error) {
uState, err := getSingleUnitState(unitName)
if err != nil {
return fmt.Errorf("Failed to list systemd unit: %v", err)
return err
}

for _, u := range listUnits {
if u.Name != unitName {
continue
}
if u.ActiveState != "active" || u.LoadState != "loaded" {
return fmt.Errorf("Failed to find an active unit %s", unitName)
}
// Get systemd state and check the state is active & loaded.
if uState.ActiveState != "active" || uState.LoadState != "loaded" {
return fmt.Errorf("Failed to find an active unit %s", unitName)
}

return nil
}

// getSingleUnitState returns a single uState of type suState, which consists
// of necessary systemd states, only for a given unit name.
func getSingleUnitState(unitName string) (suState, error) {
apiStates, err := cAPI.UnitStates()
if err != nil {
return suState{}, fmt.Errorf("Error retrieving list of units: %v", err)
}

for _, us := range apiStates {
if us.Name == unitName {
return suState{
us.SystemdLoadState,
us.SystemdActiveState,
us.SystemdSubState,
}, nil
}
}
return suState{}, fmt.Errorf("unit %s not found", unitName)
}

func machineState(machID string) (*machine.MachineState, error) {
machines, err := cAPI.Machines()
if err != nil {
Expand Down

0 comments on commit 88a0a30

Please sign in to comment.