rudy 0.2
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.
- data/CHANGES.txt +21 -0
- data/LICENSE.txt +19 -0
- data/README.rdoc +32 -0
- data/Rakefile +68 -0
- data/bin/rudy +258 -0
- data/lib/drydock.rb +525 -0
- data/lib/rudy.rb +102 -0
- data/lib/rudy/aws.rb +65 -0
- data/lib/rudy/aws/ec2.rb +197 -0
- data/lib/rudy/aws/s3.rb +3 -0
- data/lib/rudy/aws/simpledb.rb +48 -0
- data/lib/rudy/command/addresses.rb +41 -0
- data/lib/rudy/command/base.rb +275 -0
- data/lib/rudy/command/commit.rb +10 -0
- data/lib/rudy/command/disks.rb +61 -0
- data/lib/rudy/command/environment.rb +95 -0
- data/lib/rudy/command/groups.rb +59 -0
- data/lib/rudy/command/images.rb +61 -0
- data/lib/rudy/command/instances.rb +109 -0
- data/lib/rudy/command/metadata.rb +57 -0
- data/lib/rudy/command/release.rb +43 -0
- data/lib/rudy/command/volumes.rb +13 -0
- data/lib/rudy/metadata/disk.rb +142 -0
- data/lib/rudy/metadata/environment.rb +0 -0
- data/lib/rudy/scm/svn.rb +57 -0
- data/lib/rudy/utils.rb +65 -0
- data/lib/storable.rb +268 -0
- data/rudy.gemspec +52 -0
- data/support/rudy-ec2-startup +166 -0
- metadata +87 -0
data/lib/rudy/utils.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
|
2
|
+
require 'socket'
|
3
|
+
require 'open-uri'
|
4
|
+
require 'date'
|
5
|
+
|
6
|
+
require 'socket'
|
7
|
+
require 'timeout'
|
8
|
+
|
9
|
+
module Rudy
|
10
|
+
|
11
|
+
# A motley collection of methods that Rudy loves to call!
|
12
|
+
module Utils
|
13
|
+
extend self
|
14
|
+
include Socket::Constants
|
15
|
+
|
16
|
+
# Return the external IP address (the one seen by the internet)
|
17
|
+
def external_ip_address
|
18
|
+
ip = nil
|
19
|
+
%w{solutious.com/ip myip.dk/ whatismyip.com }.each do |sponge| # w/ backup
|
20
|
+
break unless ip.nil?
|
21
|
+
ip = (open("http://#{sponge}") { |f| /([0-9]{1,3}\.){3}[0-9]{1,3}/.match(f.read) }).to_s rescue nil
|
22
|
+
end
|
23
|
+
ip += "/32" if ip
|
24
|
+
ip
|
25
|
+
end
|
26
|
+
|
27
|
+
# Return the local IP address which receives external traffic
|
28
|
+
# from: http://coderrr.wordpress.com/2008/05/28/get-your-local-ip-address/
|
29
|
+
# NOTE: This <em>does not</em> open a connection to the IP address.
|
30
|
+
def internal_ip_address
|
31
|
+
# turn off reverse DNS resolution temporarily
|
32
|
+
orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true
|
33
|
+
ip = UDPSocket.open {|s| s.connect('75.101.137.7', 1); s.addr.last } # Solutious IP
|
34
|
+
ip += "/24" if ip
|
35
|
+
ip
|
36
|
+
ensure
|
37
|
+
Socket.do_not_reverse_lookup = orig
|
38
|
+
end
|
39
|
+
|
40
|
+
# Generates a canonical tag name in the form:
|
41
|
+
# rudy-2009-12-31-r1
|
42
|
+
# where r1 refers to the revision number that day
|
43
|
+
def generate_tag(revision=1)
|
44
|
+
n = DateTime.now
|
45
|
+
y = n.year.to_s.rjust(4, "20")
|
46
|
+
m = n.month.to_s.rjust(2, "0")
|
47
|
+
d = n.mday.to_s.rjust(2, "0")
|
48
|
+
"rudy-%4s-%2s-%2s-r%s" % [y, m, d, revision.to_s.rjust(2, "0")]
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
def service_available?(host, port)
|
53
|
+
begin
|
54
|
+
status = Timeout::timeout(3) do
|
55
|
+
socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
|
56
|
+
sockaddr = Socket.pack_sockaddr_in( port, host )
|
57
|
+
socket.connect( sockaddr )
|
58
|
+
end
|
59
|
+
true
|
60
|
+
rescue Errno::EAFNOSUPPORT, Errno::ECONNREFUSED, SocketError, Timeout::Error => ex
|
61
|
+
false
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/storable.rb
ADDED
@@ -0,0 +1,268 @@
|
|
1
|
+
#--
|
2
|
+
# TODO: Handle nested hashes and arrays.
|
3
|
+
# TODO: to_xml, see: http://codeforpeople.com/lib/ruby/xx/xx-2.0.0/README
|
4
|
+
#++
|
5
|
+
|
6
|
+
require 'yaml'
|
7
|
+
require 'fileutils'
|
8
|
+
|
9
|
+
|
10
|
+
# Storable makes data available in multiple formats and can
|
11
|
+
# re-create objects from files. Fields are defined using the
|
12
|
+
# Storable.field method which tells Storable the order and
|
13
|
+
# name.
|
14
|
+
class Storable
|
15
|
+
NICE_TIME_FORMAT = "%Y-%m-%d@%H:%M:%S".freeze unless defined? NICE_TIME_FORMAT
|
16
|
+
SUPPORTED_FORMATS = %w{tsv csv yaml json}.freeze unless defined? SUPPORTED_FORMATS
|
17
|
+
|
18
|
+
# This value will be used as a default unless provided on-the-fly.
|
19
|
+
# See SUPPORTED_FORMATS for available values.
|
20
|
+
attr_reader :format
|
21
|
+
|
22
|
+
# See SUPPORTED_FORMATS for available values
|
23
|
+
def format=(v)
|
24
|
+
raise "Unsupported format: #{v}" unless SUPPORTED_FORMATS.member?(v)
|
25
|
+
@format = v
|
26
|
+
end
|
27
|
+
|
28
|
+
def init
|
29
|
+
self.class.send(:class_variable_set, :@@field_names, []) unless class_variable_defined?(:@@field_names)
|
30
|
+
self.class.send(:class_variable_set, :@@field_types, []) unless class_variable_defined?(:@@field_types)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Accepts field definitions in the one of the follow formats:
|
34
|
+
#
|
35
|
+
# field :product
|
36
|
+
# field :product => Integer
|
37
|
+
#
|
38
|
+
# The order they're defined determines the order the will be output. The fields
|
39
|
+
# data is available by the standard accessors, class.product and class.product= etc...
|
40
|
+
# The value of the field will be cast to the type (if provided) when read from a file.
|
41
|
+
# The value is not touched when the type is not provided.
|
42
|
+
def self.field(args={})
|
43
|
+
# TODO: Examine casting from: http://codeforpeople.com/lib/ruby/fattr/fattr-1.0.3/
|
44
|
+
args = {args => nil} unless args.is_a? Hash
|
45
|
+
|
46
|
+
args.each_pair do |m,t|
|
47
|
+
|
48
|
+
[[:@@field_names, m], [:@@field_types, t]].each do |tuple|
|
49
|
+
class_variable_set(tuple[0], []) unless class_variable_defined?(tuple[0])
|
50
|
+
class_variable_set(tuple[0], class_variable_get(tuple[0]) << tuple[1])
|
51
|
+
end
|
52
|
+
|
53
|
+
next if method_defined?(m)
|
54
|
+
|
55
|
+
define_method(m) do instance_variable_get("@#{m}") end
|
56
|
+
define_method("#{m}=") do |val|
|
57
|
+
instance_variable_set("@#{m}",val)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns an array of field names defined by self.field
|
63
|
+
def self.field_names
|
64
|
+
class_variable_get(:@@field_names)
|
65
|
+
end
|
66
|
+
# Ditto.
|
67
|
+
def field_names
|
68
|
+
self.class.send(:class_variable_get, :@@field_names)
|
69
|
+
end
|
70
|
+
# Returns an array of field types defined by self.field. Fields that did
|
71
|
+
# not receive a type are set to nil.
|
72
|
+
def self.field_types
|
73
|
+
class_variable_get(:@@field_types)
|
74
|
+
end
|
75
|
+
# Ditto.
|
76
|
+
def field_types
|
77
|
+
self.class.send(:class_variable_get, :@@field_types)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Dump the object data to the given format.
|
81
|
+
def dump(format=nil, with_titles=true)
|
82
|
+
format ||= @format
|
83
|
+
raise "Format not defined (#{format})" unless SUPPORTED_FORMATS.member?(format)
|
84
|
+
send("to_#{format}", with_titles)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Create a new instance of the object using data from file.
|
88
|
+
def self.from_file(file_path=nil, format=nil)
|
89
|
+
raise "Cannot read file (#{file_path})" unless File.exists?(file_path)
|
90
|
+
format = format || File.extname(file_path).tr('.', '')
|
91
|
+
me = send("from_#{format}", read_file_to_array(file_path))
|
92
|
+
me.format = format
|
93
|
+
me
|
94
|
+
end
|
95
|
+
# Write the object data to the given file.
|
96
|
+
def to_file(file_path=nil, with_titles=true)
|
97
|
+
raise "Cannot store to nil path" if file_path.nil?
|
98
|
+
format = File.extname(file_path).tr('.', '')
|
99
|
+
format ||= @format
|
100
|
+
Storable.write_file(file_path, dump(format, with_titles))
|
101
|
+
end
|
102
|
+
|
103
|
+
# Create a new instance of the object from a hash.
|
104
|
+
def self.from_hash(from={})
|
105
|
+
me = self.new
|
106
|
+
|
107
|
+
return me if !from || from.empty?
|
108
|
+
|
109
|
+
fnames = field_names
|
110
|
+
fnames.each_with_index do |key,index|
|
111
|
+
|
112
|
+
|
113
|
+
|
114
|
+
# TODO: Correct this horrible implementation (sorry, me. It's just one of those days.)
|
115
|
+
|
116
|
+
if field_types[index] == Time
|
117
|
+
value = Time.parse(from[key].to_s)
|
118
|
+
elsif field_types[index] == DateTime
|
119
|
+
value = DateTime.parse(from[key].to_s)
|
120
|
+
elsif field_types[index] == TrueClass
|
121
|
+
value = (from[key].to_s == "true")
|
122
|
+
elsif field_types[index] == Float
|
123
|
+
value = from[key].to_f
|
124
|
+
elsif field_types[index] == Integer
|
125
|
+
value = from[key].to_i
|
126
|
+
elsif field_types[index] == Array
|
127
|
+
(value ||= []) << from[key]
|
128
|
+
else
|
129
|
+
value = from[key] || from[key.to_s] # support for symbol keys and string keys
|
130
|
+
value = value.first if value.is_a?(Array) && value.size == 1 # I
|
131
|
+
end
|
132
|
+
|
133
|
+
me.send("#{key}=", value) if self.method_defined?("#{key}=")
|
134
|
+
end
|
135
|
+
|
136
|
+
me
|
137
|
+
end
|
138
|
+
# Return the object data as a hash
|
139
|
+
# +with_titles+ is ignored.
|
140
|
+
def to_hash(with_titles=true)
|
141
|
+
tmp = {}
|
142
|
+
field_names.each do |fname|
|
143
|
+
tmp[fname] = self.send(fname)
|
144
|
+
end
|
145
|
+
tmp
|
146
|
+
end
|
147
|
+
|
148
|
+
# Create a new instance of the object from YAML.
|
149
|
+
# +from+ a YAML string split into an array by line.
|
150
|
+
def self.from_yaml(from=[])
|
151
|
+
# from is an array of strings
|
152
|
+
from_str = from.join('')
|
153
|
+
hash = YAML::load(from_str)
|
154
|
+
hash = from_hash(hash) if hash.is_a? Hash
|
155
|
+
hash
|
156
|
+
end
|
157
|
+
def to_yaml(with_titles=true)
|
158
|
+
to_hash.to_yaml
|
159
|
+
end
|
160
|
+
|
161
|
+
# Create a new instance of the object from a JSON string.
|
162
|
+
# +from+ a JSON string split into an array by line.
|
163
|
+
def self.from_json(from=[])
|
164
|
+
require 'json'
|
165
|
+
# from is an array of strings
|
166
|
+
from_str = from.join('')
|
167
|
+
tmp = JSON::load(from_str)
|
168
|
+
hash_sym = tmp.keys.inject({}) do |hash, key|
|
169
|
+
hash[key.to_sym] = tmp[key]
|
170
|
+
hash
|
171
|
+
end
|
172
|
+
hash_sym = from_hash(hash_sym) if hash_sym.is_a? Hash
|
173
|
+
hash_sym
|
174
|
+
end
|
175
|
+
def to_json(with_titles=true)
|
176
|
+
require 'json'
|
177
|
+
to_hash.to_json
|
178
|
+
end
|
179
|
+
|
180
|
+
# Return the object data as a delimited string.
|
181
|
+
# +with_titles+ specifiy whether to include field names (default: false)
|
182
|
+
# +delim+ is the field delimiter.
|
183
|
+
def to_delimited(with_titles=false, delim=',')
|
184
|
+
values = []
|
185
|
+
field_names.each do |fname|
|
186
|
+
values << self.send(fname.to_s) # TODO: escape values
|
187
|
+
end
|
188
|
+
output = values.join(delim)
|
189
|
+
output = field_names.join(delim) << $/ << output if with_titles
|
190
|
+
output
|
191
|
+
end
|
192
|
+
# Return the object data as a tab delimited string.
|
193
|
+
# +with_titles+ specifiy whether to include field names (default: false)
|
194
|
+
def to_tsv(with_titles=false)
|
195
|
+
to_delimited(with_titles, "\t")
|
196
|
+
end
|
197
|
+
# Return the object data as a comma delimited string.
|
198
|
+
# +with_titles+ specifiy whether to include field names (default: false)
|
199
|
+
def to_csv(with_titles=false)
|
200
|
+
to_delimited(with_titles, ',')
|
201
|
+
end
|
202
|
+
# Create a new instance from tab-delimited data.
|
203
|
+
# +from+ a JSON string split into an array by line.
|
204
|
+
def self.from_tsv(from=[])
|
205
|
+
self.from_delimited(from, "\t")
|
206
|
+
end
|
207
|
+
# Create a new instance of the object from comma-delimited data.
|
208
|
+
# +from+ a JSON string split into an array by line.
|
209
|
+
def self.from_csv(from=[])
|
210
|
+
self.from_delimited(from, ',')
|
211
|
+
end
|
212
|
+
|
213
|
+
# Create a new instance of the object from a delimited string.
|
214
|
+
# +from+ a JSON string split into an array by line.
|
215
|
+
# +delim+ is the field delimiter.
|
216
|
+
def self.from_delimited(from=[],delim=',')
|
217
|
+
return if from.empty?
|
218
|
+
# We grab an instance of the class so we can
|
219
|
+
hash = {}
|
220
|
+
|
221
|
+
fnames = values = []
|
222
|
+
if (from.size > 1 && !from[1].empty?)
|
223
|
+
fnames = from[0].chomp.split(delim)
|
224
|
+
values = from[1].chomp.split(delim)
|
225
|
+
else
|
226
|
+
fnames = self.field_names
|
227
|
+
values = from[0].chomp.split(delim)
|
228
|
+
end
|
229
|
+
|
230
|
+
fnames.each_with_index do |key,index|
|
231
|
+
next unless values[index]
|
232
|
+
hash[key.to_sym] = values[index]
|
233
|
+
end
|
234
|
+
hash = from_hash(hash) if hash.is_a? Hash
|
235
|
+
hash
|
236
|
+
end
|
237
|
+
|
238
|
+
def self.read_file_to_array(path)
|
239
|
+
contents = []
|
240
|
+
return contents unless File.exists?(path)
|
241
|
+
|
242
|
+
open(path, 'r') do |l|
|
243
|
+
contents = l.readlines
|
244
|
+
end
|
245
|
+
|
246
|
+
contents
|
247
|
+
end
|
248
|
+
|
249
|
+
def self.write_file(path, content, flush=true)
|
250
|
+
write_or_append_file('w', path, content, flush)
|
251
|
+
end
|
252
|
+
|
253
|
+
def self.append_file(path, content, flush=true)
|
254
|
+
write_or_append_file('a', path, content, flush)
|
255
|
+
end
|
256
|
+
|
257
|
+
def self.write_or_append_file(write_or_append, path, content = '', flush = true)
|
258
|
+
#STDERR.puts "Writing to #{ path }..."
|
259
|
+
create_dir(File.dirname(path))
|
260
|
+
|
261
|
+
open(path, write_or_append) do |f|
|
262
|
+
f.puts content
|
263
|
+
f.flush if flush;
|
264
|
+
end
|
265
|
+
File.chmod(0600, path)
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
data/rudy.gemspec
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
@spec = Gem::Specification.new do |s|
|
2
|
+
s.name = "rudy"
|
3
|
+
s.version = "0.2"
|
4
|
+
s.summary = "Rudy is a handy staging and deployment tool for Amazon EC2."
|
5
|
+
s.description = "Rudy is a handy staging and deployment tool for Amazon EC2."
|
6
|
+
s.author = "Delano Mandelbaum"
|
7
|
+
s.email = "delano@solutious.com"
|
8
|
+
s.homepage = "http://github.com/solutious/rudy"
|
9
|
+
|
10
|
+
# = MANIFEST =
|
11
|
+
# find {bin,lib,support,tryouts} -type f | grep -v git
|
12
|
+
s.files = %w(
|
13
|
+
CHANGES.txt
|
14
|
+
LICENSE.txt
|
15
|
+
README.rdoc
|
16
|
+
Rakefile
|
17
|
+
bin/rudy
|
18
|
+
lib/drydock.rb
|
19
|
+
lib/rudy.rb
|
20
|
+
lib/rudy/aws.rb
|
21
|
+
lib/rudy/aws/ec2.rb
|
22
|
+
lib/rudy/aws/s3.rb
|
23
|
+
lib/rudy/aws/simpledb.rb
|
24
|
+
lib/rudy/command/addresses.rb
|
25
|
+
lib/rudy/command/base.rb
|
26
|
+
lib/rudy/command/commit.rb
|
27
|
+
lib/rudy/command/disks.rb
|
28
|
+
lib/rudy/command/environment.rb
|
29
|
+
lib/rudy/command/groups.rb
|
30
|
+
lib/rudy/command/images.rb
|
31
|
+
lib/rudy/command/instances.rb
|
32
|
+
lib/rudy/command/metadata.rb
|
33
|
+
lib/rudy/command/release.rb
|
34
|
+
lib/rudy/command/volumes.rb
|
35
|
+
lib/rudy/metadata/disk.rb
|
36
|
+
lib/rudy/metadata/environment.rb
|
37
|
+
lib/rudy/scm/svn.rb
|
38
|
+
lib/rudy/utils.rb
|
39
|
+
lib/storable.rb
|
40
|
+
rudy.gemspec
|
41
|
+
support/rudy-ec2-startup
|
42
|
+
)
|
43
|
+
s.executables = %w[rudy]
|
44
|
+
|
45
|
+
s.extra_rdoc_files = %w[README.rdoc LICENSE.txt]
|
46
|
+
s.has_rdoc = true
|
47
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Rudy: Your friend in staging and deploying with EC2", "--main", "README.rdoc"]
|
48
|
+
s.require_paths = %w[lib]
|
49
|
+
s.rubygems_version = '1.1.1'
|
50
|
+
|
51
|
+
s.rubyforge_project = 'rudy'
|
52
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
# what: Rudy EC2 startup script
|
4
|
+
# who: delano@solutious.com
|
5
|
+
# when: 2009-02-20 (rev: 3)
|
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
|
+
# Expects message data in the yaml format:
|
13
|
+
#
|
14
|
+
# :dbmaster: IP ADDRESS or LOCAL HOSTNAME (default: localhost)
|
15
|
+
# :role: app, db, etc... (default: app)
|
16
|
+
# :env: stage, prod (default: stage)
|
17
|
+
# :access_key: amazon access key
|
18
|
+
# :secret_key: amazon secret key
|
19
|
+
|
20
|
+
# Put this in /etc/init.d. Then:
|
21
|
+
# * chmod 755 rudy-ec2-startup
|
22
|
+
# * cd /etc/rc3.d
|
23
|
+
# * ln -s ../init.d/rudy-ec2-startup S17rudy
|
24
|
+
# * cd /etc/rc4.d
|
25
|
+
# * ln -s ../init.d/rudy-ec2-startup S17rudy
|
26
|
+
# * cd /etc/rc5.d
|
27
|
+
# * ln -s ../init.d/rudy-ec2-startup S17rudy
|
28
|
+
|
29
|
+
require 'yaml'
|
30
|
+
require 'resolv'
|
31
|
+
|
32
|
+
LOGFILE = '/var/log/rudy-ec2-startup'
|
33
|
+
USERDATA = 'http://169.254.169.254/2008-02-01/user-data'
|
34
|
+
METADATA = 'http://169.254.169.254/2008-02-01/meta-data'
|
35
|
+
METADATAPARAMS = ['instance-id', 'instance-type']
|
36
|
+
|
37
|
+
|
38
|
+
def get_metadata
|
39
|
+
metadata = {}
|
40
|
+
|
41
|
+
begin
|
42
|
+
METADATAPARAMS.each do |param|
|
43
|
+
log " ---> #{param}"
|
44
|
+
metadata[param.to_s] = run("curl -s #{METADATA}/#{param}")
|
45
|
+
end
|
46
|
+
rescue => ex
|
47
|
+
log("Problem getting metadata: #{ex.message}")
|
48
|
+
end
|
49
|
+
metadata
|
50
|
+
end
|
51
|
+
|
52
|
+
def run(command, input='')
|
53
|
+
IO.popen(command, 'r+') do |io|
|
54
|
+
#io.puts input
|
55
|
+
#io.close_write
|
56
|
+
return io.read
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def get_formatted_time
|
61
|
+
t = Time.now
|
62
|
+
t_out = t.strftime("%H:%M:%S%p (%m/%d/%Y)")
|
63
|
+
end
|
64
|
+
|
65
|
+
def write_to_file (filename, s, type='a')
|
66
|
+
f = File.open(filename,type)
|
67
|
+
f.puts s
|
68
|
+
f.close
|
69
|
+
end
|
70
|
+
|
71
|
+
def read_file(path)
|
72
|
+
read_file_to_array(path).join('')
|
73
|
+
end
|
74
|
+
|
75
|
+
def read_file_to_array(path)
|
76
|
+
contents = []
|
77
|
+
return contents unless File.exists?(path)
|
78
|
+
open(path, 'r') do |l|
|
79
|
+
contents = l.readlines
|
80
|
+
end
|
81
|
+
contents
|
82
|
+
end
|
83
|
+
|
84
|
+
def log(s)
|
85
|
+
msg = "#{get_formatted_time}: #{s}"
|
86
|
+
write_to_file(LOGFILE, msg)
|
87
|
+
puts msg
|
88
|
+
end
|
89
|
+
|
90
|
+
begin
|
91
|
+
File.unlink(LOGFILE) if File.exists?(LOGFILE)
|
92
|
+
log "Deleted previous logfile (#{LOGFILE})"
|
93
|
+
log "Grabing configuration..."
|
94
|
+
config_yaml = run("curl -s #{USERDATA}")
|
95
|
+
|
96
|
+
log "Grabing meta-data..."
|
97
|
+
metadata = get_metadata
|
98
|
+
|
99
|
+
raise "Ooooooops, no configuration" if !config_yaml || config_yaml.empty?
|
100
|
+
|
101
|
+
config = YAML::load(config_yaml)
|
102
|
+
|
103
|
+
if config && config[:role]
|
104
|
+
myrole = config[:role].downcase
|
105
|
+
|
106
|
+
else
|
107
|
+
myrole = "app"
|
108
|
+
end
|
109
|
+
|
110
|
+
log "My role is: #{myrole}"
|
111
|
+
|
112
|
+
env = config && config[:env] ? config[:env] : "stage"
|
113
|
+
|
114
|
+
unless read_file('/etc/hosts') =~ /dbmaster/
|
115
|
+
if config && config[:dbmaster]
|
116
|
+
log "Updating dbmaster in /etc/hosts..."
|
117
|
+
|
118
|
+
case config[:dbmaster]
|
119
|
+
when /^\d.+/
|
120
|
+
ip_address = config[:dbmaster]
|
121
|
+
else
|
122
|
+
ip_address = Resolv.getaddress(config[:dbmaster])
|
123
|
+
end
|
124
|
+
|
125
|
+
log "The IP address for my dbmaster is: #{ip_address}"
|
126
|
+
write_to_file("/etc/hosts", "\n#{ip_address}\tdbmaster\n")
|
127
|
+
|
128
|
+
else
|
129
|
+
write_to_file("/etc/hosts", "\n127.0.0.1\tdbmaster\n")
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
hostname = ""
|
135
|
+
myid = "default-"
|
136
|
+
if metadata['instance-id']
|
137
|
+
myid = metadata['instance-id'][2..metadata['instance-id'].length]
|
138
|
+
log "My ID: #{myid}"
|
139
|
+
write_to_file("/etc/instance-id", myid, "w")
|
140
|
+
end
|
141
|
+
|
142
|
+
mytype = "unknown"
|
143
|
+
if metadata['instance-type']
|
144
|
+
mytype = metadata['instance-type']
|
145
|
+
log "My instance type: #{metadata['instance-type']}"
|
146
|
+
write_to_file("/etc/instance-type", metadata['instance-type'], "w")
|
147
|
+
end
|
148
|
+
|
149
|
+
|
150
|
+
hostname = "#{env}-#{myrole}-#{mytype.gsub('.', '')}-#{myid}"
|
151
|
+
log "Setting hostname to #{hostname}"
|
152
|
+
`hostname #{hostname}`
|
153
|
+
|
154
|
+
unless read_file('/etc/hosts') =~ /#{hostname}/
|
155
|
+
log "Adding an entry to /etc/hosts for: #{hostname}"
|
156
|
+
write_to_file("/etc/hosts", "\n127.0.0.1\t#{hostname}")
|
157
|
+
end
|
158
|
+
|
159
|
+
log "Done!"
|
160
|
+
|
161
|
+
rescue => ex
|
162
|
+
log ex.message
|
163
|
+
end
|
164
|
+
|
165
|
+
|
166
|
+
|