Skip to content

Commit

Permalink
Upgrade step and deprecating env vars.
Browse files Browse the repository at this point in the history
  • Loading branch information
anastasiamac committed Feb 27, 2015
1 parent 68b4ff9 commit 6429d09
Show file tree
Hide file tree
Showing 9 changed files with 235 additions and 14 deletions.
25 changes: 25 additions & 0 deletions environs/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,38 @@ func (envs *Environs) Config(name string) (*config.Config, error) {
// tools-stream has been renamed to agent-stream, so log warnings to the user
envs.logDeprecatedWarnings(attrs, newAttrs, config.ToolsStreamKey, config.AgentStreamKey)

// Block attributes only matter if they have been used
envs.checkBlocks(attrs)

cfg, err := config.New(config.UseDefaults, attrs)
if err != nil {
return nil, err
}
return cfg, nil
}

func (envs *Environs) checkBlocks(attrs map[string]interface{}) {
checkBlockVar := func(key string) {
if used, ok := attrs[key]; ok {
if used.(bool) {
envs.logBlockWarning(key, used)
}
}
}
checkBlockVar(config.PreventDestroyEnvironmentKey)
checkBlockVar(config.PreventRemoveObjectKey)
checkBlockVar(config.PreventAllChangesKey)
}

func (envs *Environs) logBlockWarning(key string, value interface{}) {
logger.Warningf(
"Config attribute %q (%v) is deprecated and will be ignored since \n"+
"upgrade process takes care of it. \n"+
"The attribute %q should be removed from your configuration.",
key, value, key,
)
}

// logDeprecatedWarnings constructs log warning messages for deprecated attributes names.
// It checks if both old and new attribute names are provided.
// When both are provided, the message warns to remove old attribute from configuration.
Expand Down
20 changes: 9 additions & 11 deletions environs/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ const (
SetNumaControlPolicyKey = "set-numa-control-policy"

// BlockKeyPrefix is the prefix used for environment variables that block commands
// TODO(anastasiamac 2015-02-27) remove it and all related post 1.24 as obsolete
BlockKeyPrefix = "block-"

// PreventDestroyEnvironmentKey stores the value for this setting
Expand Down Expand Up @@ -478,7 +479,7 @@ func ProcessDeprecatedAttributes(attrs map[string]interface{}) map[string]interf
}
}

//Update agent-stream from tools-stream if agent-stream was not specified but tools-stream was.
// Update agent-stream from tools-stream if agent-stream was not specified but tools-stream was.
if _, ok := attrs[AgentStreamKey]; !ok {
if toolsKey, ok := attrs[ToolsStreamKey]; ok {
processedAttrs[AgentStreamKey] = toolsKey
Expand Down Expand Up @@ -1226,15 +1227,15 @@ var alwaysOptional = schema.Defaults{
"disable-network-management": schema.Omit,
AgentStreamKey: schema.Omit,
SetNumaControlPolicyKey: DefaultNumaControlPolicy,
PreventDestroyEnvironmentKey: DefaultPreventDestroyEnvironment,
PreventRemoveObjectKey: DefaultPreventRemoveObject,
PreventAllChangesKey: DefaultPreventAllChanges,

// Deprecated fields, retain for backwards compatibility.
ToolsMetadataURLKey: "",
LxcUseClone: schema.Omit,
ProvisionerSafeModeKey: schema.Omit,
ToolsStreamKey: schema.Omit,
ToolsMetadataURLKey: "",
LxcUseClone: schema.Omit,
ProvisionerSafeModeKey: schema.Omit,
ToolsStreamKey: schema.Omit,
PreventDestroyEnvironmentKey: schema.Omit,
PreventRemoveObjectKey: schema.Omit,
PreventAllChangesKey: schema.Omit,

// For backward compatibility reasons, the following
// attributes default to empty strings rather than being
Expand Down Expand Up @@ -1292,9 +1293,6 @@ func allDefaults() schema.Defaults {
"prefer-ipv6": false,
"disable-network-management": false,
SetNumaControlPolicyKey: DefaultNumaControlPolicy,
PreventDestroyEnvironmentKey: DefaultPreventDestroyEnvironment,
PreventRemoveObjectKey: DefaultPreventRemoveObject,
PreventAllChangesKey: DefaultPreventAllChanges,
}
for attr, val := range alwaysOptional {
if _, ok := d[attr]; !ok {
Expand Down
3 changes: 0 additions & 3 deletions environs/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1345,9 +1345,6 @@ func (s *ConfigSuite) TestConfigAttrs(c *gc.C) {
attrs["lxc-clone-aufs"] = false
attrs["prefer-ipv6"] = false
attrs["set-numa-control-policy"] = false
attrs["block-destroy-environment"] = false
attrs["block-remove-object"] = false
attrs["block-all-changes"] = false

// Default firewall mode is instance
attrs["firewall-mode"] = string(config.FwInstance)
Expand Down
10 changes: 10 additions & 0 deletions environs/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -504,3 +504,13 @@ func (s *ConfigDeprecationSuite) TestDeprecatedToolsStreamWIthAgentWarning(c *gc
expected := fmt.Sprintf(standardDeprecationWarningWithNew)
s.checkDeprecationWarning(c, attrs, expected)
}

func (s *ConfigDeprecationSuite) TestDeprecatedBlockWarning(c *gc.C) {
assertBlockWarning := func(tst string) {
attrs := testing.Attrs{tst: true}
s.checkDeprecationWarning(c, attrs, ".*is deprecated and will be ignored since.*")
}
assertBlockWarning("block-destroy-environment")
assertBlockWarning("block-remove-object")
assertBlockWarning("block-all-changes")
}
95 changes: 95 additions & 0 deletions upgrades/block.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Copyright 2015 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package upgrades

import (
"github.com/juju/errors"

"github.com/juju/juju/api/block"
"github.com/juju/juju/environs/config"
"github.com/juju/juju/state"
"reflect"
)

func moveBlocksFromEnvironToState(context Context) error {
logger.Infof("recording existing blocks")
st := context.State()
if st == nil {
logger.Debugf("no state connection, no block recording required")
// We're running on a different node than the state server.
return nil
}
blocks, err := getCurrentBlocks(st)

if err != nil {
return errors.Trace(err)
}
err = recordCurrentBlocks(context, blocks)
if err != nil {
return errors.Trace(err)
}
err = removeBlockEnvVar(st)
if err != nil {
return errors.Trace(err)
}
return nil
}

func recordCurrentBlocks(context Context, blocks []string) error {
if len(blocks) == 0 {
// no existing blocks = nothing to do here :)
return nil
}
blockClient := block.NewClient(context.APIState())
for _, one := range blocks {
err := blockClient.SwitchBlockOn(one, "")
if !reflect.ValueOf(err).IsNil() {
return errors.Annotatef(err, "switching on %v", one)
}
}
return nil
}

func getCurrentBlocks(st *state.State) ([]string, error) {
cfg, err := getEnvironConfig(st)
if err != nil {
return nil, errors.Trace(err)
}
return getBlocks(cfg), nil
}

func getEnvironConfig(st *state.State) (*config.Config, error) {
envConfig, err := st.EnvironConfig()
if err != nil {
return nil, errors.Annotatef(err, "reading current config")
}
return envConfig, nil
}

func getBlocks(cfg *config.Config) []string {
var blocks []string
addBlock := func(aType string) {
blocks = append(blocks, aType)
}

if cfg.PreventAllChanges() {
addBlock(state.ChangeBlock.String())
}
if cfg.PreventRemoveObject() {
addBlock(state.RemoveBlock.String())
}
if cfg.PreventDestroyEnvironment() {
addBlock(state.DestroyBlock.String())
}
return blocks
}

func removeBlockEnvVar(st *state.State) error {
removeAttrs := []string{
config.PreventAllChangesKey,
config.PreventDestroyEnvironmentKey,
config.PreventRemoveObjectKey,
}
return st.UpdateEnvironConfig(map[string]interface{}{}, removeAttrs, nil)
}
89 changes: 89 additions & 0 deletions upgrades/block_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Copyright 2015 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package upgrades_test

import (
jc "github.com/juju/testing/checkers"
gc "gopkg.in/check.v1"

"github.com/juju/juju/api"
"github.com/juju/juju/api/block"
"github.com/juju/juju/juju"
jujutesting "github.com/juju/juju/juju/testing"
"github.com/juju/juju/state"
"github.com/juju/juju/upgrades"
)

type blockSuite struct {
jujutesting.JujuConnSuite
ctx upgrades.Context
blockClient *block.Client
}

var _ = gc.Suite(&blockSuite{})

func (s *blockSuite) SetUpTest(c *gc.C) {
s.JujuConnSuite.SetUpTest(c)
// apiState, _ := s.OpenAPIAsNewMachine(c, state.JobManageEnviron)

conn, err := juju.NewAPIState(s.AdminUserTag(c), s.Environ, api.DialOpts{})
c.Assert(err, jc.ErrorIsNil)
s.AddCleanup(func(*gc.C) { conn.Close() })

s.ctx = &mockContext{
agentConfig: &mockAgentConfig{dataDir: s.DataDir()},
apiState: conn,
state: s.State,
}
s.blockClient = block.NewClient(conn)
}

func (s *blockSuite) TestRecordBlocksNone(c *gc.C) {
err := upgrades.MoveBlocksFromEnvironToState(s.ctx)
c.Assert(err, jc.ErrorIsNil)
s.ensureBlocksRecorded(c, nil)
s.ensureEnvBlocksOff(c)
}

func (s *blockSuite) ensureEnvBlocksOff(c *gc.C) {
cfg, err := s.State.EnvironConfig()
c.Assert(err, jc.ErrorIsNil)
attrs := cfg.AllAttrs()
_, exists := attrs["block-destroy-environment"]
c.Assert(exists, jc.IsFalse)
_, exists = attrs["block-remove-object"]
c.Assert(exists, jc.IsFalse)
_, exists = attrs["block-all-changes"]
c.Assert(exists, jc.IsFalse)
}

func (s *blockSuite) ensureBlocksRecorded(c *gc.C, expected []string) {
blocks, err := s.blockClient.List()
c.Assert(err, jc.ErrorIsNil)

var types []string
for _, ablock := range blocks {
types = append(types, ablock.Type)
}
c.Assert(types, jc.SameContents, expected)
}

func (s *blockSuite) TestUpgradeBlocks(c *gc.C) {
err := s.State.UpdateEnvironConfig(map[string]interface{}{
"block-destroy-environment": true,
"block-remove-object": true,
"block-all-changes": true,
}, nil, nil)
c.Assert(err, jc.ErrorIsNil)

err = upgrades.MoveBlocksFromEnvironToState(s.ctx)

c.Assert(err, jc.ErrorIsNil)
s.ensureBlocksRecorded(c, []string{
state.ChangeBlock.String(),
state.DestroyBlock.String(),
state.RemoveBlock.String(),
})
s.ensureEnvBlocksOff(c)
}
1 change: 1 addition & 0 deletions upgrades/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,5 @@ var (
// 123 upgrade functions
AddEnvironmentUUIDToAgentConfig = addEnvironmentUUIDToAgentConfig
AddDefaultStoragePools = addDefaultStoragePools
MoveBlocksFromEnvironToState = moveBlocksFromEnvironToState
)
5 changes: 5 additions & 0 deletions upgrades/steps123.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,10 @@ func stepsFor123() []Step {
targets: []Target{AllMachines},
run: addEnvironmentUUIDToAgentConfig,
},
&upgradeStep{
description: "move blocks from environment to state",
targets: []Target{DatabaseMaster},
run: moveBlocksFromEnvironToState,
},
}
}
1 change: 1 addition & 0 deletions upgrades/steps123_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func (s *steps123Suite) TestStateStepsFor123(c *gc.C) {
func (s *steps123Suite) TestStepsFor123(c *gc.C) {
expected := []string{
"add environment UUID to agent config",
"move blocks from environment to state",
}
assertSteps(c, version.MustParse("1.23.0"), expected)
}

0 comments on commit 6429d09

Please sign in to comment.