github.com/rahart/packer@v0.12.2-0.20161229105310-282bb6ad370f/builder/openstack/step_run_source_server.go (about) 1 package openstack 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "log" 7 8 "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs" 9 "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" 10 "github.com/mitchellh/multistep" 11 "github.com/mitchellh/packer/packer" 12 ) 13 14 type StepRunSourceServer struct { 15 Name string 16 SourceImage string 17 SourceImageName string 18 SecurityGroups []string 19 Networks []string 20 AvailabilityZone string 21 UserData string 22 UserDataFile string 23 ConfigDrive bool 24 server *servers.Server 25 } 26 27 func (s *StepRunSourceServer) Run(state multistep.StateBag) multistep.StepAction { 28 config := state.Get("config").(Config) 29 flavor := state.Get("flavor_id").(string) 30 ui := state.Get("ui").(packer.Ui) 31 32 // We need the v2 compute client 33 computeClient, err := config.computeV2Client() 34 if err != nil { 35 err = fmt.Errorf("Error initializing compute client: %s", err) 36 state.Put("error", err) 37 return multistep.ActionHalt 38 } 39 40 networks := make([]servers.Network, len(s.Networks)) 41 for i, networkUuid := range s.Networks { 42 networks[i].UUID = networkUuid 43 } 44 45 userData := []byte(s.UserData) 46 if s.UserDataFile != "" { 47 userData, err = ioutil.ReadFile(s.UserDataFile) 48 if err != nil { 49 err = fmt.Errorf("Error reading user data file: %s", err) 50 state.Put("error", err) 51 return multistep.ActionHalt 52 } 53 } 54 55 ui.Say("Launching server...") 56 57 serverOpts := servers.CreateOpts{ 58 Name: s.Name, 59 ImageRef: s.SourceImage, 60 ImageName: s.SourceImageName, 61 FlavorRef: flavor, 62 SecurityGroups: s.SecurityGroups, 63 Networks: networks, 64 AvailabilityZone: s.AvailabilityZone, 65 UserData: userData, 66 ConfigDrive: &s.ConfigDrive, 67 ServiceClient: computeClient, 68 } 69 70 var serverOptsExt servers.CreateOptsBuilder 71 keyName, hasKey := state.GetOk("keyPair") 72 if hasKey { 73 serverOptsExt = keypairs.CreateOptsExt{ 74 CreateOptsBuilder: serverOpts, 75 KeyName: keyName.(string), 76 } 77 } else { 78 serverOptsExt = serverOpts 79 } 80 81 s.server, err = servers.Create(computeClient, serverOptsExt).Extract() 82 if err != nil { 83 err := fmt.Errorf("Error launching source server: %s", err) 84 state.Put("error", err) 85 ui.Error(err.Error()) 86 return multistep.ActionHalt 87 } 88 89 ui.Message(fmt.Sprintf("Server ID: %s", s.server.ID)) 90 log.Printf("server id: %s", s.server.ID) 91 92 ui.Say("Waiting for server to become ready...") 93 stateChange := StateChangeConf{ 94 Pending: []string{"BUILD"}, 95 Target: []string{"ACTIVE"}, 96 Refresh: ServerStateRefreshFunc(computeClient, s.server), 97 StepState: state, 98 } 99 latestServer, err := WaitForState(&stateChange) 100 if err != nil { 101 err := fmt.Errorf("Error waiting for server (%s) to become ready: %s", s.server.ID, err) 102 state.Put("error", err) 103 ui.Error(err.Error()) 104 return multistep.ActionHalt 105 } 106 107 s.server = latestServer.(*servers.Server) 108 state.Put("server", s.server) 109 110 return multistep.ActionContinue 111 } 112 113 func (s *StepRunSourceServer) Cleanup(state multistep.StateBag) { 114 if s.server == nil { 115 return 116 } 117 118 config := state.Get("config").(Config) 119 ui := state.Get("ui").(packer.Ui) 120 121 // We need the v2 compute client 122 computeClient, err := config.computeV2Client() 123 if err != nil { 124 ui.Error(fmt.Sprintf("Error terminating server, may still be around: %s", err)) 125 return 126 } 127 128 ui.Say(fmt.Sprintf("Terminating the source server: %s ...", s.server.ID)) 129 if err := servers.Delete(computeClient, s.server.ID).ExtractErr(); err != nil { 130 ui.Error(fmt.Sprintf("Error terminating server, may still be around: %s", err)) 131 return 132 } 133 134 stateChange := StateChangeConf{ 135 Pending: []string{"ACTIVE", "BUILD", "REBUILD", "SUSPENDED", "SHUTOFF", "STOPPED"}, 136 Refresh: ServerStateRefreshFunc(computeClient, s.server), 137 Target: []string{"DELETED"}, 138 } 139 140 WaitForState(&stateChange) 141 }