lib/judo/server.rb in judo-0.3.1 vs lib/judo/server.rb in judo-0.3.2

- old
+ new

@@ -1,42 +1,40 @@ module Judo class Server - attr_accessor :name, :group_name + attr_accessor :id,:group_name - def initialize(base, name, group, version = nil) + def initialize(base, id, group, version = nil) @base = base - @name = name + @id = id @group_name = group end - def create(options) + def create(name, options) raise JudoError, "no group specified" unless group_name options[:virgin] = true if options[:virgin].nil? snapshots = options[:snapshots] note = options[:note] ## a user defined note field data = options[:data] ## instance specific data passed in JUDO_DATA ip = options[:elastic_ip] ## if the ip was allocated beforehand virgin = options[:virgin] ## should the server init? + clone = options[:clone] ## if it was cloned from a snapshot version = options[:version] version ||= group.version - if @name.nil? - index = @base.servers.map { |s| (s.name =~ /^#{s.group.name}.(\d*)$/); $1.to_i }.sort.last.to_i + 1 - @name = "#{group.name}.#{index}" - end + raise JudoError, "there is already a server named #{name}" if @base.servers.detect { |s| s.name == name and s != self} + raise JudoError, "there is already a server with id #{id}" if @base.servers.detect { |s| s.id == id and s != self} - raise JudoError, "there is already a server named #{name}" if @base.servers.detect { |s| s.name == @name and s != self} - task("Creating server #{name}") do update "name" => name, "group" => group_name, "note" => note, "virgin" => virgin, "secret" => new_secret, "version" => version, - "data" => data, "elastic_ip" => ip - @base.sdb.put_attributes(@base.base_domain, "groups", group_name => name) + "data" => data, "elastic_ip" => ip, + "clone" => clone, "created_at" => Time.now.to_i + @base.sdb.put_attributes(@base.base_domain, "groups", group_name => id) end allocate_disk(snapshots) allocate_ip @@ -46,21 +44,37 @@ def group @group ||= @base.groups.detect { |g| g.name == group_name } end def fetch_state - @base.sdb.get_attributes(@base.server_domain, name)[:attributes] + @base.sdb.get_attributes(@base.server_domain, id)[:attributes] end def state - @base.servers_state[name] ||= fetch_state + @base.servers_state[id] ||= fetch_state end def get(key) state[key] && [state[key]].flatten.first end + def created_at + Time.at(get("created_at").to_i) + end + + def started_at + Time.at(get("started_at").to_i) + end + + def stopped_at + Time.at(get("stopped_at").to_i) + end + + def name + get "name" + end + def data get "data" end def instance_id @@ -126,32 +140,32 @@ def volumes Hash[ (state["volumes"] || []).map { |a| a.split(":") } ] end def update(attrs) - @base.sdb.put_attributes(@base.server_domain, name, attrs, :replace) + @base.sdb.put_attributes(@base.server_domain, id, attrs, :replace) state.merge! attrs end def add(key, value) - @base.sdb.put_attributes(@base.server_domain, name, { key => value }) + @base.sdb.put_attributes(@base.server_domain, id, { key => value }) (state[key] ||= []) << value end def remove(key, value = nil) if value - @base.sdb.delete_attributes(@base.server_domain, name, key => value) + @base.sdb.delete_attributes(@base.server_domain, id, key => value) state[key] - [value] else - @base.sdb.delete_attributes(@base.server_domain, name, [ key ]) + @base.sdb.delete_attributes(@base.server_domain, id, [ key ]) state.delete(key) end end def delete group.delete_server(self) if group - @base.sdb.delete_attributes(@base.server_domain, name) + @base.sdb.delete_attributes(@base.server_domain, id) end ######## end simple DB access ####### def instance_type @@ -337,11 +351,11 @@ ud = user_data(boot) debug(ud) result = @base.ec2.launch_instances(ami, :instance_type => instance_type, :availability_zone => config["availability_zone"], - :key_name => config["key_name"], + :key_name => @base.key_name, :group_ids => security_groups, :user_data => ud).first update "instance_id" => result[:aws_instance_id], "virgin" => false, "started_at" => Time.now.to_i end @@ -472,12 +486,13 @@ volume_id end def connect_ssh wait_for_ssh - system "chmod 600 #{group.keypair_file}" - system "ssh -i #{group.keypair_file} #{config["user"]}@#{hostname}" + @base.keypair_file do |file| + system "ssh -i #{file} #{config["user"]}@#{hostname}" + end end def ec2_instance_type ec2_instance[:aws_instance_type] rescue nil end @@ -486,20 +501,21 @@ hostname || config["state_ip"] end def reload @base.reload_ec2_instances - @base.servers_state.delete(name) + @base.servers_state.delete(id) end def user_data(judo_boot = nil) <<USER_DATA #!/bin/sh export DEBIAN_FRONTEND="noninteractive" export DEBIAN_PRIORITY="critical" -export JUDO_ID='#{name}' +export JUDO_ID='#{id}' +export JUDO_NAME='#{name}' export JUDO_DOMAIN='#{@base.domain}' export JUDO_BOOT='#{judo_boot}' export JUDO_DATA='#{data}' export SECRET='#{secret}' apt-get update @@ -530,17 +546,26 @@ end end end def snapshot(name) - snap = @base.new_snapshot(name, self.name) + snap = @base.new_snapshot(name, id) snap.create + snap end - def swapip(other) + def rename(newname) + raise JudoError, "Already a server with that name" if @base.servers.detect { |s| s.name == newname } + task("Renaming to #{newname}") do + update "name" => newname + end + end + + def swap(other) ip1 = elastic_ip ip2 = other.elastic_ip + raise JudoError, "Server must have an elastic IP to swap" unless ip1 and ip2 task("Swapping Ip Addresses") do @base.ec2.disassociate_address(ip1) @base.ec2.disassociate_address(ip2) @@ -548,9 +573,16 @@ @base.ec2.associate_address(instance_id, ip2) @base.ec2.associate_address(other.instance_id, ip1) update "elastic_ip" => ip2 other.update "elastic_ip" => ip1 + end + + task("Swapping Names") do + name1 = name + name2 = other.name + update "name" => name2 + other.update "name" => name1 end end def <=>(s) [group.name, name] <=> [s.group.name, s.name]