Skip to content
Browse files

First prototype

  • Loading branch information...
0 parents commit fb146d651bd35ef11ff7ea117a0a4e7d7c3d88fd @ripienaar committed Jul 5, 2010
Showing with 259 additions and 0 deletions.
  1. +5 −0 commands/shell.rb
  2. +20 −0 lib/ec2boot.rb
  3. +36 −0 lib/ec2boot/actions.rb
  4. +14 −0 lib/ec2boot/config.rb
  5. +12 −0 lib/ec2boot/data.rb
  6. +106 −0 lib/ec2boot/metadata.rb
  7. +25 −0 lib/ec2boot/userdata.rb
  8. +28 −0 lib/ec2boot/util.rb
  9. +13 −0 process-ec-meta-data.rb
5 commands/shell.rb
@@ -0,0 +1,5 @@
+newaction("shell") do |cmd, ud, md, config|
+ if cmd.include?(:command)
+ system(cmd[:command])
+ end
+end
20 lib/ec2boot.rb
@@ -0,0 +1,20 @@
+require 'net/http'
+require 'yaml'
+require 'fileutils'
+
+module EC2Boot
+ class URLFetchFailed<RuntimeError;end
+
+ autoload :Config, "ec2boot/config"
+ autoload :Data, "ec2boot/data"
+ autoload :UserData, "ec2boot/userdata"
+ autoload :MetaData, "ec2boot/metadata"
+ autoload :Util, "ec2boot/util"
+ autoload :Actions, "ec2boot/actions"
+end
+
+def newaction(name, &block)
+ EC2Boot::Actions.module_eval {
+ define_method("#{name}_action", &block)
+ }
+end
36 lib/ec2boot/actions.rb
@@ -0,0 +1,36 @@
+module EC2Boot
+ class Actions
+ def initialize(config)
+ @actions_dir = config.actions_dir
+
+ load_actions
+ end
+
+ def load_actions
+ Dir.entries(@actions_dir).grep(/\.rb$/).each do |cmd|
+ load [@actions_dir, cmd].join("/")
+ end
+ end
+
+ def run_actions(ud, md, config)
+ if ud.user_data.include?(:actions)
+ ud.user_data[:actions].each do |action|
+ if action.include?(:type)
+ type = action[:type].to_s
+ meth = "#{type}_action"
+
+ if respond_to?(meth)
+ send(meth, action, ud, md, config)
+ else
+ # no such method
+ end
+ else
+ # no type
+ end
+ end
+ else
+ # no :actions
+ end
+ end
+ end
+end
14 lib/ec2boot/config.rb
@@ -0,0 +1,14 @@
+module EC2Boot
+ class Config
+ attr_reader :user_data_url, :meta_data_url, :cache_dir, :actions_dir, :actions
+
+ def initialize
+ @user_data_url = "http://nephilim.ml.org/~rip/fakeec2/user-data"
+ @meta_data_url = "http://nephilim.ml.org/~rip/fakeec2/meta-data"
+ @cache_dir = "/home/rip/temp/ec2cache"
+ @actions_dir = "/home/rip/work/ec2-boot-init/commands"
+
+ @actions = Actions.new(self)
+ end
+ end
+end
12 lib/ec2boot/data.rb
@@ -0,0 +1,12 @@
+module EC2Boot
+ class Data
+ def initialize(config)
+ @fetched = false
+ @config = config
+ end
+
+ def fetched?
+ @fetched
+ end
+ end
+end
106 lib/ec2boot/metadata.rb
@@ -0,0 +1,106 @@
+module EC2Boot
+ class MetaData<Data
+ attr_reader :meta_data
+
+ def initialize(config)
+ @meta_data = nil
+
+ super(config)
+
+ FileUtils.mkdir_p(@config.cache_dir + "/meta-data")
+
+ fetch
+ end
+
+ def flat_data
+ flatten(@meta_data)
+ end
+
+ private
+ def fetch
+ @meta_data = get_tree("/")
+ @fetched = true
+ end
+
+ # Turns the multi dimensional ec2 data into a boring flat version
+ def flatten(data, prefix = "")
+ flat = {}
+
+ data.each_pair do |k,v|
+ key = prefix + k.gsub("-", "_")
+
+ if v.is_a?(String)
+ v.chomp!
+
+ # if it's got multiple lines split them out in _x
+ if v.match("\n")
+ v.split("\n").each_with_index do |val, idx|
+ flat[key + "_#{idx}"] = val
+ end
+ else
+ flat[key] = v
+ end
+ elsif v.is_a?(Hash)
+ flat.merge!(flatten(v, "#{key}_"))
+ end
+ end
+
+ flat
+ end
+
+ # gets an entire tree of ec2 data
+ def get_tree(root)
+ tree_url = @config.meta_data_url + root
+ cache_root = @config.cache_dir + "/meta-data/" + root
+
+ keys = {}
+
+ tree_root = Util.get_url(tree_url).split("\n")
+
+ tree_root.each do |branch|
+ if branch =~ /\/$/
+ # its a sub dir
+ keyname = branch.chop
+
+ FileUtils.mkdir_p(cache_root + "/" + branch)
+ keys[keyname] = get_tree(root + "/" + branch)
+ else
+ if branch =~ /(.+?)=(.+)/
+ FileUtils.mkdir_p(cache_root + "/" + $1)
+ keys[$1] = get_tree(root + "/" + $1 + "/")
+ else
+ keys[branch] = get_key(root + "/" + branch)
+ end
+ end
+ end
+
+ keys
+ end
+
+ # strip out all //'s in key paths
+ def clean_path(path)
+ path = path.gsub(/\/\//, "/")
+
+ if path.match(/\/\//)
+ path = clean_path if path.match(/\/\//)
+ end
+
+ path
+ end
+
+ # gets a key, looks in the cache first
+ def get_key(key)
+ url = @config.meta_data_url + clean_path(key)
+ cache_file = clean_path(@config.cache_dir + "/meta-data" + key)
+
+ if File.exist?(cache_file)
+ val = File.read(cache_file)
+ else
+ val = Util.get_url(url)
+ File.open(cache_file, "w") {|f| f.puts val}
+ end
+
+ val
+ end
+ end
+end
25 lib/ec2boot/userdata.rb
@@ -0,0 +1,25 @@
+module EC2Boot
+ class UserData<Data
+ attr_reader :user_data, :user_data_raw
+
+ def initialize(config)
+ @user_data = nil
+
+ super(config)
+
+ fetch
+ end
+
+ private
+ def fetch
+ @user_data_raw = Util.get_url(@config.user_data_url)
+ @user_data = YAML.load(@user_data_raw)
+
+ File.open(@config.cache_dir + "/user-data.raw", "w") do |ud|
+ ud.puts @user_data_raw
+ end
+
+ @fetched = true
+ end
+ end
+end
28 lib/ec2boot/util.rb
@@ -0,0 +1,28 @@
+module EC2Boot
+ class Util
+ def self.get_url(url)
+ Net::HTTP.get URI.parse(url)
+ end
+
+ def self.write_facts(ud, md, config)
+ File.open(config.cache_dir + "/facts.txt", "w") do |facts|
+
+ if ud.fetched?
+ if ud.user_data.include?(:facts)
+ ud.user_data[:facts].each_pair do |k,v|
+ facts.puts("#{k}=#{v}")
+ end
+ end
+ end
+
+ if md.fetched?
+ data = md.flat_data
+
+ data.keys.sort.each do |k|
+ facts.puts("ec2_#{k}=#{data[k]}")
+ end
+ end
+ end
+ end
+ end
+end
13 process-ec-meta-data.rb
@@ -0,0 +1,13 @@
+#!/usr/bin/ruby
+
+require 'pp'
+require 'ec2boot'
+
+config = EC2Boot::Config.new
+ud = EC2Boot::UserData.new(config)
+md = EC2Boot::MetaData.new(config)
+
+EC2Boot::Util.write_facts(ud, md, config)
+
+config.actions.run_actions(ud, md, config)
+

0 comments on commit fb146d6

Please sign in to comment.
Something went wrong with that request. Please try again.