Skip to content

Commit 0fb828e

Browse files
committed
Merge pull request #53 from mboersma/parallel-start-containers
feat(start/stop): allow starting or stopping > 1 unit at a time
2 parents 99f9a44 + 615a2cb commit 0fb828e

8 files changed

Lines changed: 150 additions & 169 deletions

File tree

client/api.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ package client
22

33
// Client interface used to interact with the cluster control plane
44
type Client interface {
5-
Create(string) error
6-
Destroy(string) error
7-
Start(string) error
8-
Stop(string) error
5+
Create([]string) error
6+
Destroy([]string) error
7+
Start([]string) error
8+
Stop([]string) error
99
Scale(string, int) error
1010
ListUnits() error
1111
ListUnitFiles() error

client/create.go

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,37 +11,37 @@ import (
1111

1212
// Create schedules a new unit for the given component
1313
// and blocks until the unit is loaded
14-
func (c *FleetClient) Create(target string) (err error) {
15-
var (
16-
unitName string
17-
unitFile *unit.UnitFile
18-
)
19-
// create unit file
20-
unitName, unitFile, err = c.createUnitFile(target)
21-
if err != nil {
22-
return err
23-
}
24-
// define unit
25-
u := &schema.Unit{
26-
Name: unitName,
27-
Options: schema.MapUnitFileToSchemaUnitOptions(unitFile),
28-
}
29-
// schedule unit
30-
if err := c.Fleet.CreateUnit(u); err != nil {
31-
// ignore units that already exist
32-
if err.Error() != "job already exists" {
33-
return fmt.Errorf("failed creating job %s: %v", unitName, err)
14+
func (c *FleetClient) Create(targets []string) error {
15+
units := make([]*schema.Unit, len(targets))
16+
for i, target := range targets {
17+
unitName, unitFile, err := c.createUnitFile(target)
18+
if err != nil {
19+
return err
20+
}
21+
units[i] = &schema.Unit{
22+
Name: unitName,
23+
Options: schema.MapUnitFileToSchemaUnitOptions(unitFile),
3424
}
3525
}
36-
desiredState := string(job.JobStateLoaded)
37-
err = c.Fleet.SetUnitTargetState(unitName, desiredState)
38-
if err != nil {
39-
return err
26+
for _, unit := range units {
27+
// schedule unit
28+
if err := c.Fleet.CreateUnit(unit); err != nil {
29+
// ignore units that already exist
30+
if err.Error() != "job already exists" {
31+
return fmt.Errorf("failed creating job %s: %v", unit.Name, err)
32+
}
33+
}
34+
desiredState := string(job.JobStateLoaded)
35+
if err := c.Fleet.SetUnitTargetState(unit.Name, desiredState); err != nil {
36+
return err
37+
}
4038
}
41-
outchan, errchan := waitForUnitStates([]string{unitName}, desiredState)
42-
err = printUnitState(unitName, outchan, errchan)
43-
if err != nil {
44-
return err
39+
for _, unit := range units {
40+
desiredState := string(job.JobStateLoaded)
41+
outchan, errchan := waitForUnitStates([]string{unit.Name}, desiredState)
42+
if err := printUnitState(unit.Name, outchan, errchan); err != nil {
43+
return err
44+
}
4545
}
4646
return nil
4747
}

client/destroy.go

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,26 @@ import (
88
)
99

1010
// Destroy units for a given target
11-
func (c *FleetClient) Destroy(target string) (err error) {
12-
// check if the unit exists
13-
units, err := c.Units(target)
14-
if err != nil {
15-
return err
16-
}
17-
component, num, err := splitTarget(target)
18-
if err != nil {
19-
return
20-
}
21-
// if no number is specified, destroy ALL THE UNITS!
22-
if num == 0 {
23-
num = len(units)
24-
}
25-
if strings.HasSuffix(component, "-data") {
26-
err = c.destroyDataUnit(component)
27-
} else {
28-
err = c.destroyServiceUnit(component, num)
29-
}
30-
if err != nil {
31-
return err
11+
func (c *FleetClient) Destroy(targets []string) error {
12+
for _, target := range targets {
13+
// check if the unit exists
14+
if _, err := c.Units(target); err != nil {
15+
return err
16+
}
17+
component, num, err := splitTarget(target)
18+
if err != nil {
19+
return err
20+
}
21+
if strings.HasSuffix(component, "-data") {
22+
err = c.destroyDataUnit(component)
23+
} else {
24+
err = c.destroyServiceUnit(component, num)
25+
}
26+
if err != nil {
27+
return err
28+
}
3229
}
33-
return
30+
return nil
3431
}
3532

3633
func (c *FleetClient) destroyServiceUnit(component string, num int) (err error) {

client/scale.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ func (c *FleetClient) Scale(component string, requested int) (err error) {
1717
if err != nil {
1818
return err
1919
}
20-
err = c.Create(component + "@" + strconv.Itoa(num))
21-
if err != nil {
20+
if err = c.Create([]string{component + "@" + strconv.Itoa(num)}); err != nil {
2221
return err
2322
}
2423
continue
@@ -28,8 +27,7 @@ func (c *FleetClient) Scale(component string, requested int) (err error) {
2827
if err != nil {
2928
return err
3029
}
31-
err = c.Destroy(component + "@" + strconv.Itoa(num))
32-
if err != nil {
30+
if err = c.Destroy([]string{component + "@" + strconv.Itoa(num)}); err != nil {
3331
return err
3432
}
3533
continue

client/start.go

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,37 @@ import (
88
)
99

1010
// Start launches target units and blocks until active
11-
func (c *FleetClient) Start(target string) (err error) {
12-
units, err := c.Units(target)
13-
if err != nil {
14-
return
15-
}
16-
desiredState := string(job.JobStateLaunched)
17-
for _, name := range units {
18-
err = c.Fleet.SetUnitTargetState(name, desiredState)
11+
func (c *FleetClient) Start(targets []string) error {
12+
units := make([][]string, len(targets))
13+
for i, target := range targets {
14+
u, err := c.Units(target)
1915
if err != nil {
2016
return err
2117
}
22-
// wait for systemd to tell us that it's running, not fleet
23-
var errchan chan error
24-
var outchan chan *schema.Unit
25-
// data containers are special snowflakes who just exit
26-
if strings.Contains(name, "-data.service") {
27-
outchan, errchan = waitForUnitSubStates(units, "exited")
28-
} else {
29-
outchan, errchan = waitForUnitSubStates(units, "running")
18+
units[i] = u
19+
}
20+
desiredState := string(job.JobStateLaunched)
21+
for _, names := range units {
22+
for _, name := range names {
23+
if err := c.Fleet.SetUnitTargetState(name, desiredState); err != nil {
24+
return err
25+
}
3026
}
31-
err = printUnitSubState(name, outchan, errchan)
32-
if err != nil {
33-
return err
27+
}
28+
var errchan chan error
29+
var outchan chan *schema.Unit
30+
for _, names := range units {
31+
for _, name := range names {
32+
// wait for systemd to tell us that it's running, not fleet
33+
// data containers are special snowflakes who just exit
34+
if strings.Contains(name, "-data.service") {
35+
outchan, errchan = waitForUnitSubStates(names, "exited")
36+
} else {
37+
outchan, errchan = waitForUnitSubStates(names, "running")
38+
}
39+
if err := printUnitSubState(name, outchan, errchan); err != nil {
40+
return err
41+
}
3442
}
3543
}
3644
return nil

client/stop.go

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,38 @@
11
package client
22

3-
import "github.com/coreos/fleet/job"
3+
import (
4+
"github.com/coreos/fleet/job"
5+
"github.com/coreos/fleet/schema"
6+
)
47

58
// Stop sets target units to inactive and blocks until complete
6-
func (c *FleetClient) Stop(target string) (err error) {
7-
units, err := c.Units(target)
8-
if err != nil {
9-
return
10-
}
11-
desiredState := string(job.JobStateLoaded)
12-
for _, name := range units {
13-
err = c.Fleet.SetUnitTargetState(name, desiredState)
9+
func (c *FleetClient) Stop(targets []string) error {
10+
units := make([][]string, len(targets))
11+
for i, target := range targets {
12+
u, err := c.Units(target)
1413
if err != nil {
1514
return err
1615
}
17-
outchan, errchan := waitForUnitStates(units, desiredState)
18-
err = printUnitState(name, outchan, errchan)
19-
if err != nil {
20-
return err
16+
units[i] = u
17+
}
18+
desiredState := string(job.JobStateLoaded)
19+
for _, names := range units {
20+
for _, name := range names {
21+
if err := c.Fleet.SetUnitTargetState(name, desiredState); err != nil {
22+
return err
23+
}
24+
}
25+
}
26+
var errchan chan error
27+
var outchan chan *schema.Unit
28+
for _, names := range units {
29+
for _, name := range names {
30+
outchan, errchan = waitForUnitSubStates(names, "dead")
31+
if err := printUnitSubState(name, outchan, errchan); err != nil {
32+
return err
33+
}
2134
}
2235
}
2336
return nil
37+
2438
}

0 commit comments

Comments
 (0)