lib/knife-solo/bootstraps.rb
class OperatingSystemNotSupportedError < StandardError ; end
module KnifeSolo
module Bootstraps
class OperatingSystemNotImplementedError < StandardError
end
def self.class_exists_for?(os_name)
begin
true if self.class_for_operating_system(os_name).class == Class
rescue
false
end
end
def self.class_for_operating_system(os_name)
begin
os_class_name = os_name.gsub(/\s/,'')
KnifeSolo::Bootstraps.const_get(os_class_name)
rescue
raise OperatingSystemNotImplementedError.new("#{os_name.inspect} not implemented. Feel free to add a bootstrap implementation in KnifeSolo::Bootstraps::#{os_class_name}")
end
end
module Delegates
def stream_command(cmd)
prepare.stream_command(cmd)
end
def run_command(cmd)
prepare.run_command(cmd)
end
def ui
prepare.ui
end
def chef_version
prepare.chef_version
end
def prepare
@prepare
end
end #Delegates
module InstallCommands
def bootstrap!
run_pre_bootstrap_checks
send("#{distro[:type]}_install")
install_ohai_hints
end
def distro
raise "implement distro detection for #{self.class.name}"
end
# gems to install before chef
def gem_packages
[]
end
def http_client_get_url(url, file)
stream_command <<-BASH
/bin/sh -c " \
if command -v curl >/dev/null 2>&1; then \
curl -L -o '#{file}' '#{url}'; \
else \
wget -O '#{file}' '#{url}'; \
fi; \
"
BASH
end
def omnibus_install
url = prepare.config[:omnibus_url] || "https://www.opscode.com/chef/install.sh"
file = File.basename(url)
http_client_get_url(url, file)
install_command = "sudo bash #{file} #{omnibus_options}"
stream_command(install_command)
end
def omnibus_options
options = prepare.config[:omnibus_options] || ""
if prepare.config[:prerelease]
options << " -p"
elsif chef_version
options << " -v #{chef_version}"
end
options
end
def gem_install
ui.msg "Installing rubygems from source..."
release = "rubygems-1.8.10"
file = "#{release}.tgz"
url = "http://production.cf.rubygems.org/rubygems/#{file}"
http_client_get_url(url, file)
run_command("tar zxf #{file}")
run_command("cd #{release} && sudo ruby setup.rb --no-format-executable")
run_command("sudo rm -rf #{release} #{file}")
run_command("sudo gem install --no-rdoc --no-ri #{gem_packages.join(' ')}") unless gem_packages.empty?
run_command("sudo gem install --no-rdoc --no-ri chef #{gem_options}")
end
def gem_options
if prepare.config[:prerelease]
"--prerelease"
elsif chef_version
"--version #{chef_version}"
end
end
def install_ohai_hints
hints = Chef::Config[:knife][:hints]
unless hints.nil? || hints.empty?
ui.msg "Setting Ohai hints..."
run_command("sudo mkdir -p /etc/chef/ohai/hints")
run_command("sudo rm -f /etc/chef/ohai/hints/*")
hints.each do |name, hash|
run_command("sudo tee -a /etc/chef/ohai/hints/#{name}.json > /dev/null <<EOF\n#{hash.to_json}\nEOF\n")
end
end
end
end #InstallCommands
class Base
include KnifeSolo::Bootstraps::Delegates
include KnifeSolo::Bootstraps::InstallCommands
def initialize(prepare)
# instance of Chef::Knife::SoloPrepare
@prepare = prepare
end
def run_pre_bootstrap_checks ; end
# run right before we run #{distro[:type]}_install method
# barf out here if need be
end
end # Bootstraps
end
# bootstrap classes for different OSes
Dir[File.dirname(__FILE__) + '/bootstraps/*.rb'].each {|p| require p}