beaker 1.16.0 → 1.17.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/CONTRIBUTING.md +90 -0
- data/HISTORY.md +654 -2
- data/beaker.gemspec +1 -0
- data/lib/beaker/answers/version34.rb +4 -0
- data/lib/beaker/cli.rb +49 -2
- data/lib/beaker/dsl/helpers.rb +356 -196
- data/lib/beaker/dsl/install_utils.rb +135 -16
- data/lib/beaker/dsl/patterns.rb +37 -0
- data/lib/beaker/dsl/roles.rb +29 -0
- data/lib/beaker/dsl.rb +2 -1
- data/lib/beaker/host/unix.rb +14 -10
- data/lib/beaker/host/windows.rb +2 -0
- data/lib/beaker/host.rb +96 -1
- data/lib/beaker/host_prebuilt_steps.rb +41 -51
- data/lib/beaker/hypervisor/aws_sdk.rb +80 -16
- data/lib/beaker/hypervisor/ec2_helper.rb +1 -1
- data/lib/beaker/logger.rb +17 -0
- data/lib/beaker/options/command_line_parser.rb +3 -0
- data/lib/beaker/options/hosts_file_parser.rb +7 -4
- data/lib/beaker/options/options_hash.rb +2 -2
- data/lib/beaker/options/parser.rb +1 -1
- data/lib/beaker/options/presets.rb +128 -83
- data/lib/beaker/perf.rb +58 -0
- data/lib/beaker/shared/host_manager.rb +81 -0
- data/lib/beaker/shared.rb +2 -2
- data/lib/beaker/ssh_connection.rb +14 -7
- data/lib/beaker/test_case.rb +13 -0
- data/lib/beaker/test_suite.rb +23 -5
- data/lib/beaker/version.rb +1 -1
- data/lib/beaker.rb +1 -1
- data/spec/beaker/answers_spec.rb +13 -8
- data/spec/beaker/dsl/ezbake_utils_spec.rb +8 -9
- data/spec/beaker/dsl/helpers_spec.rb +299 -51
- data/spec/beaker/dsl/install_utils_spec.rb +75 -10
- data/spec/beaker/dsl/roles_spec.rb +36 -1
- data/spec/beaker/host_prebuilt_steps_spec.rb +21 -5
- data/spec/beaker/host_spec.rb +187 -23
- data/spec/beaker/hypervisor/ec2_helper_spec.rb +4 -4
- data/spec/beaker/hypervisor/vagrant_spec.rb +1 -1
- data/spec/beaker/options/hosts_file_parser_spec.rb +5 -0
- data/spec/beaker/options/options_hash_spec.rb +2 -2
- data/spec/beaker/options/parser_spec.rb +6 -0
- data/spec/beaker/options/presets_spec.rb +18 -2
- data/spec/beaker/perf_spec.rb +87 -0
- data/spec/beaker/shared/{host_role_parser_spec.rb → host_manager_spec.rb} +36 -5
- data/spec/beaker/test_suite_spec.rb +4 -3
- data/spec/matchers.rb +31 -3
- data/spec/mocks.rb +31 -25
- metadata +24 -5
- data/lib/beaker/shared/host_role_parser.rb +0 -36
@@ -172,6 +172,17 @@ module Beaker
|
|
172
172
|
end
|
173
173
|
end
|
174
174
|
|
175
|
+
#Create the Higgs install command string based upon the host and options settings. Installation command will be run as a
|
176
|
+
#background process. The output of the command will be stored in the provided host['higgs_file'].
|
177
|
+
# @param [Host] host The host that Higgs is to be installed on
|
178
|
+
# The host object must have the 'working_dir', 'dist' and 'pe_installer' field set correctly.
|
179
|
+
# @api private
|
180
|
+
def higgs_installer_cmd host
|
181
|
+
|
182
|
+
"cd #{host['working_dir']}/#{host['dist']} ; nohup ./#{host['pe_installer']} <<<Y > #{host['higgs_file']} 2>&1 &"
|
183
|
+
|
184
|
+
end
|
185
|
+
|
175
186
|
#Determine is a given URL is accessible
|
176
187
|
#@param [String] link The URL to examine
|
177
188
|
#@return [Boolean] true if the URL has a '200' HTTP response code, false otherwise
|
@@ -420,8 +431,7 @@ module Beaker
|
|
420
431
|
version = host['pe_ver'] || opts[:pe_ver]
|
421
432
|
host['dist'] = "puppet-enterprise-#{version}-#{host['platform']}"
|
422
433
|
end
|
423
|
-
host['working_dir'] =
|
424
|
-
on host, "mkdir #{host['working_dir']}"
|
434
|
+
host['working_dir'] = host.tmpdir(Time.new.strftime("%Y-%m-%d_%H.%M.%S"))
|
425
435
|
end
|
426
436
|
|
427
437
|
fetch_puppet(hosts, opts)
|
@@ -493,6 +503,57 @@ module Beaker
|
|
493
503
|
on install_hosts, puppet_agent('-t'), :acceptable_exit_codes => [0,2]
|
494
504
|
end
|
495
505
|
|
506
|
+
#Perform a Puppet Enterprise Higgs install up until web browser interaction is required, runs on linux hosts only.
|
507
|
+
# @param [Host] host The host to install higgs on
|
508
|
+
# @param [Hash{Symbol=>Symbol, String}] opts The options
|
509
|
+
# @option opts [String] :pe_dir Default directory or URL to pull PE package from
|
510
|
+
# (Otherwise uses individual hosts pe_dir)
|
511
|
+
# @option opts [String] :pe_ver Default PE version to install
|
512
|
+
# (Otherwise uses individual hosts pe_ver)
|
513
|
+
# @raise [StandardError] When installation times out
|
514
|
+
#
|
515
|
+
# @example
|
516
|
+
# do_higgs_install(master, {:pe_dir => path, :pe_ver => version})
|
517
|
+
#
|
518
|
+
# @api private
|
519
|
+
#
|
520
|
+
def do_higgs_install host, opts
|
521
|
+
use_all_tar = ENV['PE_USE_ALL_TAR'] == 'true'
|
522
|
+
platform = use_all_tar ? 'all' : host['platform']
|
523
|
+
version = host['pe_ver'] || opts[:pe_ver]
|
524
|
+
host['dist'] = "puppet-enterprise-#{version}-#{platform}"
|
525
|
+
|
526
|
+
use_all_tar = ENV['PE_USE_ALL_TAR'] == 'true'
|
527
|
+
host['pe_installer'] ||= 'puppet-enterprise-installer'
|
528
|
+
host['working_dir'] = host.tmpdir(Time.new.strftime("%Y-%m-%d_%H.%M.%S"))
|
529
|
+
|
530
|
+
fetch_puppet([host], opts)
|
531
|
+
|
532
|
+
host['higgs_file'] = "higgs_#{File.basename(host['working_dir'])}.log"
|
533
|
+
on host, higgs_installer_cmd(host), opts
|
534
|
+
|
535
|
+
#wait for output to host['higgs_file']
|
536
|
+
#we're all done when we find this line in the PE installation log
|
537
|
+
higgs_re = /Please\s+go\s+to\s+https:\/\/.*\s+in\s+your\s+browser\s+to\s+continue\s+installation/m
|
538
|
+
res = Result.new(host, 'tmp cmd')
|
539
|
+
tries = 10
|
540
|
+
attempts = 0
|
541
|
+
prev_sleep = 0
|
542
|
+
cur_sleep = 1
|
543
|
+
while (res.stdout !~ higgs_re) and (attempts < tries)
|
544
|
+
res = on host, "cd #{host['working_dir']}/#{host['dist']} && cat #{host['higgs_file']}", :acceptable_exit_codes => (0..255)
|
545
|
+
attempts += 1
|
546
|
+
sleep( cur_sleep )
|
547
|
+
prev_sleep = cur_sleep
|
548
|
+
cur_sleep = cur_sleep + prev_sleep
|
549
|
+
end
|
550
|
+
|
551
|
+
if attempts >= tries
|
552
|
+
raise "Failed to kick off PE (Higgs) web installation"
|
553
|
+
end
|
554
|
+
|
555
|
+
end
|
556
|
+
|
496
557
|
#Sort array of hosts so that it has the correct order for PE installation based upon each host's role
|
497
558
|
# @example
|
498
559
|
# h = sorted_hosts
|
@@ -551,6 +612,10 @@ module Beaker
|
|
551
612
|
raise "install_puppet() called for unsupported platform '#{host['platform']}' on '#{host.name}'"
|
552
613
|
end
|
553
614
|
end
|
615
|
+
|
616
|
+
# Certain install paths may not create the config dirs/files needed
|
617
|
+
on host, "mkdir -p #{host['puppetpath']}"
|
618
|
+
on host, "echo '' >> #{host['hieraconf']}"
|
554
619
|
end
|
555
620
|
nil
|
556
621
|
end
|
@@ -688,20 +753,51 @@ module Beaker
|
|
688
753
|
# @raise [StandardError] if gem does not exist on target host
|
689
754
|
# @api private
|
690
755
|
def install_puppet_from_gem( host, opts )
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
on host,
|
700
|
-
|
701
|
-
|
756
|
+
# Hosts may be provisioned with csw but pkgutil won't be in the
|
757
|
+
# PATH by default to avoid changing the behavior for Puppet's tests
|
758
|
+
if host['platform'] =~ /solaris-10/
|
759
|
+
on host, 'ln -s /opt/csw/bin/pkgutil /usr/bin/pkgutil'
|
760
|
+
end
|
761
|
+
|
762
|
+
# Solaris doesn't necessarily have this, but gem needs it
|
763
|
+
if host['platform'] =~ /solaris/
|
764
|
+
on host, 'mkdir -p /var/lib'
|
765
|
+
end
|
766
|
+
|
767
|
+
unless host.check_for_command( 'gem' )
|
768
|
+
gempkg = case host['platform']
|
769
|
+
when /solaris-11/ then 'ruby-18'
|
770
|
+
when /ubuntu-14/ then 'ruby'
|
771
|
+
when /solaris-10|ubuntu|debian|el-/ then 'rubygems'
|
772
|
+
else
|
773
|
+
raise "install_puppet() called with default_action " +
|
774
|
+
"'gem_install' but program `gem' is " +
|
775
|
+
"not installed on #{host.name}"
|
776
|
+
end
|
777
|
+
|
778
|
+
host.install_package gempkg
|
779
|
+
end
|
780
|
+
|
781
|
+
if host['platform'] =~ /debian|ubuntu|solaris/
|
782
|
+
gem_env = YAML.load( on( host, 'gem environment' ).stdout )
|
783
|
+
gem_paths_array = gem_env['RubyGems Environment'].find {|h| h['GEM PATHS'] != nil }['GEM PATHS']
|
784
|
+
path_with_gem = 'export PATH=' + gem_paths_array.join(':') + ':${PATH}'
|
785
|
+
on host, "echo '#{path_with_gem}' >> ~/.bashrc"
|
786
|
+
end
|
787
|
+
|
788
|
+
if opts[:facter_version]
|
789
|
+
on host, "gem install facter -v#{opts[:facter_version]} --no-ri --no-rdoc"
|
790
|
+
end
|
791
|
+
|
792
|
+
if opts[:hiera_version]
|
793
|
+
on host, "gem install hiera -v#{opts[:hiera_version]} --no-ri --no-rdoc"
|
702
794
|
end
|
795
|
+
|
796
|
+
ver_cmd = opts[:version] ? "-v#{opts[:version]}" : ''
|
797
|
+
on host, "gem install puppet #{ver_cmd} --no-ri --no-rdoc"
|
703
798
|
end
|
704
799
|
|
800
|
+
|
705
801
|
#Install PE based upon host configuration and options
|
706
802
|
# @example
|
707
803
|
# install_pe
|
@@ -777,7 +873,7 @@ module Beaker
|
|
777
873
|
on host, "rpm -ivh --force #{rpm}"
|
778
874
|
|
779
875
|
when /^(debian|ubuntu)$/
|
780
|
-
deb = options[:release_apt_repo_url]
|
876
|
+
deb = URI.join(options[:release_apt_repo_url], "puppetlabs-release-%s.deb" % codename)
|
781
877
|
|
782
878
|
on host, "wget -O /tmp/puppet.deb #{deb}"
|
783
879
|
on host, "dpkg -i --force-all /tmp/puppet.deb"
|
@@ -888,8 +984,8 @@ module Beaker
|
|
888
984
|
scp_to host, list, config_dir
|
889
985
|
scp_to host, repo_dir, "/root/#{package_name}"
|
890
986
|
|
891
|
-
search = "
|
892
|
-
replace = "
|
987
|
+
search = "deb\\s\\+http:\\/\\/#{hostname}.*$"
|
988
|
+
replace = "deb file:\\/\\/\\/root\\/#{package_name}\\/#{codename} #{codename} main"
|
893
989
|
sed_command = "sed -i 's/#{search}/#{replace}/'"
|
894
990
|
find_and_sed = "find #{config_dir} -name \"*.list\" -exec #{sed_command} {} \\;"
|
895
991
|
|
@@ -900,6 +996,29 @@ module Beaker
|
|
900
996
|
raise "No repository installation step for #{variant} yet..."
|
901
997
|
end
|
902
998
|
end
|
999
|
+
|
1000
|
+
#Install Higgs up till the point where you need to continue installation in a web browser, defaults to execution
|
1001
|
+
#on the master node.
|
1002
|
+
#@param [Host] higgs_host The host to install Higgs on (supported on linux platform only)
|
1003
|
+
# @example
|
1004
|
+
# install_higgs
|
1005
|
+
#
|
1006
|
+
# @note Either pe_ver and pe_dir should be set in the ENV or each host should have pe_ver and pe_dir set individually.
|
1007
|
+
# Install file names are assumed to be of the format puppet-enterprise-VERSION-PLATFORM.(tar)|(tar.gz).
|
1008
|
+
#
|
1009
|
+
# @api dsl
|
1010
|
+
def install_higgs( higgs_host = master )
|
1011
|
+
#process the version files if necessary
|
1012
|
+
master['pe_dir'] ||= options[:pe_dir]
|
1013
|
+
master['pe_ver'] = master['pe_ver'] || options['pe_ver'] ||
|
1014
|
+
Beaker::Options::PEVersionScraper.load_pe_version(master[:pe_dir] || options[:pe_dir], options[:pe_version_file])
|
1015
|
+
if higgs_host['platform'] =~ /osx|windows/
|
1016
|
+
raise "Attempting higgs installation on host #{higgs_host.name} with unsupported platform #{higgs_host['platform']}"
|
1017
|
+
end
|
1018
|
+
#send in the global options hash
|
1019
|
+
do_higgs_install higgs_host, options
|
1020
|
+
end
|
1021
|
+
|
903
1022
|
end
|
904
1023
|
end
|
905
1024
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Beaker
|
2
|
+
module DSL
|
3
|
+
# These are simple patterns that appear frequently in beaker test
|
4
|
+
# code, and are provided to simplify test construction.
|
5
|
+
#
|
6
|
+
#
|
7
|
+
# It requires the class it is mixed into to provide the attribute
|
8
|
+
# `hosts` which contain the hosts to search, these should implement
|
9
|
+
# {Beaker::Host}'s interface. They, at least, must have #[]
|
10
|
+
# and #to_s available and provide an array when #[]('roles') is called.
|
11
|
+
#
|
12
|
+
module Patterns
|
13
|
+
|
14
|
+
#Execute a block selecting the hosts that match with the provided criteria
|
15
|
+
#@param [Array<Host>, Host, String, Symbol] hosts_or_filter A host role as a String or Symbol that can be
|
16
|
+
# used to search for a set of Hosts, a host name
|
17
|
+
# as a String that can be used to search for
|
18
|
+
# a set of Hosts, or a {Host}
|
19
|
+
# or Array<{Host}> to run the block against
|
20
|
+
#@param [Block] block This method will yield to a block of code passed by the caller
|
21
|
+
def block_on hosts_or_filter, &block
|
22
|
+
block_hosts = nil
|
23
|
+
if defined? hosts
|
24
|
+
block_hosts = hosts
|
25
|
+
end
|
26
|
+
filter = nil
|
27
|
+
if hosts_or_filter.is_a? String or hosts_or_filter.is_a? Symbol
|
28
|
+
filter = hosts_or_filter
|
29
|
+
else
|
30
|
+
block_hosts = hosts_or_filter
|
31
|
+
end
|
32
|
+
run_block_on block_hosts, filter, &block
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/beaker/dsl/roles.rb
CHANGED
@@ -88,6 +88,35 @@ module Beaker
|
|
88
88
|
find_only_one :default
|
89
89
|
end
|
90
90
|
|
91
|
+
#Create a new role method for a given arbitrary role name. Makes it possible to be able to run
|
92
|
+
#commands without having to refer to role by String or Symbol. Will not add a new method
|
93
|
+
#definition if the name is already in use.
|
94
|
+
# @param [String, Symbol, Array[String,Symbol]] role The role that you wish to create a definition for, either a String
|
95
|
+
# Symbol or an Array of Strings or Symbols.
|
96
|
+
# @example Basic usage
|
97
|
+
# add_role_def('myrole')
|
98
|
+
# on myrole, "run command"
|
99
|
+
def add_role_def role
|
100
|
+
if role.kind_of?(Array)
|
101
|
+
role.each do |r|
|
102
|
+
add_role_def r
|
103
|
+
end
|
104
|
+
else
|
105
|
+
if not respond_to? role
|
106
|
+
if role !~ /\A[[:alpha:]]+[a-zA-Z0-9_]*[!?=]?\Z/
|
107
|
+
raise "Role name format error for '#{role}'. Allowed characters are: \na-Z\n0-9 (as long as not at the beginning of name)\n'_'\n'?', '!' and '=' (only as individual last character at end of name)"
|
108
|
+
end
|
109
|
+
self.class.send :define_method, role.to_s do
|
110
|
+
hosts_with_role = hosts_as role.to_sym
|
111
|
+
if hosts_with_role.length == 1
|
112
|
+
hosts_with_role = hosts_with_role.pop
|
113
|
+
end
|
114
|
+
hosts_with_role
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
91
120
|
# Determine if there is a host or hosts with the given role defined
|
92
121
|
# @return [Boolean] True if there is a host with role, false otherwise
|
93
122
|
#
|
data/lib/beaker/dsl.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
[ 'install_utils', 'roles', 'outcomes', 'assertions',
|
1
|
+
[ 'install_utils', 'roles', 'outcomes', 'assertions', 'patterns',
|
2
2
|
'structure', 'helpers', 'ezbake_utils', 'wrappers' ].each do |lib|
|
3
3
|
require "beaker/dsl/#{lib}"
|
4
4
|
end
|
@@ -78,5 +78,6 @@ module Beaker
|
|
78
78
|
include Beaker::DSL::Helpers
|
79
79
|
include Beaker::DSL::EZBakeUtils
|
80
80
|
include Beaker::DSL::InstallUtils
|
81
|
+
include Beaker::DSL::Patterns
|
81
82
|
end
|
82
83
|
end
|
data/lib/beaker/host/unix.rb
CHANGED
@@ -20,16 +20,18 @@ module Unix
|
|
20
20
|
'user' => 'root',
|
21
21
|
'group' => 'pe-puppet',
|
22
22
|
'master-start-curl-retries' => 120,
|
23
|
-
'
|
24
|
-
'
|
25
|
-
'
|
26
|
-
'
|
27
|
-
'
|
28
|
-
'
|
29
|
-
'
|
30
|
-
'
|
31
|
-
'
|
32
|
-
'
|
23
|
+
'jvm-puppet-confdir' => '/etc/puppetlabs/jvm-puppet/conf.d',
|
24
|
+
'puppetservice' => 'pe-httpd',
|
25
|
+
'puppetpath' => '/etc/puppetlabs/puppet',
|
26
|
+
'puppetbin' => '/opt/puppet/bin/puppet',
|
27
|
+
'puppetbindir' => '/opt/puppet/bin',
|
28
|
+
'puppetsbindir' => '/opt/puppet/sbin',
|
29
|
+
'puppetvardir' => '/var/opt/lib/pe-puppet',
|
30
|
+
'hieradatadir' => '/var/lib/hiera',
|
31
|
+
'hieraconf' => '/etc/puppetlabs/puppet/hiera.yaml',
|
32
|
+
'distmoduledir' => '/etc/puppetlabs/puppet/modules',
|
33
|
+
'sitemoduledir' => '/opt/puppet/share/puppet/modules',
|
34
|
+
'pathseparator' => ':',
|
33
35
|
})
|
34
36
|
end
|
35
37
|
|
@@ -39,6 +41,8 @@ module Unix
|
|
39
41
|
'user' => 'root',
|
40
42
|
'group' => 'puppet',
|
41
43
|
'master-start-curl-retries' => 120,
|
44
|
+
'jvm-puppet-confdir' => '/etc/jvm-puppet/conf.d',
|
45
|
+
'puppetservice' => 'puppetmaster',
|
42
46
|
'puppetpath' => '/etc/puppet',
|
43
47
|
'puppetvardir' => '/var/lib/puppet',
|
44
48
|
'puppetbin' => '/usr/bin/puppet',
|
data/lib/beaker/host/windows.rb
CHANGED
@@ -21,6 +21,7 @@ module Windows
|
|
21
21
|
'group' => 'Administrators',
|
22
22
|
'puppetservice' => 'pe-httpd',
|
23
23
|
'puppetpath' => '`cygpath -smF 35`/PuppetLabs/puppet/etc',
|
24
|
+
'hieraconf' => '`cygpath -smF 35`/Puppetlabs/puppet/etc/hiera.yaml',
|
24
25
|
'puppetvardir' => '`cygpath -smF 35`/PuppetLabs/puppet/var',
|
25
26
|
'distmoduledir' => '`cygpath -smF 35`/PuppetLabs/puppet/etc/modules',
|
26
27
|
'sitemoduledir' => 'C:/usr/share/puppet/modules',
|
@@ -36,6 +37,7 @@ module Windows
|
|
36
37
|
'user' => 'Administrator',
|
37
38
|
'group' => 'Administrators',
|
38
39
|
'puppetpath' => '`cygpath -smF 35`/PuppetLabs/puppet/etc',
|
40
|
+
'hieraconf' => '`cygpath -smF 35`/Puppetlabs/puppet/etc/hiera.yaml',
|
39
41
|
'puppetvardir' => '`cygpath -smF 35`/PuppetLabs/puppet/var',
|
40
42
|
'distmoduledir' => '`cygpath -smF 35`/PuppetLabs/puppet/etc/modules',
|
41
43
|
'sitemoduledir' => 'C:/usr/share/puppet/modules',
|
data/lib/beaker/host.rb
CHANGED
@@ -137,6 +137,43 @@ module Beaker
|
|
137
137
|
@options.is_pe?
|
138
138
|
end
|
139
139
|
|
140
|
+
# True if this is a pe run, or if the host has had a 'use-service' property set.
|
141
|
+
def use_service_scripts?
|
142
|
+
is_pe? || self['use-service']
|
143
|
+
end
|
144
|
+
|
145
|
+
# Mirrors the true/false value of the host's 'graceful-restarts' property,
|
146
|
+
# or falls back to the value of +is_using_passenger?+ if
|
147
|
+
# 'graceful-restarts' is nil, but only if this is not a PE run (foss only).
|
148
|
+
def graceful_restarts?
|
149
|
+
graceful =
|
150
|
+
if !self['graceful-restarts'].nil?
|
151
|
+
self['graceful-restarts']
|
152
|
+
else
|
153
|
+
!is_pe? && is_using_passenger?
|
154
|
+
end
|
155
|
+
graceful
|
156
|
+
end
|
157
|
+
|
158
|
+
# Modifies the host settings to indicate that it will be using passenger service scripts,
|
159
|
+
# (apache2) by default. Does nothing if this is a PE host, since it is already using
|
160
|
+
# passenger.
|
161
|
+
# @param [String] puppetservice Name of the service script that should be
|
162
|
+
# called to stop/startPuppet on this host. Defaults to 'apache2'.
|
163
|
+
def uses_passenger!(puppetservice = 'apache2')
|
164
|
+
if !is_pe?
|
165
|
+
self['passenger'] = true
|
166
|
+
self['puppetservice'] = puppetservice
|
167
|
+
self['use-service'] = true
|
168
|
+
end
|
169
|
+
return true
|
170
|
+
end
|
171
|
+
|
172
|
+
# True if this is a PE run, or if the host's 'passenger' property has been set.
|
173
|
+
def is_using_passenger?
|
174
|
+
is_pe? || self['passenger']
|
175
|
+
end
|
176
|
+
|
140
177
|
def log_prefix
|
141
178
|
if @defaults['vmhostname']
|
142
179
|
"#{self} (#{@name})"
|
@@ -206,9 +243,66 @@ module Beaker
|
|
206
243
|
end
|
207
244
|
end
|
208
245
|
|
246
|
+
# Create the provided directory structure on the host
|
247
|
+
# @param [String] dir The directory structure to create on the host
|
248
|
+
# @return [Boolean] True, if directory construction succeeded, otherwise False
|
249
|
+
def mkdir_p dir
|
250
|
+
result = exec(Beaker::Command.new("mkdir -p #{dir}"), :acceptable_exit_codes => [0, 1])
|
251
|
+
result.exit_code == 0
|
252
|
+
end
|
253
|
+
|
254
|
+
# scp files from the localhost to this test host
|
255
|
+
# @param source [String] The path to the file/dir to upload
|
256
|
+
# @param target [String] The destination path on the host
|
257
|
+
# @param [Hash{Symbol=>String}] options Options to alter execution
|
258
|
+
# @option options [Boolean] :recursive Should we copy recursively? Defaults to 'True' in case of a directory source.
|
259
|
+
# @option options [Array<String>] :ignore An array of file/dir paths that will not be copied to the host
|
209
260
|
def do_scp_to source, target, options
|
210
261
|
@logger.debug "localhost $ scp #{source} #{@name}:#{target}"
|
211
|
-
|
262
|
+
|
263
|
+
result = Result.new(@name, [source, target])
|
264
|
+
has_ignore = options[:ignore] and not options[:ignore].empty?
|
265
|
+
# construct the regex for matching ignored files/dirs
|
266
|
+
ignore_re = nil
|
267
|
+
if has_ignore
|
268
|
+
ignore_arr = Array(options[:ignore]).map do |entry|
|
269
|
+
"((\/|\\A)#{entry}(\/|\\z))".sub(/\./, "\.")
|
270
|
+
end
|
271
|
+
ignore_re = Regexp.new(ignore_arr.join('|'))
|
272
|
+
end
|
273
|
+
|
274
|
+
# either a single file, or a directory with no ignores
|
275
|
+
if File.file?(source) or (File.directory?(source) and not has_ignore)
|
276
|
+
source_file = source
|
277
|
+
if has_ignore and (source =~ ignore_re)
|
278
|
+
@logger.debug "After rejecting ignored files/dirs, there is no file to copy"
|
279
|
+
source_file = nil
|
280
|
+
result.stdout = "No files to copy"
|
281
|
+
result.exit_code = 1
|
282
|
+
end
|
283
|
+
if source_file
|
284
|
+
result = connection.scp_to(source_file, target, options, $dry_run)
|
285
|
+
end
|
286
|
+
else # a directory with ignores
|
287
|
+
dir_source = Dir.glob("#{source}/**/*").reject do |f|
|
288
|
+
f =~ ignore_re
|
289
|
+
end
|
290
|
+
@logger.debug "After rejecting ignored files/dirs, going to scp [#{dir_source.join(", ")}]"
|
291
|
+
|
292
|
+
# create necessary directory structure on host
|
293
|
+
required_dirs = (dir_source.map{ | dir | File.dirname(dir) }).uniq
|
294
|
+
required_dirs.each do |dir|
|
295
|
+
mkdir_p( File.join(target, dir) )
|
296
|
+
end
|
297
|
+
|
298
|
+
# copy each file to the host
|
299
|
+
dir_source.each do |s|
|
300
|
+
file_path = File.join(target, s)
|
301
|
+
result = connection.scp_to(s, file_path, options, $dry_run)
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
@logger.debug result.stdout
|
212
306
|
return result
|
213
307
|
end
|
214
308
|
|
@@ -216,6 +310,7 @@ module Beaker
|
|
216
310
|
|
217
311
|
@logger.debug "localhost $ scp #{@name}:#{source} #{target}"
|
218
312
|
result = connection.scp_from(source, target, options, $dry_run)
|
313
|
+
@logger.debug result.stdout
|
219
314
|
return result
|
220
315
|
end
|
221
316
|
|