github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/provider/rackspace/environ.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package rackspace
     5  
     6  import (
     7  	"io/ioutil"
     8  	"os"
     9  	"time"
    10  
    11  	"github.com/juju/errors"
    12  	jujuos "github.com/juju/os"
    13  	"github.com/juju/os/series"
    14  	"github.com/juju/utils/ssh"
    15  
    16  	"github.com/juju/juju/environs"
    17  	"github.com/juju/juju/environs/config"
    18  	"github.com/juju/juju/environs/context"
    19  	"github.com/juju/juju/provider/common"
    20  )
    21  
    22  type environ struct {
    23  	environs.Environ
    24  }
    25  
    26  var bootstrap = common.Bootstrap
    27  
    28  // Bootstrap implements environs.Environ.
    29  func (e environ) Bootstrap(ctx environs.BootstrapContext, callCtx context.ProviderCallContext, params environs.BootstrapParams) (*environs.BootstrapResult, error) {
    30  	// can't redirect to openstack provider as usually, because correct environ should be passed for common.Bootstrap
    31  	return bootstrap(ctx, e, callCtx, params)
    32  }
    33  
    34  var waitSSH = common.WaitSSH
    35  
    36  // StartInstance implements environs.Environ.
    37  func (e environ) StartInstance(ctx context.ProviderCallContext, args environs.StartInstanceParams) (*environs.StartInstanceResult, error) {
    38  	osString, err := series.GetOSFromSeries(args.Tools.OneSeries())
    39  	if err != nil {
    40  		return nil, errors.Trace(err)
    41  	}
    42  	fwmode := e.Config().FirewallMode()
    43  	if osString == jujuos.Windows && fwmode != config.FwNone {
    44  		return nil, errors.Errorf("rackspace provider doesn't support firewalls for windows instances")
    45  
    46  	}
    47  	r, err := e.Environ.StartInstance(ctx, args)
    48  	if err != nil {
    49  		return nil, errors.Trace(err)
    50  	}
    51  	if fwmode != config.FwNone {
    52  		interrupted := make(chan os.Signal, 1)
    53  		timeout := environs.BootstrapDialOpts{
    54  			Timeout:        time.Minute * 5,
    55  			RetryDelay:     time.Second * 5,
    56  			AddressesDelay: time.Second * 20,
    57  		}
    58  		addr, err := waitSSH(
    59  			ioutil.Discard,
    60  			interrupted,
    61  			ssh.DefaultClient,
    62  			common.GetCheckNonceCommand(args.InstanceConfig),
    63  			&common.RefreshableInstance{r.Instance, e},
    64  			ctx,
    65  			timeout,
    66  			common.DefaultHostSSHOptions,
    67  		)
    68  		if err != nil {
    69  			return nil, errors.Trace(err)
    70  		}
    71  		client := newInstanceConfigurator(addr)
    72  		apiPort := 0
    73  		if args.InstanceConfig.Controller != nil {
    74  			apiPort = args.InstanceConfig.Controller.Config.APIPort()
    75  		}
    76  		err = client.DropAllPorts([]int{apiPort, 22}, addr)
    77  		if err != nil {
    78  			common.HandleCredentialError(IsAuthorisationFailure, err, ctx)
    79  			return nil, errors.Trace(err)
    80  		}
    81  	}
    82  	return r, nil
    83  }
    84  
    85  var newInstanceConfigurator = common.NewSshInstanceConfigurator
    86  
    87  // Provider implements environs.Environ.
    88  func (e environ) Provider() environs.EnvironProvider {
    89  	return providerInstance
    90  }