github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/upgrades/environconfig.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package upgrades 5 6 import ( 7 "github.com/juju/errors" 8 9 "github.com/juju/juju/environs" 10 "github.com/juju/juju/environs/config" 11 "github.com/juju/juju/state" 12 ) 13 14 // environConfigUpdater is an interface used atomically write environment 15 // config changes to the global state. 16 type environConfigUpdater interface { 17 // UpdateModelConfig atomically updates and removes environment 18 // config attributes to the global state. 19 UpdateModelConfig(map[string]interface{}, []string, state.ValidateConfigFunc) error 20 } 21 22 // environConfigReader is an interface used to read the current environment 23 // config from global state. 24 type environConfigReader interface { 25 // ModelConfig reads the current environment config from global 26 // state. 27 ModelConfig() (*config.Config, error) 28 } 29 30 func upgradeModelConfig( 31 reader environConfigReader, 32 updater environConfigUpdater, 33 registry environs.ProviderRegistry, 34 ) error { 35 cfg, err := reader.ModelConfig() 36 if err != nil { 37 return errors.Annotate(err, "reading model config") 38 } 39 provider, err := registry.Provider(cfg.Type()) 40 if err != nil { 41 return errors.Annotate(err, "getting provider") 42 } 43 44 upgrader, ok := provider.(environs.ModelConfigUpgrader) 45 if !ok { 46 logger.Debugf("provider %q has no upgrades", cfg.Type()) 47 return nil 48 } 49 newCfg, err := upgrader.UpgradeConfig(cfg) 50 if err != nil { 51 return errors.Annotate(err, "upgrading config") 52 } 53 54 newAttrs := newCfg.AllAttrs() 55 var removedAttrs []string 56 for key := range cfg.AllAttrs() { 57 if _, ok := newAttrs[key]; !ok { 58 removedAttrs = append(removedAttrs, key) 59 } 60 } 61 if err := updater.UpdateModelConfig(newAttrs, removedAttrs, nil); err != nil { 62 return errors.Annotate(err, "updating config in state") 63 } 64 return nil 65 }