lib/berkshelf.rb
# XXX: work around logger spam from hashie
# https://github.com/intridea/hashie/issues/394
begin
require "hashie"
require "hashie/logger"
Hashie.logger = Logger.new(nil)
rescue LoadError
# intentionally left blank
end
require "cleanroom"
require "digest/md5" unless defined?(Digest::MD5)
require "forwardable" unless defined?(Forwardable)
require "json" unless defined?(JSON)
require "pathname" unless defined?(Pathname)
require "semverse"
require "solve"
require "thor" unless defined?(Thor)
require "uri" unless defined?(URI)
JSON.create_id = nil
require_relative "berkshelf/core_ext"
require_relative "berkshelf/thor_ext"
require_relative "berkshelf/chef_config_compat"
module Berkshelf
Encoding.default_external = Encoding::UTF_8
def self.fix_proxies
ENV["http_proxy"] = ENV["HTTP_PROXY"] if ENV["HTTP_PROXY"] && !ENV["http_proxy"]
ENV["https_proxy"] = ENV["HTTPS_PROXY"] if ENV["HTTPS_PROXY"] && !ENV["https_proxy"]
ENV["ftp_proxy"] = ENV["FTP_PROXY"] if ENV["FTP_PROXY"] && !ENV["ftp_proxy"]
ENV["no_proxy"] = ENV["NO_PROXY"] if ENV["NO_PROXY"] && !ENV["no_proxy"]
end
fix_proxies
require_relative "berkshelf/version"
require_relative "berkshelf/errors"
module Mixin
autoload :Git, "berkshelf/mixin/git"
autoload :Logging, "berkshelf/mixin/logging"
end
autoload :FileSyncer, "berkshelf/file_syncer"
autoload :Shell, "berkshelf/shell"
autoload :Uploader, "berkshelf/uploader"
autoload :Visualizer, "berkshelf/visualizer"
autoload :BaseFormatter, "berkshelf/formatters/base"
autoload :HumanFormatter, "berkshelf/formatters/human"
autoload :JsonFormatter, "berkshelf/formatters/json"
autoload :NullFormatter, "berkshelf/formatters/null"
autoload :Location, "berkshelf/location"
autoload :BaseLocation, "berkshelf/locations/base"
autoload :GitLocation, "berkshelf/locations/git"
autoload :GithubLocation, "berkshelf/locations/github"
autoload :PathLocation, "berkshelf/locations/path"
DEFAULT_FILENAME = "Berksfile".freeze
class << self
include Mixin::Logging
attr_writer :berkshelf_path
attr_writer :ui
# @return [Pathname]
def root
@root ||= Pathname.new(File.expand_path("../", File.dirname(__FILE__)))
end
# @return [Berkshelf::Shell]
def ui
@ui ||= Berkshelf::Shell.new
end
# Returns the filepath to the location Berkshelf will use for
# storage; temp files will go here, Cookbooks will be downloaded
# to or uploaded from here. By default this is '~/.berkshelf' but
# can be overridden by specifying a value for the ENV variable
# 'BERKSHELF_PATH'.
#
# @return [String]
def berkshelf_path
@berkshelf_path ||= File.expand_path(ENV["BERKSHELF_PATH"] || "~/.berkshelf")
end
# The Berkshelf configuration.
#
# @return [Berkshelf::Config]
def config
Berkshelf::Config.instance
end
# @param [Berkshelf::Config]
def config=(config)
Berkshelf::Config.set_config(config)
end
# The Chef configuration file.
#
# @return [Berkshelf::ChefConfigCompat]
def chef_config
@chef_config ||= Berkshelf::ChefConfigCompat.new(ENV["BERKSHELF_CHEF_CONFIG"])
end
# @param [Ridley::Chef::Config]
def chef_config=(config)
@chef_config = config
end
# Initialize the filepath for the Berkshelf path..
def initialize_filesystem
FileUtils.mkdir_p(berkshelf_path, mode: 0755)
unless File.writable?(berkshelf_path)
raise InsufficientPrivledges.new(berkshelf_path)
end
end
# @return [Berkshelf::CookbookStore]
def cookbook_store
CookbookStore.instance
end
# Get the appropriate Formatter object based on the formatter
# classes that have been registered.
#
# @return [~Formatter]
def formatter
@formatter ||= HumanFormatter.new
end
def ssl_policy
@ssl_policy ||= SSLPolicy.new
end
# @raise [Berkshelf::ChefConnectionError]
def ridley_connection(options = {}, &block)
ssl_options = {}
ssl_options[:verify] = if options[:ssl_verify].nil?
Berkshelf.config.ssl.verify
else
options[:ssl_verify]
end
ssl_options[:cert_store] = ssl_policy.store if ssl_policy.store
ridley_options = {}
ridley_options[:ssl] = options[:ssl] if options.key?(:ssl)
ridley_options[:server_url] = options[:server_url] || Berkshelf.config.chef.chef_server_url
ridley_options[:client_name] = options[:client_name] || Berkshelf.config.chef.node_name
ridley_options[:client_key] = options[:client_key] || Berkshelf.config.chef.client_key
ridley_options[:ssl] = ssl_options
if !ridley_options[:server_url] || ridley_options[:server_url] =~ /^\s*$/
raise ChefConnectionError, "Missing required attribute in your Berkshelf configuration: chef.server_url"
end
if !ridley_options[:client_name] || ridley_options[:client_name] =~ /^\s*$/
raise ChefConnectionError, "Missing required attribute in your Berkshelf configuration: chef.node_name"
end
if !ridley_options[:client_key] || ridley_options[:client_key].to_s =~ /^\s*$/
raise ChefConnectionError, "Missing required attribute in your Berkshelf configuration: chef.client_key"
end
RidleyCompat.new_client(**ridley_options, &block)
rescue ChefConnectionError, BerkshelfError
raise
rescue => ex
log.exception(ex)
raise ChefConnectionError, ex # todo implement
end
# Specify the format for output
#
# @param [#to_sym] format_id
# the ID of the registered formatter to use
#
# @example Berkshelf.set_format :json
#
# @return [~Formatter]
def set_format(name)
id = name.to_s.capitalize
@formatter = Berkshelf.const_get("#{id}Formatter").new
end
# Location an executable in the current user's $PATH
#
# @return [String, nil]
# the path to the executable, or +nil+ if not present
def which(executable)
if File.file?(executable) && File.executable?(executable)
executable
elsif ENV["PATH"]
path = ENV["PATH"].split(File::PATH_SEPARATOR).find do |p|
File.executable?(File.join(p, executable))
end
path && File.expand_path(executable, path)
end
end
private
def null_stream
@null ||= begin
strm = STDOUT.clone
strm.reopen(RbConfig::CONFIG["host_os"] =~ /mswin|mingw/ ? "NUL:" : "/dev/null")
strm.sync = true
strm
end
end
end
end
require_relative "berkshelf/lockfile"
require_relative "berkshelf/berksfile"
require_relative "berkshelf/cached_cookbook"
require_relative "berkshelf/cli"
require_relative "berkshelf/community_rest"
require_relative "berkshelf/cookbook_store"
require_relative "berkshelf/config"
require_relative "berkshelf/dependency"
require_relative "berkshelf/downloader"
require_relative "berkshelf/installer"
require_relative "berkshelf/logger"
require_relative "berkshelf/resolver"
require_relative "berkshelf/source"
require_relative "berkshelf/source_uri"
require_relative "berkshelf/validator"
require_relative "berkshelf/ssl_policies"
Berkshelf.logger.level = Logger::WARN