appscale-tools 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +37 -0
- data/README +17 -0
- data/bin/appscale-add-keypair +15 -0
- data/bin/appscale-describe-instances +16 -0
- data/bin/appscale-remove-app +13 -0
- data/bin/appscale-reset-pwd +13 -0
- data/bin/appscale-run-instances +15 -0
- data/bin/appscale-terminate-instances +14 -0
- data/bin/appscale-upload-app +13 -0
- data/doc/AdvancedNode.html +163 -0
- data/doc/AppControllerClient.html +831 -0
- data/doc/AppEngineConfigException.html +165 -0
- data/doc/AppScaleException.html +165 -0
- data/doc/AppScaleTools.html +768 -0
- data/doc/BadCommandLineArgException.html +166 -0
- data/doc/BadConfigurationException.html +166 -0
- data/doc/CommonFunctions.html +2559 -0
- data/doc/EncryptionHelper.html +332 -0
- data/doc/GodInterface.html +443 -0
- data/doc/InfrastructureException.html +166 -0
- data/doc/Node.html +470 -0
- data/doc/NodeLayout.html +1297 -0
- data/doc/Object.html +539 -0
- data/doc/ParseArgs.html +268 -0
- data/doc/RemoteLogging.html +268 -0
- data/doc/SimpleNode.html +163 -0
- data/doc/UsageText.html +1204 -0
- data/doc/UserAppClient.html +993 -0
- data/doc/VMTools.html +1365 -0
- data/doc/bin/appscale-add-keypair.html +56 -0
- data/doc/bin/appscale-describe-instances.html +56 -0
- data/doc/bin/appscale-remove-app.html +56 -0
- data/doc/bin/appscale-reset-pwd.html +56 -0
- data/doc/bin/appscale-run-instances.html +56 -0
- data/doc/bin/appscale-terminate-instances.html +56 -0
- data/doc/bin/appscale-upload-app.html +56 -0
- data/doc/created.rid +21 -0
- data/doc/images/add.png +0 -0
- data/doc/images/brick.png +0 -0
- data/doc/images/brick_link.png +0 -0
- data/doc/images/bug.png +0 -0
- data/doc/images/bullet_black.png +0 -0
- data/doc/images/bullet_toggle_minus.png +0 -0
- data/doc/images/bullet_toggle_plus.png +0 -0
- data/doc/images/date.png +0 -0
- data/doc/images/delete.png +0 -0
- data/doc/images/find.png +0 -0
- data/doc/images/loadingAnimation.gif +0 -0
- data/doc/images/macFFBgHack.png +0 -0
- data/doc/images/package.png +0 -0
- data/doc/images/page_green.png +0 -0
- data/doc/images/page_white_text.png +0 -0
- data/doc/images/page_white_width.png +0 -0
- data/doc/images/plugin.png +0 -0
- data/doc/images/ruby.png +0 -0
- data/doc/images/tag_blue.png +0 -0
- data/doc/images/tag_green.png +0 -0
- data/doc/images/transparent.png +0 -0
- data/doc/images/wrench.png +0 -0
- data/doc/images/wrench_orange.png +0 -0
- data/doc/images/zoom.png +0 -0
- data/doc/index.html +116 -0
- data/doc/js/darkfish.js +153 -0
- data/doc/js/jquery.js +18 -0
- data/doc/js/navigation.js +142 -0
- data/doc/js/quicksearch.js +114 -0
- data/doc/js/search.js +94 -0
- data/doc/js/search_index.js +1 -0
- data/doc/js/searcher.js +228 -0
- data/doc/js/thickbox-compressed.js +10 -0
- data/doc/lib/app_controller_client_rb.html +60 -0
- data/doc/lib/appscale_tools_rb.html +88 -0
- data/doc/lib/common_functions_rb.html +78 -0
- data/doc/lib/custom_exceptions_rb.html +54 -0
- data/doc/lib/encryption_helper_rb.html +60 -0
- data/doc/lib/godinterface_rb.html +52 -0
- data/doc/lib/node_layout_rb.html +55 -0
- data/doc/lib/parse_args_rb.html +58 -0
- data/doc/lib/remote_log_rb.html +58 -0
- data/doc/lib/sshcopyid.html +174 -0
- data/doc/lib/usage_text_rb.html +58 -0
- data/doc/lib/user_app_client_rb.html +62 -0
- data/doc/lib/vm_tools_rb.html +62 -0
- data/doc/table_of_contents.html +496 -0
- data/lib/app_controller_client.rb +181 -0
- data/lib/appscale_tools.rb +403 -0
- data/lib/common_functions.rb +1467 -0
- data/lib/custom_exceptions.rb +25 -0
- data/lib/encryption_helper.rb +86 -0
- data/lib/godinterface.rb +152 -0
- data/lib/node_layout.rb +665 -0
- data/lib/parse_args.rb +415 -0
- data/lib/remote_log.rb +46 -0
- data/lib/sshcopyid +65 -0
- data/lib/usage_text.rb +144 -0
- data/lib/user_app_client.rb +245 -0
- data/lib/vm_tools.rb +549 -0
- data/test/tc_app_controller_client.rb +10 -0
- data/test/tc_appscale_add_keypair.rb +44 -0
- data/test/tc_appscale_describe_instances.rb +69 -0
- data/test/tc_appscale_remove_app.rb +128 -0
- data/test/tc_appscale_reset_pwd.rb +156 -0
- data/test/tc_appscale_run_instances.rb +48 -0
- data/test/tc_appscale_terminate_instances.rb +104 -0
- data/test/tc_appscale_upload_app.rb +166 -0
- data/test/tc_common_functions.rb +56 -0
- data/test/tc_encryption_helper.rb +10 -0
- data/test/tc_god_interface.rb +10 -0
- data/test/tc_node_layout.rb +93 -0
- data/test/tc_parse_args.rb +160 -0
- data/test/tc_user_app_client.rb +10 -0
- data/test/tc_vm_tools.rb +10 -0
- data/test/ts_all.rb +20 -0
- metadata +211 -0
data/lib/parse_args.rb
ADDED
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
# Programmer: Chris Bunch
|
|
3
|
+
|
|
4
|
+
$:.unshift File.join(File.dirname(__FILE__))
|
|
5
|
+
require 'common_functions'
|
|
6
|
+
require 'custom_exceptions'
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
NO_APP_FOUND = "The specified App Engine app didn't exist."
|
|
10
|
+
FILE_FLAG_NOT_VALID_MSG = "File must be either a directory or end with .tar.gz"
|
|
11
|
+
IPS_FLAG_NOT_A_YAML_MSG = "YAML file must end with .yaml or .yml"
|
|
12
|
+
MIN_FLAG_NOT_A_NUM_MSG = "Min images must be a positive integer"
|
|
13
|
+
MAX_FLAG_NOT_A_NUM_MSG = "Max images must be a positive integer"
|
|
14
|
+
TABLE_FLAG_NOT_IN_SET_MSG = "Invalid table type. Table must be set to one" +
|
|
15
|
+
" of the following: #{VALID_TABLE_TYPES.join(', ')}"
|
|
16
|
+
MIN_FLAG_NOT_POSITIVE_MSG = "Minimum image number must be larger than zero"
|
|
17
|
+
MAX_FLAG_NOT_POSITIVE_MSG = "Maximum image number must be larger than zero"
|
|
18
|
+
|
|
19
|
+
MAX_SMALLER_THAN_MIN_MSG = "Maximum image number must be larger than " +
|
|
20
|
+
"the minimum image number"
|
|
21
|
+
|
|
22
|
+
YAML_CONTROL_MSG = "The provided IP yaml file did not have one IP " +
|
|
23
|
+
"address for the controller node"
|
|
24
|
+
|
|
25
|
+
EC2_USAGE_MSG = "You did not provide an ips.yaml file, and you" +
|
|
26
|
+
" did not provide a machine id."
|
|
27
|
+
EC2_IPS_MISSING_MSG = "You did not provide an ips.yaml or it was empty."
|
|
28
|
+
INSTANCE_FLAG_NOT_IN_SET_MSG = "The instance type you provided was not " +
|
|
29
|
+
"one of the allowed values. Currently we allow m1.large, m1.xlarge, " +
|
|
30
|
+
"and c1.xlarge as the instance types."
|
|
31
|
+
INFRASTRUCTURE_FLAG_NOT_IN_SET_MSG = "The infrastructure you provided " +
|
|
32
|
+
"was not one of the allowed values. Currently we allow ec2 and euca " +
|
|
33
|
+
"as the infrastructure types."
|
|
34
|
+
|
|
35
|
+
DJINN_SERVER_DIED_MSG = "\nEither the head node was unable to get IP " +
|
|
36
|
+
"addresses for any slave nodes or a bug in the head node's code caused" +
|
|
37
|
+
" it to crash. We have left your virtual machines running in case you " +
|
|
38
|
+
"wish to submit a bug report or investigate further via " +
|
|
39
|
+
"the Troubleshooting page."
|
|
40
|
+
|
|
41
|
+
RW_REQUIRES_VOLDEMORT_MSG = "The r and w flags can only be used in " +
|
|
42
|
+
"conjunction with the Voldemort database. Please either specify the" +
|
|
43
|
+
" Voldemort database to be used or remove the r and w flags."
|
|
44
|
+
|
|
45
|
+
BACKUP_TAR_EXISTS_MSG = "The tar file you specified to back up to " +
|
|
46
|
+
"already exists. Please specify a new file name and try again."
|
|
47
|
+
BACKUP_NEPTUNE_INFO_EXISTS_MSG = "The Neptune info file you specified " +
|
|
48
|
+
" to back up to already exists. Please specify a new file name and try again."
|
|
49
|
+
|
|
50
|
+
RESTORE_TAR_NOT_EXISTS_MSG = "The tar file you specified to back up" +
|
|
51
|
+
" from does not exist. Please specify a new file name and try again."
|
|
52
|
+
RESTORE_NEPTUNE_INFO_NOT_EXISTS_MSG = "The Neptune info file you specified" +
|
|
53
|
+
" does not exist. Please specify a new file name and try again."
|
|
54
|
+
|
|
55
|
+
CONFIG_FILE_NOT_FOUND = "The configuration file you specified did not exist." +
|
|
56
|
+
" Please specify one that exists and try again."
|
|
57
|
+
NO_MIN_OR_MAX_WITH_IPS = "When using the ips flag, the min or max flags " +
|
|
58
|
+
"cannot be specified. Please only use either (1) the min and max flags or " +
|
|
59
|
+
"(2) the ips flag."
|
|
60
|
+
|
|
61
|
+
FILE_REGEX = /\.tar\.gz$/
|
|
62
|
+
POS_NUM_REGEX = /^[1-9]\d*$/
|
|
63
|
+
TAR_REGEX = /\.tar\.gz$/
|
|
64
|
+
YAML_REGEX = /\.ya?ml$/
|
|
65
|
+
|
|
66
|
+
DEFAULT_DATASTORE = "cassandra"
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
module ParseArgs
|
|
70
|
+
public
|
|
71
|
+
|
|
72
|
+
def self.get_vals_from_args(arg_list, all_flags, usage)
|
|
73
|
+
val_hash = {}
|
|
74
|
+
|
|
75
|
+
arg_hash = parse_argv(arg_list, all_flags, usage)
|
|
76
|
+
|
|
77
|
+
if arg_hash['help'] || arg_hash['h'] || arg_hash['usage']
|
|
78
|
+
raise BadCommandLineArgException.new(usage)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
if arg_hash['version']
|
|
82
|
+
raise BadCommandLineArgException.new(AS_VERSION)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
self.get_min_and_max_images_and_ips(arg_hash, val_hash)
|
|
86
|
+
|
|
87
|
+
if arg_hash['file']
|
|
88
|
+
true_location = File.expand_path(arg_hash['file'])
|
|
89
|
+
if !File.exists?(true_location)
|
|
90
|
+
raise BadCommandLineArgException.new(NO_APP_FOUND)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
if !((File.directory?(true_location)) or (true_location =~ TAR_REGEX))
|
|
94
|
+
raise BadCommandLineArgException.new(FILE_FLAG_NOT_VALID_MSG)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
val_hash['file_location'] = arg_hash['file']
|
|
98
|
+
else
|
|
99
|
+
val_hash['file_location'] = nil
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
self.get_table_args(arg_hash, val_hash)
|
|
103
|
+
self.get_cloud_args(arg_hash, val_hash)
|
|
104
|
+
|
|
105
|
+
if arg_hash['keyname']
|
|
106
|
+
val_hash['keyname'] = arg_hash['keyname']
|
|
107
|
+
else
|
|
108
|
+
val_hash['keyname'] = "appscale"
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
if arg_hash['appname']
|
|
112
|
+
val_hash['appname'] = arg_hash['appname'].gsub(/[^\w\d-]/, "")
|
|
113
|
+
else
|
|
114
|
+
val_hash['appname'] = nil
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# If the user tells us exactly how many application servers they want
|
|
118
|
+
# per application, then don't use the autoscaling support.
|
|
119
|
+
if arg_hash['appengine']
|
|
120
|
+
val_hash['appengine'] = Integer(arg_hash['appengine'])
|
|
121
|
+
val_hash['autoscale'] = false
|
|
122
|
+
else
|
|
123
|
+
val_hash['appengine'] = 1
|
|
124
|
+
val_hash['autoscale'] = true
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
if arg_hash['separate']
|
|
128
|
+
val_hash['separate'] = true
|
|
129
|
+
else
|
|
130
|
+
val_hash['separate'] = false
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
val_hash['confirm'] = !arg_hash['confirm'].nil?
|
|
134
|
+
|
|
135
|
+
self.get_backup_and_restore_params(arg_hash, val_hash)
|
|
136
|
+
self.get_developer_flags(arg_hash, val_hash)
|
|
137
|
+
|
|
138
|
+
return val_hash
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
private
|
|
142
|
+
|
|
143
|
+
def self.parse_argv(command_line, all_flags, usage)
|
|
144
|
+
if command_line.class != Array
|
|
145
|
+
raise BadCommandLineArgException.new("argv was not an Array, but was a #{command_line.class}")
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
arg_hash = {}
|
|
149
|
+
|
|
150
|
+
arg_found = nil
|
|
151
|
+
command_line.each { |arg|
|
|
152
|
+
if arg[0].chr == "-"
|
|
153
|
+
arg = arg[1, arg.length]
|
|
154
|
+
arg = arg[1, arg.length] if arg[0].chr == "-" # to handle --arg
|
|
155
|
+
arg_found = arg
|
|
156
|
+
if !all_flags.include?(arg)
|
|
157
|
+
raise BadCommandLineArgException.new("The flag #{arg} cannot be used here.")
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
arg_hash[arg] = "NO ARG"
|
|
161
|
+
elsif !arg_found.nil?
|
|
162
|
+
arg_hash[arg_found] = arg
|
|
163
|
+
arg_found = nil
|
|
164
|
+
else
|
|
165
|
+
raise BadCommandLineArgException.new("The parameter #{arg} was specified without a corresponding flag.")
|
|
166
|
+
end
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return arg_hash
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def self.get_min_and_max_images_and_ips(arg_hash, val_hash)
|
|
173
|
+
if arg_hash['min']
|
|
174
|
+
if arg_hash['min'] !~ POS_NUM_REGEX
|
|
175
|
+
raise BadCommandLineArgException.new(MIN_FLAG_NOT_A_NUM_MSG)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
min_images = Integer(arg_hash['min'])
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
if arg_hash['max']
|
|
182
|
+
if arg_hash['max'] !~ POS_NUM_REGEX
|
|
183
|
+
raise BadCommandLineArgException.new(MAX_FLAG_NOT_A_NUM_MSG)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
max_images = Integer(arg_hash['max'])
|
|
187
|
+
|
|
188
|
+
if !arg_hash['min']
|
|
189
|
+
min_images = max_images
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
if min_images and max_images and min_images > max_images
|
|
194
|
+
raise BadCommandLineArgException.new(MAX_SMALLER_THAN_MIN_MSG)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
val_hash['min_images'] = min_images
|
|
198
|
+
val_hash['max_images'] = max_images
|
|
199
|
+
|
|
200
|
+
if arg_hash['ips']
|
|
201
|
+
# users shouldn't be allowed to specify ips and min/max
|
|
202
|
+
if arg_hash['min'] or arg_hash['max']
|
|
203
|
+
raise BadCommandLineArgException.new(NO_MIN_OR_MAX_WITH_IPS)
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
begin
|
|
207
|
+
val_hash['ips'] = YAML.load_file(arg_hash['ips'])
|
|
208
|
+
rescue Errno::ENOENT
|
|
209
|
+
abort(CONFIG_FILE_NOT_FOUND)
|
|
210
|
+
end
|
|
211
|
+
else
|
|
212
|
+
val_hash['ips'] = nil
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def self.get_table_args(arg_hash, val_hash)
|
|
217
|
+
if arg_hash['table']
|
|
218
|
+
if !VALID_TABLE_TYPES.include?(arg_hash['table'])
|
|
219
|
+
raise BadCommandLineArgException.new(TABLE_FLAG_NOT_IN_SET_MSG)
|
|
220
|
+
end
|
|
221
|
+
val_hash['table'] = arg_hash['table']
|
|
222
|
+
else
|
|
223
|
+
val_hash['table'] = DEFAULT_DATASTORE
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
if arg_hash['n']
|
|
227
|
+
if arg_hash['n'] !~ POS_NUM_REGEX
|
|
228
|
+
raise BadCommandLineArgException.new("n must be a positive integer")
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
val_hash['replication'] = Integer(arg_hash['n'])
|
|
232
|
+
else
|
|
233
|
+
val_hash['replication'] = nil
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
if val_hash['table'] != 'voldemort' and (arg_hash['r'] or arg_hash['w'])
|
|
237
|
+
raise BadCommandLineArgException.new(RW_REQUIRES_VOLDEMORT_MSG)
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
if arg_hash['r']
|
|
241
|
+
if arg_hash['r'] !~ POS_NUM_REGEX
|
|
242
|
+
raise BadCommandLineArgException.new("r must be a positive integer")
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
val_hash['voldemort_r'] = Integer(arg_hash['r'])
|
|
246
|
+
else
|
|
247
|
+
val_hash['voldemort_r'] = nil
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
if arg_hash['w']
|
|
251
|
+
if arg_hash['w'] !~ POS_NUM_REGEX
|
|
252
|
+
raise BadCommandLineArgException.new("w must be a positive integer")
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
val_hash['voldemort_w'] = Integer(arg_hash['w'])
|
|
256
|
+
else
|
|
257
|
+
val_hash['voldemort_w'] = nil
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
def self.get_cloud_args(arg_hash, val_hash)
|
|
262
|
+
if arg_hash['infrastructure']
|
|
263
|
+
infra = arg_hash['infrastructure']
|
|
264
|
+
if !VALID_CLOUD_TYPES.include?(infra)
|
|
265
|
+
raise BadCommandLineArgException.new(INFRASTRUCTURE_FLAG_NOT_IN_SET_MSG)
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
if infra == "iaas"
|
|
269
|
+
val_hash['infrastructure'] = "euca"
|
|
270
|
+
else
|
|
271
|
+
val_hash['infrastructure'] = infra
|
|
272
|
+
end
|
|
273
|
+
else
|
|
274
|
+
val_hash['infrastructure'] = nil
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
#Override if --iaas is set
|
|
278
|
+
if arg_hash['iaas']
|
|
279
|
+
if arg_hash['iaas'] == "hybrid"
|
|
280
|
+
val_hash['infrastructure'] = "hybrid"
|
|
281
|
+
else
|
|
282
|
+
val_hash['infrastructure'] = "euca"
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
if arg_hash['machine']
|
|
287
|
+
val_hash['machine'] = arg_hash['machine']
|
|
288
|
+
if val_hash['machine'] == "NO ARG"
|
|
289
|
+
raise BadCommandLineArgException.new("You failed to provide an argument for the #{flag} flag. Please do so and try again.")
|
|
290
|
+
end
|
|
291
|
+
else
|
|
292
|
+
val_hash['machine'] = ENV['APPSCALE_MACHINE']
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
possible_instance_types = ["m1.small", "m1.large", "m1.xlarge", "c1.xlarge"]
|
|
296
|
+
if arg_hash['instance_type']
|
|
297
|
+
if !possible_instance_types.include?(arg_hash['instance_type'])
|
|
298
|
+
raise BadCommandLineArgException.new(INSTANCE_FLAG_NOT_IN_SET_MSG)
|
|
299
|
+
end
|
|
300
|
+
val_hash['instance_type'] = arg_hash['instance_type']
|
|
301
|
+
else
|
|
302
|
+
val_hash['instance_type'] = "m1.large"
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
if arg_hash['v'] or arg_hash['verbose']
|
|
306
|
+
val_hash['verbose'] = true
|
|
307
|
+
else
|
|
308
|
+
val_hash['verbose'] = false
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
# The group flag is used to indicate the name of the security group that should
|
|
312
|
+
# be used in EC2 and Eucalyptus deployments. If used in Xen and KVM deployments,
|
|
313
|
+
# this flag has no effect. The security group should not exist prior to running
|
|
314
|
+
# AppScale - if it does exist, the tools will abort accordingly.
|
|
315
|
+
if arg_hash['group']
|
|
316
|
+
val_hash['group'] = arg_hash['group']
|
|
317
|
+
else
|
|
318
|
+
val_hash['group'] = "appscale"
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
def self.get_backup_and_restore_params(arg_hash, val_hash)
|
|
323
|
+
if arg_hash['backup_to_tar']
|
|
324
|
+
if File.exists?(arg_hash['backup_to_tar'])
|
|
325
|
+
raise BadCommandLineArgException.new(BACKUP_TAR_EXISTS_MSG)
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
val_hash['backup_tar_location'] = arg_hash['backup_to_tar']
|
|
329
|
+
else
|
|
330
|
+
val_hash['backup_tar_location'] = nil
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
if arg_hash['backup_to_ebs']
|
|
334
|
+
val_hash['backup_ebs_location'] = arg_hash['backup_to_ebs']
|
|
335
|
+
else
|
|
336
|
+
val_hash['backup_ebs_location'] = nil
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
if arg_hash['backup_neptune_info']
|
|
340
|
+
if File.exists?(File.expand_path(arg_hash['backup_neptune_info']))
|
|
341
|
+
raise BadCommandLineArgException.new(BACKUP_NEPTUNE_INFO_EXISTS_MSG)
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
val_hash['backup_neptune_info'] = File.expand_path(arg_hash['backup_neptune_info'])
|
|
345
|
+
else
|
|
346
|
+
val_hash['backup_neptune_info'] = nil
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
if arg_hash['restore_from_tar']
|
|
350
|
+
unless File.exists?(arg_hash['restore_from_tar'])
|
|
351
|
+
raise BadCommandLineArgException.new(RESTORE_TAR_NOT_EXISTS_MSG)
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
val_hash['restore_from_tar'] = arg_hash['restore_from_tar']
|
|
355
|
+
else
|
|
356
|
+
val_hash['restore_from_tar'] = nil
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
if arg_hash['restore_neptune_info']
|
|
360
|
+
unless File.exists?(arg_hash['restore_neptune_info'])
|
|
361
|
+
raise BadCommandLineArgException.new(RESTORE_NEPTUNE_INFO_NOT_EXISTS_MSG)
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
val_hash['restore_neptune_info'] = arg_hash['restore_neptune_info']
|
|
365
|
+
else
|
|
366
|
+
val_hash['restore_neptune_info'] = nil
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
if val_hash['file_location'] && (val_hash['restore_from_tar'] || val_hash['restore_from_ebs'])
|
|
370
|
+
bad_restore_params = "You cannot restore an AppScale instance " +
|
|
371
|
+
"and upload a new application. Please remove one and try again."
|
|
372
|
+
raise BadCommandLineArgException.new(bad_restore_params)
|
|
373
|
+
end
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
# These flags are considered to be 'advanced use' flags, handling things that
|
|
377
|
+
# may not be necessary in standard AppScale deployments. This includes the
|
|
378
|
+
# functionality to rsync over an AppScale directory (scp), use 'expect' to
|
|
379
|
+
# automatically inject the user's SSH password (auto), and so on.
|
|
380
|
+
def self.get_developer_flags(arg_hash, val_hash)
|
|
381
|
+
if arg_hash['auto']
|
|
382
|
+
val_hash['auto'] = true
|
|
383
|
+
else
|
|
384
|
+
val_hash['auto'] = false
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
if arg_hash['force']
|
|
388
|
+
val_hash['force'] = true
|
|
389
|
+
else
|
|
390
|
+
val_hash['force'] = false
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
if arg_hash['scp']
|
|
394
|
+
if arg_hash['scp'] == 'NO ARG'
|
|
395
|
+
val_hash['scp'] = "~/appscale"
|
|
396
|
+
else
|
|
397
|
+
val_hash['scp'] = arg_hash['scp']
|
|
398
|
+
end
|
|
399
|
+
else
|
|
400
|
+
val_hash['scp'] = false
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
if arg_hash['test']
|
|
404
|
+
val_hash['test'] = true
|
|
405
|
+
else
|
|
406
|
+
val_hash['test'] = false
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
if arg_hash['email']
|
|
410
|
+
val_hash['email'] = arg_hash['email']
|
|
411
|
+
else
|
|
412
|
+
val_hash['email'] = false
|
|
413
|
+
end
|
|
414
|
+
end
|
|
415
|
+
end
|
data/lib/remote_log.rb
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Programmer: Navraj Chohan
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
# Imports within Ruby's standard libraries
|
|
5
|
+
require 'net/http'
|
|
6
|
+
require 'uri'
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# RemoteLogging provides callers with a mechanism by which they can save
|
|
10
|
+
# information about when the AppScale tools are successfully used. Callers
|
|
11
|
+
# should use these methods to indicate when AppScale has failed to start,
|
|
12
|
+
# and possibly any information that can be used to debug the problem.
|
|
13
|
+
module RemoteLogging
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# The location where the Google App Engine application runs that stores
|
|
17
|
+
# profiling information about how often the AppScale tools run successfully.
|
|
18
|
+
REMOTE_URL = "http://heart-beat.appspot.com/sign2"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# Provides a convenient interface to self.post that callers can use to
|
|
22
|
+
# save profiling information about running the AppScale tools.
|
|
23
|
+
def self.remote_post(num_nodes, database, infrastructure, state, success)
|
|
24
|
+
params = {"key" => "appscale",
|
|
25
|
+
"infras" => infrastructure,
|
|
26
|
+
"num_nodes" => "#{num_nodes}",
|
|
27
|
+
"state" => state,
|
|
28
|
+
"success" => success,
|
|
29
|
+
"db" => database}
|
|
30
|
+
self.post(params)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# Posts a Hash of parameters to the Google App Engine application that
|
|
35
|
+
# keeps statistics about when AppScale was started successfully or failed.
|
|
36
|
+
def self.post(params)
|
|
37
|
+
begin
|
|
38
|
+
uri = URI.parse(REMOTE_URL)
|
|
39
|
+
response = Net::HTTP.post_form(uri, params)
|
|
40
|
+
return response.body
|
|
41
|
+
rescue Exception # e.g., if the app is unresponsive
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
end
|