Permalink
Browse files

Merge pull request #240 from tmatilai/init-berks-librarian

Improve `solo init` logic with Berkshelf and Librarian-Chef
  • Loading branch information...
2 parents e5110f8 + 07647a4 commit 80d8948ef825b3bfdec89d72cd1d4951a714f3b2 @matschaffer committed May 23, 2013
View
@@ -13,14 +13,18 @@ lib/chef/knife/solo_init.rb
lib/chef/knife/solo_prepare.rb
lib/chef/knife/wash_up.rb
lib/knife-solo.rb
+lib/knife-solo/berkshelf.rb
lib/knife-solo/bootstraps.rb
lib/knife-solo/bootstraps/darwin.rb
lib/knife-solo/bootstraps/freebsd.rb
lib/knife-solo/bootstraps/linux.rb
lib/knife-solo/bootstraps/sun_os.rb
+lib/knife-solo/cookbook_manager.rb
+lib/knife-solo/cookbook_manager_selector.rb
lib/knife-solo/deprecated_command.rb
lib/knife-solo/gitignore.rb
lib/knife-solo/info.rb
+lib/knife-solo/librarian.rb
lib/knife-solo/node_config_command.rb
lib/knife-solo/resources/knife.rb
lib/knife-solo/resources/patch_cookbooks/chef-solo-search
@@ -18,9 +18,10 @@ class SoloCook < Knife
deps do
require 'chef/cookbook/chefignore'
require 'knife-solo'
+ require 'knife-solo/berkshelf'
+ require 'knife-solo/librarian'
require 'erubis'
require 'pathname'
- require 'tempfile'
KnifeSolo::SshCommand.load_deps
KnifeSolo::NodeConfigCommand.load_deps
end
@@ -81,7 +82,6 @@ def run
sync_kitchen
generate_solorb
cook unless config[:sync_only]
- cleanup
end
end
@@ -181,68 +181,13 @@ def time(msg)
end
def berkshelf_install
- if !File.exist? 'Berksfile'
- Chef::Log.debug "Berksfile not found"
- elsif !load_berkshelf
- ui.warn "Berkshelf could not be loaded"
- ui.warn "Please add the berkshelf gem to your Gemfile or install it manually with `gem install berkshelf`"
- else
- path = berkshelf_path
- if path == :tmpdir
- path = @berks_tmp_dir = Dir.mktmpdir('berks-')
- end
- ui.msg "Installing Berkshelf cookbooks to '#{path}'..."
- Berkshelf::Berksfile.from_file(expand_path('Berksfile')).install(:path => path)
- add_cookbook_path path
- end
- end
-
- def load_berkshelf
- begin
- require 'berkshelf'
- rescue LoadError
- false
- else
- true
- end
- end
-
- def berkshelf_path
- path = config_value(:berkshelf_path)
- if path.nil?
- ui.warn "`knife[:berkshelf_path]` is not set. Using temporary directory to install Berkshelf cookbooks."
- path = :tmpdir
- end
- path
+ path = KnifeSolo::Berkshelf.new(config, ui).install
+ add_cookbook_path(path) if path
end
def librarian_install
- if !File.exist? 'Cheffile'
- Chef::Log.debug "Cheffile not found"
- elsif !load_librarian
- ui.warn "Librarian-Chef could not be loaded"
- ui.warn "Please add the librarian-chef gem to your Gemfile or install it manually with `gem install librarian-chef`"
- else
- ui.msg "Installing Librarian cookbooks..."
- Librarian::Action::Resolve.new(librarian_env).run
- Librarian::Action::Install.new(librarian_env).run
- add_cookbook_path librarian_env.install_path
- end
- end
-
- def load_librarian
- begin
- require 'librarian/action'
- require 'librarian/chef'
- rescue LoadError
- false
- else
- true
- end
- end
-
- def librarian_env
- @librarian_env ||= Librarian::Chef::Environment.new
+ path = KnifeSolo::Librarian.new(config, ui).install
+ add_cookbook_path(path) if path
end
def generate_solorb
@@ -312,10 +257,6 @@ def cook
result = stream_command cmd
raise "chef-solo failed. See output above." unless result.success?
end
-
- def cleanup
- FileUtils.remove_entry_secure(@berks_tmp_dir) if @berks_tmp_dir
- end
end
end
end
@@ -8,35 +8,34 @@ class SoloInit < Knife
deps do
require 'knife-solo'
+ require 'knife-solo/cookbook_manager_selector'
require 'knife-solo/gitignore'
require 'knife-solo/tools'
end
banner "knife solo init DIRECTORY"
option :git,
- :long => '--no-git',
- :description => 'Do not generate .gitignore',
- :default => true
+ :long => '--no-git',
+ :description => 'Do not generate .gitignore'
option :berkshelf,
:long => '--[no-]berkshelf',
- :description => "Generate files for Berkshelf support, defaults to true"
+ :description => 'Generate files for Berkshelf support'
option :librarian,
:long => '--[no-]librarian',
- :description => 'Generate files for Librarian support, defaults to false'
+ :description => 'Generate files for Librarian support'
def run
@base = @name_args.first
validate!
create_kitchen
create_config
create_cupboards %w[nodes roles data_bags site-cookbooks cookbooks]
- if config_value(:librarian, false)
- bootstrap_librarian
- elsif config_value(:berkshelf, true)
- bootstrap_berkshelf
+ gitignore %w[/cookbooks/]
+ if (cm = cookbook_manager)
+ cm.bootstrap(@base)
end
end
@@ -77,30 +76,12 @@ def create_config
end
end
- def bootstrap_berkshelf
- ui.msg "Setting up Berkshelf..."
- berksfile = File.join(@base, 'Berksfile')
- unless File.exist?(berksfile)
- File.open(berksfile, 'w') do |f|
- f.puts("site :opscode")
- end
- end
- gitignore %w[/cookbooks/]
- end
-
- def bootstrap_librarian
- ui.msg "Setting up Librarian..."
- cheffile = File.join(@base, 'Cheffile')
- unless File.exist?(cheffile)
- File.open(cheffile, 'w') do |f|
- f.puts("site 'http://community.opscode.com/api/v1'")
- end
- end
- gitignore %w[/cookbooks/ /tmp/librarian/]
+ def cookbook_manager
+ KnifeSolo::CookbookManagerSelector.new(config, ui).select(@base)
end
def gitignore(*entries)
- if config[:git]
+ if config_value(:git, true)
KnifeSolo::Gitignore.new(@base).add(*entries)
end
end
@@ -0,0 +1,37 @@
+require 'digest/sha1'
+require 'knife-solo/cookbook_manager'
+require 'knife-solo/tools'
+
+module KnifeSolo
+ class Berkshelf
+ include CookbookManager
+
+ def self.gem_libraries
+ %w[berkshelf]
+ end
+
+ def self.conf_file_name
+ 'Berksfile'
+ end
+
+ def install!
+ path = berkshelf_path
+ ui.msg "Installing Berkshelf cookbooks to '#{path}'..."
+ ::Berkshelf::Berksfile.from_file('Berksfile').install(:path => path)
+ path
+ end
+
+ def berkshelf_path
+ KnifeSolo::Tools.config_value(config, :berkshelf_path) || default_path
+ end
+
+ def default_path
+ File.join(::Berkshelf.berkshelf_path, 'knife-solo',
+ Digest::SHA1.hexdigest(File.expand_path('.')))
+ end
+
+ def initial_config
+ 'site :opscode'
+ end
+ end
+end
@@ -0,0 +1,120 @@
+require 'chef/mixin/convert_to_class_name'
+require 'knife-solo/gitignore'
+require 'knife-solo/tools'
+
+module KnifeSolo
+ module CookbookManager
+ def self.included(base)
+ base.extend ClassMethods
+ base.send(:include, InstanceMethods)
+ end
+
+ module ClassMethods
+ include Chef::Mixin::ConvertToClassName
+
+ # Returns an Array of libraries to load
+ def gem_libraries
+ raise "Must be overridden by the including class"
+ end
+
+ def gem_name
+ gem_libraries.first
+ end
+
+ def load_gem
+ begin
+ gem_libraries.each { |lib| require lib }
+ true
+ rescue LoadError
+ false
+ end
+ end
+
+ # Key in Chef::Config and CLI options
+ def config_key
+ snake_case_basename(name).to_sym
+ end
+
+ # Returns the base name of the configuration file
+ def conf_file_name
+ raise "Must be overridden by the including class"
+ end
+ end
+
+ module InstanceMethods
+ attr_reader :config, :ui
+
+ def initialize(config, ui)
+ @config = config
+ @ui = ui
+ end
+
+ def to_s
+ name
+ end
+
+ def name
+ self.class.name.split('::').last
+ end
+
+ def gem_name
+ self.class.gem_name
+ end
+
+ def gem_installed?
+ self.class.load_gem
+ end
+
+ def conf_file(base = nil)
+ base ? File.join(base, self.class.conf_file_name) : self.class.conf_file_name
+ end
+
+ def enabled_by_chef_config?
+ KnifeSolo::Tools.config_value(config, self.class.config_key)
+ end
+
+ def conf_file_exists?(base = nil)
+ File.exists?(conf_file(base))
+ end
+
+ # Runs the manager and returns the path to the cookbook directory
+ def install!
+ raise "Must be overridden by the including class"
+ end
+
+ # Runs installer if the configuration file is found and gem installed
+ # Returns the cookbook path or nil
+ def install
+ if !conf_file_exists?
+ Chef::Log.debug "#{conf_file} not found"
+ elsif !self.class.load_gem
+ ui.warn "#{name} could not be loaded"
+ ui.warn "Please add the #{gem_name} gem to your Gemfile or install it manually with `gem install #{gem_name}`"
+ else
+ return install!
+ end
+ nil
+ end
+
+ def bootstrap(base)
+ ui.msg "Setting up #{name}..."
+ unless conf_file_exists?(base)
+ File.open(conf_file(base), 'w') { |f| f.puts(initial_config) }
+ end
+ if KnifeSolo::Tools.config_value(config, :git, true) && gitignores
+ KnifeSolo::Gitignore.new(base).add(gitignores)
+ end
+ end
+
+ # Returns content for configuration file when bootstrapping
+ def initial_config
+ raise "Must be overridden by the including class"
+ end
+
+ # Returns an array of strings to gitignore when bootstrapping
+ def gitignores
+ nil
+ end
+ end
+ end
+end
Oops, something went wrong.

0 comments on commit 80d8948

Please sign in to comment.