github.com/kimor79/packer@v0.8.7-0.20151221212622-d507b18eb4cf/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/mitchellh/multistep" 9 "github.com/mitchellh/packer/packer" 10 "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs" 11 "github.com/rackspace/gophercloud/openstack/compute/v2/servers" 12 ) 13 14 type StepRunSourceServer struct { 15 Name string 16 SourceImage string 17 SecurityGroups []string 18 Networks []string 19 AvailabilityZone string 20 UserData string 21 UserDataFile string 22 ConfigDrive bool 23 server *servers.Server 24 } 25 26 func (s *StepRunSourceServer) Run(state multistep.StateBag) multistep.StepAction { 27 config := state.Get("config").(Config) 28 flavor := state.Get("flavor_id").(string) 29 keyName := state.Get("keyPair").(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 s.server, err = servers.Create(computeClient, keypairs.CreateOptsExt{ 57 CreateOptsBuilder: servers.CreateOpts{ 58 Name: s.Name, 59 ImageRef: s.SourceImage, 60 FlavorRef: flavor, 61 SecurityGroups: s.SecurityGroups, 62 Networks: networks, 63 AvailabilityZone: s.AvailabilityZone, 64 UserData: userData, 65 ConfigDrive: s.ConfigDrive, 66 }, 67 68 KeyName: keyName, 69 }).Extract() 70 if err != nil { 71 err := fmt.Errorf("Error launching source server: %s", err) 72 state.Put("error", err) 73 ui.Error(err.Error()) 74 return multistep.ActionHalt 75 } 76 77 ui.Message(fmt.Sprintf("Server ID: %s", s.server.ID)) 78 log.Printf("server id: %s", s.server.ID) 79 80 ui.Say("Waiting for server to become ready...") 81 stateChange := StateChangeConf{ 82 Pending: []string{"BUILD"}, 83 Target: []string{"ACTIVE"}, 84 Refresh: ServerStateRefreshFunc(computeClient, s.server), 85 StepState: state, 86 } 87 latestServer, err := WaitForState(&stateChange) 88 if err != nil { 89 err := fmt.Errorf("Error waiting for server (%s) to become ready: %s", s.server.ID, err) 90 state.Put("error", err) 91 ui.Error(err.Error()) 92 return multistep.ActionHalt 93 } 94 95 s.server = latestServer.(*servers.Server) 96 state.Put("server", s.server) 97 98 return multistep.ActionContinue 99 } 100 101 func (s *StepRunSourceServer) Cleanup(state multistep.StateBag) { 102 if s.server == nil { 103 return 104 } 105 106 config := state.Get("config").(Config) 107 ui := state.Get("ui").(packer.Ui) 108 109 // We need the v2 compute client 110 computeClient, err := config.computeV2Client() 111 if err != nil { 112 ui.Error(fmt.Sprintf("Error terminating server, may still be around: %s", err)) 113 return 114 } 115 116 ui.Say(fmt.Sprintf("Terminating the source server: %s ...", s.server.ID)) 117 if err := servers.Delete(computeClient, s.server.ID).ExtractErr(); err != nil { 118 ui.Error(fmt.Sprintf("Error terminating server, may still be around: %s", err)) 119 return 120 } 121 122 stateChange := StateChangeConf{ 123 Pending: []string{"ACTIVE", "BUILD", "REBUILD", "SUSPENDED", "SHUTOFF", "STOPPED"}, 124 Refresh: ServerStateRefreshFunc(computeClient, s.server), 125 Target: []string{"DELETED"}, 126 } 127 128 WaitForState(&stateChange) 129 }