@@ -45,10 +45,11 @@ const (
4545)
4646
4747type InstanceInfo struct {
48- project string
49- zone string
50- name string
51- machineType string
48+ project string
49+ architecture string
50+ zone string
51+ name string
52+ machineType string
5253
5354 // External IP is filled in after instance creation
5455 externalIP string
@@ -68,12 +69,13 @@ func (i *InstanceInfo) GetNodeID() string {
6869 return common .CreateNodeID (i .project , i .zone , i .name )
6970}
7071
71- func CreateInstanceInfo (project , instanceZone , name , machineType string , cs * compute.Service ) (* InstanceInfo , error ) {
72+ func CreateInstanceInfo (project , instanceArchitecture , instanceZone , name , machineType string , cs * compute.Service ) (* InstanceInfo , error ) {
7273 return & InstanceInfo {
73- project : project ,
74- zone : instanceZone ,
75- name : name ,
76- machineType : machineType ,
74+ project : project ,
75+ architecture : instanceArchitecture ,
76+ zone : instanceZone ,
77+ name : name ,
78+ machineType : machineType ,
7779
7880 computeService : cs ,
7981 }, nil
@@ -92,7 +94,7 @@ func (i *InstanceInfo) CreateOrGetInstance(imageURL, serviceAccount string) erro
9294 return fmt .Errorf ("Failed to create firewall rule: %v" , err )
9395 }
9496
95- inst := & compute.Instance {
97+ newInst := & compute.Instance {
9698 Name : i .name ,
9799 MachineType : fmt .Sprintf ("zones/%s/machineTypes/%s" , i .zone , i .machineType ),
98100 NetworkInterfaces : []* compute.NetworkInterface {
@@ -121,31 +123,47 @@ func (i *InstanceInfo) CreateOrGetInstance(imageURL, serviceAccount string) erro
121123 Email : serviceAccount ,
122124 Scopes : []string {"https://www.googleapis.com/auth/cloud-platform" },
123125 }
124- inst .ServiceAccounts = []* compute.ServiceAccount {saObj }
126+ newInst .ServiceAccounts = []* compute.ServiceAccount {saObj }
125127
126128 if pubkey , ok := os .LookupEnv ("JENKINS_GCE_SSH_PUBLIC_KEY_FILE" ); ok {
127129 klog .V (4 ).Infof ("JENKINS_GCE_SSH_PUBLIC_KEY_FILE set to %v, adding public key to Instance" , pubkey )
128130 meta , err := generateMetadataWithPublicKey (pubkey )
129131 if err != nil {
130132 return err
131133 }
132- inst .Metadata = meta
134+ newInst .Metadata = meta
133135 }
134136
135- if _ , err := i .computeService .Instances .Get (i .project , i .zone , inst .Name ).Do (); err != nil {
136- op , err := i .computeService .Instances .Insert (i .project , i .zone , inst ).Do ()
137- klog .V (4 ).Infof ("Inserted instance %v in project: %v, zone: %v" , inst .Name , i .project , i .zone )
138- if err != nil {
139- ret := fmt .Sprintf ("could not create instance %s: API error: %v" , i .name , err )
140- if op != nil {
141- ret = fmt .Sprintf ("%s. op error: %v" , ret , op .Error )
137+ curInst , _ := i .computeService .Instances .Get (i .project , i .zone , newInst .Name ).Do ()
138+ if curInst != nil {
139+ if ! strings .Contains (curInst .MachineType , newInst .MachineType ) {
140+ klog .V (4 ).Infof ("Instance machine type doesn't match the required one. Remove instance." )
141+ if _ , err := i .computeService .Instances .Delete (i .project , i .zone , i .name ).Do (); err != nil {
142+ return err
143+ }
144+
145+ then := time .Now ()
146+ err := wait .Poll (15 * time .Second , 5 * time .Minute , func () (bool , error ) {
147+ klog .V (2 ).Infof ("Waiting for instance to be deleted. %v elapsed" , time .Since (then ))
148+ if instance , _ = i .computeService .Instances .Get (i .project , i .zone , i .name ).Do (); instance != nil {
149+ return false , nil
150+ }
151+ return true , nil
152+ })
153+ if err != nil {
154+ return err
142155 }
143- return errors .New (ret )
144- } else if op .Error != nil {
145- return fmt .Errorf ("could not create instance %s: %+v" , i .name , op .Error )
156+
157+ if err := insertInstance (i , newInst ); err != nil {
158+ return err
159+ }
160+ } else {
161+ klog .V (4 ).Infof ("Compute service GOT instance %v, skipping instance creation" , newInst .Name )
146162 }
147163 } else {
148- klog .V (4 ).Infof ("Compute service GOT instance %v, skipping instance creation" , inst .Name )
164+ if err := insertInstance (i , newInst ); err != nil {
165+ return err
166+ }
149167 }
150168
151169 then := time .Now ()
@@ -187,6 +205,21 @@ func (i *InstanceInfo) CreateOrGetInstance(imageURL, serviceAccount string) erro
187205 return nil
188206}
189207
208+ func insertInstance (i * InstanceInfo , newInst * compute.Instance ) error {
209+ op , err := i .computeService .Instances .Insert (i .project , i .zone , newInst ).Do ()
210+ klog .V (4 ).Infof ("Inserted instance %v in project: %v, zone: %v" , newInst .Name , i .project , i .zone )
211+ if err != nil {
212+ ret := fmt .Sprintf ("could not create instance %s: API error: %v" , i .name , err )
213+ if op != nil {
214+ ret = fmt .Sprintf ("%s. op error: %v" , ret , op .Error )
215+ }
216+ return errors .New (ret )
217+ } else if op .Error != nil {
218+ return fmt .Errorf ("could not create instance %s: %+v" , i .name , op .Error )
219+ }
220+ return nil
221+ }
222+
190223func (i * InstanceInfo ) DeleteInstance () {
191224 klog .V (4 ).Infof ("Deleting instance %q" , i .name )
192225 _ , err := i .computeService .Instances .Delete (i .project , i .zone , i .name ).Do ()
0 commit comments