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.
Files changed (52) hide show
  1. checksums.yaml +15 -0
  2. data/bin/cloudflock +7 -1
  3. data/bin/cloudflock-files +2 -14
  4. data/bin/cloudflock-profile +3 -15
  5. data/bin/cloudflock-servers +3 -22
  6. data/bin/cloudflock.default +3 -22
  7. data/lib/cloudflock/app/common/cleanup/unix.rb +23 -0
  8. data/lib/cloudflock/app/common/cleanup.rb +107 -0
  9. data/lib/cloudflock/app/common/exclusions/unix/centos.rb +18 -0
  10. data/lib/cloudflock/app/common/exclusions/unix/redhat.rb +18 -0
  11. data/lib/cloudflock/app/common/exclusions/unix.rb +58 -0
  12. data/lib/cloudflock/app/common/exclusions.rb +57 -0
  13. data/lib/cloudflock/app/common/platform_action.rb +59 -0
  14. data/lib/cloudflock/app/common/rackspace.rb +63 -0
  15. data/lib/cloudflock/app/common/servers.rb +673 -0
  16. data/lib/cloudflock/app/files-migrate.rb +246 -0
  17. data/lib/cloudflock/app/server-migrate.rb +327 -0
  18. data/lib/cloudflock/app/server-profile.rb +130 -0
  19. data/lib/cloudflock/app.rb +87 -0
  20. data/lib/cloudflock/error.rb +6 -19
  21. data/lib/cloudflock/errstr.rb +31 -0
  22. data/lib/cloudflock/remote/files.rb +82 -22
  23. data/lib/cloudflock/remote/ssh.rb +234 -278
  24. data/lib/cloudflock/target/servers/platform.rb +92 -115
  25. data/lib/cloudflock/target/servers/profile.rb +331 -340
  26. data/lib/cloudflock/task/server-profile.rb +651 -0
  27. data/lib/cloudflock.rb +6 -8
  28. metadata +49 -68
  29. data/lib/cloudflock/interface/cli/app/common/servers.rb +0 -128
  30. data/lib/cloudflock/interface/cli/app/files.rb +0 -179
  31. data/lib/cloudflock/interface/cli/app/servers/migrate.rb +0 -491
  32. data/lib/cloudflock/interface/cli/app/servers/profile.rb +0 -88
  33. data/lib/cloudflock/interface/cli/app/servers.rb +0 -2
  34. data/lib/cloudflock/interface/cli/console.rb +0 -213
  35. data/lib/cloudflock/interface/cli/opts/servers.rb +0 -20
  36. data/lib/cloudflock/interface/cli/opts.rb +0 -87
  37. data/lib/cloudflock/interface/cli.rb +0 -15
  38. data/lib/cloudflock/target/servers/data/exceptions/base.txt +0 -44
  39. data/lib/cloudflock/target/servers/data/exceptions/platform/amazon.txt +0 -10
  40. data/lib/cloudflock/target/servers/data/exceptions/platform/centos.txt +0 -7
  41. data/lib/cloudflock/target/servers/data/exceptions/platform/debian.txt +0 -0
  42. data/lib/cloudflock/target/servers/data/exceptions/platform/redhat.txt +0 -7
  43. data/lib/cloudflock/target/servers/data/exceptions/platform/suse.txt +0 -1
  44. data/lib/cloudflock/target/servers/data/post-migration/chroot/base.txt +0 -1
  45. data/lib/cloudflock/target/servers/data/post-migration/chroot/platform/amazon.txt +0 -19
  46. data/lib/cloudflock/target/servers/data/post-migration/pre/base.txt +0 -3
  47. data/lib/cloudflock/target/servers/data/post-migration/pre/platform/amazon.txt +0 -4
  48. data/lib/cloudflock/target/servers/migrate.rb +0 -466
  49. data/lib/cloudflock/target/servers/platform/v1.rb +0 -97
  50. data/lib/cloudflock/target/servers/platform/v2.rb +0 -93
  51. data/lib/cloudflock/target/servers.rb +0 -5
  52. data/lib/cloudflock/version.rb +0 -3
@@ -1,133 +1,110 @@
1
1
  require 'cpe'
2
2
  require 'cloudflock'
3
+ require 'fog'
3
4
 
4
- # Public: Serves as a small class to easily map host specifications to Image
5
- # and Flavor IDs in Rackspace Cloud.
6
- #
7
- # Examples
8
- #
9
- # # Build platform data for a given CPE object
10
- # platform = Platform.new(cpe)
11
- # platform.image_id
12
- # # => Fixnum
13
- class CloudFlock::Target::Servers::Platform
14
- # Public: Gets/sets whether the target platform will be managed.
15
- attr_accessor :managed
16
- # Public: Gets/sets whether the target platform will use Rack Connect.
17
- attr_accessor :rack_connect
18
-
19
- # Public: Initialize the Platform object.
5
+ module CloudFlock; module Target; module Servers
6
+ # Public: Map host specifications to Image and Flavor IDs in Rackspace Cloud.
20
7
  #
21
- # cpe - CPE object from which to generate platform object.
8
+ # Examples
22
9
  #
23
- # Raises ArgumentError if anything but a CPE object was given.
24
- # Raises KeyError if the CPE object doesn't have a vendor or version defined.
25
- def initialize(cpe)
26
- raise ArgumentError unless cpe.kind_of?(CPE)
27
- raise KeyError if cpe.vendor.nil? or cpe.version.nil?
28
-
29
- @cpe = cpe
30
- @distro = cpe.vendor
31
- @product = cpe.product
32
- @version = cpe.version
33
- @managed = false
34
- @rack_connect = false
35
-
36
- build_maps
37
- end
38
-
39
- # Public: Generate a String of the platform's name/version suitable for
40
- # display
10
+ # platform = Platform.new(cpe, fog)
11
+ # platform.get_appropriate_flavors
12
+ # # => [<Fog::Compute::RackspaceV2::Flavor>, ...]
41
13
  #
42
- # Returns a String describing the Platform
43
- def to_s
44
- "#{@distro.capitalize} #{@product.gsub(/_/, ' ').capitalize} #{@version}"
45
- end
46
-
47
- # Public: Return the Image ID to be used based on whether the account is
48
- # managed, and the platform used
49
- #
50
- # Returns the Image ID corresponding to the Platform object as a String
51
- def image
52
- [:MANAGED_MAP, :UNMANAGED_MAP].each do |map|
53
- unless self.class.const_defined?(map)
54
- raise MapUndefined, "Const #{map} is undefined; maps appear unbuilt"
14
+ # platform.to_s
15
+ # # => "CentOS Linux 6.4"
16
+ class Platform
17
+ # Public: Initialize the Platform object.
18
+ #
19
+ # cpe - CPE object to use in determining image ID.
20
+ # fog - Fog Compute object used to obtain flavor and image maps.
21
+ # (default: nil)
22
+ #
23
+ # Raises ArgumentError if anything but a CPE object is passed.
24
+ # Raises KeyError if the CPE object doesn't have vendor and version
25
+ # defined.
26
+ def initialize(cpe, fog = nil)
27
+ unless cpe.is_a?(CPE)
28
+ raise(ArgumentError, Errstr::NOT_CPE)
29
+ end
30
+ if cpe.vendor.nil? or cpe.version.nil?
31
+ raise(KeyError, Errstr::CPE_INCOMPLETE)
55
32
  end
56
- end
57
-
58
- map = @managed ? self.class::MANAGED_MAP : self.class::UNMANAGED_MAP
59
- distro = @distro.downcase.to_sym
60
33
 
61
- unless map[distro].nil?
62
- return map[distro][@version] unless map[distro][@version].nil?
63
- return map[distro]["*"] unless map[distro]["*"].nil?
34
+ @cpe = cpe
35
+ build_maps(fog)
64
36
  end
65
37
 
66
- nil
67
- end
68
-
69
- # Public: Iterate through TARGET_LIST until a suitably large flavor_id is
70
- # found, then return the appropriate index. If no entry can be found, raise
71
- # ValueError.
72
- #
73
- # symbol - A Symbol referencing the search target in TARGET_LIST.
74
- # value - A Fixnum containing the amount of memory or disk space required.
75
- #
76
- # Returns a Fixnum referencing the TARGET_LIST index.
77
- # Raises ValueError if no symbol describes an appropriate target.
78
- def get_target_by_symbol(symbol, value)
79
- unless self.class.const_defined?(:FLAVOR_LIST)
80
- raise MapUndefined, "FLAVOR_LIST is undefined; maps appear unbuild."
38
+ # Public: Generate a String describing the platform's name/version.
39
+ #
40
+ # Returns a String.
41
+ def to_s
42
+ "#{@cpe.distro.capitalize} #{@cpe.product.gsub(/_/, ' ').capitalize} " \
43
+ "#{@cpe.version}"
81
44
  end
82
45
 
83
- self.class::FLAVOR_LIST.each_with_index do |target, idx|
84
- if target[symbol] > value
85
- return idx
46
+ # Public: Given a resource map (e.g. generated by profiling a host),
47
+ # determine which flavors would be appropriate as migration targets.
48
+ #
49
+ # resource_map - Hash containing memory and hard disk usage information
50
+ # from the source host:
51
+ # :ram - Hash containing memory usage information
52
+ # :mem_used - Amount of memory used in MiB.
53
+ # (default: 0)
54
+ # :swapping? - Whether the source host is swapping.
55
+ # (default: 0)
56
+ # :hdd - Hash containing disk usage information:
57
+ # :disk - Amount of disk used in GB. (default: 0)
58
+ #
59
+ # Returns a Hash containing appropriate flavor IDs mapped to flavor names.
60
+ def get_appropriate_flavors(resource_map = {})
61
+ resource_map[:ram] ||= {mem_used: 0, swapping?: false}
62
+ resource_map[:hdd] ||= {disk: 0}
63
+ ram = resource_map[:ram] * (resource_map[:ram][:swapping?] ? 2 : 1)
64
+ disk = resource_map[:hdd][:disk] * 1.2
65
+
66
+ @flavor_map.select do |id|
67
+ @flavor_map[e][:ram] >= ram && @flavor_map[e][:disk] >= disk
86
68
  end
87
69
  end
88
70
 
89
- raise ValueError, "Unable to find a flavor matching #{symbol} #{value}"
90
- end
91
-
92
- # Internal: Build image and flavor maps
93
- #
94
- # Returns nothing
95
- def build_maps
96
- build_image_maps
97
- build_flavor_maps
98
- end
99
-
100
- # Public: Give a recommendation for a Flavor ID and an Image ID which should
101
- # suffice for a migration target host.
102
- #
103
- # args - Hash containing information on which to base the recommendation:
104
- # :memory - Hash containing memory information:
105
- # :total - Total amount of memory allocated to the host
106
- # profiled.
107
- # :mem_used - Amount of RAM in use at the time of
108
- # profiling.
109
- # :swapping? - Boolean denoting whether the host was
110
- # swapping at the time of profiling.
111
- # :disk - Fixnum containing the amount of disk which appears to be
112
- # in use at the time of profiling.
113
- #
114
- # Returns a Hash containing the Flavor ID and a String containing the
115
- # reasoning for the decision.
116
- def build_recommendation(args)
117
- recommendation = {}
118
- target_mem = get_target_by_symbol(:mem, args[:memory][:mem_used])
119
- target_mem += 1 if args[:memory][:swapping?]
120
-
121
- target_disk = get_target_by_symbol(:hdd, args[:disk])
122
-
123
- if target_mem >= target_disk
124
- recommendation[:flavor] = target_mem
125
- recommendation[:flavor_reason] = "RAM usage"
126
- else
127
- recommendation[:flavor] = target_disk
128
- recommendation[:flavor_reason] = "Disk usage"
71
+ private
72
+
73
+ # Internal: Assemble a map of flavors and images available for
74
+ # provisioning.
75
+ #
76
+ # fog - Fog Compute object used to obtain image/flavor mappings.
77
+ #
78
+ # Sets @image_map and @flavor_map.
79
+ #
80
+ # Returns nothing.
81
+ def build_maps(fog)
82
+ if fog.respond_to?(:images) && fog.respond_to?(:flavors)
83
+ @image_map = fog.images.reduce({}) do |c,e|
84
+ name, ver = map_image_id(e)
85
+ c[name] ||= []
86
+ c[name] << ver
87
+ c
88
+ end
89
+ @flavor_map = fog.flavors.reduce({}) do |c,e|
90
+ c.merge({e.id => { ram: e.ram, disk: e.disk }})
91
+ end
92
+ else
93
+ @image_map = {}
94
+ @flavor_map = {}
95
+ end
129
96
  end
130
97
 
131
- recommendation
98
+ # Internal: Convert a Fog Image Object to a tuple for easy selection later.
99
+ #
100
+ # image - Fog Image object.
101
+ #
102
+ # Returns an Array containing a String and a Hash.
103
+ def map_image_id(image)
104
+ name, _ = image.name.split(/ \d/, 2)
105
+ other = image.name.gsub(Regexp.new("^#{name} ?"), '')
106
+ version, extra = other.split(/ +/, 2)
107
+ [name, { version => { :id => image.id, :extra => extra } } ]
108
+ end
132
109
  end
133
- end
110
+ end; end; end