lib/beaker/dsl/install_utils.rb in beaker-1.18.0 vs lib/beaker/dsl/install_utils.rb in beaker-1.19.0
- old
+ new
@@ -23,10 +23,13 @@
GitURI = %r{^(git|https?|file)://|^git@|^gitmirror@}
# Github's ssh signature for cloning via ssh
GitHubSig = 'github.com,207.97.227.239 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ=='
+ # The directories in the module directory that will not be scp-ed to the test system when using `copy_module_to`
+ PUPPET_MODULE_INSTALL_IGNORE = ['.bundle', '.git', '.idea', '.vagrant', '.vendor', 'acceptance', 'spec', 'tests', 'log']
+
# @param [String] uri A uri in the format of <git uri>#<revision>
# the `git://`, `http://`, `https://`, and ssh
# (if cloning as the remote git user) protocols
# are valid for <git uri>
#
@@ -1076,8 +1079,221 @@
end
#send in the global options hash
do_higgs_install higgs_host, options
end
+ # Install the desired module on all hosts using either the PMT or a
+ # staging forge
+ #
+ # @see install_dev_puppet_module
+ def install_dev_puppet_module_on( host, opts )
+ if options[:forge_host]
+ with_forge_stubbed_on( host ) do
+ install_puppet_module_via_pmt_on( host, opts )
+ end
+ else
+ copy_module_to( host, opts )
+ end
+ end
+ alias :puppet_module_install_on :install_dev_puppet_module_on
+
+ # Install the desired module on all hosts using either the PMT or a
+ # staging forge
+ #
+ # Passes options through to either `install_puppet_module_via_pmt_on`
+ # or `copy_module_to`
+ #
+ # @param opts [Hash]
+ #
+ # @example Installing a module from the local directory
+ # install_dev_puppet_module( :source => './', :module_name => 'concat' )
+ #
+ # @example Installing a module from a staging forge
+ # options[:forge_host] = 'my-forge-api.example.com'
+ # install_dev_puppet_module( :source => './', :module_name => 'concat' )
+ #
+ # @see install_puppet_module_via_pmt
+ # @see copy_module_to
+ def install_dev_puppet_module( opts )
+ block_on( hosts ) {|h| install_dev_puppet_module_on( h, opts ) }
+ end
+ alias :puppet_module_install :install_dev_puppet_module
+
+ # Install the desired module with the PMT on a given host
+ #
+ # @param opts [Hash]
+ # @option opts [String] :module_name The short name of the module to be installed
+ # @option opts [String] :version The version of the module to be installed
+ def install_puppet_module_via_pmt_on( host, opts = {} )
+ block_on host do |h|
+ version_info = opts[:version] ? "-v #{opts[:version]}" : ""
+ if opts[:source]
+ author_name, module_name = parse_for_modulename( opts[:source] )
+ modname = "#{author_name}-#{module_name}"
+ else
+ modname = opts[:module_name]
+ end
+
+ on h, puppet("module install #{modname} #{version_info}")
+ end
+ end
+
+ # Install the desired module with the PMT on all known hosts
+ # @see #install_puppet_module_via_pmt_on
+ def install_puppet_module_via_pmt( opts = {} )
+ install_puppet_module_via_pmt_on(hosts, opts)
+ end
+
+ # Install local module for acceptance testing
+ # should be used as a presuite to ensure local module is copied to the hosts you want, particularly masters
+ # @api dsl
+ # @param [Host, Array<Host>, String, Symbol] host
+ # One or more hosts to act upon,
+ # or a role (String or Symbol) that identifies one or more hosts.
+ # @option opts [String] :source ('./')
+ # The current directory where the module sits, otherwise will try
+ # and walk the tree to figure out
+ # @option opts [String] :module_name (nil)
+ # Name which the module should be installed under, please do not include author,
+ # if none is provided it will attempt to parse the metadata.json and then the Modulefile to determine
+ # the name of the module
+ # @option opts [String] :target_module_path (host['distmoduledir']/modules)
+ # Location where the module should be installed, will default
+ # to host['distmoduledir']/modules
+ # @option opts [Array] :ignore_list
+ # @raise [ArgumentError] if not host is provided or module_name is not provided and can not be found in Modulefile
+ #
+ def copy_module_to(host, opts = {})
+ opts = {:source => './',
+ :target_module_path => host['distmoduledir'],
+ :ignore_list => PUPPET_MODULE_INSTALL_IGNORE}.merge(opts)
+ ignore_list = build_ignore_list(opts)
+ target_module_dir = on( host, "echo #{opts[:target_module_path]}" ).stdout.chomp
+ source = File.expand_path( opts[:source] )
+ if opts.has_key?(:module_name)
+ module_name = opts[:module_name]
+ else
+ _, module_name = parse_for_modulename( source )
+ end
+ scp_to host, source, File.join(target_module_dir, module_name), {:ignore => ignore_list}
+ end
+ alias :copy_root_module_to :copy_module_to
+
+ # Install a package on a host
+ #
+ # @param [Host] host A host object
+ # @param [String] package_name Name of the package to install
+ #
+ # @return [Result] An object representing the outcome of *install command*.
+ def install_package host, package_name, package_version = nil
+ host.install_package package_name, '', package_version
+ end
+
+ # Check to see if a package is installed on a remote host
+ #
+ # @param [Host] host A host object
+ # @param [String] package_name Name of the package to check for.
+ #
+ # @return [Boolean] true/false if the package is found
+ def check_for_package host, package_name
+ host.check_for_package package_name
+ end
+
+ # Upgrade a package on a host. The package must already be installed
+ #
+ # @param [Host] host A host object
+ # @param [String] package_name Name of the package to install
+ #
+ # @return [Result] An object representing the outcome of *upgrade command*.
+ def upgrade_package host, package_name
+ host.upgrade_package package_name
+ end
+
+ #Recursive method for finding the module root
+ # Assumes that a Modulefile exists
+ # @param [String] possible_module_directory
+ # will look for Modulefile and if none found go up one level and try again until root is reached
+ #
+ # @return [String,nil]
+ def parse_for_moduleroot(possible_module_directory)
+ if File.exists?("#{possible_module_directory}/Modulefile")
+ possible_module_directory
+ elsif possible_module_directory === '/'
+ logger.error "At root, can't parse for another directory"
+ nil
+ else
+ logger.debug "No Modulefile found at #{possible_module_directory}, moving up"
+ parse_for_moduleroot File.expand_path(File.join(possible_module_directory,'..'))
+ end
+ end
+
+
+ #Parse root directory of a module for module name
+ # Searches for metadata.json and then if none found, Modulefile and parses for the Name attribute
+ # @param [String] root_module_dir
+ # @return [String] module name
+ def parse_for_modulename(root_module_dir)
+ author_name, module_name = nil, nil
+ if File.exists?("#{root_module_dir}/metadata.json")
+ logger.debug "Attempting to parse Modulename from metadata.json"
+ module_json = JSON.parse(File.read "#{root_module_dir}/metadata.json")
+ if(module_json.has_key?('name'))
+ author_name, module_name = get_module_name(module_json['name'])
+ end
+ end
+ if !module_name && File.exists?("#{root_module_dir}/Modulefile")
+ logger.debug "Attempting to parse Modulename from Modulefile"
+ if /^name\s+'?(\w+-\w+)'?\s*$/i.match(File.read("#{root_module_dir}/Modulefile"))
+ author_name, module_name = get_module_name(Regexp.last_match[1])
+ end
+ end
+ if !module_name && !author_name
+ logger.debug "Unable to determine name, returning null"
+ end
+ return author_name, module_name
+ end
+
+ #Parse modulename from the pattern 'Auther-ModuleName'
+ #
+ # @param [String] author_module_name <Author>-<ModuleName> pattern
+ #
+ # @return [String,nil]
+ #
+ def get_module_name(author_module_name)
+ split_name = split_author_modulename(author_module_name)
+ if split_name
+ return split_name[:author], split_name[:module]
+ end
+ end
+
+ #Split the Author-Name into a hash
+ # @param [String] author_module_attr
+ #
+ # @return [Hash<Symbol,String>,nil] :author and :module symbols will be returned
+ #
+ def split_author_modulename(author_module_attr)
+ result = /(\w+)-(\w+)/.match(author_module_attr)
+ if result
+ {:author => result[1], :module => result[2]}
+ else
+ nil
+ end
+ end
+
+ # Build an array list of files/directories to ignore when pushing to remote host
+ # Automatically adds '..' and '.' to array. If not opts of :ignore list is provided
+ # it will use the static variable PUPPET_MODULE_INSTALL_IGNORE
+ #
+ # @param opts [Hash]
+ # @option opts [Array] :ignore_list A list of files/directories to ignore
+ def build_ignore_list(opts = {})
+ ignore_list = opts[:ignore_list] || PUPPET_MODULE_INSTALL_IGNORE
+ if !ignore_list.kind_of?(Array) || ignore_list.nil?
+ raise ArgumentError "Ignore list must be an Array"
+ end
+ ignore_list << '.' unless ignore_list.include? '.'
+ ignore_list << '..' unless ignore_list.include? '..'
+ ignore_list
+ end
end
end
end