github.com/emate/packer@v0.8.1-0.20150625195101-fe0fde195dc6/builder/openstack/step_key_pair.go (about)

     1  package openstack
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"runtime"
     7  
     8  	"github.com/mitchellh/multistep"
     9  	"github.com/mitchellh/packer/common/uuid"
    10  	"github.com/mitchellh/packer/packer"
    11  	"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs"
    12  )
    13  
    14  type StepKeyPair struct {
    15  	Debug        bool
    16  	DebugKeyPath string
    17  	keyName      string
    18  }
    19  
    20  func (s *StepKeyPair) Run(state multistep.StateBag) multistep.StepAction {
    21  	config := state.Get("config").(Config)
    22  	ui := state.Get("ui").(packer.Ui)
    23  
    24  	// We need the v2 compute client
    25  	computeClient, err := config.computeV2Client()
    26  	if err != nil {
    27  		err = fmt.Errorf("Error initializing compute client: %s", err)
    28  		state.Put("error", err)
    29  		return multistep.ActionHalt
    30  	}
    31  
    32  	ui.Say("Creating temporary keypair for this instance...")
    33  	keyName := fmt.Sprintf("packer %s", uuid.TimeOrderedUUID())
    34  	keypair, err := keypairs.Create(computeClient, keypairs.CreateOpts{
    35  		Name: keyName,
    36  	}).Extract()
    37  	if err != nil {
    38  		state.Put("error", fmt.Errorf("Error creating temporary keypair: %s", err))
    39  		return multistep.ActionHalt
    40  	}
    41  
    42  	if keypair.PrivateKey == "" {
    43  		state.Put("error", fmt.Errorf("The temporary keypair returned was blank"))
    44  		return multistep.ActionHalt
    45  	}
    46  
    47  	// If we're in debug mode, output the private key to the working
    48  	// directory.
    49  	if s.Debug {
    50  		ui.Message(fmt.Sprintf("Saving key for debug purposes: %s", s.DebugKeyPath))
    51  		f, err := os.Create(s.DebugKeyPath)
    52  		if err != nil {
    53  			state.Put("error", fmt.Errorf("Error saving debug key: %s", err))
    54  			return multistep.ActionHalt
    55  		}
    56  		defer f.Close()
    57  
    58  		// Write the key out
    59  		if _, err := f.Write([]byte(keypair.PrivateKey)); err != nil {
    60  			state.Put("error", fmt.Errorf("Error saving debug key: %s", err))
    61  			return multistep.ActionHalt
    62  		}
    63  
    64  		// Chmod it so that it is SSH ready
    65  		if runtime.GOOS != "windows" {
    66  			if err := f.Chmod(0600); err != nil {
    67  				state.Put("error", fmt.Errorf("Error setting permissions of debug key: %s", err))
    68  				return multistep.ActionHalt
    69  			}
    70  		}
    71  	}
    72  
    73  	// Set the keyname so we know to delete it later
    74  	s.keyName = keyName
    75  
    76  	// Set some state data for use in future steps
    77  	state.Put("keyPair", keyName)
    78  	state.Put("privateKey", keypair.PrivateKey)
    79  
    80  	return multistep.ActionContinue
    81  }
    82  
    83  func (s *StepKeyPair) Cleanup(state multistep.StateBag) {
    84  	// If no key name is set, then we never created it, so just return
    85  	if s.keyName == "" {
    86  		return
    87  	}
    88  
    89  	config := state.Get("config").(Config)
    90  	ui := state.Get("ui").(packer.Ui)
    91  
    92  	// We need the v2 compute client
    93  	computeClient, err := config.computeV2Client()
    94  	if err != nil {
    95  		ui.Error(fmt.Sprintf(
    96  			"Error cleaning up keypair. Please delete the key manually: %s", s.keyName))
    97  		return
    98  	}
    99  
   100  	ui.Say("Deleting temporary keypair...")
   101  	err = keypairs.Delete(computeClient, s.keyName).ExtractErr()
   102  	if err != nil {
   103  		ui.Error(fmt.Sprintf(
   104  			"Error cleaning up keypair. Please delete the key manually: %s", s.keyName))
   105  	}
   106  }