github.com/askholme/packer@v0.7.2-0.20140924152349-70d9566a6852/builder/openstack/step_run_source_server.go (about)

     1  package openstack
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/mitchellh/multistep"
     6  	"github.com/mitchellh/packer/packer"
     7  	"github.com/rackspace/gophercloud"
     8  	"log"
     9  )
    10  
    11  type StepRunSourceServer struct {
    12  	Flavor         string
    13  	Name           string
    14  	SourceImage    string
    15  	SecurityGroups []string
    16  	Networks       []string
    17  
    18  	server *gophercloud.Server
    19  }
    20  
    21  func (s *StepRunSourceServer) Run(state multistep.StateBag) multistep.StepAction {
    22  	csp := state.Get("csp").(gophercloud.CloudServersProvider)
    23  	keyName := state.Get("keyPair").(string)
    24  	ui := state.Get("ui").(packer.Ui)
    25  
    26  	// XXX - validate image and flavor is available
    27  
    28  	securityGroups := make([]map[string]interface{}, len(s.SecurityGroups))
    29  	for i, groupName := range s.SecurityGroups {
    30  		securityGroups[i] = make(map[string]interface{})
    31  		securityGroups[i]["name"] = groupName
    32  	}
    33  
    34  	networks := make([]gophercloud.NetworkConfig, len(s.Networks))
    35  	for i, networkUuid := range s.Networks {
    36  		networks[i].Uuid = networkUuid
    37  	}
    38  
    39  	server := gophercloud.NewServer{
    40  		Name:          s.Name,
    41  		ImageRef:      s.SourceImage,
    42  		FlavorRef:     s.Flavor,
    43  		KeyPairName:   keyName,
    44  		SecurityGroup: securityGroups,
    45  		Networks:      networks,
    46  	}
    47  
    48  	serverResp, err := csp.CreateServer(server)
    49  	if err != nil {
    50  		err := fmt.Errorf("Error launching source server: %s", err)
    51  		state.Put("error", err)
    52  		ui.Error(err.Error())
    53  		return multistep.ActionHalt
    54  	}
    55  
    56  	s.server, err = csp.ServerById(serverResp.Id)
    57  	log.Printf("server id: %s", s.server.Id)
    58  
    59  	ui.Say(fmt.Sprintf("Waiting for server (%s) to become ready...", s.server.Id))
    60  	stateChange := StateChangeConf{
    61  		Pending:   []string{"BUILD"},
    62  		Target:    "ACTIVE",
    63  		Refresh:   ServerStateRefreshFunc(csp, s.server),
    64  		StepState: state,
    65  	}
    66  	latestServer, err := WaitForState(&stateChange)
    67  	if err != nil {
    68  		err := fmt.Errorf("Error waiting for server (%s) to become ready: %s", s.server.Id, err)
    69  		state.Put("error", err)
    70  		ui.Error(err.Error())
    71  		return multistep.ActionHalt
    72  	}
    73  
    74  	s.server = latestServer.(*gophercloud.Server)
    75  	state.Put("server", s.server)
    76  
    77  	return multistep.ActionContinue
    78  }
    79  
    80  func (s *StepRunSourceServer) Cleanup(state multistep.StateBag) {
    81  	if s.server == nil {
    82  		return
    83  	}
    84  
    85  	csp := state.Get("csp").(gophercloud.CloudServersProvider)
    86  	ui := state.Get("ui").(packer.Ui)
    87  
    88  	ui.Say("Terminating the source server...")
    89  	if err := csp.DeleteServerById(s.server.Id); err != nil {
    90  		ui.Error(fmt.Sprintf("Error terminating server, may still be around: %s", err))
    91  		return
    92  	}
    93  
    94  	stateChange := StateChangeConf{
    95  		Pending: []string{"ACTIVE", "BUILD", "REBUILD", "SUSPENDED"},
    96  		Refresh: ServerStateRefreshFunc(csp, s.server),
    97  		Target:  "DELETED",
    98  	}
    99  
   100  	WaitForState(&stateChange)
   101  }