lib/judo/server.rb in judo-0.3.6 vs lib/judo/server.rb in judo-0.3.7

- old
+ new

@@ -1,23 +1,23 @@ module Judo class Server - attr_accessor :id,:group_name + attr_accessor :id def initialize(base, id, group, version = nil) @base = base @id = id - @group_name = group + @group = group + @judo_domain = base.domain end 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 + metadata = options[:metadata] 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] @@ -25,40 +25,65 @@ 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} task("Creating server #{name}") do - update "name" => name, "group" => group_name, - "note" => note, "virgin" => virgin, + update("name" => name, "group" => group_name, + "virgin" => virgin, "elastic_ip" => ip, "secret" => new_secret, "version" => version, - "data" => data, "elastic_ip" => ip, - "clone" => clone, "created_at" => Time.now.to_i + "clone" => clone, "created_at" => Time.now.to_i) + set_metadata(metadata) if metadata @base.sdb.put_attributes(@base.base_domain, "groups", group_name => id) end allocate_disk(snapshots) allocate_ip self end + def set_metadata(new_metadata) + puts new_metadata.inspect + clean_metadata = new_metadata.inject({}) { |buf,(k,v)| + puts [ buf, k , v ].inspect + buf[k.to_s] = v.to_s; buf } + puts clean_metadata.inspect + keys_to_remove = clean_metadata.keys - clean_metadata.keys + @metadata = clean_metadata + update encode_metadata(clean_metadata) unless clean_metadata.empty? + keys_to_remove.each { |key| remove key } + end + + def encode_metadata(data) + data.inject({}) { |buf,(key,value)| buf["metadata_#{key.to_s}"] = [value].to_json; buf } + end + + def metadata + @metadata ||= get_metadata + end + + def get_metadata + state.inject({}) do |buf,(key,value)| + if key =~ /^metadata_(.*)/ + buf[$1] = JSON.load(value.first) + end + buf + end + end + def group - @group ||= @base.groups.detect { |g| g.name == group_name } + @group_obj ||= @base.groups.detect { |g| g.name == @group } end def fetch_state @base.sdb.get_attributes(@base.server_domain, id)[:attributes] end def 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 @@ -123,10 +148,14 @@ def cloned? !!clone end + def first_boot? + virgin? + end + def virgin? get("virgin").to_s == "true" ## I'm going to set it to true and it will come back from the db as "true" -> could be "false" or false or nil also end def secret @@ -139,10 +168,16 @@ def volumes (state["volumes"] || []).inject({}) { |out, kv| k, v = kv.split(':'); out[k] = v; out } end +######## begin simple DB access ####### + + def get(key) + state[key] && [state[key]].flatten.first + end + def update(attrs) @base.sdb.put_attributes(@base.server_domain, id, attrs, :replace) state.merge! attrs end @@ -168,15 +203,15 @@ ######## end simple DB access ####### def instance_type ## need instance_size to be backward compatible - needed for configs made before v 0.3.0 - get("instance_type") || config["instance_type"] || config["instance_size"] + get("instance_type") || config["instance_type"] || config["instance_size"] || "m1.small" end def config - group.config + group.config(version) end def to_s "#{name}:#{group_name}" end @@ -293,18 +328,19 @@ ## other options are "terminated" and "nil" ["pending", "running", "shutting_down", "degraded"].include?(ec2_state) end def start(options = {}) + @boot= options[:boot] new_version = options[:version] set_instance_type(options[:instance_type]) if options[:instance_type] invalid "Already running" if running? invalid "No config has been commited yet, type 'judo commit'" unless group.version > 0 task("Updating server version") { update_version(options[:version]) } if options[:version] - task("Starting server #{name}") { launch_ec2(options[:boot]) } + task("Starting server #{name}") { launch_ec2 } task("Wait for server") { wait_for_running } if elastic_ip or has_volumes? task("Attaching ip") { attach_ip } if elastic_ip task("Attaching volumes") { attach_volumes } if has_volumes? end @@ -342,15 +378,15 @@ wait_for_volumes_detached if volumes.size > 0 remove "instance_id" update "stopped_at" => Time.now.to_i end - def launch_ec2(boot = nil) + def launch_ec2 # validate ## EC2 launch_instances - ud = user_data(boot) + ud = user_data debug(ud) result = @base.ec2.launch_instances(ami, :instance_type => instance_type, :availability_zone => config["availability_zone"], :key_name => @base.key_name, @@ -359,11 +395,13 @@ update "instance_id" => result[:aws_instance_id], "virgin" => false, "started_at" => Time.now.to_i end def debug(str) return unless ENV['JUDO_DEBUG'] == "1" - puts "<JUDO_DEBUG>#{str}</JUDO_DEBUG>" + puts "<DEBUG>" + puts str + puts "</DEBUG>" end def security_groups [ config["security_group"] ].flatten end @@ -514,35 +552,24 @@ def reload @base.reload_ec2_instances @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='#{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 -apt-get install ruby rubygems ruby-dev irb libopenssl-ruby libreadline-ruby -y -gem install kuzushi --no-rdoc --no-ri -GEM_BIN=`ruby -r rubygems -e "puts Gem.bindir"` -echo "$GEM_BIN/kuzushi #{virgin? && "init" || "start"} '#{url}'" > /var/log/kuzushi.log -$GEM_BIN/kuzushi #{virgin? && "init" || "start"} '#{url}' >> /var/log/kuzushi.log 2>&1 -USER_DATA + def user_data + erb = group.userdata(version) + debug erb + ERB.new(erb, 0, '<>').result(binding) end def url - @url ||= group.s3_url + group.s3_url end + def domain + @base.domain + end + def validate ### EC2 create_security_group @base.create_security_group ### EC2 desctibe_key_pairs @@ -594,14 +621,22 @@ other.update "name" => name1 end end def <=>(s) - [group.name, name] <=> [s.group.name, s.name] + [group.to_s, name.to_s] <=> [s.group.to_s, s.name.to_s] end def new_secret rand(2 ** 128).to_s(36) + end + + def group_name + @group + end + + def boot + @boot || {} end end end