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

fleetctl: Adding restart command #1238

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions Documentation/using-the-client.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,16 @@ Start and stop units with the `start` and `stop` commands:
$ fleetctl start goodbye.service
Unit goodbye.service launched on 85c0c595.../172.17.8.102

$ fleetctl restart goodbye.service
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move the restart-related documentation to the bottom of the "Start and stop units" block.

Unit goodbye.service loaded on 85c0c595.../172.17.8.102
Unit goodbye.service launched on 85c0c595.../172.17.8.102

$ fleetctl stop goodbye.service
Unit goodbye.service loaded on 85c0c595.../172.17.8.102
```

If the unit does not exist when calling `start`, fleetctl will first search for a local unit file, submit it and schedule it.
If the unit is stopped when calling `restart`, fleetctl will start it.

### Scheduling units

Expand Down
1 change: 1 addition & 0 deletions fleetctl/fleetctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ func init() {
cmdSSH,
cmdStartUnit,
cmdStatusUnits,
cmdRestartUnit,
cmdStopUnit,
cmdSubmitUnit,
cmdUnloadUnit,
Expand Down
104 changes: 104 additions & 0 deletions fleetctl/restart.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
Copyright 2014 CoreOS, Inc.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2015


Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
"os"

"github.com/coreos/fleet/job"
"github.com/coreos/fleet/log"
"github.com/coreos/fleet/schema"
)

var cmdRestartUnit = &Command{
Name: "restart",
Summary: "Instruct systemd to rolling restart one or more units in the cluster.",
Usage: "[--block-attempts=N] UNIT...",
Description: `Restarts one or more units in the cluster. If they are stopped it starts them.

Instructs systemd on the host machine to stop then start the unit, deferring to systemd
completely for any custom restart directives (i.e. ExecStop options in the unit
file).

For units which are not global, restart operations are performed synchronously,
which means fleetctl will block until it detects that the unit(s) have
transitioned to a stopped state and then back to a started state. This behaviour can be configured with the
respective --block-attempts options. Restart operations on global
units are always non-blocking.

Restart a single unit:
fleetctl restart foo.service

Restart an entire directory of units with glob matching, without waiting:
fleetctl restart myservice/*`,
Run: runRestartUnit,
}

func init() {
cmdRestartUnit.Flags.IntVar(&sharedFlags.BlockAttempts, "block-attempts", 0, "Wait until the units are stopped/started, performing up to N attempts before giving up. A value of 0 indicates no limit. Does not apply to global units.")
}

func runRestartUnit(args []string) (exit int) {
units, err := findUnits(args)
if err != nil {
stderr("%v", err)
return 1
}
if len(units) == 0 {
stderr("No units were found")
return 1
}
for _, u := range units {
if job.JobState(u.CurrentState) == job.JobStateInactive && !suToGlobal(u) {
stderr("Unable to restart unit %s in state %s", u.Name, job.JobStateInactive)
return 1
} else if job.JobState(u.CurrentState) == job.JobStateLoaded {
log.Infof("Unit(%s) already %s, starting.", u.Name, job.JobStateLoaded)

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

func setUnitStateAndWait(unit schema.Unit, targetState job.JobState, blockAttempts int) (exit int) {
cAPI.SetUnitTargetState(unit.Name, string(targetState))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handle the error from this


if !suToGlobal(unit) {
errchan := waitForUnitStates([]string{unit.Name}, targetState, blockAttempts, os.Stdout)
for err := range errchan {
stderr("Error waiting for unit %s to change states: %v", unit.Name, err)
return 1
}
}
return
}