Class: Awsborn::Server
- Inherits:
-
Object
- Object
- Awsborn::Server
- Defined in:
- lib/awsborn/server.rb
Constant Summary collapse
- AVAILABILITY_ZONES =
%w[ us-east-1a us-east-1b us-east-1c us-east-1d us-west-1a us-west-1b eu-west-1a eu-west-1b ap-southeast-1a ap-southeast-1b ]
- INSTANCE_TYPES_32_BIT =
%w[m1.small c1.medium t1.micro]
- INSTANCE_TYPES_64_BIT =
%w[m1.large m1.xlarge m2.xlarge m2.2xlarge m2.4xlarge c1.xlarge cc1.4xlarge t1.micro]
- INSTANCE_TYPES =
(INSTANCE_TYPES_32_BIT + INSTANCE_TYPES_64_BIT).uniq
- SYMBOL_CONSTANT_MAP =
(AVAILABILITY_ZONES + INSTANCE_TYPES).inject({}) { |memo,str| memo[str.tr('-.','_').to_sym] = str; memo }
Class Attribute Summary collapse
-
.children ⇒ Object
Returns the value of attribute children.
-
.clusters ⇒ Object
Returns the value of attribute clusters.
-
.logger ⇒ Object
Returns the value of attribute logger.
Class Method Summary collapse
- .bootstrap_script(*args) ⇒ Object
- .cluster(&block) ⇒ Object
-
.image_id(*args) ⇒ Object
Set image_id.
- .inherited(klass) ⇒ Object
- .instance_type(*args) ⇒ Object
- .keys(*args) ⇒ Object
- .monitor(*args) ⇒ Object
- .security_group(*args) ⇒ Object
- .sudo_user(*args) ⇒ Object
Instance Method Summary collapse
- #associate_address ⇒ Object
- #attach_volumes ⇒ Object
- #bootstrap ⇒ Object
- #constant(symbol) ⇒ Object
- #cook ⇒ Object
- #copy_sudo_users_keys_to_root ⇒ Object
- #ec2 ⇒ Object
-
#initialize(name, options = {}) ⇒ Server
constructor
A new instance of Server.
- #install_ssh_keys(temp_key_pair = nil) ⇒ Object
- #install_ssh_keys_for_sudo_user_or_root(temp_key_pair) ⇒ Object
- #key_data ⇒ Object
- #launch_instance(key_pair) ⇒ Object
- #logger ⇒ Object
- #refresh ⇒ Object
- #run_chef ⇒ Object
- #running? ⇒ Boolean
- #start(key_pair) ⇒ Object
- #start_or_stop_monitoring ⇒ Object
- #update_known_hosts ⇒ Object
- #upload_cookbooks ⇒ Object
Constructor Details
#initialize(name, options = {}) ⇒ Server
Returns a new instance of Server.
4 5 6 7 8 |
# File 'lib/awsborn/server.rb', line 4 def initialize (name, = {}) @name = name @options = .dup self.host_name = elastic_ip end |
Class Attribute Details
.children ⇒ Object
Returns the value of attribute children.
11 12 13 |
# File 'lib/awsborn/server.rb', line 11 def children @children end |
.clusters ⇒ Object
Returns the value of attribute clusters.
11 12 13 |
# File 'lib/awsborn/server.rb', line 11 def clusters @clusters end |
.logger ⇒ Object
Returns the value of attribute logger.
11 12 13 |
# File 'lib/awsborn/server.rb', line 11 def logger @logger end |
Class Method Details
.bootstrap_script(*args) ⇒ Object
43 44 45 46 |
# File 'lib/awsborn/server.rb', line 43 def bootstrap_script (*args) @bootstrap_script = args.first unless args.empty? @bootstrap_script end |
.cluster(&block) ⇒ Object
52 53 54 55 56 |
# File 'lib/awsborn/server.rb', line 52 def cluster (&block) @clusters ||= [] @clusters << ServerCluster.build(self, &block) @clusters.last end |
.image_id(*args) ⇒ Object
Set image_id. Examples:
image_id 'ami-123123'
image_id 'ami-123123', :sudo_user => 'ubuntu'
image_id :i386 => 'ami-323232', :x64 => 'ami-646464', :sudo_user => 'ubuntu'
20 21 22 23 24 25 26 |
# File 'lib/awsborn/server.rb', line 20 def image_id (*args) unless args.empty? @image_id = args.first @sudo_user = args.last[:sudo_user] if args.last.is_a?(Hash) end @image_id end |
.inherited(klass) ⇒ Object
12 13 14 15 |
# File 'lib/awsborn/server.rb', line 12 def inherited (klass) @children ||= [] @children << klass end |
.instance_type(*args) ⇒ Object
27 28 29 30 |
# File 'lib/awsborn/server.rb', line 27 def instance_type (*args) @instance_type = args.first unless args.empty? @instance_type end |
.keys(*args) ⇒ Object
35 36 37 38 |
# File 'lib/awsborn/server.rb', line 35 def keys (*args) @keys = args unless args.empty? @keys end |
.monitor(*args) ⇒ Object
47 48 49 50 |
# File 'lib/awsborn/server.rb', line 47 def monitor (*args) @monitor = args.first unless args.empty? @monitor end |
.security_group(*args) ⇒ Object
31 32 33 34 |
# File 'lib/awsborn/server.rb', line 31 def security_group (*args) @security_group = args.first unless args.empty? @security_group end |
.sudo_user(*args) ⇒ Object
39 40 41 42 |
# File 'lib/awsborn/server.rb', line 39 def sudo_user (*args) @sudo_user = args.first unless args.empty? @sudo_user end |
Instance Method Details
#associate_address ⇒ Object
150 151 152 153 154 |
# File 'lib/awsborn/server.rb', line 150 def associate_address logger.debug "Associating address #{elastic_ip} to #{name}" ec2.associate_address(elastic_ip) self.host_name = elastic_ip end |
#attach_volumes ⇒ Object
164 165 166 167 168 169 170 171 |
# File 'lib/awsborn/server.rb', line 164 def attach_volumes logger.debug "Attaching volumes #{disk.values.join(', ')} to #{name}" disk.each_pair do |device, str_or_ary| volume = str_or_ary.is_a?(Array) ? str_or_ary.first : str_or_ary device = "/dev/#{device}" if device.is_a?(Symbol) || ! device.match('/') res = ec2.attach_volume(volume, device) end end |
#bootstrap ⇒ Object
156 157 158 159 160 161 162 |
# File 'lib/awsborn/server.rb', line 156 def bootstrap logger.debug "Bootstrapping #{name}" script = bootstrap_script basename = File.basename(script) system "scp #{script} root@#{host_name}:/tmp" system "ssh root@#{host_name} 'cd /tmp && chmod 700 #{basename} && ./#{basename}'" end |
#constant(symbol) ⇒ Object
299 300 301 |
# File 'lib/awsborn/server.rb', line 299 def constant (symbol) SYMBOL_CONSTANT_MAP[symbol] end |
#cook ⇒ Object
173 174 175 176 |
# File 'lib/awsborn/server.rb', line 173 def cook upload_cookbooks run_chef end |
#copy_sudo_users_keys_to_root ⇒ Object
146 147 148 |
# File 'lib/awsborn/server.rb', line 146 def copy_sudo_users_keys_to_root system("ssh #{sudo_user}@#{host_name} 'sudo cp .ssh/authorized_keys /root/.ssh/authorized_keys'") end |
#ec2 ⇒ Object
198 199 200 |
# File 'lib/awsborn/server.rb', line 198 def ec2 @ec2 ||= Ec2.new(zone) end |
#install_ssh_keys(temp_key_pair = nil) ⇒ Object
126 127 128 129 130 131 |
# File 'lib/awsborn/server.rb', line 126 def install_ssh_keys (temp_key_pair = nil) logger.debug "Installing ssh keys on #{name}" raise ArgumentError, "No host_name for #{name}" unless host_name install_ssh_keys_for_sudo_user_or_root (temp_key_pair) copy_sudo_users_keys_to_root if sudo_user end |
#install_ssh_keys_for_sudo_user_or_root(temp_key_pair) ⇒ Object
133 134 135 136 137 138 |
# File 'lib/awsborn/server.rb', line 133 def install_ssh_keys_for_sudo_user_or_root (temp_key_pair) current_key = "-i #{temp_key_pair.path}" if temp_key_pair IO.popen("ssh #{current_key} #{sudo_user || 'root'}@#{host_name} 'cat > .ssh/authorized_keys'", "w") do |pipe| pipe.puts key_data end end |
#key_data ⇒ Object
140 141 142 143 144 |
# File 'lib/awsborn/server.rb', line 140 def key_data Dir[*keys].inject([]) do |memo, file_name| memo + File.readlines(file_name).map { |line| line.chomp } end.join("\n") end |
#launch_instance(key_pair) ⇒ Object
108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/awsborn/server.rb', line 108 def launch_instance (key_pair) @launch_response = ec2.launch_instance(image_id, :instance_type => constant(instance_type), :availability_zone => constant(zone), :key_name => key_pair.name, :group_ids => security_group, :monitoring_enabled => monitor ) logger.debug @launch_response Awsborn.wait_for("instance #{instance_id} (#{name}) to start", 10) { instance_running? } self.host_name = aws_dns_name end |
#logger ⇒ Object
303 304 305 |
# File 'lib/awsborn/server.rb', line 303 def logger @logger ||= self.class.logger end |
#refresh ⇒ Object
72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/awsborn/server.rb', line 72 def refresh start_or_stop_monitoring unless monitor.nil? associate_address if elastic_ip begin update_known_hosts install_ssh_keys if keys rescue SecurityError => e logger.warn "Could not update known_hosts for #{name}:" logger.warn e end end |
#run_chef ⇒ Object
192 193 194 195 196 |
# File 'lib/awsborn/server.rb', line 192 def run_chef logger.info "Running chef on #{host_name}" # Absolute path to config files to avoid a nasty irrational bug. sh "ssh root@#{host_name} \"cd #{Awsborn.remote_chef_path}; chef-solo -l #{Awsborn.chef_log_level} -c #{Awsborn.remote_chef_path}/config/solo.rb -j #{Awsborn.remote_chef_path}/config/dna.json\"" end |
#running? ⇒ Boolean
62 63 64 65 66 67 68 69 70 |
# File 'lib/awsborn/server.rb', line 62 def running? map = {} disk_volume_ids.each { |vol_id| map[vol_id] = ec2.instance_id_for_volume(vol_id) } ids = map.values.uniq if ids.size > 1 raise ServerError, "Volumes for #{self.class.name}:#{name} are connected to several instances: #{map.inspect}" end ec2.instance_id = ids.first end |
#start(key_pair) ⇒ Object
93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/awsborn/server.rb', line 93 def start (key_pair) launch_instance(key_pair) update_known_hosts install_ssh_keys(key_pair) if keys if elastic_ip associate_address update_known_hosts end bootstrap if bootstrap_script attach_volumes end |
#start_or_stop_monitoring ⇒ Object
85 86 87 88 89 90 91 |
# File 'lib/awsborn/server.rb', line 85 def start_or_stop_monitoring if monitor && ! ec2.monitoring? ec2.monitor elsif ec2.monitoring? && ! monitor ec2.unmonitor end end |
#update_known_hosts ⇒ Object
122 123 124 |
# File 'lib/awsborn/server.rb', line 122 def update_known_hosts KnownHostsUpdater.update_for_server self end |
#upload_cookbooks ⇒ Object
178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/awsborn/server.rb', line 178 def upload_cookbooks logger.info "Uploading cookbooks to #{host_name}" cookbooks_dir = '../cookbooks' # Hard coded for now temp_link = File.directory?(cookbooks_dir) && ! File.directory?('cookbooks') File.symlink(cookbooks_dir, 'cookbooks') if temp_link File.open("config/dna.json", "w") { |f| f.write(chef_dna.to_json) } system "rsync -rL --delete --exclude '.*' ./ root@#{host_name}:#{Awsborn.remote_chef_path}" ensure File.delete("config/dna.json") File.delete("cookbooks") if temp_link end |