solutious-rudy 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,76 @@
1
+ @spec = Gem::Specification.new do |s|
2
+ s.name = "rudy"
3
+ s.version = "0.4.0"
4
+ s.summary = "Your friend in staging and deploying with EC2."
5
+ s.description = s.summary
6
+ s.author = "Delano Mandelbaum"
7
+ s.email = "delano@solutious.com"
8
+ s.homepage = "http://github.com/solutious/rudy"
9
+
10
+ # = MANIFEST =
11
+ # git ls-files
12
+ s.files = %w(
13
+ CHANGES.txt
14
+ LICENSE.txt
15
+ README.rdoc
16
+ Rakefile
17
+ bin/rudy
18
+ bin/rudy-ec2
19
+ lib/aws_sdb.rb
20
+ lib/aws_sdb/error.rb
21
+ lib/aws_sdb/service.rb
22
+ lib/console.rb
23
+ lib/rudy.rb
24
+ lib/rudy/aws.rb
25
+ lib/rudy/aws/ec2.rb
26
+ lib/rudy/aws/s3.rb
27
+ lib/rudy/aws/simpledb.rb
28
+ lib/rudy/command/addresses.rb
29
+ lib/rudy/command/backups.rb
30
+ lib/rudy/command/base.rb
31
+ lib/rudy/command/config.rb
32
+ lib/rudy/command/deploy.rb
33
+ lib/rudy/command/disks.rb
34
+ lib/rudy/command/environment.rb
35
+ lib/rudy/command/groups.rb
36
+ lib/rudy/command/images.rb
37
+ lib/rudy/command/instances.rb
38
+ lib/rudy/command/machines.rb
39
+ lib/rudy/command/metadata.rb
40
+ lib/rudy/command/release.rb
41
+ lib/rudy/command/volumes.rb
42
+ lib/rudy/config.rb
43
+ lib/rudy/metadata.rb
44
+ lib/rudy/metadata/backup.rb
45
+ lib/rudy/metadata/disk.rb
46
+ lib/rudy/scm/svn.rb
47
+ lib/rudy/utils.rb
48
+ lib/storable.rb
49
+ lib/tryouts.rb
50
+ rudy.gemspec
51
+ support/mailtest
52
+ support/rudy-ec2-startup
53
+ tryouts/console_tryout.rb
54
+ )
55
+ s.executables = %w[rudy rudy-ec2]
56
+
57
+ s.extra_rdoc_files = %w[README.rdoc LICENSE.txt]
58
+ s.has_rdoc = true
59
+ s.rdoc_options = ["--line-numbers", "--title", "Rudy: #{s.summary}", "--main", "README.rdoc"]
60
+ s.require_paths = %w[lib]
61
+ s.rubygems_version = '1.1.1'
62
+
63
+
64
+ s.add_dependency 'drydock'
65
+ s.add_dependency 'caesars'
66
+ s.add_dependency 'echoe'
67
+ s.add_dependency 'right_aws'
68
+ s.add_dependency 'net-ssh'
69
+ s.add_dependency 'net-scp'
70
+ s.add_dependency 'net-ssh-gateway'
71
+ s.add_dependency 'net-ssh-multi'
72
+ s.add_dependency 'highline'
73
+
74
+
75
+ s.rubyforge_project = 'rudy'
76
+ end
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # A simple SMTP mailer.
4
+ # You can use this to test mail configuration between machines.
5
+
6
+ # Usage: mailtest hostname email
7
+
8
+ require 'net/smtp'
9
+
10
+ unless ARGV.size == 2
11
+ puts "Usage: mailtest HOSTNAME EMAIL"
12
+ exit 1
13
+ end
14
+
15
+ HOSTNAME = ARGV[0]
16
+ EMAIL = ARGV[1]
17
+
18
+ def send_email(from, from_alias, to, to_alias, subject, message)
19
+ msg = <<END_OF_MESSAGE
20
+ From: #{from_alias} <#{from}>
21
+ To: #{to_alias} <#{to}>
22
+ Subject: #{subject}
23
+
24
+ #{message}
25
+ END_OF_MESSAGE
26
+
27
+ Net::SMTP.start(HOSTNAME) do |smtp|
28
+ smtp.send_message msg, from, to
29
+ end
30
+ end
31
+
32
+ begin
33
+ spice = sprintf("%.3f", rand)
34
+ send_email(HOSTNAME, "Rudy", EMAIL, "Rudy's Friend", "Mail config (#{spice})", "You received this email via #{HOSTNAME}")
35
+ rescue => ex
36
+ puts "ERROR: #{ex.message}"
37
+ exit 1
38
+ end
39
+
40
+ puts "Success!"
@@ -0,0 +1,200 @@
1
+ #!/usr/bin/ruby
2
+
3
+ # what: Rudy EC2 startup script
4
+ # who: delano@solutious.com
5
+ # when: 2009-02-25 (rev: 4)
6
+
7
+ # NOTE: This is a prototype version of this script. A cleaner version
8
+ # with better documentation is forthcoming.
9
+
10
+ # Runs when an ec2 instance startups up.
11
+ # Grabs configuration from the run time user data and stores it locally.
12
+ # See Rudy::Command::Instances#start_instance for the expected yaml format.
13
+
14
+ # Put this in /etc/init.d. Then:
15
+ # * chmod 755 rudy-ec2-startup
16
+ # * cd /etc/rc3.d
17
+ # * ln -s ../init.d/rudy-ec2-startup S17rudy
18
+ # * cd /etc/rc4.d
19
+ # * ln -s ../init.d/rudy-ec2-startup S17rudy
20
+ # * cd /etc/rc5.d
21
+ # * ln -s ../init.d/rudy-ec2-startup S17rudy
22
+
23
+ require 'yaml'
24
+ require 'resolv'
25
+
26
+ LOGFILE = '/var/log/rudy-ec2-startup'
27
+ USERDATA = 'http://169.254.169.254/2008-02-01/user-data'
28
+ METADATA = 'http://169.254.169.254/2008-02-01/meta-data'
29
+
30
+ #LOGFILE = '/tmp/rudy-ec2-startup'
31
+ #USERDATA = 'http://127.0.0.1/2008-02-01/user-data'
32
+ #METADATA = 'http://127.0.0.1/2008-02-01/meta-data'
33
+
34
+ METADATAPARAMS = ['instance-id', 'instance-type']
35
+
36
+ RUDY_CONFIG_DIR=File.join('.rudy')
37
+ RUDY_CONFIG_FILE=File.join('config')
38
+
39
+ module Rudy
40
+ module EC2Startup
41
+ extend self
42
+
43
+ VERSION = 4.freeze
44
+
45
+ def process_config
46
+ begin
47
+ File.unlink(LOGFILE) if File.exists?(LOGFILE)
48
+ log "RUDY (rev#{VERSION}) is in the house"
49
+
50
+ log "Grabing configuration..."
51
+ config_yaml = run("curl -s #{USERDATA}")
52
+
53
+ log "Grabing meta-data..."
54
+ metadata = get_metadata
55
+
56
+ log "Processing metadata..."
57
+ METADATAPARAMS.each do |name|
58
+ default = name.gsub('instance-', '')
59
+ value = (metadata[name] && !metadata[name].empty?) ? metadata[name] : default
60
+ log " ---> #{name}: #{value}"
61
+ write_to_file("/etc/ec2/#{name}", value, "w")
62
+ end
63
+
64
+ log "Processing userdata..."
65
+
66
+ if !config_yaml || config_yaml.empty?
67
+ raise "Nothing to process (did you supply user-data when you created the instance)"
68
+ end
69
+
70
+ config = YAML::load(config_yaml)
71
+ config ||= {}
72
+
73
+ # Print to STDOUT and NOT to the log.
74
+ # We don't want sensitive config values available in the log
75
+ puts "CONFIG: " << config_yaml
76
+
77
+ zone = config[:zone] ? config[:zone].downcase : "zone"
78
+ environment = config[:environment] ? config[:environment].downcase : "env"
79
+ role = config[:role] ? config[:role].downcase : "role"
80
+ position = config[:position] ? config[:position].downcase : "00"
81
+
82
+ hostname = [zone, environment, role, position].join('-')
83
+ log "Setting hostname: #{hostname}"
84
+ `hostname #{hostname}`
85
+
86
+ config[:hosts] ||= {}
87
+ config[:hosts][hostname] = '127.0.0.1'
88
+
89
+ if config[:userdata] && config[:userdata].is_a?(Hash)
90
+ # TODO: How to we get the path to any user's home directory?
91
+ # (when we're not running as that user.)
92
+ config[:userdata].each_pair do |n,hash|
93
+ fileparts = (n == :root) ? ['/root'] : [user_home_dir(n)]
94
+ fileparts << RUDY_CONFIG_DIR
95
+ dirpath = File.join(fileparts)
96
+ filepath = File.join(dirpath, RUDY_CONFIG_FILE)
97
+
98
+ # Backwards compatability
99
+ if !File.directory?(dirpath)
100
+ log "Deleting the deprecated #{dirpath} config"
101
+ File.unlink(dirpath)
102
+ end
103
+
104
+ unless File.exists?(dirpath)
105
+ log "Creating #{dirpath}"
106
+ Dir.mkdir(dirpath, 0700)
107
+ end
108
+
109
+ log "Writing to #{filepath}"
110
+ user_data = {
111
+ :userdata => hash
112
+ }
113
+ write_to_file(filepath, user_data.to_yaml, "w")
114
+ end
115
+ end
116
+
117
+ if config[:hosts] && config[:hosts].is_a?(Hash)
118
+ unless read_file('/etc/hosts') =~ /----- RUDY SAYS -----/
119
+ log "Updating /etc/hosts..."
120
+ write_to_file("/etc/hosts", "\n# ----- RUDY SAYS -----\n", :append)
121
+ config[:hosts].each_pair do |name, address|
122
+ # Respect existing entries
123
+ next if read_file('/etc/hosts') =~ /#{name}/
124
+
125
+ ip_address = (address !~ /^\d.+/) ? Resolv.getaddress(address) : address
126
+
127
+ log " ---> #{name}: #{ip_address}"
128
+ write_to_file("/etc/hosts", "\n#{ip_address}\t#{name}\n", :append)
129
+ end
130
+ end
131
+ end
132
+
133
+ log "Done!"
134
+
135
+ rescue => ex
136
+ log "ERROR: #{ex.message}"
137
+ end
138
+ end
139
+
140
+
141
+ def get_metadata
142
+ metadata = {}
143
+
144
+ begin
145
+ METADATAPARAMS.each do |param|
146
+ log " ---> #{param}"
147
+ metadata[param.to_s] = run("curl -s #{METADATA}/#{param}")
148
+ metadata[param.to_s] = nil if metadata[param.to_s].empty?
149
+ end
150
+ rescue => ex
151
+ log("Problem getting metadata: #{ex.message}")
152
+ end
153
+ metadata
154
+ end
155
+
156
+ def run(command, input='')
157
+ IO.popen(command, 'r+') do |io|
158
+ io.read
159
+ end
160
+ end
161
+
162
+ def get_formatted_time
163
+ t = Time.now
164
+ t_out = t.strftime("%H:%M:%S%p (%m/%d/%Y)")
165
+ end
166
+
167
+ def write_to_file(filename, s, type)
168
+ type = (type == :append) ? 'a' : 'w'
169
+ f = File.open(filename,type)
170
+ f.puts s
171
+ f.close
172
+ end
173
+
174
+ def read_file(path)
175
+ read_file_to_array(path).join('')
176
+ end
177
+
178
+ def read_file_to_array(path)
179
+ contents = []
180
+ return contents unless File.exists?(path)
181
+ open(path, 'r') do |l|
182
+ contents = l.readlines
183
+ end
184
+ contents
185
+ end
186
+
187
+ def user_home_dir(user)
188
+ (`su #{user} -c "echo \\$HOME"` || '').chomp
189
+ end
190
+
191
+ def log(s)
192
+ msg = "#{get_formatted_time}: #{s}"
193
+ write_to_file(LOGFILE, msg, :append)
194
+ puts msg
195
+ end
196
+
197
+ end
198
+ end
199
+
200
+ Rudy::EC2Startup.process_config
@@ -0,0 +1,91 @@
1
+ RUDY_HOME = File.join(File.dirname(__FILE__), '..')
2
+ RUDY_LIB = File.join(RUDY_HOME, 'lib')
3
+ $:.unshift RUDY_LIB # Put our local lib in first place
4
+
5
+ require 'yaml'
6
+ require 'date'
7
+
8
+ require 'tryouts'
9
+ require 'console'
10
+
11
+ raise "Sorry Ruby 1.9 only!" unless RUBY_VERSION =~ /1.9/
12
+
13
+ before do
14
+ @title = "RUDY v0.3"
15
+ @now_utc = Time.now.utc.strftime("%Y-%m-%d %H:%M:%S")
16
+ @props = {
17
+ :zone => "us-east-1b",
18
+ :environment => "stage",
19
+ :role =>"app",
20
+ :position => "01"
21
+ }
22
+ # PROMPT_COMMAND
23
+ end
24
+
25
+ after do
26
+ #Console.clear
27
+ end
28
+
29
+
30
+ tryout :positioned do
31
+ Console.print_at(@title, {:y => Cursor.y, :x => Cursor.x })
32
+ sleep 1
33
+ Console.print_at(@now_utc, {:y => Cursor.y, :x => Console.width, :minus => true})
34
+ puts
35
+ sleep 1
36
+ Console.print_left(@title)
37
+ sleep 1
38
+ Console.print_right(@now_utc)
39
+ puts
40
+ sleep 1
41
+ Console.print_spaced('1'*25, 2, 3, '4'*30, 5, 6)
42
+ puts
43
+ sleep 1
44
+ Console.print_center(Window.bar(50))
45
+
46
+ end
47
+
48
+ tryout :u_r_d_l do
49
+ puts
50
+ Cursor.up && print('.')
51
+ sleep 1
52
+ Cursor.right && print('.')
53
+ sleep 1
54
+ Cursor.left && Cursor.down && print('.')
55
+ sleep 1
56
+ Cursor.left(3) && print('.')
57
+ end
58
+
59
+ tryout :update_inplace do
60
+ [(0..11).to_a, (90..110).to_a].flatten.each do |i|
61
+ Console.print_at(i, {:y => Cursor.y, :x => 4 })
62
+ sleep 0.05
63
+ end
64
+
65
+ end
66
+
67
+
68
+ tryout :danger! do
69
+ win = Window.new(:width => 100, :height => 100)
70
+
71
+ # DEBUGGING: There is a threading bug where the values of props and the
72
+ # string to print are being shared. Make Console and class and give an instance
73
+ # to each thread. However, that could fuck up shit like Cursor.position.
74
+
75
+
76
+ win.static(:right, 0.2, {:y => 0}) do
77
+ Time.now.utc.strftime("%Y-%m-%d %H:%M:%S").colour(:blue, :white, :underline)
78
+ end
79
+ win.static(:left, 0.2) do
80
+ rand
81
+ end
82
+
83
+ win.join_threads
84
+
85
+ puts $/, "Done!"
86
+
87
+ end
88
+
89
+
90
+
91
+
metadata ADDED
@@ -0,0 +1,188 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: solutious-rudy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.0
5
+ platform: ruby
6
+ authors:
7
+ - Delano Mandelbaum
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-02-25 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: drydock
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: caesars
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: echoe
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: right_aws
47
+ type: :runtime
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ - !ruby/object:Gem::Dependency
56
+ name: net-ssh
57
+ type: :runtime
58
+ version_requirement:
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ version:
65
+ - !ruby/object:Gem::Dependency
66
+ name: net-scp
67
+ type: :runtime
68
+ version_requirement:
69
+ version_requirements: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: "0"
74
+ version:
75
+ - !ruby/object:Gem::Dependency
76
+ name: net-ssh-gateway
77
+ type: :runtime
78
+ version_requirement:
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: "0"
84
+ version:
85
+ - !ruby/object:Gem::Dependency
86
+ name: net-ssh-multi
87
+ type: :runtime
88
+ version_requirement:
89
+ version_requirements: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: "0"
94
+ version:
95
+ - !ruby/object:Gem::Dependency
96
+ name: highline
97
+ type: :runtime
98
+ version_requirement:
99
+ version_requirements: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: "0"
104
+ version:
105
+ description: Your friend in staging and deploying with EC2.
106
+ email: delano@solutious.com
107
+ executables:
108
+ - rudy
109
+ - rudy-ec2
110
+ extensions: []
111
+
112
+ extra_rdoc_files:
113
+ - README.rdoc
114
+ - LICENSE.txt
115
+ files:
116
+ - CHANGES.txt
117
+ - LICENSE.txt
118
+ - README.rdoc
119
+ - Rakefile
120
+ - bin/rudy
121
+ - bin/rudy-ec2
122
+ - lib/aws_sdb.rb
123
+ - lib/aws_sdb/error.rb
124
+ - lib/aws_sdb/service.rb
125
+ - lib/console.rb
126
+ - lib/rudy.rb
127
+ - lib/rudy/aws.rb
128
+ - lib/rudy/aws/ec2.rb
129
+ - lib/rudy/aws/s3.rb
130
+ - lib/rudy/aws/simpledb.rb
131
+ - lib/rudy/command/addresses.rb
132
+ - lib/rudy/command/backups.rb
133
+ - lib/rudy/command/base.rb
134
+ - lib/rudy/command/config.rb
135
+ - lib/rudy/command/deploy.rb
136
+ - lib/rudy/command/disks.rb
137
+ - lib/rudy/command/environment.rb
138
+ - lib/rudy/command/groups.rb
139
+ - lib/rudy/command/images.rb
140
+ - lib/rudy/command/instances.rb
141
+ - lib/rudy/command/machines.rb
142
+ - lib/rudy/command/metadata.rb
143
+ - lib/rudy/command/release.rb
144
+ - lib/rudy/command/volumes.rb
145
+ - lib/rudy/config.rb
146
+ - lib/rudy/metadata.rb
147
+ - lib/rudy/metadata/backup.rb
148
+ - lib/rudy/metadata/disk.rb
149
+ - lib/rudy/scm/svn.rb
150
+ - lib/rudy/utils.rb
151
+ - lib/storable.rb
152
+ - lib/tryouts.rb
153
+ - rudy.gemspec
154
+ - support/mailtest
155
+ - support/rudy-ec2-startup
156
+ - tryouts/console_tryout.rb
157
+ has_rdoc: true
158
+ homepage: http://github.com/solutious/rudy
159
+ post_install_message:
160
+ rdoc_options:
161
+ - --line-numbers
162
+ - --title
163
+ - "Rudy: Your friend in staging and deploying with EC2."
164
+ - --main
165
+ - README.rdoc
166
+ require_paths:
167
+ - lib
168
+ required_ruby_version: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: "0"
173
+ version:
174
+ required_rubygems_version: !ruby/object:Gem::Requirement
175
+ requirements:
176
+ - - ">="
177
+ - !ruby/object:Gem::Version
178
+ version: "0"
179
+ version:
180
+ requirements: []
181
+
182
+ rubyforge_project: rudy
183
+ rubygems_version: 1.2.0
184
+ signing_key:
185
+ specification_version: 2
186
+ summary: Your friend in staging and deploying with EC2.
187
+ test_files: []
188
+