Class: Souffle::Provider::Base
- Inherits:
-
Object
- Object
- Souffle::Provider::Base
- Defined in:
- lib/souffle/provider.rb
Overview
The souffle cloud provider class.
Instance Attribute Summary collapse
-
#system ⇒ Object
Returns the value of attribute system.
Class Method Summary collapse
-
.update_status ⇒ Object
Updates the souffle status with the latest provider information.
Instance Method Summary collapse
-
#boot(node) ⇒ Object
Wait until ssh is available for the node and then connect.
-
#cookbook_paths ⇒ Array
The list of cookbooks and their full paths.
-
#create_cookbooks_tarball ⇒ String
Creates a new cookbook tarball for the deployment.
-
#create_node(node, tag = nil) ⇒ Object
Takes a node definition and begins the provisioning process.
-
#create_raid ⇒ Object
Creates a raid array for a given provider.
-
#create_ssh_dir_if_missing ⇒ Object
Creates the ssh directory for a given provider if it does not exist.
-
#create_system(system, tag = nil) ⇒ Object
Creates a system for a given provider.
-
#generate_chef_json(node) ⇒ String
Generates the json required for chef-solo to run on a node.
-
#initialize(system = Souffle::System.new) ⇒ Base
constructor
Initialize a new provider for a given system.
-
#name ⇒ String
The name of the given provider.
-
#role_paths ⇒ Array
The list of roles and their full paths.
-
#rsync_file(ipaddress, file, path = '.') ⇒ Object
Rsync’s a file to a remote node.
-
#ssh_block(address, user = "root", pass = nil, opts = {}) {|EventMachine::Ssh::Session| ... } ⇒ Object
Yields an ssh object to manage the commands naturally from there.
-
#ssh_key(key_name) ⇒ String
The path to the ssh key with the given name.
-
#ssh_key_exists?(key_name) ⇒ Boolean
Grabs an ssh key for a given aws node.
-
#ssh_key_path ⇒ String
The path to the ssh keys for the provider.
-
#wait_for_boot(address, user = "root", pass = nil, opts = {}, timeout = 200) {|Eventmachine::Ssh:Session| ... } ⇒ Object
Waits for ssh to be accessible for a node for the initial connection and yields an ssh object to manage the commands naturally from there.
Constructor Details
#initialize(system = Souffle::System.new) ⇒ Base
Initialize a new provider for a given system.
34 35 36 37 |
# File 'lib/souffle/provider.rb', line 34 def initialize(system=Souffle::System.new) @system ||= system create_ssh_dir_if_missing end |
Instance Attribute Details
#system ⇒ Object
Returns the value of attribute system.
29 30 31 |
# File 'lib/souffle/provider.rb', line 29 def system @system end |
Class Method Details
.update_status ⇒ Object
Updates the souffle status with the latest provider information.
269 |
# File 'lib/souffle/provider.rb', line 269 def update_status; end |
Instance Method Details
#boot(node) ⇒ Object
Wait until ssh is available for the node and then connect.
47 48 |
# File 'lib/souffle/provider.rb', line 47 def boot(node) end |
#cookbook_paths ⇒ Array
The list of cookbooks and their full paths.
215 216 217 218 219 220 221 222 |
# File 'lib/souffle/provider.rb', line 215 def cookbook_paths Array(Souffle::Config[:chef_cookbook_path]).inject([]) do |_paths, path| Dir.glob("#{File.(path)}/*").each do |cb| _paths << cb if File.directory? cb end _paths end end |
#create_cookbooks_tarball ⇒ String
Creates a new cookbook tarball for the deployment.
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 |
# File 'lib/souffle/provider.rb', line 239 def create_cookbooks_tarball tarball_name = "cookbooks-latest.tar.gz" temp_dir = File.join(Dir.tmpdir, "chef-cookbooks-latest") temp_cookbook_dir = File.join(temp_dir, "cookbooks") temp_roles_dir = File.join(temp_dir, "roles") tarball_dir = "#{File.dirname(Souffle::Config[:config_file])}/tarballs" tarball_path = File.join(tarball_dir, tarball_name) FileUtils.mkdir_p(tarball_dir) unless File.exists?(tarball_dir) FileUtils.mkdir_p(temp_dir) unless File.exists?(temp_dir) FileUtils.mkdir(temp_cookbook_dir) unless File.exists?(temp_cookbook_dir) FileUtils.mkdir(temp_roles_dir) unless File.exists?(temp_roles_dir) cookbook_paths.each { |pkg| FileUtils.cp_r(pkg, temp_cookbook_dir) } role_paths.each { |role| FileUtils.cp(role, temp_roles_dir) } tar_command = "tar -C #{temp_dir} -czf #{tarball_path} " tar_command << "./cookbooks ./roles" if EM.reactor_running? EM::DeferrableChildProcess.open(tar_command) do FileUtils.rm_rf temp_dir end else Kernel.system(tar_command) FileUtils.rm_rf temp_dir end tarball_path end |
#create_node(node, tag = nil) ⇒ Object
Takes a node definition and begins the provisioning process.
66 67 68 69 |
# File 'lib/souffle/provider.rb', line 66 def create_node(node, tag=nil) error_msg = "#{self.class.to_s}: you must override create_node" raise Souffle::Exceptions::Provider, error_msg end |
#create_raid ⇒ Object
Creates a raid array for a given provider. Intended to be overridden.
overridden.
75 76 77 78 |
# File 'lib/souffle/provider.rb', line 75 def create_raid error_msg = "#{self.class.to_s}: you must override create_raid" raise Souffle::Exceptions::Provider, error_msg end |
#create_ssh_dir_if_missing ⇒ Object
Creates the ssh directory for a given provider if it does not exist.
179 180 181 182 183 184 185 |
# File 'lib/souffle/provider.rb', line 179 def create_ssh_dir_if_missing FileUtils.mkdir_p(ssh_key_path) unless Dir.exists?(ssh_key_path) rescue error_msg = "The ssh key directory does not have write permissions: " error_msg << ssh_key_path raise Souffle::Exceptions::PermissionErrorSshKeys, error_msg end |
#create_system(system, tag = nil) ⇒ Object
Creates a system for a given provider. Intended to be overridden.
overrridden.
57 58 59 60 |
# File 'lib/souffle/provider.rb', line 57 def create_system(system, tag=nil) error_msg = "#{self.class.to_s}: you must override create_system" raise Souffle::Exceptions::Provider, error_msg end |
#generate_chef_json(node) ⇒ String
Generates the json required for chef-solo to run on a node.
85 86 87 88 89 90 91 |
# File 'lib/souffle/provider.rb', line 85 def generate_chef_json(node) json_info = Hash.new json_info[:domain] = node.try_opt(:domain) || "souffle" json_info.merge!(node.[:attributes]) json_info[:run_list] = node.run_list JSON.pretty_generate(json_info) end |
#name ⇒ String
The name of the given provider.
42 43 44 |
# File 'lib/souffle/provider.rb', line 42 def name self.class.name.split('::').last end |
#role_paths ⇒ Array
The list of roles and their full paths.
227 228 229 230 231 232 233 234 |
# File 'lib/souffle/provider.rb', line 227 def role_paths Array(Souffle::Config[:chef_role_path]).inject([]) do |_paths, path| Dir.glob("#{File.(path)}/*").each do |role| _paths << role if role[-3..-1].eql?(".rb") end _paths end end |
#rsync_file(ipaddress, file, path = '.') ⇒ Object
Rsync’s a file to a remote node.
200 201 202 203 204 205 206 207 208 209 210 |
# File 'lib/souffle/provider.rb', line 200 def rsync_file(ipaddress, file, path='.') ssh_command = "ssh -o UserKnownHostsFile=/dev/null " ssh_command << "-o StrictHostKeyChecking=no -o LogLevel=quiet" rsync_command = "rsync -qar -e \"#{ssh_command}\" " rsync_command << "#{file} root@#{ipaddress}:#{path}" if EM.reactor_running? EM.system(rsync_command) else IO.popen(rsync_command) end end |
#ssh_block(address, user = "root", pass = nil, opts = {}) {|EventMachine::Ssh::Session| ... } ⇒ Object
Yields an ssh object to manage the commands naturally from there.
will be attempted. see Net::SSH.start #wait_for and #send_wait calls.
148 149 150 151 152 153 154 155 156 157 |
# File 'lib/souffle/provider.rb', line 148 def ssh_block(address, user="root", pass=nil, opts={}) opts[:password] = pass unless pass.nil? opts[:paranoid] = false EM::Ssh.start(address, user, opts) do |connection| connection.errback do |err| Souffle::Log.error "SSH Error: #{err} (#{err.class})" end connection.callback { |ssh| yield(ssh) if block_given?; ssh.close } end end |
#ssh_key(key_name) ⇒ String
The path to the ssh key with the given name.
164 165 166 |
# File 'lib/souffle/provider.rb', line 164 def ssh_key(key_name) "#{ssh_key_path}/#{key_name}" end |
#ssh_key_exists?(key_name) ⇒ Boolean
Grabs an ssh key for a given aws node.
for the node.
174 175 176 |
# File 'lib/souffle/provider.rb', line 174 def ssh_key_exists?(key_name) File.exists? ssh_key(key_name) end |
#ssh_key_path ⇒ String
The path to the ssh keys for the provider.
190 191 192 193 |
# File 'lib/souffle/provider.rb', line 190 def ssh_key_path File.join(File.dirname( Souffle::Config[:config_file]), "ssh", name.downcase) end |
#wait_for_boot(address, user = "root", pass = nil, opts = {}, timeout = 200) {|Eventmachine::Ssh:Session| ... } ⇒ Object
Waits for ssh to be accessible for a node for the initial connection and yields an ssh object to manage the commands naturally from there.
will be attempted. see Net::SSH.start #wait_for and #send_wait calls.
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/souffle/provider.rb', line 109 def wait_for_boot(address, user="root", pass=nil, opts={}, timeout=200) Souffle::Log.info "Waiting for ssh for #{address}..." is_booted = false timer = EM::PeriodicTimer.new(EM::Ssh::Connection::TIMEOUT) do opts[:password] = pass unless pass.nil? opts[:paranoid] = false EM::Ssh.start(address, user, opts) do |connection| connection.errback { |err| nil } connection.callback do |ssh| is_booted = true yield(ssh) if block_given? ssh.close end end end EM::Timer.new(timeout) do unless is_booted Souffle::Log.error "SSH Boot timeout for #{address}..." timer.cancel end end end |