github.com/mmcquillan/packer@v1.1.1-0.20171009221028-c85cf0483a5d/builder/alicloud/ecs/step_config_key_pair.go (about)

     1  package ecs
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"runtime"
     8  
     9  	"github.com/denverdino/aliyungo/common"
    10  	"github.com/denverdino/aliyungo/ecs"
    11  	"github.com/hashicorp/packer/packer"
    12  	"github.com/mitchellh/multistep"
    13  )
    14  
    15  type StepConfigAlicloudKeyPair struct {
    16  	Debug                bool
    17  	SSHAgentAuth         bool
    18  	DebugKeyPath         string
    19  	TemporaryKeyPairName string
    20  	KeyPairName          string
    21  	PrivateKeyFile       string
    22  	RegionId             string
    23  
    24  	keyName string
    25  }
    26  
    27  func (s *StepConfigAlicloudKeyPair) Run(state multistep.StateBag) multistep.StepAction {
    28  	ui := state.Get("ui").(packer.Ui)
    29  
    30  	if s.PrivateKeyFile != "" {
    31  		ui.Say("Using existing SSH private key")
    32  		privateKeyBytes, err := ioutil.ReadFile(s.PrivateKeyFile)
    33  		if err != nil {
    34  			state.Put("error", fmt.Errorf(
    35  				"Error loading configured private key file: %s", err))
    36  			return multistep.ActionHalt
    37  		}
    38  
    39  		state.Put("keyPair", s.KeyPairName)
    40  		state.Put("privateKey", string(privateKeyBytes))
    41  
    42  		return multistep.ActionContinue
    43  	}
    44  
    45  	if s.SSHAgentAuth && s.KeyPairName == "" {
    46  		ui.Say("Using SSH Agent with key pair in source image")
    47  		return multistep.ActionContinue
    48  	}
    49  
    50  	if s.SSHAgentAuth && s.KeyPairName != "" {
    51  		ui.Say(fmt.Sprintf("Using SSH Agent for existing key pair %s", s.KeyPairName))
    52  		state.Put("keyPair", s.KeyPairName)
    53  		return multistep.ActionContinue
    54  	}
    55  
    56  	if s.TemporaryKeyPairName == "" {
    57  		ui.Say("Not using temporary keypair")
    58  		state.Put("keyPair", "")
    59  		return multistep.ActionContinue
    60  	}
    61  
    62  	client := state.Get("client").(*ecs.Client)
    63  
    64  	ui.Say(fmt.Sprintf("Creating temporary keypair: %s", s.TemporaryKeyPairName))
    65  	keyResp, err := client.CreateKeyPair(&ecs.CreateKeyPairArgs{
    66  		KeyPairName: s.TemporaryKeyPairName,
    67  		RegionId:    common.Region(s.RegionId),
    68  	})
    69  	if err != nil {
    70  		state.Put("error", fmt.Errorf("Error creating temporary keypair: %s", err))
    71  		return multistep.ActionHalt
    72  	}
    73  
    74  	// Set the keyname so we know to delete it later
    75  	s.keyName = s.TemporaryKeyPairName
    76  
    77  	// Set some state data for use in future steps
    78  	state.Put("keyPair", s.keyName)
    79  	state.Put("privateKey", keyResp.PrivateKeyBody)
    80  
    81  	// If we're in debug mode, output the private key to the working
    82  	// directory.
    83  	if s.Debug {
    84  		ui.Message(fmt.Sprintf("Saving key for debug purposes: %s", s.DebugKeyPath))
    85  		f, err := os.Create(s.DebugKeyPath)
    86  		if err != nil {
    87  			state.Put("error", fmt.Errorf("Error saving debug key: %s", err))
    88  			return multistep.ActionHalt
    89  		}
    90  		defer f.Close()
    91  
    92  		// Write the key out
    93  		if _, err := f.Write([]byte(keyResp.PrivateKeyBody)); err != nil {
    94  			state.Put("error", fmt.Errorf("Error saving debug key: %s", err))
    95  			return multistep.ActionHalt
    96  		}
    97  
    98  		// Chmod it so that it is SSH ready
    99  		if runtime.GOOS != "windows" {
   100  			if err := f.Chmod(0600); err != nil {
   101  				state.Put("error", fmt.Errorf("Error setting permissions of debug key: %s", err))
   102  				return multistep.ActionHalt
   103  			}
   104  		}
   105  	}
   106  
   107  	return multistep.ActionContinue
   108  }
   109  
   110  func (s *StepConfigAlicloudKeyPair) Cleanup(state multistep.StateBag) {
   111  	// If no key name is set, then we never created it, so just return
   112  	// If we used an SSH private key file, do not go about deleting
   113  	// keypairs
   114  	if s.PrivateKeyFile != "" || (s.KeyPairName == "" && s.keyName == "") {
   115  		return
   116  	}
   117  
   118  	client := state.Get("client").(*ecs.Client)
   119  	ui := state.Get("ui").(packer.Ui)
   120  
   121  	// Remove the keypair
   122  	ui.Say("Deleting temporary keypair...")
   123  	err := client.DeleteKeyPairs(&ecs.DeleteKeyPairsArgs{
   124  		RegionId:     common.Region(s.RegionId),
   125  		KeyPairNames: "[\"" + s.keyName + "\"]",
   126  	})
   127  	if err != nil {
   128  		ui.Error(fmt.Sprintf(
   129  			"Error cleaning up keypair. Please delete the key manually: %s", s.keyName))
   130  	}
   131  
   132  	// Also remove the physical key if we're debugging.
   133  	if s.Debug {
   134  		if err := os.Remove(s.DebugKeyPath); err != nil {
   135  			ui.Error(fmt.Sprintf(
   136  				"Error removing debug key '%s': %s", s.DebugKeyPath, err))
   137  		}
   138  	}
   139  }