-
Notifications
You must be signed in to change notification settings - Fork 57
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
(QA-2514) PE-client-tools helpers (#15)
* (QA-2514) PE-client-tools helpers * (maint) Add install helpers for pe-client-tools This commit adds three helper methods to install pe-client-tools on Windows. The first is a general method that is designed to abstract away the installation of pe-client-tools on supported operating systems. Currently, it only accommodates development builds of the tools based on the provided SHA and SUITE_VERSION environment variables available. The second is a generic method to install an msi package on a target host. Beaker's built in method of this name assumes that msi installed involves the installation of puppet, so this method overrides that one without such an assumption. The this is a generic method to install a dmg package on a target host. Beaker's built in `install_package` method for osx does not accommodate for an installer `pkg` file that is named differently from the containing `dmg`. This method forces the user to supply both names explicitly. * (maint) Remove install helpers for pe-client-tools This commit removes the dmg and msi helper methods instroduced earlier. These two methods have bee moved into beaker. * basic spec tests for ExecutableHelper & ConfigFileHelper
- Loading branch information
Showing
7 changed files
with
476 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
require "beaker/dsl/patterns" | ||
|
||
module Beaker | ||
module DSL | ||
module PEClientTools | ||
module ConfigFileHelper | ||
|
||
# Helper method to write config files for pe-client-tools | ||
# @param [Beaker::Host] host The beaker host that gets the config file | ||
# @param [String] config_level 'user' or 'global' | ||
# @param [String] tool 'access', 'code', 'db', 'query', 'orchestrator', 'job', 'app' | ||
# @param [String] contents The contents of the config file | ||
def write_client_tool_config_on(host, config_level, tool, contents) | ||
|
||
# TODO take a hash and parse file or take literal string | ||
|
||
file = "#{Private.config_path(host, config_level)}/#{Private.file_name(tool)}" | ||
create_remote_file(host, file, contents) | ||
end | ||
|
||
|
||
class Private | ||
|
||
require 'beaker/dsl/patterns' | ||
|
||
extend Beaker::DSL | ||
extend Beaker::DSL::Patterns | ||
|
||
def self.file_name(tool) | ||
if tool =~ /orchestrator|job|app/i | ||
'puppet-orchestrator.conf' | ||
elsif tool =~ /code/i | ||
'puppet-code.conf' | ||
elsif tool =~ /access/i | ||
'puppet-access.conf' | ||
elsif tool =~ /db|query/i | ||
'puppetdb.conf' | ||
else | ||
raise ArgumentError.new("Unknown pe-client-tool type '#{tool}'") | ||
end | ||
end | ||
|
||
def self.config_path(host, config_level) | ||
|
||
puppetlabs_dir = 'puppetlabs' | ||
puppetlabs_dir.prepend('.') if config_level == 'user' | ||
client_tools_path_array = [puppetlabs_dir, 'client-tools'] | ||
|
||
case config_level | ||
|
||
when /global/ | ||
@base_path = global_base_path(host) | ||
when /user/ | ||
@base_path = home_dir(host) | ||
else | ||
raise ArgumentError.new("Unknown config level #{config_level}") | ||
end | ||
|
||
client_tools_dir = client_tools_path_array.unshift(@base_path).join(path_separator(host)) | ||
opts = {:cmdexe => true} | ||
|
||
if host.platform =~ /win/ | ||
host.exec(Beaker::Command.new('MD', [client_tools_dir.gsub('\\', '\\\\\\')], opts), :accept_all_exit_codes => true) | ||
else | ||
host.exec(Beaker::Command.new("mkdir -p #{client_tools_dir}", [], opts), :accept_all_exit_codes => true) | ||
end | ||
client_tools_dir | ||
end | ||
|
||
def self.home_dir(host) | ||
|
||
if (host.platform =~ /win/) then | ||
@cmd = Beaker::Command.new('echo', ['%userprofile%'], :cmdexe => true) | ||
else | ||
@cmd = Beaker::Command.new('echo', ['$HOME']) | ||
end | ||
host.exec(@cmd).stdout.chomp | ||
end | ||
|
||
def self.global_base_path(host) | ||
|
||
(host.platform =~ /win/) ?host.exec(Beaker::Command.new('echo', ['%PROGRAMDATA%'], :cmdexe => true)).stdout.chomp : '/etc//' | ||
end | ||
|
||
def self.path_separator(host) | ||
|
||
(host.platform =~ /win/) ? '\\' : '/' | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
require "beaker/dsl/patterns" | ||
require "beaker/dsl/helpers" | ||
require "beaker/dsl/wrappers" | ||
|
||
module Beaker | ||
module DSL | ||
module PEClientTools | ||
module ExecutableHelper | ||
|
||
# puppet-access helper win/lin/osx | ||
# @param [BEAKER::Host] host The SUT that should run the puppet-access command | ||
# @param [String] args The arguments to puppet-access | ||
# @param [Hash] opts options hash to the Beaker Command | ||
# @param [Block] &block optional block | ||
def puppet_access_on(*args, &block) | ||
Private.new.tool(:access, *args, &block) | ||
end | ||
|
||
# puppet-code helper win/lin/osx | ||
# @param [BEAKER::Host] host The SUT that should run the puppet-code command | ||
# @param [String] args The arguments to puppet-code | ||
# @param [Hash] opts options hash to the Beaker Command | ||
# @param [Block] &block optional block | ||
def puppet_code_on(*args, &block) | ||
Private.new.tool(:code, *args, &block) | ||
end | ||
|
||
# puppet-job helper win/lin/osx | ||
# @param [BEAKER::Host] host The SUT that should run the puppet-job command | ||
# @param [String] args The arguments to puppet-job | ||
# @param [Hash] opts options hash to the Beaker Command | ||
# @param [Block] &block optional block | ||
def puppet_job_on(*args, &block) | ||
Private.new.tool(:job, *args, &block) | ||
end | ||
|
||
# puppet-app helper win/lin/osx | ||
# @param [BEAKER::Host] host The SUT that should run the puppet-app command | ||
# @param [String] args The arguments to puppet-app | ||
# @param [Hash] opts options hash to the Beaker Command | ||
# @param [Block] &block optional block | ||
def puppet_app_on(*args, &block) | ||
Private.new.tool(:app, *args, &block) | ||
end | ||
|
||
# puppet-db helper win/lin/osx | ||
# @param [BEAKER::Host] host The SUT that should run the puppet-db command | ||
# @param [String] args The arguments to puppet-db | ||
# @param [Hash] opts options hash to the Beaker Command | ||
# @param [Block] &block optional block | ||
def puppet_db_on(*args, &block) | ||
Private.new.tool(:db, *args, &block) | ||
end | ||
|
||
# puppet-query helper win/lin/osx | ||
# @param [BEAKER::Host] host The SUT that should run the puppet-query command | ||
# @param [String] args The arguments to puppet-query | ||
# @param [Hash] opts options hash to the Beaker Command | ||
# @param [Block] &block optional block | ||
def puppet_query_on(*args, &block) | ||
Private.new.tool(:query, *args, &block) | ||
end | ||
|
||
# Logs a user in on a SUT with puppet-access/RBAC API (windows) | ||
# @param [Beaker::Host] host The SUT to perform the login on | ||
# @param [Scooter::HttpDispatchers::ConsoleDispatcher] credentialed_dispatcher A Scooter dispatcher that has credentials for the user | ||
# @option attribute_hash [String] :name The environment variable | ||
# @option attribute_hash [String] :default The default value for the environment variable | ||
# @option attribute_hash [String] :message A message describing the use of this variable | ||
# @option attribute_hash [Boolean] :required Used internally by CommandFlag, ignored for a standalone EnvVar | ||
def login_with_puppet_access_on(host, credentialed_dispatcher, opts={}) | ||
|
||
lifetime = opts[:lifetime] || nil | ||
unless host.platform =~ /win/ | ||
|
||
user = credentialed_dispatcher.credentials.login | ||
password = credentialed_dispatcher.credentials.password | ||
puppet_access_on(host, 'login', {:stdin => "#{user}\n#{password}\n"}) | ||
else | ||
|
||
# this is a hack | ||
# puppet-access needs to support alternative to interactive login | ||
# create .puppetlabs dir | ||
cmd = Beaker::Command.new('echo', ['%userprofile%'], :cmdexe => true) | ||
user_home_dir = host.exec(cmd).stdout.chomp | ||
win_token_path = "#{user_home_dir}\\.puppetlabs\\" | ||
host.exec(Beaker::Command.new('MD', [win_token_path.gsub('\\', '\\\\\\')], :cmdexe => true), :accept_all_exit_codes => true) | ||
|
||
token = credentialed_dispatcher.acquire_token_with_credentials(lifetime) | ||
create_remote_file(host, "#{win_token_path}\\token", token) | ||
end | ||
end | ||
|
||
class Private | ||
|
||
include Beaker::DSL | ||
include Beaker::DSL::Wrappers | ||
include Beaker::DSL::Helpers::HostHelpers | ||
include Beaker::DSL::Patterns | ||
|
||
attr_accessor :logger | ||
|
||
def tool(tool, *args, &block) | ||
|
||
host = args.shift | ||
@logger = host.logger | ||
options = {} | ||
options.merge!(args.pop) if args.last.is_a?(Hash) | ||
|
||
if host.platform =~ /win/i | ||
|
||
program_files = host.exec(Beaker::Command.new('echo', ['%PROGRAMFILES%'], :cmdexe => true)).stdout.chomp | ||
client_tools_dir = "#{program_files}\\#{['Puppet Labs', 'Client', 'tools', 'bin'].join('\\')}\\" | ||
tool_executable = "\"#{client_tools_dir}puppet-#{tool.to_s}.exe\"" | ||
|
||
#TODO does this need to be more detailed to pass exit codes???? | ||
# TODO make batch file direct output to separate file | ||
batch_contents =<<-EOS | ||
call #{tool_executable} #{args.join(' ')} | ||
EOS | ||
|
||
@command = build_win_batch_command( host, batch_contents, {:cmdexe => true}) | ||
else | ||
|
||
tool_executable = '/opt/puppetlabs/client-tools/bin/' << "puppet-#{tool.to_s}" | ||
@command = Beaker::Command.new(tool_executable, args, {:cmdexe => true}) | ||
end | ||
|
||
result = host.exec(@command, options) | ||
|
||
# Also, let additional checking be performed by the caller. | ||
if block_given? | ||
case block.arity | ||
#block with arity of 0, just hand back yourself | ||
when 0 | ||
yield self | ||
#block with arity of 1 or greater, hand back the result object | ||
else | ||
yield result | ||
end | ||
end | ||
result | ||
end | ||
|
||
def build_win_batch_command( host, batch_contents, command_options) | ||
timestamp = Time.new.strftime('%Y-%m-%d_%H.%M.%S') | ||
# Create Temp file | ||
# make file fully qualified | ||
batch_file = "#{host.system_temp_path}\\#{timestamp}.bat" | ||
create_remote_file(host, batch_file, batch_contents) | ||
Beaker::Command.new("\"#{batch_file}\"", [], command_options) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
module Beaker | ||
module DSL | ||
module InstallUtils | ||
module PEClientTools | ||
|
||
def install_pe_client_tools_on(hosts, opts = {}) | ||
# FIXME: accomodate production released location(s) | ||
#{{{ | ||
product = 'pe-client-tools' | ||
required_keys = [:puppet_collection, :pe_client_tools_sha, :pe_client_tools_version] | ||
|
||
unless required_keys.all? { |opt| opts.keys.include?(opt) } | ||
raise ArgumentError, "The keys #{required_keys.to_s} are required in the opts hash" | ||
end | ||
urls = { :dev_builds_url => "http://builds.delivery.puppetlabs.net", | ||
} | ||
|
||
opts = urls.merge(opts) | ||
|
||
block_on hosts do |host| | ||
package_name = nil | ||
variant, version, arch, codename = host['platform'].to_array | ||
case host['platform'] | ||
when /el-|fedora|sles|centos|cisco_/ | ||
release_path = "#{opts[:dev_builds_url]}/#{product}/#{ opts[:pe_client_tools_sha] }/artifacts/#{variant}/#{version}/#{opts[:puppet_collection]}/#{arch}" | ||
package_name = product.dup | ||
package_name << "-#{opts[:pe_client_tools_version]}-1.#{variant}#{version}.#{arch}.rpm" if opts[:pe_client_tools_version] | ||
when /debian|ubuntu|cumulus|huaweios/ | ||
release_path = "#{opts[:dev_builds_url]}/#{product}/#{ opts[:pe_client_tools_sha] }/artifacts/deb/#{codename}/#{opts[:puppet_collection]}" | ||
package_name = product.dup | ||
package_name << "_#{opts[:pe_client_tools_version]}-1#{host['platform'].codename}_#{arch}.deb" if opts[:pe_client_tools_version] | ||
when /windows/ | ||
release_path = "#{opts[:dev_builds_url]}/#{product}/#{ opts[:pe_client_tools_sha] }/artifacts/#{variant}/#{opts[:puppet_collection]}/x#{arch}" | ||
package_name = product.dup | ||
package_name << "-#{opts[:pe_client_tools_version]}.1-x#{arch}_VANAGON.msi" if opts[:pe_client_tools_version] | ||
when /osx/ | ||
release_path = "#{opts[:dev_builds_url]}/#{product}/#{ opts[:pe_client_tools_sha] }/artifacts/apple/#{version}/#{opts[:puppet_collection]}/#{arch}" | ||
package_base = product.dup | ||
package_base << "-#{opts[:pe_client_tools_version]}" if opts[:pe_client_tools_version] | ||
package_name = package_base.dup | ||
package_name << '-1' if opts[:pe_client_tools_version] | ||
installer = package_name + '-installer.pkg' | ||
package_name << ".#{variant}#{version}.dmg" if opts[:pe_client_tools_version] | ||
else | ||
raise "install_puppet_agent_on() called for unsupported " + | ||
"platform '#{host['platform']}' on '#{host.name}'" | ||
end | ||
|
||
if package_name | ||
case host['platform'] | ||
when /windows/ | ||
generic_install_msi_on(host, File.join(release_path, package_name), {}, {:debug => true}) | ||
else | ||
copy_dir_local = File.join('tmp', 'repo_configs') | ||
fetch_http_file(release_path, package_name, copy_dir_local) | ||
scp_to host, File.join(copy_dir_local, package_name), host.external_copy_base | ||
|
||
if host['platform'] =~ /debian|ubuntu|cumulus|huaweios/ | ||
on host, "dpkg -i #{package_name}" | ||
elsif host['platform'] =~ /osx/ | ||
host.generic_install_dmg(package_name, package_base, installer) | ||
else | ||
host.install_package( package_name ) | ||
end | ||
end | ||
end | ||
end | ||
#}}} | ||
end | ||
|
||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
require 'spec_helper' | ||
require 'beaker' | ||
|
||
class MixedWithConfigFileHelper | ||
include Beaker::DSL::PEClientTools::ConfigFileHelper | ||
end | ||
|
||
describe MixedWithConfigFileHelper do | ||
|
||
it 'has a method to write a config file' do | ||
expect(subject.respond_to?('write_client_tool_config_on')).not_to be(false) | ||
end | ||
end |
Oops, something went wrong.