cloudflock 0.6.1 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/bin/cloudflock +7 -1
- data/bin/cloudflock-files +2 -14
- data/bin/cloudflock-profile +3 -15
- data/bin/cloudflock-servers +3 -22
- data/bin/cloudflock.default +3 -22
- data/lib/cloudflock/app/common/cleanup/unix.rb +23 -0
- data/lib/cloudflock/app/common/cleanup.rb +107 -0
- data/lib/cloudflock/app/common/exclusions/unix/centos.rb +18 -0
- data/lib/cloudflock/app/common/exclusions/unix/redhat.rb +18 -0
- data/lib/cloudflock/app/common/exclusions/unix.rb +58 -0
- data/lib/cloudflock/app/common/exclusions.rb +57 -0
- data/lib/cloudflock/app/common/platform_action.rb +59 -0
- data/lib/cloudflock/app/common/rackspace.rb +63 -0
- data/lib/cloudflock/app/common/servers.rb +673 -0
- data/lib/cloudflock/app/files-migrate.rb +246 -0
- data/lib/cloudflock/app/server-migrate.rb +327 -0
- data/lib/cloudflock/app/server-profile.rb +130 -0
- data/lib/cloudflock/app.rb +87 -0
- data/lib/cloudflock/error.rb +6 -19
- data/lib/cloudflock/errstr.rb +31 -0
- data/lib/cloudflock/remote/files.rb +82 -22
- data/lib/cloudflock/remote/ssh.rb +234 -278
- data/lib/cloudflock/target/servers/platform.rb +92 -115
- data/lib/cloudflock/target/servers/profile.rb +331 -340
- data/lib/cloudflock/task/server-profile.rb +651 -0
- data/lib/cloudflock.rb +6 -8
- metadata +49 -68
- data/lib/cloudflock/interface/cli/app/common/servers.rb +0 -128
- data/lib/cloudflock/interface/cli/app/files.rb +0 -179
- data/lib/cloudflock/interface/cli/app/servers/migrate.rb +0 -491
- data/lib/cloudflock/interface/cli/app/servers/profile.rb +0 -88
- data/lib/cloudflock/interface/cli/app/servers.rb +0 -2
- data/lib/cloudflock/interface/cli/console.rb +0 -213
- data/lib/cloudflock/interface/cli/opts/servers.rb +0 -20
- data/lib/cloudflock/interface/cli/opts.rb +0 -87
- data/lib/cloudflock/interface/cli.rb +0 -15
- data/lib/cloudflock/target/servers/data/exceptions/base.txt +0 -44
- data/lib/cloudflock/target/servers/data/exceptions/platform/amazon.txt +0 -10
- data/lib/cloudflock/target/servers/data/exceptions/platform/centos.txt +0 -7
- data/lib/cloudflock/target/servers/data/exceptions/platform/debian.txt +0 -0
- data/lib/cloudflock/target/servers/data/exceptions/platform/redhat.txt +0 -7
- data/lib/cloudflock/target/servers/data/exceptions/platform/suse.txt +0 -1
- data/lib/cloudflock/target/servers/data/post-migration/chroot/base.txt +0 -1
- data/lib/cloudflock/target/servers/data/post-migration/chroot/platform/amazon.txt +0 -19
- data/lib/cloudflock/target/servers/data/post-migration/pre/base.txt +0 -3
- data/lib/cloudflock/target/servers/data/post-migration/pre/platform/amazon.txt +0 -4
- data/lib/cloudflock/target/servers/migrate.rb +0 -466
- data/lib/cloudflock/target/servers/platform/v1.rb +0 -97
- data/lib/cloudflock/target/servers/platform/v2.rb +0 -93
- data/lib/cloudflock/target/servers.rb +0 -5
- data/lib/cloudflock/version.rb +0 -3
@@ -1,466 +0,0 @@
|
|
1
|
-
require 'cloudflock/remote/ssh'
|
2
|
-
require 'thread'
|
3
|
-
require 'cpe'
|
4
|
-
|
5
|
-
# Public: Provides methods to facilitate as many discrete steps of a migration
|
6
|
-
# between like hosts as possible. The assumption is made that the destination
|
7
|
-
# host will be put into rescue mode, or will otherwise be able to recover if
|
8
|
-
# any files transferred overwrite extant files on the filesystem (e.g. glibc.)
|
9
|
-
# The steps are as granular as possible to avoid the requirement that every
|
10
|
-
# step is strictly followed.
|
11
|
-
#
|
12
|
-
# Examples
|
13
|
-
#
|
14
|
-
# # Perform setup of source and destination hosts, but don't migrate
|
15
|
-
# setup_managed(destination_host)
|
16
|
-
# setup_source(source_host)
|
17
|
-
#
|
18
|
-
# # Assume that all setup has been done; migrate the host with no watchdogs
|
19
|
-
# migrate_server(source_host, destination_host)
|
20
|
-
module CloudFlock::Target::Servers::Migrate extend self
|
21
|
-
# Internal: location of the directory containing data for exclusions/clean-up
|
22
|
-
DATA_LOCATION = File.expand_path('../../servers/data', __FILE__)
|
23
|
-
|
24
|
-
# Public: Monitor for managed cloud scripts to complete. Return true if they
|
25
|
-
# do, false otherwise.
|
26
|
-
#
|
27
|
-
# host - SSH object logged in to the destination host.
|
28
|
-
# timeout - Fixnum containing the number of seconds to wait. (default: 1200)
|
29
|
-
#
|
30
|
-
# Returns true or false depending on whether or not manages scripts have
|
31
|
-
# finished.
|
32
|
-
def setup_managed(host, timeout = 3600)
|
33
|
-
i = 0
|
34
|
-
finished = false
|
35
|
-
managed_check = %w{[ -f /tmp/rs_managed_cloud_automation_complete ] &&
|
36
|
-
printf 'DONE' || printf 'GOING'}.join(' ')
|
37
|
-
while i < timeout && !finished
|
38
|
-
i += sleep(60)
|
39
|
-
mc_task_status = host.set_timeout(60) do
|
40
|
-
host.query("MANAGED_CHECK", managed_check)
|
41
|
-
end
|
42
|
-
finished = true if mc_task_status == "DONE"
|
43
|
-
end
|
44
|
-
|
45
|
-
finished
|
46
|
-
end
|
47
|
-
|
48
|
-
# Public: Prepare the destination host for automated migration steps by
|
49
|
-
# installing rsync, mounting the primary disk to /mnt/migration_target,
|
50
|
-
# installing a temporary ssh public key for root, and backing up the original
|
51
|
-
# passwd, shadow and group files (in case of managed migration).
|
52
|
-
#
|
53
|
-
# host - SSH object logged in to the destination host.
|
54
|
-
# pubkey - String containing the text of the ssh public key to install for
|
55
|
-
# root.
|
56
|
-
#
|
57
|
-
# Returns nothing.
|
58
|
-
def setup_destination(host, pubkey)
|
59
|
-
host.set_timeout(300)
|
60
|
-
|
61
|
-
host.puts("mkdir /mnt/migration_target")
|
62
|
-
host.prompt
|
63
|
-
|
64
|
-
disk = host.query("DISK_XVDB1", "[ -e /dev/xvdb1 ] && printf 'xvdb1'")
|
65
|
-
disk = "sda1" if disk.empty?
|
66
|
-
host.puts("mount -o acl /dev/#{disk} /mnt/migration_target")
|
67
|
-
host.prompt
|
68
|
-
|
69
|
-
preserve_files = ["passwd", "shadow", "group"]
|
70
|
-
path = "/mnt/migration_target/etc"
|
71
|
-
preserve_files.each do |file|
|
72
|
-
copy_command = "[ -f #{path}/migration.#{file} ] || /bin/cp -a " +
|
73
|
-
"#{path}/#{file} #{path}/migration.#{file}"
|
74
|
-
host.puts(copy_command)
|
75
|
-
host.prompt
|
76
|
-
end
|
77
|
-
|
78
|
-
package_manager = host.query("MANAGER", "which {yum,apt-get} 2>/dev/null")
|
79
|
-
host.set_timeout(120) do
|
80
|
-
host.puts("#{package_manager} install rsync -y")
|
81
|
-
host.prompt
|
82
|
-
end
|
83
|
-
|
84
|
-
host.puts("rsync")
|
85
|
-
host.expect(/rsync error/)
|
86
|
-
host.prompt
|
87
|
-
|
88
|
-
ssh_key = "mkdir $HOME/.ssh; chmod 0700 $HOME/.ssh; printf " +
|
89
|
-
"'#{pubkey}\\n' >> $HOME/.ssh/authorized_keys"
|
90
|
-
host.puts(ssh_key)
|
91
|
-
host.prompt
|
92
|
-
end
|
93
|
-
|
94
|
-
# Public: Prepare the source host for automated migration by populating the
|
95
|
-
# exclusions list in /root/.rackspace/migration_exceptions.txt and creating a
|
96
|
-
# temporary ssh public key in /tmp/RACKSPACE_MIGRATION/
|
97
|
-
#
|
98
|
-
# host - SSH object logged in to the source host.
|
99
|
-
# exclusions - String containing the exclusions list for the source host.
|
100
|
-
#
|
101
|
-
# Returns a String object containing the host's new ssh public key.
|
102
|
-
def setup_source(host, exclusions)
|
103
|
-
host.puts("mkdir /root/.rackspace")
|
104
|
-
host.prompt
|
105
|
-
|
106
|
-
exclude = "cat <<EOF > /root/.rackspace/migration_exceptions.txt" +
|
107
|
-
"\n#{exclusions}\nEOF"
|
108
|
-
host.puts(exclude)
|
109
|
-
host.prompt
|
110
|
-
|
111
|
-
ssh_keygen = %w{mkdir /tmp/RACKSPACE_MIGRATION && ssh-keygen -b 2048 -q -t
|
112
|
-
rsa -f /tmp/RACKSPACE_MIGRATION/migration_id_rsa -P
|
113
|
-
''}.join(' ')
|
114
|
-
host.puts(ssh_keygen)
|
115
|
-
host.prompt
|
116
|
-
|
117
|
-
host.query("PUBKEY", "cat /tmp/RACKSPACE_MIGRATION/migration_id_rsa.pub")
|
118
|
-
end
|
119
|
-
|
120
|
-
# Public: Check for connectivity over RFC 1918 networks for a pair of hosts.
|
121
|
-
# Return the first network address which offers connectivity.
|
122
|
-
#
|
123
|
-
# source_host - SSH object logged in to the source host.
|
124
|
-
# destination_host - SSH object logged in to the destination host.
|
125
|
-
#
|
126
|
-
# Returns a String containing an IP address if connectivity is verified.
|
127
|
-
# Returns nil otherwise.
|
128
|
-
def check_servicenet(source_host, destination_host)
|
129
|
-
keygen_command = "ssh-keygen -lf /etc/ssh/ssh_host_rsa_key.pub"
|
130
|
-
destination_rsa = destination_host.query("RSA_FINGERPRINT", keygen_command)
|
131
|
-
destination_rsa.gsub!(/^[^ ]* /, '').gsub!(/ .*/, '')
|
132
|
-
|
133
|
-
ip_discovery = %w{ifconfig|grep 'inet addr:10\.' | sed
|
134
|
-
's/.*addr:\([^ ]*\) .*/\1/g' | xargs}.join(' ')
|
135
|
-
ips = destination_host.query("IFCONFIG", ip_discovery)
|
136
|
-
|
137
|
-
ips.split(/\s+/).each do |addr|
|
138
|
-
# Change NumberOfPasswordPrompts to 0, and StrictHostKeyChecking to yes
|
139
|
-
ssh_arguments = CloudFlock::Remote::SSH::SSH_ARGUMENTS.gsub(/1/, '0')
|
140
|
-
ssh_arguments.gsub!("-o StrictHostKeyChecking=no", '')
|
141
|
-
source_host.puts("ssh #{ssh_arguments} #{addr}")
|
142
|
-
remote_rsa = source_host.set_timeout(30) do
|
143
|
-
source_host.expect(/^RSA.*$/, true)
|
144
|
-
end
|
145
|
-
source_host.set_timeout(120) do
|
146
|
-
source_host.send("\C-c")
|
147
|
-
source_host.prompt
|
148
|
-
end
|
149
|
-
next if remote_rsa.nil?
|
150
|
-
|
151
|
-
return addr unless remote_rsa.to_s.match(destination_rsa).nil?
|
152
|
-
end
|
153
|
-
|
154
|
-
nil
|
155
|
-
end
|
156
|
-
|
157
|
-
# Public: Commense migration by launching 2 rsync processes: the first to
|
158
|
-
# move the bulk of the data in question and the second to provide a delta,
|
159
|
-
# ensuring a more complete dataset transfer.
|
160
|
-
#
|
161
|
-
# source_host - SSH object logged in to the source host.
|
162
|
-
# destination_host - SSH object logged in to the destination host.
|
163
|
-
# args - Hash containing additional parameters for operation.
|
164
|
-
# (default: {}):
|
165
|
-
# :target_addr - String containing the address to use when
|
166
|
-
# communicating with the destination host.
|
167
|
-
# :rsync - String containing path to rsync binary on
|
168
|
-
# the source machine. If this is nil, copy
|
169
|
-
# rsync from the destination machine to
|
170
|
-
# /root/.rackspace/ for the purposes of
|
171
|
-
# carrying out the migration.
|
172
|
-
# (default: nil)
|
173
|
-
#
|
174
|
-
# Returns a Thread object encapsulating the migration.
|
175
|
-
# Raises ArgumentError if args[:target_addr] is not set.
|
176
|
-
def migrate_server(source_host, args)
|
177
|
-
if args[:target_addr].nil?
|
178
|
-
raise ArgumentError, "Need target address for server"
|
179
|
-
end
|
180
|
-
|
181
|
-
# If we lack rsync, fetch it from the destination server
|
182
|
-
unless args[:rsync]
|
183
|
-
source_host.puts("mkdir /root/.rackspace")
|
184
|
-
source_host.prompt
|
185
|
-
|
186
|
-
rsync_install = "scp #{CloudFlock::Remote::SSH::SSH_ARGUMENTS} -i " +
|
187
|
-
"/tmp/RACKSPACE_MIGRATION/migration_id_rsa " +
|
188
|
-
"root@#{args[:host]}:/usr/bin/rsync " +
|
189
|
-
"/root/.rackspace/rsync"
|
190
|
-
source_host.puts(rsync_install)
|
191
|
-
source_host.prompt
|
192
|
-
args[:rsync] = "/root/.rackspace/rsync"
|
193
|
-
end
|
194
|
-
|
195
|
-
2.times do
|
196
|
-
finished = false
|
197
|
-
until finished
|
198
|
-
source_host.send("\C-c")
|
199
|
-
sleep 45
|
200
|
-
source_host.puts
|
201
|
-
while source_host.prompt(true)
|
202
|
-
end
|
203
|
-
|
204
|
-
finished = migration_watcher(source_host, args)
|
205
|
-
end
|
206
|
-
|
207
|
-
sed_command = 'sed -i "s/\/var\/log//g" ' +
|
208
|
-
'/root/.rackspace/migration_exceptions.txt'
|
209
|
-
source_host.puts(sed_command)
|
210
|
-
source_host.prompt
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
# Public: Build exclusions list from generic and targeted exclusions
|
215
|
-
# definitions per CPE.
|
216
|
-
#
|
217
|
-
# cpe - CPE object to use in generating the default exclusions list.
|
218
|
-
#
|
219
|
-
# Returns a String containing the exclusions list generated.
|
220
|
-
def build_default_exclusions(cpe)
|
221
|
-
exclude = ""
|
222
|
-
exclude << File.open("#{DATA_LOCATION}/exceptions/base.txt", "r").read
|
223
|
-
vendor = cpe.vendor.downcase
|
224
|
-
version = cpe.version.to_s.downcase
|
225
|
-
path = "#{DATA_LOCATION}/exceptions/platform/"
|
226
|
-
|
227
|
-
if File.exists?("#{path}#{vendor}.txt")
|
228
|
-
exclude << File.open("#{path}#{vendor}.txt", "r").read
|
229
|
-
end
|
230
|
-
if File.exists?("#{path}#{vendor}_#{version}.txt")
|
231
|
-
exclude << File.open("#{path}#{vendor}_#{version}.txt", "r").read
|
232
|
-
end
|
233
|
-
|
234
|
-
exclude
|
235
|
-
end
|
236
|
-
|
237
|
-
# Public: Restore the rackconnect user in order to maintain Rack Connect
|
238
|
-
# functionality for a host on which Rack Connect automation has previously
|
239
|
-
# run.
|
240
|
-
#
|
241
|
-
# destination_host - SSH object logged in to the destination host.
|
242
|
-
#
|
243
|
-
# Returns true if the rackconnect user is restored, false otherwise.
|
244
|
-
def cleanup_rackconnect_destination(destination_host)
|
245
|
-
return false unless restore_user(destination_host, "rackconnect")
|
246
|
-
|
247
|
-
sudoers = "cat <<EOF >> /etc/sudoers\n\nrackconnect ALL=(ALL) NOPASSWD: " +
|
248
|
-
"ALL\nDefaults:rackconnect !requiretty\nEOF"
|
249
|
-
|
250
|
-
destination_host.puts(sudoers)
|
251
|
-
destination_host.prompt
|
252
|
-
|
253
|
-
true
|
254
|
-
end
|
255
|
-
|
256
|
-
# Public: Restore the rack user in order to maintain access on hosts which
|
257
|
-
# belong to a Managed Cloud account, on which Managed Cloud automation has
|
258
|
-
# already run.
|
259
|
-
#
|
260
|
-
# destination_host - SSH object logged in to the destination host.
|
261
|
-
#
|
262
|
-
# Returns true if the rack user is restored, false otherwise.
|
263
|
-
def cleanup_manage_destination(destination_host)
|
264
|
-
return false unless restore_user(destination_host, "rack")
|
265
|
-
|
266
|
-
sudoers = "cat <<EOF >> /etc/sudoers\n\nrack ALL=(ALL) NOPASSWD: ALL\nEOF"
|
267
|
-
destination_host.puts(sudoers)
|
268
|
-
destination_host.prompt
|
269
|
-
|
270
|
-
true
|
271
|
-
end
|
272
|
-
|
273
|
-
# Public: Perform post-migration clean up of a destination host. Base
|
274
|
-
# clean up off of cleanup scripts located at data/cleanup/.
|
275
|
-
#
|
276
|
-
# destination_host - SSH object logged in to the destination host.
|
277
|
-
# cpe - CPE object describing the platform in question.
|
278
|
-
#
|
279
|
-
# Returns nothing.
|
280
|
-
def clean_destination(destination_host, cpe)
|
281
|
-
clean_pre = ""
|
282
|
-
clean_chroot = ""
|
283
|
-
clean_post = ""
|
284
|
-
|
285
|
-
vendor = cpe.vendor.downcase
|
286
|
-
version = cpe.version.to_s.downcase
|
287
|
-
|
288
|
-
# Build pre-chroot, chroot and post-chroot scripts
|
289
|
-
["pre", "chroot", "post"].each do |name|
|
290
|
-
clean = eval("clean_#{name}")
|
291
|
-
clean << "#/bin/bash\n\n"
|
292
|
-
path = "#{DATA_LOCATION}/post-migration/#{name}"
|
293
|
-
|
294
|
-
if File.exists? "#{path}/base.txt"
|
295
|
-
clean << File.open("#{path}/base.txt", "r").read
|
296
|
-
end
|
297
|
-
if File.exists? "#{path}/platform/#{vendor}.txt"
|
298
|
-
clean << File.open("#{path}/platform/#{vendor}.txt", "r").read
|
299
|
-
end
|
300
|
-
if File.exists? "#{path}/platform/#{vendor}_#{version}.txt"
|
301
|
-
clean << File.open("#{path}/platform/#{vendor}_#{version}.txt", "r").read
|
302
|
-
end
|
303
|
-
end
|
304
|
-
|
305
|
-
pre_command = "cat <<EOF > /root/migration_clean_pre.sh\n" +
|
306
|
-
"#{clean_pre.gsub(/\$/, '\\$')}\nEOF"
|
307
|
-
chroot_command = "cat <<EOF > /mnt/migration_target/root/migration_" +
|
308
|
-
"clean_chroot.sh\n#{clean_chroot.gsub(/\$/, '\\$')}\nEOF"
|
309
|
-
post_command = "cat <<EOF > /root/migration_clean_post.sh\n" +
|
310
|
-
"#{clean_post.gsub(/\$/, '\\$')}\nEOF"
|
311
|
-
[pre_command, chroot_command, post_command].each do |command|
|
312
|
-
destination_host.puts(command)
|
313
|
-
destination_host.prompt
|
314
|
-
end
|
315
|
-
|
316
|
-
# Perform pre-chroot steps
|
317
|
-
long_run(destination_host, "/bin/bash /root/migration_clean_pre.sh")
|
318
|
-
|
319
|
-
# Chroot into the new environment
|
320
|
-
destination_host.puts("chroot /mnt/migration_target /bin/bash")
|
321
|
-
|
322
|
-
# Set host prompt, etc
|
323
|
-
destination_host.puts("export PS1='#{CloudFlock::Remote::SSH::PROMPT} '")
|
324
|
-
destination_host.get_root('')
|
325
|
-
|
326
|
-
# Perform chroot steps
|
327
|
-
long_run(destination_host, "/bin/bash /root/migration_clean_chroot.sh")
|
328
|
-
destination_host.puts("rm -f /root/migration_clean_chroot.sh")
|
329
|
-
destination_host.prompt
|
330
|
-
|
331
|
-
# Add Rack Connect and Managed users
|
332
|
-
cleanup_manage_destination(destination_host)
|
333
|
-
cleanup_rackconnect_destination(destination_host)
|
334
|
-
|
335
|
-
destination_host.puts("exit")
|
336
|
-
destination_host.prompt
|
337
|
-
|
338
|
-
# Perform post-chroot steps
|
339
|
-
long_run(destination_host, "/bin/bash /root/migration_clean_post.sh")
|
340
|
-
end
|
341
|
-
|
342
|
-
# Internal: Execute rsync and return true if everything appears to have completed successfully
|
343
|
-
#
|
344
|
-
# source_host - SSH object logged in to the source host.
|
345
|
-
# args - Hash containing additional parameters for operation.
|
346
|
-
# Expected parameters are:
|
347
|
-
# :target_addr - String containing the address to use when
|
348
|
-
# communicating with the destination host.
|
349
|
-
# :rsync - String containing path to rsync binary on
|
350
|
-
# the source machine. If this is nil, copy
|
351
|
-
# rsync from the destination machine to
|
352
|
-
# /root/.rackspace/ for the purposes of
|
353
|
-
# carrying out the migration.
|
354
|
-
# (default: nil)
|
355
|
-
# :timeout - Fixnum containing the number of seconds
|
356
|
-
# to wait before reporting failure/hung
|
357
|
-
# rsync process. If this is set to -1, a
|
358
|
-
# failure will never be reported--use
|
359
|
-
# Watchdogs in this case to prevent
|
360
|
-
# indefinite migrations. (default: 14400)
|
361
|
-
#
|
362
|
-
# Returns true if rsync finishes.
|
363
|
-
# Returns false if rsync does not complete within timeout.
|
364
|
-
def migration_watcher(source_host, args)
|
365
|
-
rsync_command = "#{args[:rsync]} -azP -e 'ssh " +
|
366
|
-
"#{CloudFlock::Remote::SSH::SSH_ARGUMENTS} -i " +
|
367
|
-
"/tmp/RACKSPACE_MIGRATION/migration_id_rsa' " +
|
368
|
-
"--exclude-from='/root/.rackspace/" +
|
369
|
-
"migration_exceptions.txt' / " +
|
370
|
-
"root@#{args[:target_addr]}:/mnt/migration_target"
|
371
|
-
source_host.puts(rsync_command)
|
372
|
-
|
373
|
-
source_host.set_timeout(60)
|
374
|
-
if(args[:timeout] >= 0)
|
375
|
-
i = args[:timeout]/60 + 1
|
376
|
-
else
|
377
|
-
i = -1
|
378
|
-
end
|
379
|
-
|
380
|
-
begin
|
381
|
-
source_host.prompt
|
382
|
-
rescue Timeout::Error
|
383
|
-
i -= 1
|
384
|
-
retry unless i == 0
|
385
|
-
return false
|
386
|
-
end
|
387
|
-
|
388
|
-
true
|
389
|
-
end
|
390
|
-
|
391
|
-
# Internal: Create user and restore entries from backup passwd and shadow
|
392
|
-
# files.
|
393
|
-
#
|
394
|
-
# destination_host - SSH object logged in to the host on which to restore a
|
395
|
-
# user.
|
396
|
-
# username - String containing the user to restore.
|
397
|
-
#
|
398
|
-
# Returns true if success, false otherwise.
|
399
|
-
def restore_user(destination_host, username)
|
400
|
-
username.strip!
|
401
|
-
sanity_check = "(grep '^#{username}:' /etc/migration.passwd && grep " +
|
402
|
-
"'^#{username}:' /etc/migration.shadow) >/dev/null " +
|
403
|
-
"2>/dev/null && printf 'PRESENT'"
|
404
|
-
|
405
|
-
sane = destination_host.query("USER_CHECK", sanity_check)
|
406
|
-
return false if sane.empty?
|
407
|
-
|
408
|
-
steps = ["useradd #{username}",
|
409
|
-
"chown -R #{username}.#{username} /home/#{username}",
|
410
|
-
"sed -i '/^#{username}:.*$/d' /etc/shadow",
|
411
|
-
"grep '^#{username}:' /etc/migration.shadow >> /etc/shadow"]
|
412
|
-
steps.each do |step|
|
413
|
-
destination_host.puts(step)
|
414
|
-
destination_host.prompt
|
415
|
-
end
|
416
|
-
|
417
|
-
true
|
418
|
-
end
|
419
|
-
|
420
|
-
# Internal: Insure that new output is being produced by a running process
|
421
|
-
# which is expected to run over an indeterminate amount of time to catch
|
422
|
-
# hanging processes, but not punish properly running ones.
|
423
|
-
#
|
424
|
-
# host - SSH object pointing to the host in question.
|
425
|
-
# command - String containing the command to be executed.
|
426
|
-
# timeout - Fixnum containing the maximum number of seconds for new output
|
427
|
-
# to be produced. (default: 30)
|
428
|
-
#
|
429
|
-
# Returns nothing.
|
430
|
-
# Raises any exception passed other than Timeout::Error (IE ProcessError).
|
431
|
-
def long_run(host, command, timeout=30)
|
432
|
-
unless host.kind_of?(CloudFlock::Remote::SSH)
|
433
|
-
raise ArgumentError, "Host must be a SSH Object"
|
434
|
-
end
|
435
|
-
unless command.kind_of?(String)
|
436
|
-
raise ArgumentError, "Command must be a String"
|
437
|
-
end
|
438
|
-
|
439
|
-
last_line = ''
|
440
|
-
newline_count = 0
|
441
|
-
fail_count = 0
|
442
|
-
fail_max = 10
|
443
|
-
|
444
|
-
host.puts(command.strip)
|
445
|
-
host.set_timeout(timeout) do
|
446
|
-
begin
|
447
|
-
host.prompt
|
448
|
-
rescue Timeout::Error
|
449
|
-
lines = host.buffer.split(/\n/)
|
450
|
-
current_line = lines[-1]
|
451
|
-
current_count = lines.length
|
452
|
-
|
453
|
-
if last_line == current_line && newline_count == current_count
|
454
|
-
fail_count += 1
|
455
|
-
raise LongRunFailed if fail_count == fail_max
|
456
|
-
else
|
457
|
-
fail_count = 0
|
458
|
-
last_line = current_line
|
459
|
-
newline_count = current_count
|
460
|
-
end
|
461
|
-
|
462
|
-
retry
|
463
|
-
end
|
464
|
-
end
|
465
|
-
end
|
466
|
-
end
|
@@ -1,97 +0,0 @@
|
|
1
|
-
require 'cloudflock/target/servers/platform'
|
2
|
-
|
3
|
-
# Public: Serves as a small class to easily map host specifications to Image
|
4
|
-
# and Flavor IDs in Rackspace Cloud.
|
5
|
-
#
|
6
|
-
# Examples
|
7
|
-
#
|
8
|
-
# # Build platform data for a given CPE object
|
9
|
-
# platform = Platform.new(cpe)
|
10
|
-
# platform.image_id
|
11
|
-
# # => Fixnum
|
12
|
-
class CloudFlock::Target::Servers::Platform::V1 <
|
13
|
-
CloudFlock::Target::Servers::Platform
|
14
|
-
# Public: Build the class constant Hashes for mapping given Platforms to
|
15
|
-
# Rackspace Cloud Image IDs.
|
16
|
-
#
|
17
|
-
# Returns nothing.
|
18
|
-
def build_image_maps
|
19
|
-
self.class.const_set(:UNMANAGED_MAP, {
|
20
|
-
amazon:
|
21
|
-
{
|
22
|
-
"*" => 118
|
23
|
-
},
|
24
|
-
arch:
|
25
|
-
{
|
26
|
-
"*" => 118
|
27
|
-
},
|
28
|
-
centos:
|
29
|
-
{
|
30
|
-
"5" => 114, "6" => 118
|
31
|
-
},
|
32
|
-
debian:
|
33
|
-
{
|
34
|
-
"5" => 103, "6" => 104
|
35
|
-
},
|
36
|
-
fedora:
|
37
|
-
{
|
38
|
-
"14" => 106, "15" => 116,
|
39
|
-
"16" => 120, "17" => 126
|
40
|
-
},
|
41
|
-
gentoo:
|
42
|
-
{
|
43
|
-
"*" => 108
|
44
|
-
},
|
45
|
-
redhat:
|
46
|
-
{
|
47
|
-
"5" => 110, "6" => 111
|
48
|
-
},
|
49
|
-
ubuntu:
|
50
|
-
{
|
51
|
-
"*" => 10,
|
52
|
-
"10.04" => 49, "10.10" => 49,
|
53
|
-
"11.04" => 115, "11.10" => 119,
|
54
|
-
"12.04" => 125, "12.10" => 125
|
55
|
-
}
|
56
|
-
})
|
57
|
-
|
58
|
-
self.class.const_set(:MANAGED_MAP, {
|
59
|
-
amazon:
|
60
|
-
{
|
61
|
-
"*" => 212
|
62
|
-
},
|
63
|
-
centos:
|
64
|
-
{
|
65
|
-
"5" => 200, "6" => 212
|
66
|
-
},
|
67
|
-
redhat:
|
68
|
-
{
|
69
|
-
"5" => 202, "6" => 204
|
70
|
-
},
|
71
|
-
ubuntu:
|
72
|
-
{
|
73
|
-
"*" => 206,
|
74
|
-
"10.04" => 206, "10.10" => 206,
|
75
|
-
"11.04" => 210, "11.10" => 214,
|
76
|
-
"12.04" => 216
|
77
|
-
}
|
78
|
-
})
|
79
|
-
end
|
80
|
-
|
81
|
-
# Public: Build the class constant Hash for mapping server sizes to available
|
82
|
-
# Rackspace Cloud Flavor IDs.
|
83
|
-
#
|
84
|
-
# Returns nothing.
|
85
|
-
def build_flavor_maps
|
86
|
-
self.class.const_set(:FLAVOR_LIST, [
|
87
|
-
{id: 1, mem: 256, hdd: 10},
|
88
|
-
{id: 2, mem: 512, hdd: 20},
|
89
|
-
{id: 3, mem: 1024, hdd: 40},
|
90
|
-
{id: 4, mem: 2048, hdd: 80},
|
91
|
-
{id: 5, mem: 4096, hdd: 160},
|
92
|
-
{id: 6, mem: 8192, hdd: 320},
|
93
|
-
{id: 7, mem: 15872, hdd: 620},
|
94
|
-
{id: 8, mem: 30720, hdd: 1200}
|
95
|
-
])
|
96
|
-
end
|
97
|
-
end
|
@@ -1,93 +0,0 @@
|
|
1
|
-
require 'cloudflock/target/servers/platform'
|
2
|
-
|
3
|
-
# Public: Override the Platform class provided by the servers provider to build
|
4
|
-
# Image ID maps corresponding to to Rackspace Open Cloud UUIDs.
|
5
|
-
class CloudFlock::Target::Servers::Platform::V2 <
|
6
|
-
CloudFlock::Target::Servers::Platform
|
7
|
-
# Public: Build the class constant Hashes for mapping given Platforms to
|
8
|
-
# Rackspace Open Cloud Image IDs.
|
9
|
-
#
|
10
|
-
# Returns nothing.
|
11
|
-
def build_image_maps
|
12
|
-
self.class.const_set(:UNMANAGED_MAP, {
|
13
|
-
amazon:
|
14
|
-
{
|
15
|
-
"*" => "a3a2c42f-575f-4381-9c6d-fcd3b7d07d17"
|
16
|
-
},
|
17
|
-
arch:
|
18
|
-
{
|
19
|
-
"*" => "c94f5e59-0760-467a-ae70-9a37cfa6b94e"
|
20
|
-
},
|
21
|
-
centos:
|
22
|
-
{
|
23
|
-
"5" => "03318d19-b6e6-4092-9b5c-4758ee0ada60",
|
24
|
-
"6" => "a3a2c42f-575f-4381-9c6d-fcd3b7d07d17"
|
25
|
-
},
|
26
|
-
debian:
|
27
|
-
{
|
28
|
-
"6" => "a10eacf7-ac15-4225-b533-5744f1fe47c1"
|
29
|
-
},
|
30
|
-
fedora:
|
31
|
-
{
|
32
|
-
"16" => "bca91446-e60e-42e7-9e39-0582e7e20fb9",
|
33
|
-
"17" => "d42f821e-c2d1-4796-9f07-af5ed7912d0e"
|
34
|
-
},
|
35
|
-
gentoo:
|
36
|
-
{
|
37
|
-
"*" => "110d5bd8-a0dc-4cf5-8e75-149a58c17bbf"
|
38
|
-
},
|
39
|
-
redhat:
|
40
|
-
{
|
41
|
-
"5" => "644be485-411d-4bac-aba5-5f60641d92b5",
|
42
|
-
"6" => "d6dd6c70-a122-4391-91a8-decb1a356549"
|
43
|
-
},
|
44
|
-
ubuntu:
|
45
|
-
{
|
46
|
-
"10.04" => "d531a2dd-7ae9-4407-bb5a-e5ea03303d98",
|
47
|
-
"11.04" => "8bf22129-8483-462b-a020-1754ec822770",
|
48
|
-
"11.10" => "3afe97b2-26dc-49c5-a2cc-a2fc8d80c001",
|
49
|
-
"12.04" => "5cebb13a-f783-4f8c-8058-c4182c724ccd"
|
50
|
-
}
|
51
|
-
})
|
52
|
-
|
53
|
-
self.class.const_set(:MANAGED_MAP, {
|
54
|
-
amazon:
|
55
|
-
{
|
56
|
-
"*" => "c195ef3b-9195-4474-b6f7-16e5bd86acd0"
|
57
|
-
},
|
58
|
-
centos:
|
59
|
-
{
|
60
|
-
"5" => "03318d19-b6e6-4092-9b5c-4758ee0ada60",
|
61
|
-
"6" => "c195ef3b-9195-4474-b6f7-16e5bd86acd0"
|
62
|
-
},
|
63
|
-
redhat:
|
64
|
-
{
|
65
|
-
"5" => "644be485-411d-4bac-aba5-5f60641d92b5",
|
66
|
-
"6" => "d6dd6c70-a122-4391-91a8-decb1a356549"
|
67
|
-
},
|
68
|
-
ubuntu:
|
69
|
-
{
|
70
|
-
"10.04" => "d531a2dd-7ae9-4407-bb5a-e5ea03303d98",
|
71
|
-
"11.04" => "8bf22129-8483-462b-a020-1754ec822770",
|
72
|
-
"11.10" => "3afe97b2-26dc-49c5-a2cc-a2fc8d80c001",
|
73
|
-
"12.04" => "5cebb13a-f783-4f8c-8058-c4182c724ccd"
|
74
|
-
}
|
75
|
-
})
|
76
|
-
end
|
77
|
-
|
78
|
-
# Public: Build the class constant Hash for mapping server sizes to available
|
79
|
-
# Rackspace Cloud Flavor IDs.
|
80
|
-
#
|
81
|
-
# Returns nothing.
|
82
|
-
def build_flavor_maps
|
83
|
-
self.class.const_set(:FLAVOR_LIST, [
|
84
|
-
{id: 2, mem: 512, hdd: 20},
|
85
|
-
{id: 3, mem: 1024, hdd: 40},
|
86
|
-
{id: 4, mem: 2048, hdd: 80},
|
87
|
-
{id: 5, mem: 4096, hdd: 160},
|
88
|
-
{id: 6, mem: 8192, hdd: 320},
|
89
|
-
{id: 7, mem: 15872, hdd: 620},
|
90
|
-
{id: 8, mem: 30720, hdd: 1200}
|
91
|
-
])
|
92
|
-
end
|
93
|
-
end
|
data/lib/cloudflock/version.rb
DELETED