github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/provider/cloudsigma/environ.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package cloudsigma 5 6 import ( 7 "sync" 8 9 "github.com/altoros/gosigma" 10 "github.com/juju/errors" 11 "github.com/juju/utils/arch" 12 13 "github.com/juju/juju/constraints" 14 "github.com/juju/juju/environs" 15 "github.com/juju/juju/environs/config" 16 "github.com/juju/juju/environs/simplestreams" 17 "github.com/juju/juju/instance" 18 "github.com/juju/juju/provider/common" 19 ) 20 21 const ( 22 CloudsigmaCloudImagesURLTemplate = "https://%v.cloudsigma.com/" 23 ) 24 25 // This file contains the core of the Environ implementation. 26 type environ struct { 27 common.SupportsUnitPlacementPolicy 28 name string 29 30 lock sync.Mutex 31 archMutex sync.Mutex 32 33 ecfg *environConfig 34 client *environClient 35 supportedArchitectures []string 36 } 37 38 // Name returns the Environ's name. 39 func (env *environ) Name() string { 40 return env.name 41 } 42 43 // Provider returns the EnvironProvider that created this Environ. 44 func (*environ) Provider() environs.EnvironProvider { 45 return providerInstance 46 } 47 48 // SetConfig updates the Environ's configuration. 49 // 50 // Calls to SetConfig do not affect the configuration of values previously obtained 51 // from Storage. 52 func (env *environ) SetConfig(cfg *config.Config) error { 53 env.lock.Lock() 54 defer env.lock.Unlock() 55 56 ecfg, err := validateConfig(cfg, env.ecfg) 57 if err != nil { 58 return errors.Trace(err) 59 } 60 61 if env.client == nil || env.ecfg == nil || env.ecfg.clientConfigChanged(ecfg) { 62 client, err := newClient(ecfg) 63 if err != nil { 64 return errors.Trace(err) 65 } 66 67 env.client = client 68 } 69 70 env.ecfg = ecfg 71 72 return nil 73 } 74 75 // Config returns the configuration data with which the Environ was created. 76 // Note that this is not necessarily current; the canonical location 77 // for the configuration data is stored in the state. 78 func (env *environ) Config() *config.Config { 79 return env.ecfg.Config 80 } 81 82 // Bootstrap initializes the state for the environment, possibly 83 // starting one or more instances. If the configuration's 84 // AdminSecret is non-empty, the administrator password on the 85 // newly bootstrapped state will be set to a hash of it (see 86 // utils.PasswordHash), When first connecting to the 87 // environment via the juju package, the password hash will be 88 // automatically replaced by the real password. 89 // 90 // The supplied constraints are used to choose the initial instance 91 // specification, and will be stored in the new environment's state. 92 // 93 // Bootstrap is responsible for selecting the appropriate tools, 94 // and setting the agent-version configuration attribute prior to 95 // bootstrapping the environment. 96 func (env *environ) Bootstrap(ctx environs.BootstrapContext, params environs.BootstrapParams) (*environs.BootstrapResult, error) { 97 return common.Bootstrap(ctx, env, params) 98 } 99 100 func (e *environ) ControllerInstances() ([]instance.Id, error) { 101 return e.client.getControllerIds() 102 } 103 104 // Destroy shuts down all known machines and destroys the 105 // rest of the environment. Note that on some providers, 106 // very recently started instances may not be destroyed 107 // because they are not yet visible. 108 // 109 // When Destroy has been called, any Environ referring to the 110 // same remote environment may become invalid 111 func (env *environ) Destroy() error { 112 // You can probably ignore this method; the common implementation should work. 113 return common.Destroy(env) 114 } 115 116 // PrecheckInstance performs a preflight check on the specified 117 // series and constraints, ensuring that they are possibly valid for 118 // creating an instance in this environment. 119 // 120 // PrecheckInstance is best effort, and not guaranteed to eliminate 121 // all invalid parameters. If PrecheckInstance returns nil, it is not 122 // guaranteed that the constraints are valid; if a non-nil error is 123 // returned, then the constraints are definitely invalid. 124 func (env *environ) PrecheckInstance(series string, cons constraints.Value, placement string) error { 125 return nil 126 } 127 128 // Region is specified in the HasRegion interface. 129 func (env *environ) Region() (simplestreams.CloudSpec, error) { 130 env.lock.Lock() 131 defer env.lock.Unlock() 132 return simplestreams.CloudSpec{ 133 Region: env.ecfg.region(), 134 Endpoint: env.ecfg.endpoint(), 135 }, nil 136 } 137 138 func (env *environ) MetadataLookupParams(region string) (*simplestreams.MetadataLookupParams, error) { 139 if region == "" { 140 region = gosigma.DefaultRegion 141 } 142 env.lock.Lock() 143 defer env.lock.Unlock() 144 return &simplestreams.MetadataLookupParams{ 145 Region: region, 146 Endpoint: gosigma.ResolveEndpoint(region), 147 Architectures: arch.AllSupportedArches, 148 Series: config.PreferredSeries(env.ecfg), 149 }, nil 150 }