solutious-rudy 0.7.3 → 0.7.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. data/CHANGES.txt +28 -5
  2. data/README.rdoc +1 -1
  3. data/Rudyfile +51 -19
  4. data/bin/ird +153 -0
  5. data/bin/rudy +18 -23
  6. data/bin/rudy-ec2 +5 -10
  7. data/bin/rudy-s3 +1 -3
  8. data/bin/rudy-sdb +0 -2
  9. data/examples/README.md +10 -0
  10. data/examples/debian-sinatra-passenger/commands.rb +19 -0
  11. data/examples/debian-sinatra-passenger/machines.rb +32 -0
  12. data/examples/debian-sinatra-passenger/routines.rb +30 -0
  13. data/examples/debian-sinatra-thin/commands.rb +17 -0
  14. data/examples/debian-sinatra-thin/machines.rb +35 -0
  15. data/examples/debian-sinatra-thin/routines.rb +72 -0
  16. data/lib/rudy.rb +8 -17
  17. data/lib/rudy/aws.rb +1 -2
  18. data/lib/rudy/aws/ec2/address.rb +0 -1
  19. data/lib/rudy/aws/ec2/snapshot.rb +11 -0
  20. data/lib/rudy/aws/s3.rb +6 -3
  21. data/lib/rudy/cli.rb +12 -2
  22. data/lib/rudy/cli/aws/ec2/candy.rb +19 -48
  23. data/lib/rudy/cli/aws/ec2/images.rb +109 -122
  24. data/lib/rudy/cli/aws/s3/buckets.rb +1 -2
  25. data/lib/rudy/cli/config.rb +13 -0
  26. data/lib/rudy/cli/disks.rb +24 -1
  27. data/lib/rudy/cli/routines.rb +10 -11
  28. data/lib/rudy/config.rb +6 -9
  29. data/lib/rudy/config/objects.rb +4 -0
  30. data/lib/rudy/global.rb +4 -5
  31. data/lib/rudy/huxtable.rb +23 -8
  32. data/lib/rudy/machines.rb +11 -4
  33. data/lib/rudy/metadata.rb +8 -94
  34. data/lib/rudy/metadata/backup.rb +113 -0
  35. data/lib/rudy/metadata/backups.rb +65 -0
  36. data/lib/rudy/{disks.rb → metadata/disk.rb} +36 -69
  37. data/lib/rudy/metadata/disks.rb +67 -0
  38. data/lib/rudy/metadata/objectbase.rb +104 -0
  39. data/lib/rudy/mixins.rb +2 -0
  40. data/lib/rudy/routines.rb +173 -88
  41. data/lib/rudy/routines/helpers/dependshelper.rb +34 -0
  42. data/lib/rudy/routines/helpers/diskhelper.rb +174 -5
  43. data/lib/rudy/routines/helpers/scmhelper.rb +2 -2
  44. data/lib/rudy/routines/helpers/scripthelper.rb +11 -4
  45. data/lib/rudy/routines/passthrough.rb +3 -1
  46. data/lib/rudy/routines/reboot.rb +75 -0
  47. data/lib/rudy/routines/startup.rb +3 -3
  48. data/lib/rudy/scm/git.rb +17 -17
  49. data/lib/rudy/scm/svn.rb +46 -5
  50. data/lib/rudy/utils.rb +3 -2
  51. data/rudy.gemspec +24 -46
  52. data/test/30_sdb_metadata/10_disks_test.rb +5 -5
  53. metadata +35 -67
  54. data/lib/annoy.rb +0 -298
  55. data/lib/console.rb +0 -404
  56. data/lib/escape.rb +0 -305
  57. data/lib/rudy/backup.rb +0 -135
  58. data/lib/storable.rb +0 -292
  59. data/lib/sysinfo.rb +0 -285
  60. data/lib/tryouts.rb +0 -33
  61. data/vendor/highline-1.5.1/CHANGELOG +0 -222
  62. data/vendor/highline-1.5.1/INSTALL +0 -35
  63. data/vendor/highline-1.5.1/LICENSE +0 -7
  64. data/vendor/highline-1.5.1/README +0 -63
  65. data/vendor/highline-1.5.1/Rakefile +0 -82
  66. data/vendor/highline-1.5.1/TODO +0 -6
  67. data/vendor/highline-1.5.1/examples/ansi_colors.rb +0 -38
  68. data/vendor/highline-1.5.1/examples/asking_for_arrays.rb +0 -18
  69. data/vendor/highline-1.5.1/examples/basic_usage.rb +0 -75
  70. data/vendor/highline-1.5.1/examples/color_scheme.rb +0 -32
  71. data/vendor/highline-1.5.1/examples/limit.rb +0 -12
  72. data/vendor/highline-1.5.1/examples/menus.rb +0 -65
  73. data/vendor/highline-1.5.1/examples/overwrite.rb +0 -19
  74. data/vendor/highline-1.5.1/examples/page_and_wrap.rb +0 -322
  75. data/vendor/highline-1.5.1/examples/password.rb +0 -7
  76. data/vendor/highline-1.5.1/examples/trapping_eof.rb +0 -22
  77. data/vendor/highline-1.5.1/examples/using_readline.rb +0 -17
  78. data/vendor/highline-1.5.1/lib/highline.rb +0 -758
  79. data/vendor/highline-1.5.1/lib/highline/color_scheme.rb +0 -120
  80. data/vendor/highline-1.5.1/lib/highline/compatibility.rb +0 -17
  81. data/vendor/highline-1.5.1/lib/highline/import.rb +0 -43
  82. data/vendor/highline-1.5.1/lib/highline/menu.rb +0 -395
  83. data/vendor/highline-1.5.1/lib/highline/question.rb +0 -463
  84. data/vendor/highline-1.5.1/lib/highline/system_extensions.rb +0 -193
  85. data/vendor/highline-1.5.1/setup.rb +0 -1360
  86. data/vendor/highline-1.5.1/test/tc_color_scheme.rb +0 -56
  87. data/vendor/highline-1.5.1/test/tc_highline.rb +0 -823
  88. data/vendor/highline-1.5.1/test/tc_import.rb +0 -54
  89. data/vendor/highline-1.5.1/test/tc_menu.rb +0 -429
  90. data/vendor/highline-1.5.1/test/ts_all.rb +0 -15
@@ -85,27 +85,24 @@ module Rudy
85
85
  unless File.exists?(Rudy::CONFIG_FILE)
86
86
  puts "Creating #{Rudy::CONFIG_FILE}"
87
87
  rudy_config = Rudy::Utils.without_indent %Q{
88
- # Amazon Web Services
89
- # Account access indentifiers.
90
- accounts do
91
- aws do
88
+ accounts do # Account Access Indentifiers
89
+ aws do # amazon web services
92
90
  name "Rudy Default"
93
91
  accountnum ""
94
92
  accesskey ""
95
93
  secretkey ""
96
- privatekey "~/path/2/pk-xxxx.pem"
94
+ privatekey "~/path/2/pk-xxxx.pem"
97
95
  cert "~/path/2/cert-xxxx.pem"
98
96
  end
99
97
  end
100
98
 
101
- # Global Defaults
102
- defaults do
99
+ defaults do # Global Defaults
103
100
  region :"us-east-1"
104
101
  zone :"us-east-1b"
105
102
  environment :stage
106
103
  role :app
107
- position "01"
108
- user ENV['USER'].to_sym
104
+ user Rudy.sysinfo.user.to_sym
105
+ color false # set to true for terminal colors
109
106
  end
110
107
  }
111
108
  Rudy::Utils.write_to_file(Rudy::CONFIG_FILE, rudy_config, 'w', 0600)
@@ -117,7 +117,11 @@ class Rudy::Config
117
117
  forced_hash :create
118
118
  forced_hash :destroy
119
119
  forced_hash :restore
120
+ forced_hash :umount
121
+ forced_hash :unmount
120
122
  forced_hash :mount
123
+ forced_hash :snapshot
124
+ forced_hash :restore
121
125
 
122
126
  # Script blocks
123
127
  forced_hash :before
@@ -85,23 +85,22 @@ module Rudy
85
85
  postprocess
86
86
  end
87
87
 
88
-
88
+ def to_s(*args)
89
+ super()
90
+ end
91
+
89
92
  private
90
93
 
91
94
 
92
95
  def postprocess
93
96
  apply_environment_variables
94
97
  apply_system_defaults
95
-
96
98
  @nocolor = !@color unless @color.nil?
97
99
  @cert &&= File.expand_path(@cert)
98
100
  @privatekey &&= File.expand_path(@privatekey)
99
101
  @position &&= @position.to_s.rjust(2, '0')
100
102
  @format &&= @format.to_sym rescue nil
101
-
102
- @nocolor ? String.disable_color : String.enable_color
103
103
  @quiet ? Rudy.enable_quiet : Rudy.disable_quiet
104
- @yes ? Annoy.enable_skip : Annoy.disable_skip
105
104
  end
106
105
 
107
106
  def apply_environment_variables
@@ -12,7 +12,9 @@ module Rudy
12
12
  # include Rudy::Huxtable
13
13
  #
14
14
  # def print_config
15
- # p self.config.defaults
15
+ # p @@config.defaults # {:nocolor => true, ...}
16
+ # p @@global.verbose # => 1
17
+ # p @@logger.class # => StringIO
16
18
  # end
17
19
  #
18
20
  # end
@@ -105,15 +107,15 @@ module Rudy
105
107
  # If there's a private key path in the config this will return
106
108
  # the basename (it's assumed the Amazon KeyPair has the same
107
109
  # name as the file). Otherwise this returns the Rudy style
108
- # name: <tt>key-ENV-ROLE-USER</tt>. Or if this the user is
109
- # root: <tt>key-ENV-ROLE</tt>
110
+ # name: <tt>key-ZONE-ENV-ROLE-USER</tt>. Or if this the user is
111
+ # root: <tt>key-ZONE-ENV-ROLE</tt>
110
112
  def user_keypairname(user)
111
113
  kp = user_keypairpath(user)
112
114
  if kp
113
115
  kp = Huxtable.keypair_path_to_name(kp)
114
116
  else
115
117
  n = (user.to_s == 'root') ? '' : "-#{user}"
116
- "key-%s%s" % [current_machine_group, n]
118
+ "key-%s-%s%s" % [@@global.zone, current_machine_group, n]
117
119
  end
118
120
  end
119
121
  def root_keypairname
@@ -136,7 +138,7 @@ module Rudy
136
138
  # These are used as the root SSH keys. If we can find a user defined key, we'll
137
139
  # check the config path for a generated one.
138
140
  if !path && name.to_s == 'root'
139
- path = File.join(self.config_dirname, "key-#{current_machine_group}")
141
+ path = File.join(self.config_dirname, "key-#{@@global.zone}-#{current_machine_group}")
140
142
  end
141
143
  path = File.expand_path(path) if path && File.exists?(path)
142
144
  path
@@ -257,8 +259,8 @@ module Rudy
257
259
  # Return a hash:
258
260
  #
259
261
  # :after:
260
- # - :root: pwd
261
- # - :rudy: pwd
262
+ # - :root: !ruby/object:Proc {}
263
+ # - :rudy: !ruby/object:Proc {}
262
264
  # :disks:
263
265
  # :create:
264
266
  # /rudy/example1:
@@ -268,12 +270,18 @@ module Rudy
268
270
  # :device: /dev/sdm
269
271
  # :size: 1
270
272
  #
273
+ # NOTE: dashes in +action+ are converted to underscores. We do this
274
+ # because routine names are defined by method names and valid
275
+ # method names don't use dashes. This way, we can use a dash on the
276
+ # command-line which looks nicer (underscore still works of course).
271
277
  def fetch_routine_config(action)
272
278
  raise "No action specified" unless action
273
279
  raise NoConfig unless @@config
274
280
  raise NoRoutinesConfig unless @@config.routines
275
281
  raise NoGlobal unless @@global
276
282
 
283
+ action = action.to_s.tr('-', '_')
284
+
277
285
  zon, env, rol = @@global.zone, @@global.environment, @@global.role
278
286
 
279
287
  disk_defs = fetch_machine_param(:disks) || {}
@@ -288,7 +296,10 @@ module Rudy
288
296
  return routine unless routine.has_key?(:disks)
289
297
 
290
298
  routine.disks.each_pair do |raction,disks|
291
-
299
+ unless disks.kind_of?(Hash)
300
+ @@logger.puts "#{raction} is not defined. Check your #{action} routines config.".color(:red)
301
+ next
302
+ end
292
303
  disks.each_pair do |path, props|
293
304
  unless disk_defs.has_key?(path)
294
305
  @@logger.puts "#{path} is not defined. Check your #{action} machines config.".color(:red)
@@ -304,6 +315,10 @@ module Rudy
304
315
  routine
305
316
  end
306
317
 
318
+ # Is +action+ a valid routine for the current machine group?
319
+ def valid_routine?(action)
320
+ !fetch_routine_config(action).nil?
321
+ end
307
322
 
308
323
  def fetch_machine_param(parameter)
309
324
  raise "No parameter specified" unless parameter
@@ -168,8 +168,7 @@ module Rudy
168
168
  end
169
169
 
170
170
  end
171
-
172
-
171
+
173
172
 
174
173
  class Machines
175
174
  include Rudy::MetaData
@@ -267,8 +266,16 @@ module Rudy
267
266
  # TODO: add logic that checks whether the instances are running.
268
267
  end
269
268
 
270
-
271
-
269
+ end
270
+
271
+
272
+ class Machines::Offline
273
+ def list(more=[], less=[], &each_mach)
274
+ m = Rudy::Machine.new
275
+ m.dns_public = 'localhost'
276
+ each_mach.call(m) if each_mach
277
+ [m]
278
+ end
272
279
  end
273
280
 
274
281
  end
@@ -1,92 +1,4 @@
1
1
 
2
-
3
- module Rudy
4
- module MetaData
5
- module ObjectBase
6
- include Rudy::Huxtable
7
-
8
- def initialize(*args)
9
- a, s, r = @@global.accesskey, @@global.secretkey, @@global.region
10
- @sdb = Rudy::AWS::SDB.new(a, s, r)
11
- @ec2inst = Rudy::AWS::EC2::Instances.new(a, s, r)
12
- @rvol = Rudy::AWS::EC2::Volumes.new(a, s, r)
13
- @radd = Rudy::AWS::EC2::Addresses.new(a, s, r)
14
- init(*args)
15
- end
16
-
17
- def init(*args); raise "Must override init"; end
18
-
19
- def valid?; raise "#{self.class} must override 'valid?'"; end
20
-
21
- def to_query(more=[], less=[])
22
- Rudy::AWS::SDB.generate_query build_criteria(more, less)
23
- end
24
-
25
- def to_select(more=[], less=[])
26
- Rudy::AWS::SDB.generate_select ['*'], Rudy::DOMAIN, build_criteria(more, less)
27
- end
28
-
29
- def name(identifier, zon, env, rol, pos, *other)
30
- pos = pos.to_s.rjust 2, '0'
31
- [identifier, zon, env, rol, pos, *other].flatten.compact.join(Rudy::DELIM)
32
- end
33
-
34
- def save(replace=true)
35
- replace = true if replace.nil?
36
- @sdb ||= Rudy::AWS::SDB.new(@@global.accesskey, @@global.secretkey, @@global.region)
37
- @sdb.put(Rudy::DOMAIN, name, self.to_hash, replace) # Always returns nil
38
- true
39
- end
40
-
41
- def destroy
42
- @sdb ||= Rudy::AWS::SDB.new(@@global.accesskey, @@global.secretkey, @@global.region)
43
- @sdb.destroy(Rudy::DOMAIN, name)
44
- true
45
- end
46
-
47
- def refresh
48
- @sdb ||= Rudy::AWS::SDB.new(@@global.accesskey, @@global.secretkey, @@global.region)
49
- h = @sdb.get(Rudy::DOMAIN, name) || {}
50
- from_hash(h)
51
- end
52
-
53
- def ==(other)
54
- return false unless other.is_a?(self.class)
55
- self.name == other.name
56
- end
57
-
58
- def to_s
59
- str = ""
60
- field_names.each do |key|
61
- str << sprintf(" %22s: %s#{$/}", key, self.send(key.to_sym))
62
- end
63
- str
64
- end
65
-
66
-
67
- protected
68
-
69
- # Builds a zipped Array from a list of criteria.
70
- # The list of criteria is made up of metadata object attributes.
71
- # The list is constructed by taking the adding +more+, and
72
- # subtracting +less+ from <tt>:rtype, :region, :zone, :environment, :role, :position</tt>
73
- #
74
- # Returns [[:rtype, value], [:zone, value], ...]
75
- def build_criteria(more=[], less=[])
76
- criteria = [:rtype, :region, :zone, :environment, :role, :position, *more].compact
77
- criteria -= [*less].flatten.uniq.compact
78
- values = criteria.collect do |n|
79
- self.send(n.to_sym)
80
- end
81
- criteria.zip(values)
82
- end
83
-
84
- end
85
- end
86
- end
87
-
88
-
89
-
90
2
  module Rudy
91
3
  module MetaData
92
4
  include Rudy::Huxtable
@@ -113,25 +25,27 @@ module Rudy
113
25
 
114
26
  # Returns a generic zipped Array of metadata
115
27
  # (There is region, zone, environment, role, but no rtype)
116
- def build_criteria(more=[], less=[])
28
+ def build_criteria(more=[], less=[], local={})
117
29
  # TODO: This build_criteria treats "more" differently than the
118
30
  # ObjectBase one. Sort it out! (This way is better)
119
31
  names = [:region, :zone, :environment, :role].compact
120
32
  names -= [*less].flatten.uniq.compact
121
33
  values = names.collect do |n|
122
- @@global.send(n.to_sym)
34
+ local[n.to_sym] || @@global.send(n.to_sym)
123
35
  end
124
36
  names.zip(values) + more
125
37
  end
126
38
 
127
- def to_query(more=[], less=[])
128
- Rudy::AWS::SDB.generate_query build_criteria(more, less)
39
+ def to_query(more=[], less=[], local={})
40
+ Rudy::AWS::SDB.generate_query build_criteria(more, less, local)
129
41
  end
130
42
 
131
- def to_select(more=[], less=[])
132
- Rudy::AWS::SDB.generate_select ['*'], Rudy::DOMAIN, build_criteria(more, less)
43
+ def to_select(more=[], less=[], local={})
44
+ Rudy::AWS::SDB.generate_select ['*'], Rudy::DOMAIN, build_criteria(more, less, local)
133
45
  end
134
46
 
135
47
  end
136
48
  end
137
49
 
50
+ Rudy::Utils.require_glob(RUDY_LIB, 'rudy', 'metadata', 'objectbase.rb')
51
+ Rudy::Utils.require_glob(RUDY_LIB, 'rudy', 'metadata', '*.rb')
@@ -0,0 +1,113 @@
1
+ module Rudy::MetaData
2
+ class Backup < Storable
3
+ include Rudy::MetaData::ObjectBase
4
+
5
+ field :rtype
6
+ field :awsid
7
+
8
+ field :region
9
+ field :zone
10
+ field :environment
11
+ field :role
12
+ field :position
13
+ field :path
14
+
15
+ field :date
16
+ field :time
17
+ field :second
18
+
19
+ field :created => Integer
20
+
21
+ field :size
22
+ field :fstype
23
+ field :volume
24
+
25
+ require 'date'
26
+
27
+
28
+ def init(volume=nil, path=nil, position=nil)
29
+ # NOTE: Arguments must be optional or Storable will raise an exception!
30
+ @volume= volume
31
+ @path = path
32
+ @rtype = 'back'
33
+ @region = @@global.region
34
+ @zone = @@global.zone
35
+ @environment = @@global.environment
36
+ @role = @@global.role
37
+ @position = position || @@global.position
38
+
39
+
40
+ now = Time.now.utc
41
+ datetime = Backup.format_timestamp(now).split(Rudy::DELIM)
42
+ @created = now.to_i
43
+ @date, @time, @second = datetime
44
+
45
+ postprocess
46
+ end
47
+
48
+
49
+ def name
50
+ sep=File::SEPARATOR
51
+ dirs = @path.split sep if @path && !@path.empty?
52
+ dirs.shift while dirs && (dirs[0].nil? || dirs[0].empty?)
53
+ args = [dirs, @date, @time, @second].flatten
54
+ super("back", @zone, @environment, @role, @position, *args)
55
+ end
56
+
57
+ def nice_time
58
+ return "" unless @date && @time
59
+ t = @date.scan(/(\d\d\d\d)(\d\d)(\d\d)/).join('-')
60
+ t << " " << @time.scan(/(\d\d)(\d\d)/).join(':')
61
+ t
62
+ end
63
+
64
+ def to_s(*args)
65
+ str = ""
66
+ field_names.each do |key|
67
+ str << sprintf(" %22s: %s#{$/}", key, self.send(key.to_sym))
68
+ end
69
+ str
70
+ end
71
+
72
+ def disk
73
+ rdisk = Rudy::Disks.new
74
+ disk = Rudy::MetaData::Disk.new(@path, nil, nil, @position)
75
+ disk.region, disk.zone = @region, @zone
76
+ disk.environment, disk.role, disk.position = @environment, @role, @position
77
+ diskobj = rdisk.get(disk.name)
78
+ diskobj || disk
79
+ end
80
+
81
+ def create(volume=nil)
82
+ volume ||= @volume
83
+ vol = @rsnap.create(volume)
84
+ @awsid = vol.awsid
85
+ self.save
86
+ self
87
+ end
88
+
89
+ # 20090224-1813-36
90
+ def Backup.format_timestamp(dat)
91
+ mon, day, hour, min, sec = [dat.mon, dat.day, dat.hour, dat.min, dat.sec].collect { |v| v.to_s.rjust(2, "0") }
92
+ [dat.year, mon, day, Rudy::DELIM, hour, min, Rudy::DELIM, sec].join
93
+ end
94
+
95
+ def to_query(more=[], less=[])
96
+ query = super([:path, :date, :time, :second, *more], less)
97
+ end
98
+
99
+ def to_select(more=[], less=[])
100
+ query = super([:path, :date, :time, :second, *more], less)
101
+ end
102
+
103
+ # Does this disk have enough info to be saved or used?
104
+ # The test is based on the same criteria for building
105
+ # SimpleDB queries.
106
+ def valid?
107
+ criteria = build_criteria([:path]).flatten
108
+ criteria.size == criteria.compact.size
109
+ end
110
+
111
+ end
112
+ end
113
+
@@ -0,0 +1,65 @@
1
+
2
+
3
+ module Rudy
4
+ class Backups
5
+ include Rudy::MetaData
6
+
7
+ def init
8
+ now = Time.now.utc
9
+ datetime = Rudy::MetaData::Backup.format_timestamp(now).split(Rudy::DELIM)
10
+ @created = now.to_i
11
+ @date, @time, @second = datetime
12
+ end
13
+
14
+ #def create(&each_mach)
15
+
16
+ #end
17
+
18
+
19
+ def destroy(&each_mach)
20
+ list do |backup|
21
+ puts "Destroying #{backup.name}"
22
+ backup.destroy
23
+ end
24
+ end
25
+
26
+ def list(more=[], less=[], local={}, &each_backup)
27
+ backups = list_as_hash(more, less, local, &each_backup)
28
+ backups &&= backups.values
29
+ backups
30
+ end
31
+
32
+ def list_as_hash(more=[], less=[], local={}, &each_backup)
33
+ query = to_select([:rtype, 'back'], less, local)
34
+ list = @sdb.select(query) || {}
35
+ backups = {}
36
+ list.each_pair do |n,d|
37
+ backups[n] = Rudy::MetaData::Backup.from_hash(d)
38
+ end
39
+ backups.each_pair { |n,backup| each_backup.call(backup) } if each_backup
40
+ backups = nil if backups.empty?
41
+ backups
42
+ end
43
+
44
+ def get(rname=nil)
45
+ dhash = @sdb.get(Rudy::DOMAIN, rname)
46
+ return nil if dhash.nil? || dhash.empty?
47
+ d = Rudy::MetaData::Backup.from_hash(dhash)
48
+ d.update if d
49
+ d
50
+ end
51
+
52
+
53
+ def running?
54
+ !list.nil?
55
+ # TODO: add logic that checks whether the instances are running.
56
+ end
57
+
58
+ def to_select(*args)
59
+ query = super(*args)
60
+ query << " and created != '0' order by created desc"
61
+ end
62
+
63
+ end
64
+ end
65
+