dollhouse 0.1.2 → 0.2.0.beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bin/dollhouse +8 -24
- data/lib/dollhouse/config_loader.rb +0 -16
- data/lib/dollhouse/deployment.rb +0 -7
- data/lib/dollhouse/dollhouse.rb +17 -12
- data/lib/dollhouse/{online_server.rb → instance.rb} +21 -14
- data/lib/dollhouse/instances.rb +5 -1
- data/lib/dollhouse/manual_config.rb +1 -10
- data/lib/dollhouse/remote_server.rb +2 -2
- data/lib/dollhouse/version.rb +1 -1
- metadata +14 -30
- data/lib/dollhouse/cloud_adapter.rb +0 -21
- data/lib/dollhouse/rackspace_cloud_adapter.rb +0 -101
    
        data/bin/dollhouse
    CHANGED
    
    | @@ -6,45 +6,29 @@ require 'dollhouse' | |
| 6 6 | 
             
            require 'main'
         | 
| 7 7 |  | 
| 8 8 | 
             
            Main do
         | 
| 9 | 
            -
              mode ' | 
| 10 | 
            -
                argument('deployment') { required }
         | 
| 11 | 
            -
                argument('prefix') { optional }
         | 
| 12 | 
            -
                def run
         | 
| 13 | 
            -
                  Dollhouse.launch_from(Dir.pwd)
         | 
| 14 | 
            -
                  Dollhouse.initiate_deployment(params['deployment'].value.to_sym, :prefix => params['prefix'].value)
         | 
| 15 | 
            -
                end
         | 
| 16 | 
            -
              end
         | 
| 17 | 
            -
             | 
| 18 | 
            -
              mode 'exec' do
         | 
| 19 | 
            -
                argument('server_name') { required }
         | 
| 20 | 
            -
                argument('cmd') { required }
         | 
| 21 | 
            -
                def run
         | 
| 22 | 
            -
                  Dollhouse.launch_from(Dir.pwd)
         | 
| 23 | 
            -
                  Dollhouse.instances[params['server_name'].value].instance_eval params['cmd'].value
         | 
| 24 | 
            -
                end
         | 
| 25 | 
            -
              end
         | 
| 26 | 
            -
             | 
| 27 | 
            -
              mode 'destroy' do
         | 
| 9 | 
            +
              mode 'run' do
         | 
| 28 10 | 
             
                argument('server_name') { required }
         | 
| 11 | 
            +
                argument('task_name') { required }
         | 
| 29 12 | 
             
                def run
         | 
| 30 13 | 
             
                  Dollhouse.launch_from(Dir.pwd)
         | 
| 31 | 
            -
                  Dollhouse. | 
| 14 | 
            +
                  Dollhouse.run(params['server_name'].value, params['task_name'].value)
         | 
| 32 15 | 
             
                end
         | 
| 33 16 | 
             
              end
         | 
| 34 17 |  | 
| 35 18 | 
             
              mode 'list' do
         | 
| 36 19 | 
             
                def run
         | 
| 37 20 | 
             
                  Dollhouse.launch_from(Dir.pwd)
         | 
| 38 | 
            -
                   | 
| 21 | 
            +
                  puts Dollhouse.instances.list
         | 
| 39 22 | 
             
                end
         | 
| 40 23 | 
             
              end
         | 
| 41 24 |  | 
| 42 | 
            -
               | 
| 25 | 
            +
              # bit hax
         | 
| 26 | 
            +
              mode 'exec' do
         | 
| 43 27 | 
             
                argument('server_name') { required }
         | 
| 44 | 
            -
                argument(' | 
| 28 | 
            +
                argument('cmd') { required }
         | 
| 45 29 | 
             
                def run
         | 
| 46 30 | 
             
                  Dollhouse.launch_from(Dir.pwd)
         | 
| 47 | 
            -
                  Dollhouse. | 
| 31 | 
            +
                  Dollhouse.execute(params['server_name'].value, params['cmd'].value)
         | 
| 48 32 | 
             
                end
         | 
| 49 33 | 
             
              end
         | 
| 50 34 |  | 
| @@ -18,22 +18,6 @@ module Dollhouse | |
| 18 18 | 
             
              end
         | 
| 19 19 |  | 
| 20 20 | 
             
              class ServerBuilder < Struct.new(:name)
         | 
| 21 | 
            -
                def instance_type t
         | 
| 22 | 
            -
                  @instance_type = t
         | 
| 23 | 
            -
                end
         | 
| 24 | 
            -
             | 
| 25 | 
            -
                def os o
         | 
| 26 | 
            -
                  @os = o
         | 
| 27 | 
            -
                end
         | 
| 28 | 
            -
             | 
| 29 | 
            -
                def from_latest_snapshot snapshot_name
         | 
| 30 | 
            -
                  @snapshot = snapshot_name
         | 
| 31 | 
            -
                end
         | 
| 32 | 
            -
             | 
| 33 | 
            -
                def first_boot &blk
         | 
| 34 | 
            -
                  callbacks[:first_boot] = blk
         | 
| 35 | 
            -
                end
         | 
| 36 | 
            -
             | 
| 37 21 | 
             
                def task name, &blk
         | 
| 38 22 | 
             
                  callbacks[name.to_s] = blk
         | 
| 39 23 | 
             
                end
         | 
    
        data/lib/dollhouse/deployment.rb
    CHANGED
    
    | @@ -16,13 +16,6 @@ module Dollhouse | |
| 16 16 | 
             
                  end
         | 
| 17 17 | 
             
                end
         | 
| 18 18 |  | 
| 19 | 
            -
                def server_online cloud_name, server
         | 
| 20 | 
            -
                  online_server = OnlineServer[cloud_name, self.name, server.name, :running]
         | 
| 21 | 
            -
                  Dollhouse.instances.server_came_online online_server
         | 
| 22 | 
            -
                  online_server.bootstrap
         | 
| 23 | 
            -
                  online_server.instance_eval &server.callbacks[:first_boot]
         | 
| 24 | 
            -
                end
         | 
| 25 | 
            -
             | 
| 26 19 | 
             
                def self.[](deployment)
         | 
| 27 20 | 
             
                  raise "Unknown deployment #{deployment}" unless all.has_key? deployment.to_s
         | 
| 28 21 | 
             
                  all[deployment.to_s]
         | 
    
        data/lib/dollhouse/dollhouse.rb
    CHANGED
    
    | @@ -1,18 +1,23 @@ | |
| 1 1 | 
             
            module Dollhouse
         | 
| 2 | 
            -
               | 
| 3 | 
            -
                 | 
| 4 | 
            -
                # may need something cleverer in the future
         | 
| 5 | 
            -
                require dir + '/config/dollhouse/config.rb'
         | 
| 6 | 
            -
                Dir.glob(dir + '/config/dollhouse/auth.rb') { |f| require f } #optional require
         | 
| 7 | 
            -
                Dir.glob(dir + '/config/dollhouse/deployments/*.rb') { |f| require f }
         | 
| 8 | 
            -
              end
         | 
| 2 | 
            +
              class << self
         | 
| 3 | 
            +
                attr_accessor :root, :instances
         | 
| 9 4 |  | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 5 | 
            +
                def launch_from(dir)
         | 
| 6 | 
            +
                  self.root = dir
         | 
| 7 | 
            +
                  # may need something cleverer in the future
         | 
| 8 | 
            +
                  raise "You should be running this in your application root, or at least somewhere with a config/dollhouse subdirectory" if !File.exists?(File.join(dir, 'config', 'dollhouse'))
         | 
| 9 | 
            +
                  Dir.glob(dir + '/config/dollhouse/config.rb') { |f| require f } #optional require
         | 
| 10 | 
            +
                  Dir.glob(dir + '/config/dollhouse/auth.rb') { |f| require f } #optional require
         | 
| 11 | 
            +
                  Dir.glob(dir + '/config/dollhouse/deployments/*.rb') { |f| require f }
         | 
| 12 | 
            +
                end
         | 
| 13 13 |  | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 14 | 
            +
                def run(server_name, task_name)
         | 
| 15 | 
            +
                  instances[server_name].run_task task_name
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                def execute(server_name, cmd)
         | 
| 19 | 
            +
                  instances[server_name].instance_eval cmd
         | 
| 20 | 
            +
                end
         | 
| 16 21 |  | 
| 17 22 | 
             
                def instances
         | 
| 18 23 | 
             
                  @instances ||= Instances.new
         | 
| @@ -1,35 +1,31 @@ | |
| 1 1 | 
             
            module Dollhouse
         | 
| 2 | 
            -
              class  | 
| 2 | 
            +
              class Instance < Struct.new(:instance_name, :deployment_name, :server_name, :ip)
         | 
| 3 3 | 
             
                attr_accessor :user, :password
         | 
| 4 4 |  | 
| 5 5 | 
             
                def bootstrap
         | 
| 6 | 
            -
                   | 
| 6 | 
            +
                  cloud_adapter.execute(instance_name, %Q{bash -c "`wget -O- babushka.me/up/hard`"}, default_opts)
         | 
| 7 7 | 
             
                end
         | 
| 8 8 |  | 
| 9 9 | 
             
                def babushka taskname, vars = {}
         | 
| 10 10 | 
             
                  # not used yet, but this makes sense. --defaults (or headless) is the default!
         | 
| 11 11 | 
             
                  if vars == :no_defaults
         | 
| 12 | 
            -
                     | 
| 12 | 
            +
                    cloud_adapter.execute(instance_name, "babushka '#{taskname}'", default_opts)
         | 
| 13 13 | 
             
                  else
         | 
| 14 14 | 
             
                    if !vars.empty?
         | 
| 15 15 | 
             
                      write_file(".babushka/vars/#{taskname}", {
         | 
| 16 16 | 
             
                        :vars => vars.map_keys(&:to_s).map_values { |v| {:value => v} }
         | 
| 17 17 | 
             
                      }.to_yaml)
         | 
| 18 18 | 
             
                    end
         | 
| 19 | 
            -
                     | 
| 19 | 
            +
                    cloud_adapter.execute(instance_name, "babushka '#{taskname}' --defaults", default_opts)
         | 
| 20 20 | 
             
                  end
         | 
| 21 21 | 
             
                end
         | 
| 22 22 |  | 
| 23 23 | 
             
                def shell cmd, opts = {}
         | 
| 24 | 
            -
                   | 
| 24 | 
            +
                  cloud_adapter.execute(instance_name, cmd, default_opts.merge(opts))
         | 
| 25 25 | 
             
                end
         | 
| 26 26 |  | 
| 27 27 | 
             
                def write_file path, content, opts = {}
         | 
| 28 | 
            -
                   | 
| 29 | 
            -
                end
         | 
| 30 | 
            -
             | 
| 31 | 
            -
                def destroy
         | 
| 32 | 
            -
                  Dollhouse.cloud_adapter.destroy(name_in_cloud)
         | 
| 28 | 
            +
                  cloud_adapter.write_file(instance_name, path, content, default_opts.merge(opts))
         | 
| 33 29 | 
             
                end
         | 
| 34 30 |  | 
| 35 31 | 
             
                def as user, opts = {}, &blk
         | 
| @@ -42,10 +38,6 @@ module Dollhouse | |
| 42 38 | 
             
                  self.password = old_password
         | 
| 43 39 | 
             
                end
         | 
| 44 40 |  | 
| 45 | 
            -
                def take_snapshot name
         | 
| 46 | 
            -
                  Dollhouse.cloud_adapter.take_snapshot(name_in_cloud, name + "-" + Time.now.strftime("%Y%M%d-%H%M%S"))
         | 
| 47 | 
            -
                end
         | 
| 48 | 
            -
             | 
| 49 41 | 
             
                def server
         | 
| 50 42 | 
             
                  deployment.servers.find { |s| s.name == server_name }
         | 
| 51 43 | 
             
                end
         | 
| @@ -58,6 +50,16 @@ module Dollhouse | |
| 58 50 | 
             
                  instance_eval &server.callbacks[task_name]
         | 
| 59 51 | 
             
                end
         | 
| 60 52 |  | 
| 53 | 
            +
                def to_yaml
         | 
| 54 | 
            +
                  {instance_name => {'deployment_name' => deployment_name, 'server_name' => server_name, 'ip' => ip}}
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                def self.from_yaml(hash)
         | 
| 58 | 
            +
                  hash.map_values_with_keys { |k,v|
         | 
| 59 | 
            +
                    Instance[k, v['deployment_name'], v['server_name'], v['ip']]
         | 
| 60 | 
            +
                  }
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
             | 
| 61 63 | 
             
                private
         | 
| 62 64 |  | 
| 63 65 | 
             
                def default_opts
         | 
| @@ -66,5 +68,10 @@ module Dollhouse | |
| 66 68 | 
             
                  opts.merge!({:sudo_password => password}) if password
         | 
| 67 69 | 
             
                  opts
         | 
| 68 70 | 
             
                end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                # This could return different adapters, that connect to servers in different ways. For now we have a simple
         | 
| 73 | 
            +
                def cloud_adapter
         | 
| 74 | 
            +
                  @cloud_adapter ||= ManualConfig.new
         | 
| 75 | 
            +
                end
         | 
| 69 76 | 
             
              end
         | 
| 70 77 | 
             
            end
         | 
    
        data/lib/dollhouse/instances.rb
    CHANGED
    
    | @@ -15,12 +15,16 @@ module Dollhouse | |
| 15 15 |  | 
| 16 16 | 
             
                def online_servers
         | 
| 17 17 | 
             
                  @online_servers = if File.exists? "#{Dollhouse.root}/config/dollhouse/instances/servers.yml"
         | 
| 18 | 
            -
                    YAML::load_file("#{Dollhouse.root}/config/dollhouse/instances/servers.yml")  | 
| 18 | 
            +
                    Instance.from_yaml(YAML::load_file("#{Dollhouse.root}/config/dollhouse/instances/servers.yml") || {})
         | 
| 19 19 | 
             
                  else
         | 
| 20 20 | 
             
                    {}
         | 
| 21 21 | 
             
                  end
         | 
| 22 22 | 
             
                end
         | 
| 23 23 |  | 
| 24 | 
            +
                def list
         | 
| 25 | 
            +
                  online_servers.inspect
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 24 28 | 
             
                private
         | 
| 25 29 |  | 
| 26 30 | 
             
                def save!
         | 
| @@ -1,22 +1,13 @@ | |
| 1 1 | 
             
            module Dollhouse
         | 
| 2 | 
            -
              class ManualConfig | 
| 2 | 
            +
              class ManualConfig
         | 
| 3 3 | 
             
                def execute(name, cmd, opts = {})
         | 
| 4 4 | 
             
                  #nasty, but sudo_password isn't valid for starting a connection
         | 
| 5 5 | 
             
                  sudo_password = opts.delete(:sudo_password)
         | 
| 6 6 | 
             
                  ssh_conn(Dollhouse.instances[name].ip, opts[:user] || 'root', opts) do
         | 
| 7 | 
            -
                    p "Executing: #{cmd}"
         | 
| 8 7 | 
             
                    exec cmd, {:sudo_password => sudo_password}
         | 
| 9 8 | 
             
                  end
         | 
| 10 9 | 
             
                end
         | 
| 11 10 |  | 
| 12 | 
            -
                def boot_new_server(name, callback, opts)
         | 
| 13 | 
            -
                  raise "You can't, you fool!"
         | 
| 14 | 
            -
                end
         | 
| 15 | 
            -
             | 
| 16 | 
            -
                def list
         | 
| 17 | 
            -
                  Dollhouse.instances.online_servers.values.select { |i| i.status == :running }
         | 
| 18 | 
            -
                end
         | 
| 19 | 
            -
             | 
| 20 11 | 
             
                def write_file(name, path, content, opts)
         | 
| 21 12 | 
             
                  ssh_conn(Dollhouse.instances[name].ip, opts[:user] || 'root', opts) do
         | 
| 22 13 | 
             
                    write_file(path) do |out|
         | 
| @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            # Let it be known, dgoodlad is a profase.
         | 
| 1 | 
            +
            # Let it be known, @dgoodlad is a profase.
         | 
| 2 2 |  | 
| 3 3 | 
             
            require 'net/ssh'
         | 
| 4 4 | 
             
            require 'net/sftp'
         | 
| @@ -48,7 +48,7 @@ module Dollhouse | |
| 48 48 | 
             
                      output = ''
         | 
| 49 49 | 
             
                      status_code = nil
         | 
| 50 50 |  | 
| 51 | 
            -
                      puts "Executing | 
| 51 | 
            +
                      puts "## Executing: #{command}"
         | 
| 52 52 |  | 
| 53 53 | 
             
                      ch.exec(command) do |ch, success|
         | 
| 54 54 | 
             
                        raise "Failed to start execution!" unless success
         | 
    
        data/lib/dollhouse/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,13 +1,15 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification 
         | 
| 2 2 | 
             
            name: dollhouse
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            -
              hash:  | 
| 5 | 
            -
              prerelease:  | 
| 4 | 
            +
              hash: 62196353
         | 
| 5 | 
            +
              prerelease: true
         | 
| 6 6 | 
             
              segments: 
         | 
| 7 7 | 
             
              - 0
         | 
| 8 | 
            -
              - 1
         | 
| 9 8 | 
             
              - 2
         | 
| 10 | 
            -
               | 
| 9 | 
            +
              - 0
         | 
| 10 | 
            +
              - beta
         | 
| 11 | 
            +
              - 1
         | 
| 12 | 
            +
              version: 0.2.0.beta.1
         | 
| 11 13 | 
             
            platform: ruby
         | 
| 12 14 | 
             
            authors: 
         | 
| 13 15 | 
             
            - Glen Maddern
         | 
| @@ -15,7 +17,7 @@ autorequire: | |
| 15 17 | 
             
            bindir: bin
         | 
| 16 18 | 
             
            cert_chain: []
         | 
| 17 19 |  | 
| 18 | 
            -
            date: 2010-11- | 
| 20 | 
            +
            date: 2010-11-12 00:00:00 +11:00
         | 
| 19 21 | 
             
            default_executable: 
         | 
| 20 22 | 
             
            dependencies: 
         | 
| 21 23 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| @@ -98,26 +100,10 @@ dependencies: | |
| 98 100 | 
             
                    version: 0.10.3
         | 
| 99 101 | 
             
              type: :runtime
         | 
| 100 102 | 
             
              version_requirements: *id005
         | 
| 101 | 
            -
            - !ruby/object:Gem::Dependency 
         | 
| 102 | 
            -
              name: bundler
         | 
| 103 | 
            -
              prerelease: false
         | 
| 104 | 
            -
              requirement: &id006 !ruby/object:Gem::Requirement 
         | 
| 105 | 
            -
                none: false
         | 
| 106 | 
            -
                requirements: 
         | 
| 107 | 
            -
                - - ~>
         | 
| 108 | 
            -
                  - !ruby/object:Gem::Version 
         | 
| 109 | 
            -
                    hash: 17
         | 
| 110 | 
            -
                    segments: 
         | 
| 111 | 
            -
                    - 1
         | 
| 112 | 
            -
                    - 0
         | 
| 113 | 
            -
                    - 3
         | 
| 114 | 
            -
                    version: 1.0.3
         | 
| 115 | 
            -
              type: :development
         | 
| 116 | 
            -
              version_requirements: *id006
         | 
| 117 103 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| 118 104 | 
             
              name: cucumber
         | 
| 119 105 | 
             
              prerelease: false
         | 
| 120 | 
            -
              requirement: & | 
| 106 | 
            +
              requirement: &id006 !ruby/object:Gem::Requirement 
         | 
| 121 107 | 
             
                none: false
         | 
| 122 108 | 
             
                requirements: 
         | 
| 123 109 | 
             
                - - ~>
         | 
| @@ -129,11 +115,11 @@ dependencies: | |
| 129 115 | 
             
                    - 3
         | 
| 130 116 | 
             
                    version: 0.9.3
         | 
| 131 117 | 
             
              type: :development
         | 
| 132 | 
            -
              version_requirements: * | 
| 118 | 
            +
              version_requirements: *id006
         | 
| 133 119 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| 134 120 | 
             
              name: rake
         | 
| 135 121 | 
             
              prerelease: false
         | 
| 136 | 
            -
              requirement: & | 
| 122 | 
            +
              requirement: &id007 !ruby/object:Gem::Requirement 
         | 
| 137 123 | 
             
                none: false
         | 
| 138 124 | 
             
                requirements: 
         | 
| 139 125 | 
             
                - - ~>
         | 
| @@ -145,11 +131,11 @@ dependencies: | |
| 145 131 | 
             
                    - 7
         | 
| 146 132 | 
             
                    version: 0.8.7
         | 
| 147 133 | 
             
              type: :development
         | 
| 148 | 
            -
              version_requirements: * | 
| 134 | 
            +
              version_requirements: *id007
         | 
| 149 135 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| 150 136 | 
             
              name: rspec
         | 
| 151 137 | 
             
              prerelease: false
         | 
| 152 | 
            -
              requirement: & | 
| 138 | 
            +
              requirement: &id008 !ruby/object:Gem::Requirement 
         | 
| 153 139 | 
             
                none: false
         | 
| 154 140 | 
             
                requirements: 
         | 
| 155 141 | 
             
                - - ~>
         | 
| @@ -161,7 +147,7 @@ dependencies: | |
| 161 147 | 
             
                    - 0
         | 
| 162 148 | 
             
                    version: 2.0.0
         | 
| 163 149 | 
             
              type: :development
         | 
| 164 | 
            -
              version_requirements: * | 
| 150 | 
            +
              version_requirements: *id008
         | 
| 165 151 | 
             
            description: Dollhouse is a way to deploy servers. It is designed to be used with Babushka.
         | 
| 166 152 | 
             
            email: glen.maddern@gmail.com
         | 
| 167 153 | 
             
            executables: 
         | 
| @@ -173,14 +159,12 @@ extra_rdoc_files: [] | |
| 173 159 | 
             
            files: 
         | 
| 174 160 | 
             
            - bin/dollhouse
         | 
| 175 161 | 
             
            - lib/core_ext/hash.rb
         | 
| 176 | 
            -
            - lib/dollhouse/cloud_adapter.rb
         | 
| 177 162 | 
             
            - lib/dollhouse/config_loader.rb
         | 
| 178 163 | 
             
            - lib/dollhouse/deployment.rb
         | 
| 179 164 | 
             
            - lib/dollhouse/dollhouse.rb
         | 
| 165 | 
            +
            - lib/dollhouse/instance.rb
         | 
| 180 166 | 
             
            - lib/dollhouse/instances.rb
         | 
| 181 167 | 
             
            - lib/dollhouse/manual_config.rb
         | 
| 182 | 
            -
            - lib/dollhouse/online_server.rb
         | 
| 183 | 
            -
            - lib/dollhouse/rackspace_cloud_adapter.rb
         | 
| 184 168 | 
             
            - lib/dollhouse/remote_server.rb
         | 
| 185 169 | 
             
            - lib/dollhouse/server.rb
         | 
| 186 170 | 
             
            - lib/dollhouse/version.rb
         | 
| @@ -1,21 +0,0 @@ | |
| 1 | 
            -
            module Dollhouse
         | 
| 2 | 
            -
              class CloudAdapter
         | 
| 3 | 
            -
                def initialize
         | 
| 4 | 
            -
                  raise NotImplementedError, %Q{
         | 
| 5 | 
            -
                  Must implement the following methods:
         | 
| 6 | 
            -
             | 
| 7 | 
            -
                  boot_new_server(name, callback, opts)
         | 
| 8 | 
            -
                  - name is the unique id for the server in this cloud
         | 
| 9 | 
            -
                  - callback is a lambda to be fired_off when that server comes online
         | 
| 10 | 
            -
                  - generally, opts has :machine_id, :ram_size, :data_center, :backup_image_id
         | 
| 11 | 
            -
             | 
| 12 | 
            -
                  execute(server_name, cmd, opts)
         | 
| 13 | 
            -
             | 
| 14 | 
            -
                  write_file(server_name, path, content, opts)
         | 
| 15 | 
            -
             | 
| 16 | 
            -
                  list
         | 
| 17 | 
            -
             | 
| 18 | 
            -
                } unless [:boot_new_server, :execute, :write_file, :list].all? { |m| self.class.method_defined? m }
         | 
| 19 | 
            -
                end
         | 
| 20 | 
            -
              end
         | 
| 21 | 
            -
            end
         | 
| @@ -1,101 +0,0 @@ | |
| 1 | 
            -
            module Dollhouse
         | 
| 2 | 
            -
              class RackspaceCloudAdapter < CloudAdapter
         | 
| 3 | 
            -
                FLAVORS = {"256mb" => 1, "512mb" => 2, "1024mb" => 3, "2048mb" => 4}
         | 
| 4 | 
            -
                IMAGES = {"Ubuntu 10.04" => 49}
         | 
| 5 | 
            -
             | 
| 6 | 
            -
                def conn
         | 
| 7 | 
            -
                  require 'fog'
         | 
| 8 | 
            -
                  @conn ||= Fog::Rackspace::Servers.new(
         | 
| 9 | 
            -
                              :rackspace_api_key => Auth::Rackspace::API_KEY,
         | 
| 10 | 
            -
                              :rackspace_username => Auth::Rackspace::USERNAME
         | 
| 11 | 
            -
                  )
         | 
| 12 | 
            -
                end
         | 
| 13 | 
            -
             | 
| 14 | 
            -
                def boot_new_server(name, callback, opts)
         | 
| 15 | 
            -
                  flavor_num = FLAVORS[opts[:instance_type]]
         | 
| 16 | 
            -
                  raise "Unknown instance_type of #{opts[:instance_type].inspect}. Permitted values are #{FLAVORS.keys.inspect}" unless flavor_num
         | 
| 17 | 
            -
                  image_num = if opts[:snapshot]
         | 
| 18 | 
            -
                    image = conn.images.select { |i| i.created_at && i.name =~ Regexp.new(Regexp.escape(opts[:snapshot])) }.sort_by { |i| i.created_at }.last
         | 
| 19 | 
            -
                    raise "Snapshot name of #{opts[:snapshot]} doesn't match any images!" unless image
         | 
| 20 | 
            -
                    puts "Booting from image: #{image.inspect}"
         | 
| 21 | 
            -
                    image.id
         | 
| 22 | 
            -
                  else
         | 
| 23 | 
            -
                    raise "Unknown os of #{opts[:os].inspect}. Permitted values are #{IMAGES.keys.inspect}" unless IMAGES[opts[:os]]
         | 
| 24 | 
            -
                    IMAGES[opts[:os]]
         | 
| 25 | 
            -
                  end
         | 
| 26 | 
            -
             | 
| 27 | 
            -
                  puts "Booting server #{name}"
         | 
| 28 | 
            -
                  server = conn.servers.create(:flavor_id => flavor_num, :image_id => image_num, :name => name)
         | 
| 29 | 
            -
             | 
| 30 | 
            -
                  puts "Server booted: #{server.inspect}"
         | 
| 31 | 
            -
                  # make this asynch soon
         | 
| 32 | 
            -
                  server.wait_for { ready? }
         | 
| 33 | 
            -
                  puts "Server #{name} online. Adding our private key"
         | 
| 34 | 
            -
                  server.public_key_path = Auth::KEYPAIR + ".pub"
         | 
| 35 | 
            -
                  server.setup
         | 
| 36 | 
            -
                  puts "Done. Ready to go!"
         | 
| 37 | 
            -
             | 
| 38 | 
            -
                  callback.call
         | 
| 39 | 
            -
                end
         | 
| 40 | 
            -
             | 
| 41 | 
            -
                def execute(name, cmd, opts = {})
         | 
| 42 | 
            -
                  #nasty, but sudo_password isn't valid for starting a connection
         | 
| 43 | 
            -
                  sudo_password = opts.delete(:sudo_password)
         | 
| 44 | 
            -
                  ssh_conn(name, opts) do
         | 
| 45 | 
            -
                    p "Executing: #{cmd}"
         | 
| 46 | 
            -
                    exec cmd, {:sudo_password => sudo_password}
         | 
| 47 | 
            -
                  end
         | 
| 48 | 
            -
                end
         | 
| 49 | 
            -
             | 
| 50 | 
            -
                def write_file(name, path, content, opts = {})
         | 
| 51 | 
            -
                  ssh_conn(name, opts) do
         | 
| 52 | 
            -
                    write_file(path) do |out|
         | 
| 53 | 
            -
                      out.puts content
         | 
| 54 | 
            -
                    end
         | 
| 55 | 
            -
                  end
         | 
| 56 | 
            -
                end
         | 
| 57 | 
            -
             | 
| 58 | 
            -
                def destroy name
         | 
| 59 | 
            -
                  server = get_server name
         | 
| 60 | 
            -
                  puts "Killing server #{server.inspect}"
         | 
| 61 | 
            -
                  server.destroy
         | 
| 62 | 
            -
                  puts "Done."
         | 
| 63 | 
            -
                end
         | 
| 64 | 
            -
             | 
| 65 | 
            -
                def take_snapshot name, snapshot_name
         | 
| 66 | 
            -
                  response = conn.create_image get_server(name).id, 'name' => snapshot_name
         | 
| 67 | 
            -
                  puts "Created image: #{response.body['image'].inspect}"
         | 
| 68 | 
            -
                end
         | 
| 69 | 
            -
             | 
| 70 | 
            -
                def list
         | 
| 71 | 
            -
                  conn.servers
         | 
| 72 | 
            -
                end
         | 
| 73 | 
            -
             | 
| 74 | 
            -
                private
         | 
| 75 | 
            -
             | 
| 76 | 
            -
                def ssh_conn(name, opts, &blk)
         | 
| 77 | 
            -
                  #nasty, but sudo_password isn't valid for starting a connection
         | 
| 78 | 
            -
                  opts.delete(:sudo_password)
         | 
| 79 | 
            -
                  ssh_conns[[name, opts]].instance_eval(&blk)
         | 
| 80 | 
            -
                end
         | 
| 81 | 
            -
             | 
| 82 | 
            -
                def ssh_conns
         | 
| 83 | 
            -
                  @ssh_conns ||= Hash.new { |h, (name, opts)|
         | 
| 84 | 
            -
                    puts "Establishing connection to #{name}:"
         | 
| 85 | 
            -
                    #change this to use instances.yml, or something
         | 
| 86 | 
            -
                    server = get_server name
         | 
| 87 | 
            -
                    host = server.addresses['public'].first
         | 
| 88 | 
            -
                    user = opts[:user] || 'root'
         | 
| 89 | 
            -
                    puts "Connecting to #{host} as #{user}..."
         | 
| 90 | 
            -
             | 
| 91 | 
            -
                    h[[name, opts]] = RemoteServer.new(host, user, {:forward_agent => true}.merge(opts))
         | 
| 92 | 
            -
                  }
         | 
| 93 | 
            -
                end
         | 
| 94 | 
            -
             | 
| 95 | 
            -
                def get_server name
         | 
| 96 | 
            -
                  server = conn.servers.find { |s| s.name == name }
         | 
| 97 | 
            -
                  raise "Can't find server #{name}" if server.nil?
         | 
| 98 | 
            -
                  server
         | 
| 99 | 
            -
                end
         | 
| 100 | 
            -
              end
         | 
| 101 | 
            -
            end
         |