-
Notifications
You must be signed in to change notification settings - Fork 0
/
ec2.js
174 lines (145 loc) · 5.56 KB
/
ec2.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
var helper = require('./helper'),
Q = require('q');
var EC2 = new helper.AWS.EC2();
// NOTE: wait until instance reaches 'status' provided and is ready to be used;
function waitFor(status, params, callback) {
var deferred = Q.defer();
var par = params || {};
EC2.waitFor(status, par, function (err, data) {
if (err) deferred.reject("ERROR : waitFor() : " + err + err.stack);
else deferred.resolve(data);
});
return deferred.promise.nodeify(callback);
};
// NOTE: create new instances
exports.createInstances = function (count, userData, callback) {
var deferred = Q.defer();
var params = {
// NOTE: my AMI with git, nodejs and npm pre-installed
ImageId: 'ami-456d3975', //default 64-bit ubuntu 14: 'ami-37501207',
InstanceType: 't1.micro',
MaxCount: count,
/* required */
MinCount: count,
/* required */
InstanceInitiatedShutdownBehavior: 'terminate',
KeyName: 'CS553',
SecurityGroups: ['CS553'],
IamInstanceProfile: {
Name: 'dev'
},
UserData: userData
};
EC2.runInstances(params, function (err, data) {
if (err) deferred.reject("ERROR : createInstances() : " + err + err.stack);
else {
var instanceIds = data.Instances.filter(function (instance, i) {
return instance.State.Name == 'pending';
}).map(function (instance, i) {
return instance.InstanceId;
});
var par = {
InstanceIds: instanceIds
};
waitFor('instanceRunning', par).then(function (data) {
deferred.resolve(data);
}, function (error) {
deferred.reject(error);
});
}
});
return deferred.promise.nodeify(callback);
};
// NOTE: create spot instances
exports.createSpotInstances = function (instanceCount, userData, callback) {
var deferred = Q.defer();
var params = {
SpotPrice: '0.0040',
/* required */
InstanceCount: instanceCount,
LaunchSpecification: {
IamInstanceProfile: {
Name: 'dev'
},
ImageId: 'ami-456d3975',
InstanceType: 't1.micro',
KeyName: 'CS553',
SecurityGroups: ['CS553'],
UserData: userData
},
Type: 'one-time'
};
EC2.requestSpotInstances(params, function (err, data) {
if (err) deferred.reject("ERROR : createSpotInstances() : " + err + err.stack);
else {
var instanceIds = data.SpotInstanceRequests.filter(function (instance, i) {
return instance.State == 'open';
}).map(function (instance, i) {
return instance.SpotInstanceRequestId;
});
var par = {
SpotInstanceRequestIds: instanceIds
};
// NOTE: call waitFor('spotInstanceRequestFulfilled') every 15 seconds until request is 'fulfilled'
var interval = setInterval(function () {
waitFor('spotInstanceRequestFulfilled', par).then(function (data) {
if (data.SpotInstanceRequests && data.SpotInstanceRequests.length > 0 && data.SpotInstanceRequests[0].Status.Code == 'fulfilled') {
clearInterval(interval);
var par = {
InstanceIds: [data.SpotInstanceRequests[0].InstanceId]
};
// NOTE: Wait until instance is in 'Running' state
waitFor('instanceRunning', par).then(function (data) {
//NOTE: Cancel Spot Instance Request
var params = {
SpotInstanceRequestIds: instanceIds
};
EC2.cancelSpotInstanceRequests(params, function (err, data) {
if (err) console.log("ERROR: cancelSpotInstanceRequest() : " + err + err.stack);
else console.log("Successfully cancelled SpotInstanceRequest : ", instanceIds);
});
deferred.resolve(data);
}, function (error) {
deferred.reject(error);
});
}
}, function (err) {
deferred.reject(err);
});
}, 15000);
}
});
return deferred.promise.nodeify(callback);
};
// NOTE: get number of spot instances in 'pending' and 'running' states
exports.describeInstances = function (callback) {
var deferred = Q.defer();
var params = {
Filters: [
{
Name: 'instance-lifecycle',
Values: ['spot']
},
{
Name: 'instance-state-name',
Values: ['pending', 'running']
}
]
};
EC2.describeInstances(params, function (err, data) {
if (err) deferred.reject(err + err.stack);
else deferred.resolve(data);
});
return deferred.promise.nodeify(callback);
};
// NOTE: terminate instances using intsanceID
/*exports.terminateInstances = function (instanceIds, callback) {
var deferred = Q.defer();
var params = {
InstanceIds: instanceIds
};
EC2.terminateInstances(params, function (err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
};*/