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