Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/2.2' into 2.2-into-develop
Browse files Browse the repository at this point in the history
Bring in the changes from 2.2
 * force-upgrade script
 * juju upgrade-juju --force
 * support for bionic (should have already landed in a different way)

Conflicts:
	.ci/check-merge.groovy
	Makefile
	dependencies.tsv
	scripts/win-installer/setup.iss
	snap/snapcraft.yaml
	version/version.go
  • Loading branch information
jameinel committed Oct 26, 2017
2 parents 41e2d35 + 699a961 commit 34c00d5
Show file tree
Hide file tree
Showing 21 changed files with 294 additions and 77 deletions.
4 changes: 2 additions & 2 deletions api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,8 @@ func (c *Client) Close() error {

// SetModelAgentVersion sets the model agent-version setting
// to the given value.
func (c *Client) SetModelAgentVersion(version version.Number) error {
args := params.SetModelAgentVersion{Version: version}
func (c *Client) SetModelAgentVersion(version version.Number, ignoreAgentVersions bool) error {
args := params.SetModelAgentVersion{Version: version, IgnoreAgentVersions: ignoreAgentVersions}
return c.facade.FacadeCall("SetModelAgentVersion", args, nil)
}

Expand Down
2 changes: 1 addition & 1 deletion api/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ func (s *clientSuite) TestSetModelAgentVersionDuringUpgrade(c *gc.C) {
_, err = s.State.EnsureUpgradeInfo(machine.Id(), agentVersion, nextVersion)
c.Assert(err, jc.ErrorIsNil)

err = s.APIState.Client().SetModelAgentVersion(nextVersion)
err = s.APIState.Client().SetModelAgentVersion(nextVersion, false)

// Expect an error with a error code that indicates this specific
// situation. The client needs to be able to reliably identify
Expand Down
2 changes: 1 addition & 1 deletion apiserver/facades/agent/upgrader/upgrader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ func (s *upgraderSuite) bumpDesiredAgentVersion(c *gc.C) version.Number {
s.rawMachine.SetAgentVersion(current)
newer := current
newer.Patch++
err := s.State.SetModelAgentVersion(newer.Number)
err := s.State.SetModelAgentVersion(newer.Number, false)
c.Assert(err, jc.ErrorIsNil)
cfg, err := s.IAASModel.ModelConfig()
c.Assert(err, jc.ErrorIsNil)
Expand Down
2 changes: 1 addition & 1 deletion apiserver/facades/client/client/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ type Backend interface {
RemoteConnectionStatus(string) (*state.RemoteConnectionStatus, error)
RemoveUserAccess(names.UserTag, names.Tag) error
SetAnnotations(state.GlobalEntity, map[string]string) error
SetModelAgentVersion(version.Number) error
SetModelAgentVersion(version.Number, bool) error
SetModelConstraints(constraints.Value) error
Unit(string) (Unit, error)
UpdateModelConfig(map[string]interface{}, []string, ...state.ValidateConfigFunc) error
Expand Down
2 changes: 1 addition & 1 deletion apiserver/facades/client/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,7 @@ func (c *Client) SetModelAgentVersion(args params.SetModelAgentVersion) error {
}
}

return c.api.stateAccessor.SetModelAgentVersion(args.Version)
return c.api.stateAccessor.SetModelAgentVersion(args.Version, args.IgnoreAgentVersions)
}

// AbortCurrentUpgrade aborts and archives the current upgrade
Expand Down
69 changes: 54 additions & 15 deletions apiserver/facades/client/client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ func (s *serverSuite) assertModelVersion(c *gc.C, st *state.State, expected stri
c.Assert(agentVersion, gc.Equals, expected)
}

func (s *serverSuite) TestSetEnvironAgentVersion(c *gc.C) {
func (s *serverSuite) TestSetModelAgentVersion(c *gc.C) {
args := params.SetModelAgentVersion{
Version: version.MustParse("9.8.7"),
}
Expand All @@ -234,6 +234,45 @@ func (s *serverSuite) TestSetEnvironAgentVersion(c *gc.C) {
s.assertModelVersion(c, s.State, "9.8.7")
}

func (s *serverSuite) TestSetModelAgentVersionForced(c *gc.C) {
// Get the agent-version set in the model.
cfg, err := s.State.ModelConfig()
c.Assert(err, jc.ErrorIsNil)
agentVersion, ok := cfg.AgentVersion()
c.Assert(ok, jc.IsTrue)
currentVersion := agentVersion.String()

// Add a machine with the current version and a unit with a different version
machine, err := s.State.AddMachine("series", state.JobHostUnits)
c.Assert(err, jc.ErrorIsNil)
service, err := s.State.AddApplication(state.AddApplicationArgs{Name: "wordpress", Charm: s.AddTestingCharm(c, "wordpress")})
c.Assert(err, jc.ErrorIsNil)
unit, err := service.AddUnit()
c.Assert(err, jc.ErrorIsNil)

err = machine.SetAgentVersion(version.MustParseBinary(currentVersion + "-quantal-amd64"))
c.Assert(err, jc.ErrorIsNil)
err = unit.SetAgentVersion(version.MustParseBinary("1.0.2-quantal-amd64"))
c.Assert(err, jc.ErrorIsNil)

// This should be refused because an agent doesn't match "currentVersion"
args := params.SetModelAgentVersion{
Version: version.MustParse("9.8.7"),
}
err = s.client.SetModelAgentVersion(args)
c.Check(err, gc.ErrorMatches, "some agents have not upgraded to the current model version .*: unit-wordpress-0")
// Version hasn't changed
s.assertModelVersion(c, s.State, currentVersion)
// But we can force it
args = params.SetModelAgentVersion{
Version: version.MustParse("7.8.6"),
IgnoreAgentVersions: true,
}
err = s.client.SetModelAgentVersion(args)
c.Assert(err, jc.ErrorIsNil)
s.assertModelVersion(c, s.State, "7.8.6")
}

func (s *serverSuite) makeMigratingModel(c *gc.C, name string, mode state.MigrationMode) {
otherSt := s.Factory.MakeModel(c, &factory.ModelParams{
Name: name,
Expand All @@ -246,7 +285,7 @@ func (s *serverSuite) makeMigratingModel(c *gc.C, name string, mode state.Migrat
c.Assert(err, jc.ErrorIsNil)
}

func (s *serverSuite) TestControllerModelSetEnvironAgentVersionBlockedByImportingModel(c *gc.C) {
func (s *serverSuite) TestControllerModelSetModelAgentVersionBlockedByImportingModel(c *gc.C) {
s.Factory.MakeUser(c, &factory.UserParams{Name: "some-user"})
s.makeMigratingModel(c, "to-migrate", state.MigrationModeImporting)
args := params.SetModelAgentVersion{
Expand All @@ -256,7 +295,7 @@ func (s *serverSuite) TestControllerModelSetEnvironAgentVersionBlockedByImportin
c.Assert(err, gc.ErrorMatches, `model "some-user/to-migrate" is importing, upgrade blocked`)
}

func (s *serverSuite) TestControllerModelSetEnvironAgentVersionBlockedByExportingModel(c *gc.C) {
func (s *serverSuite) TestControllerModelSetModelAgentVersionBlockedByExportingModel(c *gc.C) {
s.Factory.MakeUser(c, &factory.UserParams{Name: "some-user"})
s.makeMigratingModel(c, "to-migrate", state.MigrationModeExporting)
args := params.SetModelAgentVersion{
Expand All @@ -266,7 +305,7 @@ func (s *serverSuite) TestControllerModelSetEnvironAgentVersionBlockedByExportin
c.Assert(err, gc.ErrorMatches, `model "some-user/to-migrate" is exporting, upgrade blocked`)
}

func (s *serverSuite) TestUserModelSetEnvironAgentVersionNotAffectedByMigration(c *gc.C) {
func (s *serverSuite) TestUserModelSetModelAgentVersionNotAffectedByMigration(c *gc.C) {
s.Factory.MakeUser(c, &factory.UserParams{Name: "some-user"})
otherSt := s.Factory.MakeModel(c, nil)
defer otherSt.Close()
Expand Down Expand Up @@ -326,7 +365,7 @@ func (s *serverSuite) TestCheckProviderAPIFail(c *gc.C) {
s.assertCheckProviderAPI(c, errors.New("instances error"), "cannot make API call to provider: instances error")
}

func (s *serverSuite) assertSetEnvironAgentVersion(c *gc.C) {
func (s *serverSuite) assertSetModelAgentVersion(c *gc.C) {
args := params.SetModelAgentVersion{
Version: version.MustParse("9.8.7"),
}
Expand All @@ -339,27 +378,27 @@ func (s *serverSuite) assertSetEnvironAgentVersion(c *gc.C) {
c.Assert(agentVersion, gc.Equals, "9.8.7")
}

func (s *serverSuite) assertSetEnvironAgentVersionBlocked(c *gc.C, msg string) {
func (s *serverSuite) assertSetModelAgentVersionBlocked(c *gc.C, msg string) {
args := params.SetModelAgentVersion{
Version: version.MustParse("9.8.7"),
}
err := s.client.SetModelAgentVersion(args)
s.AssertBlocked(c, err, msg)
}

func (s *serverSuite) TestBlockDestroySetEnvironAgentVersion(c *gc.C) {
s.BlockDestroyModel(c, "TestBlockDestroySetEnvironAgentVersion")
s.assertSetEnvironAgentVersion(c)
func (s *serverSuite) TestBlockDestroySetModelAgentVersion(c *gc.C) {
s.BlockDestroyModel(c, "TestBlockDestroySetModelAgentVersion")
s.assertSetModelAgentVersion(c)
}

func (s *serverSuite) TestBlockRemoveSetEnvironAgentVersion(c *gc.C) {
s.BlockRemoveObject(c, "TestBlockRemoveSetEnvironAgentVersion")
s.assertSetEnvironAgentVersion(c)
func (s *serverSuite) TestBlockRemoveSetModelAgentVersion(c *gc.C) {
s.BlockRemoveObject(c, "TestBlockRemoveSetModelAgentVersion")
s.assertSetModelAgentVersion(c)
}

func (s *serverSuite) TestBlockChangesSetEnvironAgentVersion(c *gc.C) {
s.BlockAllChanges(c, "TestBlockChangesSetEnvironAgentVersion")
s.assertSetEnvironAgentVersionBlocked(c, "TestBlockChangesSetEnvironAgentVersion")
func (s *serverSuite) TestBlockChangesSetModelAgentVersion(c *gc.C) {
s.BlockAllChanges(c, "TestBlockChangesSetModelAgentVersion")
s.assertSetModelAgentVersionBlocked(c, "TestBlockChangesSetModelAgentVersion")
}

func (s *serverSuite) TestAbortCurrentUpgrade(c *gc.C) {
Expand Down
4 changes: 2 additions & 2 deletions apiserver/facades/client/client/perm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ func opClientSetModelAgentVersion(c *gc.C, st api.Connection, mst *state.State)
return func() {}, err
}
ver := version.Number{Major: 1, Minor: 2, Patch: 3}
err = st.Client().SetModelAgentVersion(ver)
err = st.Client().SetModelAgentVersion(ver, false)
if err != nil {
return func() {}, err
}
Expand All @@ -440,7 +440,7 @@ func opClientSetModelAgentVersion(c *gc.C, st api.Connection, mst *state.State)
oldAgentVersion, found := attrs["agent-version"]
if found {
versionString := oldAgentVersion.(string)
st.Client().SetModelAgentVersion(version.MustParse(versionString))
st.Client().SetModelAgentVersion(version.MustParse(versionString), false)
}
}, nil
}
Expand Down
2 changes: 1 addition & 1 deletion apiserver/facades/client/modelmanager/modelmanager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1001,7 +1001,7 @@ func (s *modelManagerStateSuite) TestCreateModelSameAgentVersion(c *gc.C) {
}

func (s *modelManagerStateSuite) TestCreateModelBadAgentVersion(c *gc.C) {
err := s.BackingState.SetModelAgentVersion(coretesting.FakeVersionNumber)
err := s.BackingState.SetModelAgentVersion(coretesting.FakeVersionNumber, false)
c.Assert(err, jc.ErrorIsNil)

admin := s.AdminUserTag(c)
Expand Down
3 changes: 2 additions & 1 deletion apiserver/params/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ type UnsetModelDefaults struct {
// SetModelAgentVersion contains the arguments for
// SetModelAgentVersion client API call.
type SetModelAgentVersion struct {
Version version.Number `json:"version"`
Version version.Number `json:"version"`
IgnoreAgentVersions bool `json:"force,omitempty"`
}

// ModelMigrationStatus holds information about the progress of a (possibly
Expand Down
11 changes: 9 additions & 2 deletions cmd/juju/commands/upgradejuju.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ type upgradeJujuCommand struct {
ResetPrevious bool
AssumeYes bool

// IgnoreAgentVersions is used to allow an admin to request an agent version without waiting for all agents to be at the right
// version.
IgnoreAgentVersions bool

// minMajorUpgradeVersion maps known major numbers to
// the minimum version that can be upgraded to that
// major version. For example, users must be running
Expand All @@ -102,6 +106,8 @@ func (c *upgradeJujuCommand) SetFlags(f *gnuflag.FlagSet) {
f.BoolVar(&c.ResetPrevious, "reset-previous-upgrade", false, "Clear the previous (incomplete) upgrade status (use with care)")
f.BoolVar(&c.AssumeYes, "y", false, "Answer 'yes' to confirmation prompts")
f.BoolVar(&c.AssumeYes, "yes", false, "")
f.BoolVar(&c.IgnoreAgentVersions, "ignore-agent-versions", false,
"Don't check if all agents have already reached the current version (old controllers will ignore this flag see juju-force-upgrade)")
}

func (c *upgradeJujuCommand) Init(args []string) error {
Expand Down Expand Up @@ -171,7 +177,7 @@ type upgradeJujuAPI interface {
FindTools(majorVersion, minorVersion int, series, arch string) (result params.FindToolsResult, err error)
UploadTools(r io.ReadSeeker, vers version.Binary, additionalSeries ...string) (coretools.List, error)
AbortCurrentUpgrade() error
SetModelAgentVersion(version version.Number) error
SetModelAgentVersion(version version.Number, ignoreAgentVersion bool) error
Close() error
}

Expand Down Expand Up @@ -360,7 +366,8 @@ func (c *upgradeJujuCommand) Run(ctx *cmd.Context) (err error) {
return block.ProcessBlockedError(err, block.BlockChange)
}
}
if err := client.SetModelAgentVersion(context.chosen); err != nil {
logger.Criticalf("********** SetModelAgentVersion: %s %t", context.chosen.String(), c.IgnoreAgentVersions)
if err := client.SetModelAgentVersion(context.chosen, c.IgnoreAgentVersions); err != nil {
if params.IsCodeUpgradeInProgress(err) {
return errors.Errorf("%s\n\n"+
"Please wait for the upgrade to complete or if there was a problem with\n"+
Expand Down
48 changes: 40 additions & 8 deletions cmd/juju/commands/upgradejuju_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,7 @@ func (s *UpgradeJujuSuite) TestUpgradeJujuWithImplicitUploadNewerClient(c *gc.C)
c.Assert(fakeAPI.tools, gc.Not(gc.HasLen), 0)
c.Assert(fakeAPI.tools[0].Version.Number, gc.Equals, version.MustParse("1.100.0.1"))
c.Assert(fakeAPI.modelAgentVersion, gc.Equals, fakeAPI.tools[0].Version.Number)
c.Assert(fakeAPI.ignoreAgentVersions, jc.IsFalse)
}

func (s *UpgradeJujuSuite) TestUpgradeJujuWithImplicitUploadNonController(c *gc.C) {
Expand All @@ -518,6 +519,7 @@ func (s *UpgradeJujuSuite) TestUpgradeJujuWithImplicitUploadNonController(c *gc.
cmd := newUpgradeJujuCommand(nil)
_, err := cmdtesting.RunCommand(c, cmd)
c.Assert(err, gc.ErrorMatches, "no more recent supported versions available")
c.Assert(fakeAPI.ignoreAgentVersions, jc.IsFalse)
}

func (s *UpgradeJujuSuite) TestBlockUpgradeJujuWithRealUpload(c *gc.C) {
Expand Down Expand Up @@ -548,6 +550,30 @@ func (s *UpgradeJujuSuite) TestFailUploadOnNonController(c *gc.C) {
c.Assert(err, gc.ErrorMatches, "--build-agent can only be used with the controller model")
}

func (s *UpgradeJujuSuite) TestUpgradeJujuWithIgnoreAgentVersions(c *gc.C) {
s.Reset(c)
fakeAPI := &fakeUpgradeJujuAPINoState{
name: "dummy-model",
uuid: "deadbeef-0bad-400d-8000-4b1d0d06f00d",
controllerUUID: "deadbeef-1bad-500d-9000-4b1d0d06f00d",
agentVersion: "1.99.99",
}
s.PatchValue(&getUpgradeJujuAPI, func(*upgradeJujuCommand) (upgradeJujuAPI, error) {
return fakeAPI, nil
})
s.PatchValue(&getModelConfigAPI, func(*upgradeJujuCommand) (modelConfigAPI, error) {
return fakeAPI, nil
})
s.PatchValue(&jujuversion.Current, version.MustParse("1.100.0"))
cmd := newUpgradeJujuCommand(nil)
_, err := cmdtesting.RunCommand(c, cmd, "--ignore-agent-versions")
c.Assert(err, jc.ErrorIsNil)
c.Assert(fakeAPI.tools, gc.Not(gc.HasLen), 0)
c.Assert(fakeAPI.tools[0].Version.Number, gc.Equals, version.MustParse("1.100.0.1"))
c.Assert(fakeAPI.modelAgentVersion, gc.Equals, fakeAPI.tools[0].Version.Number)
c.Assert(fakeAPI.ignoreAgentVersions, jc.IsTrue)
}

type DryRunTest struct {
about string
cmdArgs []string
Expand Down Expand Up @@ -857,6 +883,7 @@ func (s *UpgradeJujuSuite) TestResetPreviousUpgrade(c *gc.C) {
expectedVersion = fakeAPI.nextVersion.Number
}
c.Assert(fakeAPI.setVersionCalledWith, gc.Equals, expectedVersion)
c.Assert(fakeAPI.setIgnoreCalledWith, gc.Equals, false)
}

const expectUpgrade = true
Expand Down Expand Up @@ -908,6 +935,7 @@ type fakeUpgradeJujuAPI struct {
setVersionErr error
abortCurrentUpgradeCalled bool
setVersionCalledWith version.Number
setIgnoreCalledWith bool
tools []string
findToolsCalled bool
}
Expand All @@ -916,6 +944,7 @@ func (a *fakeUpgradeJujuAPI) reset() {
a.setVersionErr = nil
a.abortCurrentUpgradeCalled = false
a.setVersionCalledWith = version.Number{}
a.setIgnoreCalledWith = false
a.tools = []string{}
a.findToolsCalled = false
}
Expand Down Expand Up @@ -974,8 +1003,9 @@ func (a *fakeUpgradeJujuAPI) AbortCurrentUpgrade() error {
return nil
}

func (a *fakeUpgradeJujuAPI) SetModelAgentVersion(v version.Number) error {
func (a *fakeUpgradeJujuAPI) SetModelAgentVersion(v version.Number, ignoreAgentVersions bool) error {
a.setVersionCalledWith = v
a.setIgnoreCalledWith = ignoreAgentVersions
return a.setVersionErr
}

Expand All @@ -986,12 +1016,13 @@ func (a *fakeUpgradeJujuAPI) Close() error {
// Mock an API with no state
type fakeUpgradeJujuAPINoState struct {
upgradeJujuAPI
name string
uuid string
controllerUUID string
agentVersion string
tools coretools.List
modelAgentVersion version.Number
name string
uuid string
controllerUUID string
agentVersion string
tools coretools.List
modelAgentVersion version.Number
ignoreAgentVersions bool
}

func (a *fakeUpgradeJujuAPINoState) Close() error {
Expand All @@ -1018,8 +1049,9 @@ func (a *fakeUpgradeJujuAPINoState) UploadTools(r io.ReadSeeker, vers version.Bi
return a.tools, nil
}

func (a *fakeUpgradeJujuAPINoState) SetModelAgentVersion(version version.Number) error {
func (a *fakeUpgradeJujuAPINoState) SetModelAgentVersion(version version.Number, ignoreAgentVersions bool) error {
a.modelAgentVersion = version
a.ignoreAgentVersions = ignoreAgentVersions
return nil
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/jujud/agent/machine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ func (s *MachineSuite) testUpgradeRequest(c *gc.C, agent runner, tag string, cur
newVers.Patch++
newTools := envtesting.AssertUploadFakeToolsVersions(
c, s.DefaultToolsStorage, s.Environ.Config().AgentStream(), s.Environ.Config().AgentStream(), newVers)[0]
err := s.State.SetModelAgentVersion(newVers.Number)
err := s.State.SetModelAgentVersion(newVers.Number, true)
c.Assert(err, jc.ErrorIsNil)
err = runWithTimeout(agent)
envtesting.CheckUpgraderReadyError(c, err, &upgrader.UpgradeReadyError{
Expand Down
Loading

0 comments on commit 34c00d5

Please sign in to comment.