diff --git a/cmd/juju/application/bundle/bundle.go b/cmd/juju/application/bundle/bundle.go index 5ff52085f5ce..53b3ce70cb1d 100644 --- a/cmd/juju/application/bundle/bundle.go +++ b/cmd/juju/application/bundle/bundle.go @@ -330,12 +330,13 @@ func verifyBundle(data *charm.BundleData, bundleDir string, verifyConstraints fu return err } + var errs []string // This method cannot be included within data.Verify because // to verify corresponding series and base match we need to be // able to compare them. The charm package, however, treats bases // and series generically and is unable to do this. if err := verifyMixedSeriesBasesMatch(data); err != nil { - return errors.Trace(err) + errs = append(errs, err.Error()) } var verifyError error @@ -346,9 +347,8 @@ func verifyBundle(data *charm.BundleData, bundleDir string, verifyConstraints fu } if verr, ok := errors.Cause(verifyError).(*charm.VerificationError); ok { - errs := make([]string, len(verr.Errors)) - for i, err := range verr.Errors { - errs[i] = err.Error() + for _, err := range verr.Errors { + errs = append(errs, err.Error()) } return errors.New("the provided bundle has the following errors:\n" + strings.Join(errs, "\n")) } @@ -369,7 +369,7 @@ func verifyMixedSeriesBasesMatch(data *charm.BundleData) error { return errors.Trace(err) } if s != data.Series { - return errors.NewNotValid(nil, fmt.Sprintf("bundle series %q and base %q must match if supplied", data.Series, data.DefaultBase)) + return errors.NewNotValid(nil, fmt.Sprintf("bundle series %q and base %q must match if both supplied", data.Series, data.DefaultBase)) } } @@ -384,7 +384,7 @@ func verifyMixedSeriesBasesMatch(data *charm.BundleData) error { return errors.Trace(err) } if s != m.Series { - return errors.NewNotValid(nil, fmt.Sprintf("machine %q series %q and base %q must match if supplied", name, m.Series, m.Base)) + return errors.NewNotValid(nil, fmt.Sprintf("machine %q series %q and base %q must match if both supplied", name, m.Series, m.Base)) } } } @@ -400,7 +400,7 @@ func verifyMixedSeriesBasesMatch(data *charm.BundleData) error { return errors.Trace(err) } if s != app.Series { - return errors.NewNotValid(nil, fmt.Sprintf("application %q series %q and base %q must match if supplied", name, app.Series, app.Base)) + return errors.NewNotValid(nil, fmt.Sprintf("application %q series %q and base %q must match if both supplied", name, app.Series, app.Base)) } } } diff --git a/cmd/juju/application/bundle/bundle_test.go b/cmd/juju/application/bundle/bundle_test.go index 22960f6d8af1..837f3a324106 100644 --- a/cmd/juju/application/bundle/bundle_test.go +++ b/cmd/juju/application/bundle/bundle_test.go @@ -107,13 +107,13 @@ func (s *buildModelRepSuite) TestBuildModelRepresentationApplicationsWithSubordi Name: "default", }, Machines: map[string]params.MachineStatus{ - "0": {Base: params.Base{Name: "ubuntu", Channel: "18.04"}}, - "1": {Base: params.Base{Name: "ubuntu", Channel: "18.04"}}, + "0": {Base: params.Base{Name: "ubuntu", Channel: "22.04"}}, + "1": {Base: params.Base{Name: "ubuntu", Channel: "22.04"}}, }, Applications: map[string]params.ApplicationStatus{ "wordpress": { Charm: "wordpress", - Base: params.Base{Name: "ubuntu", Channel: "18.04"}, + Base: params.Base{Name: "ubuntu", Channel: "22.04"}, Life: life.Alive, Units: map[string]params.UnitStatus{ "0": {Machine: "0"}, @@ -121,7 +121,7 @@ func (s *buildModelRepSuite) TestBuildModelRepresentationApplicationsWithSubordi }, "sub": { Charm: "sub", - Base: params.Base{Name: "ubuntu", Channel: "18.04"}, + Base: params.Base{Name: "ubuntu", Channel: "22.04"}, Life: life.Alive, SubordinateTo: []string{"wordpress"}, }, @@ -323,7 +323,7 @@ func (s *composeAndVerifyRepSuite) TestComposeAndVerifyBundleMixingBaseAndSeries s.expectBasePath() obtained, _, err := ComposeAndVerifyBundle(s.bundleDataSource, []string{s.overlayFile}) - c.Assert(err, gc.ErrorMatches, `application "wordpress" series "jammy" and base "ubuntu@20.04" must match if supplied`) + c.Assert(err, gc.ErrorMatches, `(?s)the provided bundle has the following errors:.*application "wordpress" series "jammy" and base "ubuntu@20.04" must match if both supplied.*invalid constraints.*`) c.Assert(obtained, gc.IsNil) } @@ -359,12 +359,12 @@ func (s *buildModelRepSuite) TestBuildModelRepresentationApplicationsWithExposed Name: "default", }, Machines: map[string]params.MachineStatus{ - "0": {Base: params.Base{Name: "ubuntu", Channel: "18.04"}}, + "0": {Base: params.Base{Name: "ubuntu", Channel: "22.04"}}, }, Applications: map[string]params.ApplicationStatus{ "wordpress": { Charm: "wordpress", - Base: params.Base{Name: "ubuntu", Channel: "18.04"}, + Base: params.Base{Name: "ubuntu", Channel: "22.04"}, Life: life.Alive, Units: map[string]params.UnitStatus{ "0": {Machine: "0"}, @@ -572,6 +572,7 @@ applications: series: focal base: ubuntu@20.04 num_units: 1 + constraints: image-id=ubuntu-bf2 to: - "0" wordpress: