awsborn 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.mdown +4 -0
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/awsborn/awsborn.rb +3 -2
- data/lib/awsborn/ec2.rb +22 -10
- data/lib/awsborn/server.rb +60 -13
- data/lib/awsborn/server_cluster.rb +9 -9
- metadata +7 -7
data/README.mdown
CHANGED
@@ -30,6 +30,7 @@ that are not running.
|
|
30
30
|
security_group 'Basic web'
|
31
31
|
keys 'keys/*.pub'
|
32
32
|
bootstrap_script 'chef-bootstrap.sh'
|
33
|
+
monitor true
|
33
34
|
end
|
34
35
|
|
35
36
|
log_servers = LogServer.cluster do
|
@@ -179,6 +180,9 @@ attached and the other isn't, one of these things will happen:
|
|
179
180
|
* Hack RightAws to verify certificates.
|
180
181
|
* Elastic Load Balancing.
|
181
182
|
* Launch servers in parallel.
|
183
|
+
* Make `image_id` a hash with different AMIs for different instance types.
|
184
|
+
* Make `image_id` overridable per server.
|
185
|
+
|
182
186
|
|
183
187
|
## Note on Patches/Pull Requests
|
184
188
|
|
data/Rakefile
CHANGED
@@ -10,7 +10,7 @@ begin
|
|
10
10
|
gem.email = "david@icehouse.se"
|
11
11
|
gem.homepage = "http://github.com/icehouse/awsborn"
|
12
12
|
gem.authors = ["David Vrensk"]
|
13
|
-
gem.add_dependency "right_aws", ">= 1.
|
13
|
+
gem.add_dependency "icehouse-right_aws", ">= 1.11.0"
|
14
14
|
gem.add_development_dependency "rspec", ">= 1.2.9"
|
15
15
|
gem.add_development_dependency "webmock", ">= 0.9.1"
|
16
16
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/lib/awsborn/awsborn.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
module Awsborn
|
2
2
|
class SecurityError < StandardError ; end
|
3
|
+
class ServerError < StandardError ; end
|
3
4
|
|
4
5
|
class << self
|
5
6
|
attr_writer :access_key_id, :secret_access_key, :logger
|
6
7
|
attr_accessor :verbose
|
7
|
-
|
8
|
+
|
8
9
|
Awsborn.verbose = true
|
9
|
-
|
10
|
+
|
10
11
|
def access_key_id
|
11
12
|
@access_key_id ||= ENV['AMAZON_ACCESS_KEY_ID']
|
12
13
|
end
|
data/lib/awsborn/ec2.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
module Awsborn
|
2
2
|
class Ec2
|
3
|
-
|
3
|
+
extend Forwardable
|
4
|
+
def_delegators :Awsborn, :logger
|
5
|
+
|
4
6
|
attr_accessor :instance_id
|
5
7
|
|
6
8
|
def connection
|
@@ -45,17 +47,12 @@ module Awsborn
|
|
45
47
|
def delete_key_pair (key_pair)
|
46
48
|
connection.delete_key_pair(key_pair.name)
|
47
49
|
end
|
48
|
-
|
49
|
-
def
|
50
|
+
|
51
|
+
def instance_id_for_volume (volume_id)
|
50
52
|
response = connection.describe_volumes(volume_id).first
|
51
|
-
|
52
|
-
self.instance_id = response[:aws_instance_id]
|
53
|
-
true
|
54
|
-
else
|
55
|
-
false
|
56
|
-
end
|
53
|
+
response[:aws_status] == 'in-use' ? response[:aws_instance_id] : nil
|
57
54
|
end
|
58
|
-
|
55
|
+
|
59
56
|
IP4_REGEXP = /^(\d{1,3}\.){3}\d{1,3}$/
|
60
57
|
|
61
58
|
def associate_address (address)
|
@@ -83,5 +80,20 @@ module Awsborn
|
|
83
80
|
def attach_volume (volume, device)
|
84
81
|
connection.attach_volume(volume, instance_id, device)
|
85
82
|
end
|
83
|
+
|
84
|
+
def monitoring?
|
85
|
+
%w[enabled pending].include?(describe_instance[:monitoring_state])
|
86
|
+
end
|
87
|
+
|
88
|
+
def monitor
|
89
|
+
logger.debug "Activating monitoring for #{instance_id}"
|
90
|
+
connection.monitor_instances(instance_id)
|
91
|
+
end
|
92
|
+
|
93
|
+
def unmonitor
|
94
|
+
logger.debug "Deactivating monitoring for #{instance_id}"
|
95
|
+
connection.unmonitor_instances(instance_id)
|
96
|
+
end
|
97
|
+
|
86
98
|
end
|
87
99
|
end
|
data/lib/awsborn/server.rb
CHANGED
@@ -36,6 +36,10 @@ module Awsborn
|
|
36
36
|
@bootstrap_script = args.first unless args.empty?
|
37
37
|
@bootstrap_script
|
38
38
|
end
|
39
|
+
def monitor (*args)
|
40
|
+
@monitor = args.first unless args.empty?
|
41
|
+
@monitor
|
42
|
+
end
|
39
43
|
|
40
44
|
def cluster (&block)
|
41
45
|
ServerCluster.build self, &block
|
@@ -45,12 +49,37 @@ module Awsborn
|
|
45
49
|
end
|
46
50
|
end
|
47
51
|
|
48
|
-
def
|
49
|
-
|
50
|
-
ec2.
|
52
|
+
def running?
|
53
|
+
map = {}
|
54
|
+
disk.values.each { |vol_id| map[vol_id] = ec2.instance_id_for_volume(vol_id) }
|
55
|
+
ids = map.values.uniq
|
56
|
+
if ids.size > 1
|
57
|
+
raise ServerError, "Volumes for #{self.class.name}:#{name} are connected to several instances: #{map.inspect}"
|
58
|
+
end
|
59
|
+
ec2.instance_id = ids.first
|
51
60
|
end
|
52
|
-
alias :running? :one_of_my_disks_is_attached_to_a_running_instance?
|
53
61
|
|
62
|
+
def refresh
|
63
|
+
start_or_stop_monitoring unless monitor.nil?
|
64
|
+
associate_address if elastic_ip
|
65
|
+
|
66
|
+
begin
|
67
|
+
update_known_hosts
|
68
|
+
install_ssh_keys if keys
|
69
|
+
rescue SecurityError => e
|
70
|
+
logger.warn "Could not update known_hosts for #{name}:"
|
71
|
+
logger.warn e
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def start_or_stop_monitoring
|
76
|
+
if monitor && ! ec2.monitoring?
|
77
|
+
ec2.monitor
|
78
|
+
elsif ec2.monitoring? && ! monitor
|
79
|
+
ec2.unmonitor
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
54
83
|
def start (key_pair)
|
55
84
|
launch_instance(key_pair)
|
56
85
|
|
@@ -71,7 +100,8 @@ module Awsborn
|
|
71
100
|
:instance_type => constant(instance_type),
|
72
101
|
:availability_zone => constant(zone),
|
73
102
|
:key_name => key_pair.name,
|
74
|
-
:group_ids => security_group
|
103
|
+
:group_ids => security_group,
|
104
|
+
:monitor_enabled => monitor
|
75
105
|
)
|
76
106
|
logger.debug @launch_response
|
77
107
|
|
@@ -83,33 +113,42 @@ module Awsborn
|
|
83
113
|
KnownHostsUpdater.update_for_server self
|
84
114
|
end
|
85
115
|
|
86
|
-
def install_ssh_keys (temp_key_pair)
|
87
|
-
|
88
|
-
|
89
|
-
|
116
|
+
def install_ssh_keys (temp_key_pair = nil)
|
117
|
+
logger.debug "Installing ssh keys on #{name}"
|
118
|
+
raise ArgumentError, "No host_name for #{name}" unless host_name
|
119
|
+
install_ssh_keys_for_sudo_user_or_root (temp_key_pair)
|
120
|
+
copy_sudo_users_keys_to_root if sudo_user
|
121
|
+
end
|
122
|
+
|
123
|
+
def install_ssh_keys_for_sudo_user_or_root (temp_key_pair)
|
124
|
+
current_key = "-i #{temp_key_pair.path}" if temp_key_pair
|
125
|
+
IO.popen("ssh #{current_key} #{sudo_user || 'root'}@#{host_name} 'cat > .ssh/authorized_keys'", "w") do |pipe|
|
90
126
|
pipe.puts key_data
|
91
127
|
end
|
92
|
-
if sudo_user
|
93
|
-
system("ssh #{sudo_user}@#{aws_dns_name} 'sudo cp .ssh/authorized_keys /root/.ssh/authorized_keys'")
|
94
|
-
end
|
95
128
|
end
|
96
|
-
|
129
|
+
|
97
130
|
def key_data
|
98
131
|
Dir[*keys].inject([]) do |memo, file_name|
|
99
132
|
memo + File.readlines(file_name).map { |line| line.chomp }
|
100
133
|
end.join("\n")
|
101
134
|
end
|
102
135
|
|
136
|
+
def copy_sudo_users_keys_to_root
|
137
|
+
system("ssh #{sudo_user}@#{host_name} 'sudo cp .ssh/authorized_keys /root/.ssh/authorized_keys'")
|
138
|
+
end
|
139
|
+
|
103
140
|
def path_relative_to_script (path)
|
104
141
|
File.join(File.dirname(File.expand_path($0)), path)
|
105
142
|
end
|
106
143
|
|
107
144
|
def associate_address
|
145
|
+
logger.debug "Associating address #{elastic_ip} to #{name}"
|
108
146
|
ec2.associate_address(elastic_ip)
|
109
147
|
self.host_name = elastic_ip
|
110
148
|
end
|
111
149
|
|
112
150
|
def bootstrap
|
151
|
+
logger.debug "Bootstrapping #{name}"
|
113
152
|
script = path_relative_to_script(bootstrap_script)
|
114
153
|
basename = File.basename(script)
|
115
154
|
system "scp #{script} root@#{elastic_ip}:/tmp"
|
@@ -117,6 +156,7 @@ module Awsborn
|
|
117
156
|
end
|
118
157
|
|
119
158
|
def attach_volumes
|
159
|
+
logger.debug "Attaching volumes #{disk.values.join(', ')} to #{name}"
|
120
160
|
disk.each_pair do |device, volume|
|
121
161
|
device = "/dev/#{device}" if device.is_a?(Symbol) || ! device.match('/')
|
122
162
|
res = ec2.attach_volume(volume, device)
|
@@ -129,6 +169,10 @@ module Awsborn
|
|
129
169
|
|
130
170
|
begin :accessors
|
131
171
|
attr_accessor :name, :host_name, :logger
|
172
|
+
def host_name= (string)
|
173
|
+
logger.debug "Setting host_name of #{name} to #{string}"
|
174
|
+
@host_name = string
|
175
|
+
end
|
132
176
|
def zone
|
133
177
|
@options[:zone]
|
134
178
|
end
|
@@ -153,6 +197,9 @@ module Awsborn
|
|
153
197
|
def keys
|
154
198
|
@options[:keys] || self.class.keys
|
155
199
|
end
|
200
|
+
def monitor
|
201
|
+
@options[:monitor] || self.class.monitor
|
202
|
+
end
|
156
203
|
def elastic_ip
|
157
204
|
@options[:ip]
|
158
205
|
end
|
@@ -23,19 +23,19 @@ module Awsborn
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def launch
|
26
|
-
|
26
|
+
running, missing = @instances.partition { |e| e.running? }
|
27
|
+
refresh_running(running) if running.any?
|
28
|
+
start_missing_instances(missing) if missing.any?
|
27
29
|
end
|
28
30
|
|
29
|
-
def
|
30
|
-
|
31
|
-
return if to_start.empty?
|
32
|
-
generate_key_pair(to_start)
|
33
|
-
to_start.each { |e| e.start(@key_pair) }
|
34
|
-
delete_key_pair(to_start)
|
31
|
+
def refresh_running (instances)
|
32
|
+
instances.each { |e| e.refresh }
|
35
33
|
end
|
36
34
|
|
37
|
-
def
|
38
|
-
|
35
|
+
def start_missing_instances (instances)
|
36
|
+
generate_key_pair(instances)
|
37
|
+
instances.each { |e| e.start(@key_pair) }
|
38
|
+
delete_key_pair(instances)
|
39
39
|
end
|
40
40
|
|
41
41
|
def generate_key_pair (instances)
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 2
|
8
|
+
- 0
|
9
|
+
version: 0.2.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- David Vrensk
|
@@ -14,11 +14,11 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-04-
|
17
|
+
date: 2010-04-14 00:00:00 +02:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
|
-
name: right_aws
|
21
|
+
name: icehouse-right_aws
|
22
22
|
prerelease: false
|
23
23
|
requirement: &id001 !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
@@ -26,9 +26,9 @@ dependencies:
|
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
segments:
|
28
28
|
- 1
|
29
|
-
-
|
29
|
+
- 11
|
30
30
|
- 0
|
31
|
-
version: 1.
|
31
|
+
version: 1.11.0
|
32
32
|
type: :runtime
|
33
33
|
version_requirements: *id001
|
34
34
|
- !ruby/object:Gem::Dependency
|