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 }