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  }