Skip to content

Commit 080f3c7

Browse files
committed
Merge branch 'master' into trevj-cloud-social-hardening
2 parents de61813 + e8af960 commit 080f3c7

2 files changed

Lines changed: 32 additions & 37 deletions

File tree

src/cloud/digitalocean/provisioner.ts

Lines changed: 23 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ class Provisioner {
7272
}).then((keys: KeyPair) => {
7373
// Get SSH keys
7474
this.state_.ssh = keys;
75-
return this.getDroplet_(name).then((unused :any) => {
75+
76+
return this.getDropletByName_(name).then((unused :any) => {
7677
// Droplet exists so raise error
7778
return Promise.reject({
7879
'errcode': 'VM_AE',
@@ -85,23 +86,25 @@ class Provisioner {
8586
});
8687
}).then(() => {
8788
// Get the droplet's configuration
88-
return this.doRequest_('GET', 'droplets/' + this.state_.cloud.vm.id);
89-
}).then((resp: any) => {
89+
return this.getDropletByName_(name);
90+
}).then((droplet:any) => {
9091
this.sendStatus_('CLOUD_DONE_VM');
91-
this.state_.cloud.vm = resp.droplet;
92+
this.state_.cloud.vm = droplet;
9293
this.state_.network = {
9394
'ssh_port': 22
9495
};
9596
// Retrieve public IPv4 address
96-
for (var i = 0; i < resp.droplet.networks.v4.length; i++) {
97-
if (resp.droplet.networks.v4[i].type === 'public') {
98-
this.state_.network['ipv4'] = resp.droplet.networks.v4[i].ip_address;
97+
for (var i = 0; i < droplet.networks.v4.length; i++) {
98+
if (droplet.networks.v4[i].type === 'public') {
99+
this.state_.network['ipv4'] = droplet.networks.v4[i].ip_address;
100+
break;
99101
}
100102
}
101103
// Retrieve public IPv6 address
102-
for (var i = 0; i < resp.droplet.networks.v6.length; i++) {
103-
if (resp.droplet.networks.v6[i].type === 'public') {
104-
this.state_.network['ipv6'] = resp.droplet.networks.v6[i].ip_address;
104+
for (var i = 0; i < droplet.networks.v6.length; i++) {
105+
if (droplet.networks.v6[i].type === 'public') {
106+
this.state_.network['ipv6'] = droplet.networks.v6[i].ip_address;
107+
break;
105108
}
106109
}
107110
console.log(this.state_);
@@ -132,10 +135,10 @@ class Provisioner {
132135
private destroyServer_ = (name: string): Promise<void> => {
133136
return this.doRequest_('GET', 'droplets').then((resp: any) => {
134137
// Find and delete the server with the same name
135-
return this.getDroplet_(name);
136-
}).then((resp: any) => {
138+
return this.getDropletByName_(name);
139+
}).then((droplet: any) => {
137140
this.state_.cloud = this.state_.cloud || {};
138-
this.state_.cloud.vm = this.state_.cloud.vm || resp.droplet;
141+
this.state_.cloud.vm = this.state_.cloud.vm || droplet;
139142
// Make sure there are no actions in progress before deleting
140143
this.sendStatus_('CLOUD_WAITING_VM');
141144
return this.waitDigitalOceanActions_();
@@ -169,10 +172,10 @@ class Provisioner {
169172
return this.doOAuth_().then((oauthObj: any) => {
170173
this.state_.oauth = oauthObj;
171174
}).then(() => {
172-
return this.getDroplet_(name);
173-
}).then((resp: any) => {
175+
return this.getDropletByName_(name);
176+
}).then((droplet: any) => {
174177
this.state_.cloud = this.state_.cloud || {};
175-
this.state_.cloud.vm = this.state_.cloud.vm || resp.droplet;
178+
this.state_.cloud.vm = this.state_.cloud.vm || droplet;
176179
// Make sure there are no actions in progress before rebooting
177180
this.sendStatus_('CLOUD_WAITING_VM');
178181
return this.waitDigitalOceanActions_();
@@ -188,20 +191,12 @@ class Provisioner {
188191
});
189192
}
190193

191-
/**
192-
* Finds a droplet with this name
193-
* @param {String} droplet name, as a string
194-
* @return {Promise.<Object>}, resolves with {droplet: droplet_with_name}
195-
* or rejects if droplet doesn't exist
196-
*/
197-
private getDroplet_ = (name: string) : Promise<Object> => {
194+
// Resolves with the (de-serialised) droplet, rejecting if not found.
195+
private getDropletByName_ = (name: string) : Promise<Object> => {
198196
return this.doRequest_('GET', 'droplets').then((resp: any) => {
199-
// Find and delete the server with the same name
200-
for (var i = 0; i < resp.droplets.length; i++) {
197+
for (let i = 0; i < resp.droplets.length; i++) {
201198
if (resp.droplets[i].name === name) {
202-
return Promise.resolve({
203-
droplet: resp.droplets[i]
204-
});
199+
return Promise.resolve(resp.droplets[i]);
205200
}
206201
}
207202
return Promise.reject({

src/promises/promises.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
/// <reference path='../../../third_party/typings/browser.d.ts' />
22

33
// Invokes f up to maxAttempts number of times, resolving with its result
4-
// on the first success and rejecting on maxAttempts-th failure.
5-
export const retry = <T>(f: () => Promise<T>, maxAttempts: number): Promise<T> => {
6-
return f().catch((e:Error) => {
7-
--maxAttempts;
8-
if (maxAttempts > 0) {
9-
return retry(f, maxAttempts);
10-
} else {
11-
return Promise.reject(e);
12-
}
4+
// on the first success and rejecting on the maxAttempts-th failure, waiting,
5+
// if specified, intervalMs ms between each attempt.
6+
export const retry = <T>(f: () => Promise<T>, maxAttempts: number, intervalMs = 0): Promise<T> => {
7+
return f().catch((e: Error) => {
8+
return maxAttempts <= 1 ? Promise.reject(e) : new Promise<T>((F, R) => {
9+
setTimeout(() => {
10+
retry(f, maxAttempts - 1, intervalMs).then(F, R);
11+
}, intervalMs);
12+
});
1313
});
1414
};
1515

0 commit comments

Comments
 (0)