Skip to content

Commit

Permalink
Expose 'juju upgrade-juju --force'
Browse files Browse the repository at this point in the history
Rename 'force-upgrade' to 'juju-force-upgrade'.
Expose a new value in the API that allows us to pass Force
through to the state code.
  • Loading branch information
jameinel committed Oct 24, 2017
1 parent c8cfee0 commit 45af426
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 22 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, force bool) error {
args := params.SetModelAgentVersion{Version: version, Force: force}
return c.facade.FacadeCall("SetModelAgentVersion", args, nil)
}

Expand Down
2 changes: 1 addition & 1 deletion apiserver/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,7 @@ func (c *Client) SetModelAgentVersion(args params.SetModelAgentVersion) error {
}
}

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

// AbortCurrentUpgrade aborts and archives the current upgrade
Expand Down
69 changes: 54 additions & 15 deletions apiserver/client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,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 @@ -226,6 +226,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"),
Force: 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 @@ -238,7 +277,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 @@ -248,7 +287,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 @@ -258,7 +297,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 @@ -318,7 +357,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 @@ -331,27 +370,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/client/perm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,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 @@ -433,7 +433,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
1 change: 1 addition & 0 deletions apiserver/params/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ type UnsetModelDefaults struct {
// SetModelAgentVersion client API call.
type SetModelAgentVersion struct {
Version version.Number `json:"version"`
Force bool `json:"force,omitempty"`
}

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

// Force is used to allow an admin to request an agent version without waiting for all agents to be at the right
// version.
Force 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 @@ -101,6 +105,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.Force, "force", 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
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright 2017 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package main

import (
Expand All @@ -18,7 +21,7 @@ import (
jversion "github.com/juju/juju/version"
)

var logger = loggo.GetLogger("forceagentversion")
var logger = loggo.GetLogger("juju.forceupgrade")

func checkErr(label string, err error) {
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion state/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3711,7 +3711,7 @@ func (s *StateSuite) TestSetModelAgentVersionExcessiveContention(c *gc.C) {
assertAgentVersion(c, s.State, currentVersion)
}

func (s *StateSuite) TestSetModelAgentVerisonMixedVersions(c *gc.C) {
func (s *StateSuite) TestSetModelAgentVersionMixedVersions(c *gc.C) {
_, currentVersion := s.prepareAgentVersionTests(c, s.State)
machine, err := s.State.Machine("0")
c.Assert(err, jc.ErrorIsNil)
Expand Down

0 comments on commit 45af426

Please sign in to comment.