New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow add-machine to take a -n param #198
Changes from all commits
bc8ec2f
aca8ed5
fcca20d
4e529c4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,9 @@ | |
package main | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/juju/cmd" | ||
"github.com/juju/names" | ||
|
@@ -44,7 +46,9 @@ access the environment storage. | |
|
||
Examples: | ||
juju add-machine (starts a new machine) | ||
juju add-machine -n 2 (starts 2 new machines) | ||
juju add-machine lxc (starts a new machine with an lxc container) | ||
juju add-machine lxc -n 2 (starts 2 new machines with an lxc container) | ||
juju add-machine lxc:4 (starts a new lxc container on machine 4) | ||
juju add-machine --constraints mem=8G (starts a machine with at least 8GB RAM) | ||
juju add-machine ssh:user@10.10.0.3 (manually provisions a machine with ssh) | ||
|
@@ -62,6 +66,8 @@ type AddMachineCommand struct { | |
Constraints constraints.Value | ||
// Placement is passed verbatim to the API, to be parsed and evaluated server-side. | ||
Placement *instance.Placement | ||
|
||
NumMachines int | ||
} | ||
|
||
func (c *AddMachineCommand) Info() *cmd.Info { | ||
|
@@ -75,6 +81,7 @@ func (c *AddMachineCommand) Info() *cmd.Info { | |
|
||
func (c *AddMachineCommand) SetFlags(f *gnuflag.FlagSet) { | ||
f.StringVar(&c.Series, "series", "", "the charm series") | ||
f.IntVar(&c.NumMachines, "n", 1, "The number of machines to add") | ||
f.Var(constraints.ConstraintsValue{Target: &c.Constraints}, "constraints", "additional machine constraints") | ||
} | ||
|
||
|
@@ -94,9 +101,22 @@ func (c *AddMachineCommand) Init(args []string) error { | |
if err != nil { | ||
return err | ||
} | ||
if c.NumMachines > 1 && c.Placement != nil && c.Placement.Directive != "" { | ||
return fmt.Errorf("cannot use -n when specifying a placement directive") | ||
} | ||
return nil | ||
} | ||
|
||
type AddMachineAPI interface { | ||
Close() error | ||
AddMachines([]params.AddMachineParams) ([]params.AddMachinesResult, error) | ||
AddMachines1dot18([]params.AddMachineParams) ([]params.AddMachinesResult, error) | ||
} | ||
|
||
var getAddMachineAPI = func(envname string) (AddMachineAPI, error) { | ||
return juju.NewAPIClientFromName(envname) | ||
} | ||
|
||
func (c *AddMachineCommand) Run(ctx *cmd.Context) error { | ||
if c.Placement != nil && c.Placement.Scope == "ssh" { | ||
args := manual.ProvisionMachineArgs{ | ||
|
@@ -110,7 +130,7 @@ func (c *AddMachineCommand) Run(ctx *cmd.Context) error { | |
return err | ||
} | ||
|
||
client, err := juju.NewAPIClientFromName(c.EnvName) | ||
client, err := getAddMachineAPI(c.EnvName) | ||
if err != nil { | ||
return err | ||
} | ||
|
@@ -127,7 +147,12 @@ func (c *AddMachineCommand) Run(ctx *cmd.Context) error { | |
Constraints: c.Constraints, | ||
Jobs: []params.MachineJob{params.JobHostUnits}, | ||
} | ||
results, err := client.AddMachines([]params.AddMachineParams{machineParams}) | ||
machines := make([]params.AddMachineParams, c.NumMachines) | ||
for i := 0; i < c.NumMachines; i++ { | ||
machines[i] = machineParams | ||
} | ||
|
||
results, err := client.AddMachines(machines) | ||
if params.IsCodeNotImplemented(err) { | ||
if c.Placement != nil { | ||
containerType, parseErr := instance.ParseContainerType(c.Placement.Scope) | ||
|
@@ -150,17 +175,31 @@ func (c *AddMachineCommand) Run(ctx *cmd.Context) error { | |
return err | ||
} | ||
|
||
// Currently, only one machine is added, but in future there may be several added in one call. | ||
machineInfo := results[0] | ||
if machineInfo.Error != nil { | ||
return machineInfo.Error | ||
} | ||
machineId := machineInfo.Machine | ||
errs := []error{} | ||
for _, machineInfo := range results { | ||
if machineInfo.Error != nil { | ||
errs = append(errs, machineInfo.Error) | ||
continue | ||
} | ||
machineId := machineInfo.Machine | ||
|
||
if names.IsContainerMachine(machineId) { | ||
ctx.Infof("created container %v", machineId) | ||
} else { | ||
ctx.Infof("created machine %v", machineId) | ||
if names.IsContainerMachine(machineId) { | ||
ctx.Infof("created container %v", machineId) | ||
} else { | ||
ctx.Infof("created machine %v", machineId) | ||
} | ||
} | ||
if len(errs) == 1 { | ||
fmt.Fprintf(ctx.Stderr, "failed to create 1 machine\n") | ||
return errs[0] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm +1 on returning the original error if there's only one failure, but I think we need to be consistent with the error output. I think it might be better just to print out the "failed to create N machine(s)" regardless of how many there are, and then return cmd.ErrSilent. Also, I think you want to be printing to ctx.Stderr() for errors -- they shouldn't be hidden by |
||
} | ||
if len(errs) > 1 { | ||
fmt.Fprintf(ctx.Stderr, "failed to create %d machines\n", len(errs)) | ||
returnErr := []string{} | ||
for _, e := range errs { | ||
returnErr = append(returnErr, fmt.Sprintf("%s", e)) | ||
} | ||
return errors.New(strings.Join(returnErr, ", ")) | ||
} | ||
return nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This won't work. "lxc" is a placement directive.
EDIT: ah, I see what you did now. Never mind.