Skip to content

Commit

Permalink
Merge pull request juju#3952 from axw/upgrade-distro-info-master
Browse files Browse the repository at this point in the history
upgrades: update distro-info before upgrade

When upgrading a controller, run "apt-get update"
and then upgrade distro-info. This ensures that
the controller is aware of any new series that
may be supported by the upgraded version of Juju.

(Review request: http://reviews.vapour.ws/r/3376/)
  • Loading branch information
jujubot committed Dec 16, 2015
2 parents 2f43c1e + 6a3e5fc commit 8a29637
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 7 deletions.
2 changes: 1 addition & 1 deletion dependencies.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ github.com/juju/schema git afe1151cb49d1d7ed3c75592dfc6f38703f2e988 2015-08-07T0
github.com/juju/syslog git 6be94e8b718766e9ff7a37342157fe4795da7cfa 2015-02-05T15:59:36Z
github.com/juju/testing git 3a4202497a8bff67966ecb327a0505fea8bb6ead 2015-11-23T15:50:06Z
github.com/juju/txn git 99ec629d0066a4d73c54d8e021a7fc1dc07df614 2015-06-09T16:58:27Z
github.com/juju/utils git 3d0905454f10e9da0eb5d2b4e4c2242c05de30d6 2015-12-08T02:44:23Z
github.com/juju/utils git 7a81685981edd1e510a64157df96026782cd4b04 2015-12-11T00:56:23Z
github.com/juju/xml git eb759a627588d35166bc505fceb51b88500e291e 2015-04-13T13:11:21Z
github.com/julienschmidt/httprouter git 109e267447e95ad1bb48b758e40dd7453eb7b039 2015-09-05T17:25:33Z
github.com/lxc/lxd git 42b4c228e84cba622f221e04a1fa7164a416a440 2015-10-27T22:33:42Z
Expand Down
8 changes: 8 additions & 0 deletions featuretests/upgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/juju/names"
jc "github.com/juju/testing/checkers"
"github.com/juju/utils/arch"
pacman "github.com/juju/utils/packaging/manager"
"github.com/juju/utils/series"
gc "gopkg.in/check.v1"

Expand Down Expand Up @@ -67,6 +68,13 @@ func (s *upgradeSuite) SetUpTest(c *gc.C) {
// Ensure we don't fail disk space check.
s.PatchValue(&upgrades.MinDiskSpaceMib, uint64(0))

// Consume apt-get commands that get run before upgrades.
aptCmds := s.AgentSuite.HookCommandOutput(&pacman.CommandOutput, nil, nil)
go func() {
for _ = range aptCmds {
}
}()

// TODO(mjs) - the following should maybe be part of AgentSuite.SetUpTest()
s.PatchValue(&cmdutil.EnsureMongoServer, func(mongo.EnsureServerParams) error {
return nil
Expand Down
24 changes: 23 additions & 1 deletion upgrades/preupgradesteps.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,28 @@ import (
"github.com/dustin/go-humanize"
"github.com/juju/errors"
"github.com/juju/utils/du"
"github.com/juju/utils/packaging/manager"
"github.com/juju/utils/series"

"github.com/juju/juju/agent"
"github.com/juju/juju/state"
)

// PreUpgradeSteps runs various checks and prepares for performing an upgrade.
// If any check fails, an error is returned which aborts the upgrade.
func PreUpgradeSteps(st *state.State, agentConf agent.Config, isMaster bool) error {
func PreUpgradeSteps(st *state.State, agentConf agent.Config, isStateServer, isMaster bool) error {
if err := checkDiskSpace(agentConf.DataDir()); err != nil {
return err
}
if isStateServer {
// Update distro info in case the new Juju controller version
// is aware of new supported series. We'll keep going if this
// fails, and the user can manually update it if they need to.
logger.Infof("updating distro-info")
if err := updateDistroInfo(); err != nil {
logger.Warningf("failed to update distro-info: %v", err)
}
}
return nil
}

Expand All @@ -33,3 +44,14 @@ func checkDiskSpace(dir string) error {
}
return nil
}

func updateDistroInfo() error {
pm := manager.NewAptPackageManager()
if err := pm.Update(); err != nil {
return errors.Annotate(err, "updating package list")
}
if err := pm.Install("distro-info"); err != nil {
return errors.Annotate(err, "updating distro-info package")
}
return series.UpdateSeriesVersions()
}
40 changes: 39 additions & 1 deletion upgrades/preupgradesteps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
package upgrades_test

import (
"os/exec"

"github.com/dustin/go-humanize"
jc "github.com/juju/testing/checkers"
pkgmgr "github.com/juju/utils/packaging/manager"
gc "gopkg.in/check.v1"

"github.com/juju/juju/testing"
Expand All @@ -20,6 +24,40 @@ var _ = gc.Suite(&preupgradechecksSuite{})
func (s *preupgradechecksSuite) TestCheckFreeDiskSpace(c *gc.C) {
// Expect an impossibly large amount of free disk.
s.PatchValue(&upgrades.MinDiskSpaceMib, uint64(humanize.PiByte/humanize.MiByte))
err := upgrades.PreUpgradeSteps(nil, &mockAgentConfig{dataDir: "/"}, false)
err := upgrades.PreUpgradeSteps(nil, &mockAgentConfig{dataDir: "/"}, false, false)
c.Assert(err, gc.ErrorMatches, "not enough free disk space for upgrade: .*")
}

func (s *preupgradechecksSuite) TestUpdateDistroInfo(c *gc.C) {
s.PatchValue(&upgrades.MinDiskSpaceMib, uint64(0))
expectedAptCommandArgs := [][]string{
{"update"},
{"install", "distro-info"},
}

commandChan := s.HookCommandOutput(&pkgmgr.CommandOutput, nil, nil)
err := upgrades.PreUpgradeSteps(nil, &mockAgentConfig{dataDir: "/"}, true, false)
c.Assert(err, jc.ErrorIsNil)

var commands []*exec.Cmd
for i := 0; i < cap(expectedAptCommandArgs)+1; i++ {
select {
case cmd := <-commandChan:
commands = append(commands, cmd)
default:
break
}
}
if len(commands) != len(expectedAptCommandArgs) {
c.Fatalf("expected %d commands, got %d", len(expectedAptCommandArgs), len(commands))
}

assertAptCommand := func(cmd *exec.Cmd, tailArgs ...string) {
args := cmd.Args
c.Assert(len(args), jc.GreaterThan, len(tailArgs))
c.Assert(args[0], gc.Equals, "apt-get")
c.Assert(args[len(args)-len(tailArgs):], gc.DeepEquals, tailArgs)
}
assertAptCommand(commands[0], "update")
assertAptCommand(commands[1], "install", "distro-info")
}
6 changes: 3 additions & 3 deletions worker/upgradesteps/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func NewWorker(
apiConn api.Connection,
jobs []multiwatcher.MachineJob,
openState func() (*state.State, func(), error),
preUpgradeSteps func(st *state.State, agentConf agent.Config, isMasterServer bool) error,
preUpgradeSteps func(st *state.State, agentConf agent.Config, isStateServer, isMasterServer bool) error,
machine StatusSetter,
) (worker.Worker, error) {
tag, ok := agent.CurrentConfig().Tag().(names.MachineTag)
Expand Down Expand Up @@ -128,7 +128,7 @@ type upgradesteps struct {
apiConn api.Connection
jobs []multiwatcher.MachineJob
openState func() (*state.State, func(), error)
preUpgradeSteps func(st *state.State, agentConf agent.Config, isMaster bool) error
preUpgradeSteps func(st *state.State, agentConf agent.Config, isStateServer, isMaster bool) error
machine StatusSetter

fromVersion version.Number
Expand Down Expand Up @@ -254,7 +254,7 @@ func (w *upgradesteps) runUpgrades() error {

func (w *upgradesteps) prepareForUpgrade() (*state.UpgradeInfo, error) {
logger.Infof("checking that upgrade can proceed")
if err := w.preUpgradeSteps(w.st, w.agent.CurrentConfig(), w.isMaster); err != nil {
if err := w.preUpgradeSteps(w.st, w.agent.CurrentConfig(), w.st != nil, w.isMaster); err != nil {
return nil, errors.Annotatef(err, "%s cannot be upgraded", names.ReadableString(w.tag))
}

Expand Down
2 changes: 1 addition & 1 deletion worker/upgradesteps/worker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ func (s *UpgradeSuite) openStateForUpgrade() (*state.State, func(), error) {
return st, func() { st.Close() }, nil
}

func (s *UpgradeSuite) preUpgradeSteps(st *state.State, agentConf agent.Config, isStateServer bool) error {
func (s *UpgradeSuite) preUpgradeSteps(st *state.State, agentConf agent.Config, isStateServer, isMasterStateServer bool) error {
if s.preUpgradeError {
return errors.New("preupgrade error")
}
Expand Down

0 comments on commit 8a29637

Please sign in to comment.