123
123
type bootstrapCommand struct {
124
124
modelcmd.ModelCommandBase
126
Constraints constraints.Value
127
BootstrapConstraints constraints.Value
128
BootstrapSeries string
129
BootstrapImage string
131
MetadataSource string
133
KeepBrokenEnvironment bool
135
AgentVersionParam string
136
AgentVersion *version.Number
137
config common.ConfigFlag
126
Constraints constraints.Value
127
ConstraintsStr string
128
BootstrapConstraints constraints.Value
129
BootstrapConstraintsStr string
130
BootstrapSeries string
131
BootstrapImage string
133
MetadataSource string
135
KeepBrokenEnvironment bool
137
AgentVersionParam string
138
AgentVersion *version.Number
139
config common.ConfigFlag
140
142
showRegionsForCloud string
159
161
func (c *bootstrapCommand) SetFlags(f *gnuflag.FlagSet) {
160
162
c.ModelCommandBase.SetFlags(f)
161
f.Var(constraints.ConstraintsValue{Target: &c.Constraints}, "constraints", "Set model constraints")
162
f.Var(constraints.ConstraintsValue{Target: &c.BootstrapConstraints}, "bootstrap-constraints", "Specify bootstrap machine constraints")
163
f.StringVar(&c.ConstraintsStr, "constraints", "", "Set model constraints")
164
f.StringVar(&c.BootstrapConstraintsStr, "bootstrap-constraints", "", "Specify bootstrap machine constraints")
163
165
f.StringVar(&c.BootstrapSeries, "bootstrap-series", "", "Specify the series of the bootstrap machine")
164
166
if featureflag.Enabled(feature.ImageMetadata) {
165
167
f.StringVar(&c.BootstrapImage, "bootstrap-image", "", "Specify the image of the bootstrap machine")
195
197
if c.BootstrapSeries != "" && !charm.IsValidSeries(c.BootstrapSeries) {
196
198
return errors.NotValidf("series %q", c.BootstrapSeries)
198
if c.BootstrapImage != "" {
199
if c.BootstrapSeries == "" {
200
return errors.Errorf("--bootstrap-image must be used with --bootstrap-series")
202
cons, err := constraints.Merge(c.Constraints, c.BootstrapConstraints)
204
return errors.Trace(err)
207
return errors.Errorf("--bootstrap-image must be used with --bootstrap-constraints, specifying architecture")
211
201
// Parse the placement directive. Bootstrap currently only
212
202
// supports provider-specific placement directives.
290
280
specify a credential using the --credential argument`[1:],
283
func (c *bootstrapCommand) parseConstraints(ctx *cmd.Context) (err error) {
284
allAliases := map[string]string{}
285
defer common.WarnConstraintAliases(ctx, allAliases)
286
if c.ConstraintsStr != "" {
287
cons, aliases, err := constraints.ParseWithAliases(c.ConstraintsStr)
288
for k, v := range aliases {
296
if c.BootstrapConstraintsStr != "" {
297
cons, aliases, err := constraints.ParseWithAliases(c.BootstrapConstraintsStr)
298
for k, v := range aliases {
304
c.BootstrapConstraints = cons
293
309
// Run connects to the environment specified on the command line and bootstraps
294
310
// a juju in that environment if none already exists. If there is as yet no environments.yaml file,
295
311
// the user is informed how to create one.
296
312
func (c *bootstrapCommand) Run(ctx *cmd.Context) (resultErr error) {
313
if err := c.parseConstraints(ctx); err != nil {
316
if c.BootstrapImage != "" {
317
if c.BootstrapSeries == "" {
318
return errors.Errorf("--bootstrap-image must be used with --bootstrap-series")
320
cons, err := constraints.Merge(c.Constraints, c.BootstrapConstraints)
322
return errors.Trace(err)
325
return errors.Errorf("--bootstrap-image must be used with --bootstrap-constraints, specifying architecture")
297
328
if c.interactive {
298
329
if err := c.runInteractive(ctx); err != nil {
299
330
return errors.Trace(err)
390
421
store := c.ClientStore()
391
422
var detectedCredentialName string
392
423
credential, credentialName, regionName, err := modelcmd.GetCredentials(
393
store, c.Region, c.CredentialName, c.Cloud, cloud.Type,
424
ctx, store, modelcmd.GetCredentialsParams{
427
CloudRegion: c.Region,
428
CredentialName: c.CredentialName,
395
431
if errors.Cause(err) == modelcmd.ErrMultipleCredentials {
396
432
return ambiguousCredentialError