cloudflock 0.6.1 → 0.7.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.
- 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