test-kitchen 1.3.1 → 1.4.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.cane +2 -0
- data/.gitignore +4 -0
- data/CHANGELOG.md +45 -0
- data/Rakefile +15 -0
- data/features/kitchen_action_commands.feature +12 -9
- data/features/kitchen_defaults.feature +38 -0
- data/features/kitchen_init_command.feature +0 -1
- data/features/kitchen_list_command.feature +2 -2
- data/features/kitchen_login_command.feature +7 -1
- data/features/kitchen_test_command.feature +4 -4
- data/lib/kitchen.rb +40 -11
- data/lib/kitchen/cli.rb +38 -22
- data/lib/kitchen/command/list.rb +5 -2
- data/lib/kitchen/config.rb +45 -18
- data/lib/kitchen/configurable.rb +137 -1
- data/lib/kitchen/data_munger.rb +248 -17
- data/lib/kitchen/driver.rb +1 -1
- data/lib/kitchen/driver/base.rb +1 -83
- data/lib/kitchen/driver/dummy.rb +0 -5
- data/lib/kitchen/driver/ssh_base.rb +177 -22
- data/lib/kitchen/instance.rb +140 -20
- data/lib/kitchen/logger.rb +43 -8
- data/lib/kitchen/login_command.rb +14 -5
- data/lib/kitchen/platform.rb +19 -0
- data/lib/kitchen/provisioner.rb +5 -3
- data/lib/kitchen/provisioner/base.rb +46 -48
- data/lib/kitchen/provisioner/chef/common_sandbox.rb +322 -0
- data/lib/kitchen/provisioner/chef_base.rb +179 -286
- data/lib/kitchen/provisioner/chef_solo.rb +11 -5
- data/lib/kitchen/provisioner/chef_zero.rb +108 -94
- data/lib/kitchen/provisioner/dummy.rb +47 -0
- data/lib/kitchen/provisioner/shell.rb +45 -12
- data/lib/kitchen/rake_tasks.rb +1 -1
- data/lib/kitchen/ssh.rb +1 -1
- data/lib/kitchen/thor_tasks.rb +1 -1
- data/lib/kitchen/transport.rb +54 -0
- data/lib/kitchen/transport/base.rb +146 -0
- data/lib/kitchen/transport/dummy.rb +75 -0
- data/lib/kitchen/transport/ssh.rb +325 -0
- data/lib/kitchen/transport/winrm.rb +508 -0
- data/lib/kitchen/transport/winrm/command_executor.rb +188 -0
- data/lib/kitchen/transport/winrm/file_transporter.rb +454 -0
- data/lib/kitchen/transport/winrm/logging.rb +50 -0
- data/lib/kitchen/transport/winrm/template.rb +74 -0
- data/lib/kitchen/transport/winrm/tmp_zip.rb +187 -0
- data/lib/kitchen/verifier.rb +55 -0
- data/lib/kitchen/verifier/base.rb +191 -0
- data/lib/kitchen/verifier/busser.rb +266 -0
- data/lib/kitchen/verifier/dummy.rb +75 -0
- data/lib/kitchen/version.rb +1 -1
- data/spec/kitchen/cli_spec.rb +56 -0
- data/spec/kitchen/config_spec.rb +61 -20
- data/spec/kitchen/configurable_spec.rb +327 -1
- data/spec/kitchen/data_munger_spec.rb +777 -14
- data/spec/kitchen/driver/base_spec.rb +7 -38
- data/spec/kitchen/driver/dummy_spec.rb +0 -29
- data/spec/kitchen/driver/ssh_base_spec.rb +580 -236
- data/spec/kitchen/driver_spec.rb +1 -0
- data/spec/kitchen/instance_spec.rb +383 -83
- data/spec/kitchen/login_command_spec.rb +29 -10
- data/spec/kitchen/platform_spec.rb +58 -2
- data/spec/kitchen/provisioner/base_spec.rb +170 -18
- data/spec/kitchen/provisioner/chef_base_spec.rb +454 -104
- data/spec/kitchen/provisioner/chef_solo_spec.rb +307 -104
- data/spec/kitchen/provisioner/chef_zero_spec.rb +561 -230
- data/spec/kitchen/provisioner/dummy_spec.rb +91 -0
- data/spec/kitchen/provisioner/shell_spec.rb +158 -56
- data/spec/kitchen/provisioner_spec.rb +37 -0
- data/spec/kitchen/ssh_spec.rb +19 -19
- data/spec/kitchen/transport/base_spec.rb +89 -0
- data/spec/kitchen/transport/ssh_spec.rb +1147 -0
- data/spec/kitchen/transport/winrm/command_executor_spec.rb +400 -0
- data/spec/kitchen/transport/winrm/file_transporter_spec.rb +876 -0
- data/spec/kitchen/transport/winrm/logging_spec.rb +92 -0
- data/spec/kitchen/transport/winrm/template_spec.rb +51 -0
- data/spec/kitchen/transport/winrm/tmp_zip_spec.rb +132 -0
- data/spec/kitchen/transport/winrm_spec.rb +1069 -0
- data/spec/kitchen/transport_spec.rb +112 -0
- data/spec/kitchen/verifier/base_spec.rb +310 -0
- data/spec/kitchen/verifier/busser_spec.rb +540 -0
- data/spec/kitchen/verifier/dummy_spec.rb +91 -0
- data/spec/kitchen/verifier_spec.rb +120 -0
- data/spec/kitchen_spec.rb +7 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/support/powershell_max_size_spec.rb +40 -0
- data/support/busser_install_command.ps1 +14 -0
- data/support/busser_install_command.sh +15 -0
- data/support/check_files.ps1.erb +48 -0
- data/support/chef_base_init_command.ps1 +18 -0
- data/support/chef_base_init_command.sh +2 -0
- data/support/chef_base_install_command.ps1 +76 -0
- data/support/chef_base_install_command.sh +137 -0
- data/support/chef_zero_prepare_command_legacy.ps1 +9 -0
- data/support/chef_zero_prepare_command_legacy.sh +10 -0
- data/support/decode_files.ps1.erb +61 -0
- data/test-kitchen.gemspec +2 -0
- metadata +97 -8
- data/lib/kitchen/busser.rb +0 -316
- data/spec/kitchen/busser_spec.rb +0 -490
- data/support/chef_helpers.sh +0 -16
@@ -0,0 +1,137 @@
|
|
1
|
+
# Check whether a command exists - returns 0 if it does, 1 if it does not
|
2
|
+
exists() {
|
3
|
+
if command -v $1 >/dev/null 2>&1
|
4
|
+
then
|
5
|
+
return 0
|
6
|
+
else
|
7
|
+
return 1
|
8
|
+
fi
|
9
|
+
}
|
10
|
+
|
11
|
+
# do_wget URL FILENAME
|
12
|
+
do_wget() {
|
13
|
+
echo "trying wget..."
|
14
|
+
wget -O "$2" "$1" 2>/tmp/stderr
|
15
|
+
# check for bad return status
|
16
|
+
test $? -ne 0 && return 1
|
17
|
+
# check for 404 or empty file
|
18
|
+
grep "ERROR 404" /tmp/stderr 2>&1 >/dev/null
|
19
|
+
if test $? -eq 0 || test ! -s "$2"; then
|
20
|
+
return 1
|
21
|
+
fi
|
22
|
+
return 0
|
23
|
+
}
|
24
|
+
|
25
|
+
# do_curl URL FILENAME
|
26
|
+
do_curl() {
|
27
|
+
echo "trying curl..."
|
28
|
+
curl -L "$1" > "$2"
|
29
|
+
# check for bad return status
|
30
|
+
[ $? -ne 0 ] && return 1
|
31
|
+
# check for bad output or empty file
|
32
|
+
grep "The specified key does not exist." "$2" 2>&1 >/dev/null
|
33
|
+
if test $? -eq 0 || test ! -s "$2"; then
|
34
|
+
return 1
|
35
|
+
fi
|
36
|
+
return 0
|
37
|
+
}
|
38
|
+
|
39
|
+
# do_fetch URL FILENAME
|
40
|
+
do_fetch() {
|
41
|
+
echo "trying fetch..."
|
42
|
+
fetch -o "$2" "$1" 2>/tmp/stderr
|
43
|
+
# check for bad return status
|
44
|
+
test $? -ne 0 && return 1
|
45
|
+
return 0
|
46
|
+
}
|
47
|
+
|
48
|
+
# do_perl URL FILENAME
|
49
|
+
do_perl() {
|
50
|
+
echo "trying perl..."
|
51
|
+
perl -e "use LWP::Simple; getprint($ARGV[0]);" "$1" > "$2"
|
52
|
+
# check for bad return status
|
53
|
+
test $? -ne 0 && return 1
|
54
|
+
# check for bad output or empty file
|
55
|
+
# grep "The specified key does not exist." "$2" 2>&1 >/dev/null
|
56
|
+
# if test $? -eq 0 || test ! -s "$2"; then
|
57
|
+
# unable_to_retrieve_package
|
58
|
+
# fi
|
59
|
+
return 0
|
60
|
+
}
|
61
|
+
|
62
|
+
# do_python URL FILENAME
|
63
|
+
do_python() {
|
64
|
+
echo "trying python..."
|
65
|
+
python -c "import sys,urllib2 ; sys.stdout.write(urllib2.urlopen(sys.argv[1]).read())" "$1" > "$2"
|
66
|
+
# check for bad return status
|
67
|
+
test $? -ne 0 && return 1
|
68
|
+
# check for bad output or empty file
|
69
|
+
#grep "The specified key does not exist." "$2" 2>&1 >/dev/null
|
70
|
+
#if test $? -eq 0 || test ! -s "$2"; then
|
71
|
+
# unable_to_retrieve_package
|
72
|
+
#fi
|
73
|
+
return 0
|
74
|
+
}
|
75
|
+
|
76
|
+
# do_download URL FILENAME
|
77
|
+
do_download() {
|
78
|
+
PATH=/opt/local/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
79
|
+
export PATH
|
80
|
+
|
81
|
+
echo "downloading $1"
|
82
|
+
echo " to file $2"
|
83
|
+
|
84
|
+
# we try all of these until we get success.
|
85
|
+
# perl, in particular may be present but LWP::Simple may not be installed
|
86
|
+
|
87
|
+
if exists wget; then
|
88
|
+
do_wget $1 $2 && return 0
|
89
|
+
fi
|
90
|
+
|
91
|
+
if exists curl; then
|
92
|
+
do_curl $1 $2 && return 0
|
93
|
+
fi
|
94
|
+
|
95
|
+
if exists fetch; then
|
96
|
+
do_fetch $1 $2 && return 0
|
97
|
+
fi
|
98
|
+
|
99
|
+
if exists perl; then
|
100
|
+
do_perl $1 $2 && return 0
|
101
|
+
fi
|
102
|
+
|
103
|
+
if exists python; then
|
104
|
+
do_python $1 $2 && return 0
|
105
|
+
fi
|
106
|
+
|
107
|
+
echo ">>>>>> wget, curl, fetch, perl or python not found on this instance."
|
108
|
+
return 16
|
109
|
+
}
|
110
|
+
|
111
|
+
# @param $1 the omnibus root directory
|
112
|
+
# @param $2 the requested version of omnibus package
|
113
|
+
# @return 0 if omnibus needs to be installed, non-zero otherwise
|
114
|
+
should_update_chef() {
|
115
|
+
if test ! -d "$1" ; then return 0
|
116
|
+
elif test "$2" = "true" ; then return 1
|
117
|
+
elif test "$2" = "latest" ; then return 0
|
118
|
+
fi
|
119
|
+
|
120
|
+
local version="`$1/bin/chef-solo -v | cut -d " " -f 2`"
|
121
|
+
|
122
|
+
echo "$version" | grep "^$2" 2>&1 >/dev/null
|
123
|
+
if test $? -eq 0 ; then
|
124
|
+
return 1
|
125
|
+
else
|
126
|
+
return 0
|
127
|
+
fi
|
128
|
+
}
|
129
|
+
|
130
|
+
should_update_chef "$chef_omnibus_root" "$version"
|
131
|
+
if test $? -eq 0 ; then
|
132
|
+
echo "-----> Installing Chef Omnibus ($pretty_version)"
|
133
|
+
do_download "$chef_omnibus_url" /tmp/install.sh
|
134
|
+
$sudo_sh /tmp/install.sh $install_flags
|
135
|
+
else
|
136
|
+
echo "-----> Chef Omnibus installation detected ($pretty_version)"
|
137
|
+
fi
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# we are installing the first version of chef that bundled chef-zero in order
|
2
|
+
# to get chef-zero and Chef::ChefFS only. The version of Chef that gets run
|
3
|
+
# will be the installed omnibus package. Yep, this is funky :)
|
4
|
+
|
5
|
+
if ((& "$gem" list chef-zero -i) -ne "true") {
|
6
|
+
Write-Host ">>>>>> Attempting to use chef-zero with old version of Chef`n"
|
7
|
+
Write-Host "-----> Installing chef zero dependencies`n"
|
8
|
+
& "$gem" install chef --version 11.8.0 --no-ri --no-rdoc --conservative
|
9
|
+
}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# we are installing the first version of chef that bundled chef-zero in order
|
2
|
+
# to get chef-zero and Chef::ChefFS only. The version of Chef that gets run
|
3
|
+
# will be the installed omnibus package. Yep, this is funky :)
|
4
|
+
|
5
|
+
$gem list chef-zero -i 2>&1 >/dev/null
|
6
|
+
if test $? -ne 0 ; then
|
7
|
+
echo ">>>>>> Attempting to use chef-zero with old version of Chef"
|
8
|
+
echo "-----> Installing chef zero dependencies"
|
9
|
+
$gem install chef --version 11.8.0 --no-ri --no-rdoc --conservative
|
10
|
+
fi
|
@@ -0,0 +1,61 @@
|
|
1
|
+
$hash_file = "<%= hash_file %>"
|
2
|
+
|
3
|
+
Function Cleanup($o) { if (($o -ne $null) -and ($o.GetType().GetMethod("Dispose") -ne $null)) { $o.Dispose() } }
|
4
|
+
|
5
|
+
Function Decode-Base64File($src, $dst) {
|
6
|
+
Try {
|
7
|
+
$in = (Get-Item $src).OpenRead()
|
8
|
+
$b64 = New-Object -TypeName System.Security.Cryptography.FromBase64Transform
|
9
|
+
$m = [System.Security.Cryptography.CryptoStreamMode]::Read
|
10
|
+
$d = New-Object -TypeName System.Security.Cryptography.CryptoStream $in,$b64,$m
|
11
|
+
Copy-Stream $d ($out = [System.IO.File]::OpenWrite($dst))
|
12
|
+
} Finally { Cleanup $in; Cleanup $out; Cleanup $d }
|
13
|
+
}
|
14
|
+
|
15
|
+
Function Copy-Stream($src, $dst) { $b = New-Object Byte[] 4096; while (($i = $src.Read($b, 0, $b.Length)) -ne 0) { $dst.Write($b, 0, $i) } }
|
16
|
+
|
17
|
+
Function Decode-Files($hash) {
|
18
|
+
$hash.GetEnumerator() | ForEach-Object {
|
19
|
+
$tmp = Unresolve-Path $_.Key
|
20
|
+
$sMd5 = (Get-Item $tmp).BaseName.Replace("b64-", "")
|
21
|
+
$tzip, $dst = (Unresolve-Path $_.Value["tmpzip"]), (Unresolve-Path $_.Value["dst"])
|
22
|
+
$decoded = if ($tzip -ne $null) { $tzip } else { $dst }
|
23
|
+
Decode-Base64File $tmp $decoded
|
24
|
+
Remove-Item $tmp -Force
|
25
|
+
$dMd5 = Get-MD5Sum $decoded
|
26
|
+
$verifies = if ($sMd5 -eq $dMd5) { $true } else { $false }
|
27
|
+
if ($tzip) { Unzip-File $tzip $dst; Remove-Item $tzip -Force }
|
28
|
+
New-Object psobject -Property @{ dst = $dst; verifies = $verifies; src_md5 = $sMd5; dst_md5 = $dMd5; tmpfile = $tmp; tmpzip = $tzip }
|
29
|
+
} | Select-Object -Property dst,verifies,src_md5,dst_md5,tmpfile,tmpzip
|
30
|
+
}
|
31
|
+
|
32
|
+
Function Get-MD5Sum($src) {
|
33
|
+
Try {
|
34
|
+
$c = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
|
35
|
+
$bytes = $c.ComputeHash(($in = (Get-Item $src).OpenRead()))
|
36
|
+
return ([System.BitConverter]::ToString($bytes)).Replace("-", "").ToLower()
|
37
|
+
} Finally { Cleanup $c; Cleanup $in }
|
38
|
+
}
|
39
|
+
|
40
|
+
Function Invoke-Input($in) {
|
41
|
+
$in = Unresolve-Path $in
|
42
|
+
Decode-Base64File $in ($decoded = "$($in).ps1")
|
43
|
+
$expr = Get-Content $decoded | Out-String
|
44
|
+
Remove-Item $in,$decoded -Force
|
45
|
+
return Invoke-Expression "$expr"
|
46
|
+
}
|
47
|
+
|
48
|
+
Function Release-COM($o) { if ($o -ne $null) { [void][System.Runtime.Interopservices.Marshal]::ReleaseComObject($o) } }
|
49
|
+
|
50
|
+
Function Unresolve-Path($p) { if ($p -eq $null) { return $null } else { return $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($p) } }
|
51
|
+
|
52
|
+
Function Unzip-File($src, $dst) {
|
53
|
+
$r = "HKLM:\Software\Microsoft\NET Framework Setup\NDP\v4"
|
54
|
+
if (($PSVersionTable.PSVersion.Major -ge 3) -and ((gp "$r\Full").Version -like "4.5*" -or (gp "$r\Client").Version -like "4.5*")) {
|
55
|
+
[System.Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem") | Out-Null; [System.IO.Compression.ZipFile]::ExtractToDirectory("$src", "$dst")
|
56
|
+
} else {
|
57
|
+
Try { $s = New-Object -ComObject Shell.Application; ($dp = $s.NameSpace($dst)).CopyHere(($z = $s.NameSpace($src)).Items(), 0x610) } Finally { Release-Com $s; Release-Com $z; Release-COM $dp }
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
Decode-Files (Invoke-Input $hash_file) | ConvertTo-Csv -NoTypeInformation
|
data/test-kitchen.gemspec
CHANGED
@@ -26,8 +26,10 @@ Gem::Specification.new do |gem|
|
|
26
26
|
gem.add_dependency "mixlib-shellout", ">= 1.2", "< 3.0"
|
27
27
|
gem.add_dependency "net-scp", "~> 1.1"
|
28
28
|
gem.add_dependency "net-ssh", "~> 2.7"
|
29
|
+
gem.add_dependency "winrm", "~> 1.3"
|
29
30
|
gem.add_dependency "safe_yaml", "~> 1.0"
|
30
31
|
gem.add_dependency "thor", "~> 0.18"
|
32
|
+
gem.add_dependency "rubyzip", ">= 1.1.7", "~> 1.1"
|
31
33
|
|
32
34
|
gem.add_development_dependency "pry"
|
33
35
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: test-kitchen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0.beta.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fletcher Nichol
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-03-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mixlib-shellout
|
@@ -58,6 +58,20 @@ dependencies:
|
|
58
58
|
- - "~>"
|
59
59
|
- !ruby/object:Gem::Version
|
60
60
|
version: '2.7'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: winrm
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '1.3'
|
68
|
+
type: :runtime
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '1.3'
|
61
75
|
- !ruby/object:Gem::Dependency
|
62
76
|
name: safe_yaml
|
63
77
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,6 +100,26 @@ dependencies:
|
|
86
100
|
- - "~>"
|
87
101
|
- !ruby/object:Gem::Version
|
88
102
|
version: '0.18'
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: rubyzip
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 1.1.7
|
110
|
+
- - "~>"
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '1.1'
|
113
|
+
type: :runtime
|
114
|
+
prerelease: false
|
115
|
+
version_requirements: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: 1.1.7
|
120
|
+
- - "~>"
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '1.1'
|
89
123
|
- !ruby/object:Gem::Dependency
|
90
124
|
name: pry
|
91
125
|
requirement: !ruby/object:Gem::Requirement
|
@@ -292,6 +326,7 @@ files:
|
|
292
326
|
- features/kitchen_action_commands.feature
|
293
327
|
- features/kitchen_command.feature
|
294
328
|
- features/kitchen_console_command.feature
|
329
|
+
- features/kitchen_defaults.feature
|
295
330
|
- features/kitchen_diagnose_command.feature
|
296
331
|
- features/kitchen_driver_create_command.feature
|
297
332
|
- features/kitchen_driver_discover_command.feature
|
@@ -307,7 +342,6 @@ files:
|
|
307
342
|
- features/support/env.rb
|
308
343
|
- lib/kitchen.rb
|
309
344
|
- lib/kitchen/base64_stream.rb
|
310
|
-
- lib/kitchen/busser.rb
|
311
345
|
- lib/kitchen/cli.rb
|
312
346
|
- lib/kitchen/collection.rb
|
313
347
|
- lib/kitchen/color.rb
|
@@ -344,6 +378,7 @@ files:
|
|
344
378
|
- lib/kitchen/provisioner.rb
|
345
379
|
- lib/kitchen/provisioner/base.rb
|
346
380
|
- lib/kitchen/provisioner/chef/berkshelf.rb
|
381
|
+
- lib/kitchen/provisioner/chef/common_sandbox.rb
|
347
382
|
- lib/kitchen/provisioner/chef/librarian.rb
|
348
383
|
- lib/kitchen/provisioner/chef_base.rb
|
349
384
|
- lib/kitchen/provisioner/chef_solo.rb
|
@@ -356,11 +391,25 @@ files:
|
|
356
391
|
- lib/kitchen/state_file.rb
|
357
392
|
- lib/kitchen/suite.rb
|
358
393
|
- lib/kitchen/thor_tasks.rb
|
394
|
+
- lib/kitchen/transport.rb
|
395
|
+
- lib/kitchen/transport/base.rb
|
396
|
+
- lib/kitchen/transport/dummy.rb
|
397
|
+
- lib/kitchen/transport/ssh.rb
|
398
|
+
- lib/kitchen/transport/winrm.rb
|
399
|
+
- lib/kitchen/transport/winrm/command_executor.rb
|
400
|
+
- lib/kitchen/transport/winrm/file_transporter.rb
|
401
|
+
- lib/kitchen/transport/winrm/logging.rb
|
402
|
+
- lib/kitchen/transport/winrm/template.rb
|
403
|
+
- lib/kitchen/transport/winrm/tmp_zip.rb
|
359
404
|
- lib/kitchen/util.rb
|
405
|
+
- lib/kitchen/verifier.rb
|
406
|
+
- lib/kitchen/verifier/base.rb
|
407
|
+
- lib/kitchen/verifier/busser.rb
|
408
|
+
- lib/kitchen/verifier/dummy.rb
|
360
409
|
- lib/kitchen/version.rb
|
361
410
|
- lib/vendor/hash_recursive_merge.rb
|
362
411
|
- spec/kitchen/base64_stream_spec.rb
|
363
|
-
- spec/kitchen/
|
412
|
+
- spec/kitchen/cli_spec.rb
|
364
413
|
- spec/kitchen/collection_spec.rb
|
365
414
|
- spec/kitchen/color_spec.rb
|
366
415
|
- spec/kitchen/config_spec.rb
|
@@ -385,17 +434,41 @@ files:
|
|
385
434
|
- spec/kitchen/provisioner/chef_base_spec.rb
|
386
435
|
- spec/kitchen/provisioner/chef_solo_spec.rb
|
387
436
|
- spec/kitchen/provisioner/chef_zero_spec.rb
|
437
|
+
- spec/kitchen/provisioner/dummy_spec.rb
|
388
438
|
- spec/kitchen/provisioner/shell_spec.rb
|
389
439
|
- spec/kitchen/provisioner_spec.rb
|
390
440
|
- spec/kitchen/shell_out_spec.rb
|
391
441
|
- spec/kitchen/ssh_spec.rb
|
392
442
|
- spec/kitchen/state_file_spec.rb
|
393
443
|
- spec/kitchen/suite_spec.rb
|
444
|
+
- spec/kitchen/transport/base_spec.rb
|
445
|
+
- spec/kitchen/transport/ssh_spec.rb
|
446
|
+
- spec/kitchen/transport/winrm/command_executor_spec.rb
|
447
|
+
- spec/kitchen/transport/winrm/file_transporter_spec.rb
|
448
|
+
- spec/kitchen/transport/winrm/logging_spec.rb
|
449
|
+
- spec/kitchen/transport/winrm/template_spec.rb
|
450
|
+
- spec/kitchen/transport/winrm/tmp_zip_spec.rb
|
451
|
+
- spec/kitchen/transport/winrm_spec.rb
|
452
|
+
- spec/kitchen/transport_spec.rb
|
394
453
|
- spec/kitchen/util_spec.rb
|
454
|
+
- spec/kitchen/verifier/base_spec.rb
|
455
|
+
- spec/kitchen/verifier/busser_spec.rb
|
456
|
+
- spec/kitchen/verifier/dummy_spec.rb
|
457
|
+
- spec/kitchen/verifier_spec.rb
|
395
458
|
- spec/kitchen_spec.rb
|
396
459
|
- spec/spec_helper.rb
|
460
|
+
- spec/support/powershell_max_size_spec.rb
|
461
|
+
- support/busser_install_command.ps1
|
462
|
+
- support/busser_install_command.sh
|
463
|
+
- support/check_files.ps1.erb
|
397
464
|
- support/chef-client-zero.rb
|
398
|
-
- support/
|
465
|
+
- support/chef_base_init_command.ps1
|
466
|
+
- support/chef_base_init_command.sh
|
467
|
+
- support/chef_base_install_command.ps1
|
468
|
+
- support/chef_base_install_command.sh
|
469
|
+
- support/chef_zero_prepare_command_legacy.ps1
|
470
|
+
- support/chef_zero_prepare_command_legacy.sh
|
471
|
+
- support/decode_files.ps1.erb
|
399
472
|
- support/download_helpers.sh
|
400
473
|
- support/dummy-validation.pem
|
401
474
|
- templates/driver/CHANGELOG.md.erb
|
@@ -429,9 +502,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
429
502
|
version: 1.9.1
|
430
503
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
431
504
|
requirements:
|
432
|
-
- - "
|
505
|
+
- - ">"
|
433
506
|
- !ruby/object:Gem::Version
|
434
|
-
version:
|
507
|
+
version: 1.3.1
|
435
508
|
requirements: []
|
436
509
|
rubyforge_project:
|
437
510
|
rubygems_version: 2.4.5
|
@@ -443,6 +516,7 @@ test_files:
|
|
443
516
|
- features/kitchen_action_commands.feature
|
444
517
|
- features/kitchen_command.feature
|
445
518
|
- features/kitchen_console_command.feature
|
519
|
+
- features/kitchen_defaults.feature
|
446
520
|
- features/kitchen_diagnose_command.feature
|
447
521
|
- features/kitchen_driver_create_command.feature
|
448
522
|
- features/kitchen_driver_discover_command.feature
|
@@ -457,7 +531,7 @@ test_files:
|
|
457
531
|
- features/step_definitions/output_steps.rb
|
458
532
|
- features/support/env.rb
|
459
533
|
- spec/kitchen/base64_stream_spec.rb
|
460
|
-
- spec/kitchen/
|
534
|
+
- spec/kitchen/cli_spec.rb
|
461
535
|
- spec/kitchen/collection_spec.rb
|
462
536
|
- spec/kitchen/color_spec.rb
|
463
537
|
- spec/kitchen/config_spec.rb
|
@@ -482,13 +556,28 @@ test_files:
|
|
482
556
|
- spec/kitchen/provisioner/chef_base_spec.rb
|
483
557
|
- spec/kitchen/provisioner/chef_solo_spec.rb
|
484
558
|
- spec/kitchen/provisioner/chef_zero_spec.rb
|
559
|
+
- spec/kitchen/provisioner/dummy_spec.rb
|
485
560
|
- spec/kitchen/provisioner/shell_spec.rb
|
486
561
|
- spec/kitchen/provisioner_spec.rb
|
487
562
|
- spec/kitchen/shell_out_spec.rb
|
488
563
|
- spec/kitchen/ssh_spec.rb
|
489
564
|
- spec/kitchen/state_file_spec.rb
|
490
565
|
- spec/kitchen/suite_spec.rb
|
566
|
+
- spec/kitchen/transport/base_spec.rb
|
567
|
+
- spec/kitchen/transport/ssh_spec.rb
|
568
|
+
- spec/kitchen/transport/winrm/command_executor_spec.rb
|
569
|
+
- spec/kitchen/transport/winrm/file_transporter_spec.rb
|
570
|
+
- spec/kitchen/transport/winrm/logging_spec.rb
|
571
|
+
- spec/kitchen/transport/winrm/template_spec.rb
|
572
|
+
- spec/kitchen/transport/winrm/tmp_zip_spec.rb
|
573
|
+
- spec/kitchen/transport/winrm_spec.rb
|
574
|
+
- spec/kitchen/transport_spec.rb
|
491
575
|
- spec/kitchen/util_spec.rb
|
576
|
+
- spec/kitchen/verifier/base_spec.rb
|
577
|
+
- spec/kitchen/verifier/busser_spec.rb
|
578
|
+
- spec/kitchen/verifier/dummy_spec.rb
|
579
|
+
- spec/kitchen/verifier_spec.rb
|
492
580
|
- spec/kitchen_spec.rb
|
493
581
|
- spec/spec_helper.rb
|
582
|
+
- spec/support/powershell_max_size_spec.rb
|
494
583
|
has_rdoc:
|
data/lib/kitchen/busser.rb
DELETED
@@ -1,316 +0,0 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
#
|
3
|
-
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
4
|
-
#
|
5
|
-
# Copyright (C) 2012, 2013, Fletcher Nichol
|
6
|
-
#
|
7
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
-
# you may not use this file except in compliance with the License.
|
9
|
-
# You may obtain a copy of the License at
|
10
|
-
#
|
11
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
-
#
|
13
|
-
# Unless required by applicable law or agreed to in writing, software
|
14
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
-
# See the License for the specific language governing permissions and
|
17
|
-
# limitations under the License.
|
18
|
-
|
19
|
-
require "base64"
|
20
|
-
require "digest"
|
21
|
-
|
22
|
-
module Kitchen
|
23
|
-
|
24
|
-
# Command string generator to interface with Busser. The commands that are
|
25
|
-
# generated are safe to pass to an SSH command or as an unix command
|
26
|
-
# argument (escaped in single quotes).
|
27
|
-
#
|
28
|
-
# @author Fletcher Nichol <fnichol@nichol.ca>
|
29
|
-
class Busser
|
30
|
-
|
31
|
-
# Constructs a new Busser command generator, given a suite name.
|
32
|
-
#
|
33
|
-
# @param [String] suite_name name of suite on which to operate
|
34
|
-
# (**Required**)
|
35
|
-
# @param [Hash] opts optional configuration
|
36
|
-
# @option opts [String] :kitchen_root local path to the root of the project
|
37
|
-
# @option opts [String] :instance_ruby_bindir path to the directory
|
38
|
-
# containing the Ruby binary on the remote instance
|
39
|
-
# @option opts [TrueClass, FalseClass] :sudo whether or not to invoke
|
40
|
-
# sudo before commands requiring root access (default: `true`)
|
41
|
-
def initialize(suite_name, opts = {})
|
42
|
-
validate_options(suite_name)
|
43
|
-
|
44
|
-
kitchen_root = opts.fetch(:kitchen_root) { Dir.pwd }
|
45
|
-
test_base_path = opts.fetch(:test_base_path, Kitchen::DEFAULT_TEST_DIR)
|
46
|
-
|
47
|
-
@config = Hash.new
|
48
|
-
@config[:kitchen_root] = kitchen_root
|
49
|
-
@config[:test_base_path] = File.expand_path(test_base_path, kitchen_root)
|
50
|
-
@config[:suite_name] = suite_name
|
51
|
-
@config[:sudo] = opts.fetch(:sudo, true)
|
52
|
-
@config[:ruby_bindir] = opts.fetch(:ruby_bindir, DEFAULT_RUBY_BINDIR)
|
53
|
-
@config[:root_path] = opts.fetch(:root_path, DEFAULT_ROOT_PATH)
|
54
|
-
@config[:version] = opts.fetch(:version, "busser")
|
55
|
-
@config[:busser_bin] = opts.fetch(:busser_bin, File.join(@config[:root_path], "bin/busser"))
|
56
|
-
end
|
57
|
-
|
58
|
-
# Returns the name of this busser, suitable for display in a CLI.
|
59
|
-
#
|
60
|
-
# @return [String] name of this busser
|
61
|
-
def name
|
62
|
-
config[:suite_name]
|
63
|
-
end
|
64
|
-
|
65
|
-
# Returns an array of configuration keys.
|
66
|
-
#
|
67
|
-
# @return [Array] array of configuration keys
|
68
|
-
def config_keys
|
69
|
-
config.keys
|
70
|
-
end
|
71
|
-
|
72
|
-
# Provides hash-like access to configuration keys.
|
73
|
-
#
|
74
|
-
# @param attr [Object] configuration key
|
75
|
-
# @return [Object] value at configuration key
|
76
|
-
def [](attr)
|
77
|
-
config[attr]
|
78
|
-
end
|
79
|
-
|
80
|
-
# Returns a Hash of configuration and other useful diagnostic information.
|
81
|
-
#
|
82
|
-
# @return [Hash] a diagnostic hash
|
83
|
-
def diagnose
|
84
|
-
result = Hash.new
|
85
|
-
config_keys.sort.each { |k| result[k] = config[k] }
|
86
|
-
result
|
87
|
-
end
|
88
|
-
|
89
|
-
# Returns a command string which installs Busser, and installs all
|
90
|
-
# required Busser plugins for the suite.
|
91
|
-
#
|
92
|
-
# If no work needs to be performed, for example if there are no tests for
|
93
|
-
# the given suite, then `nil` will be returned.
|
94
|
-
#
|
95
|
-
# @return [String] a command string to setup the test suite, or nil if no
|
96
|
-
# work needs to be performed
|
97
|
-
def setup_cmd
|
98
|
-
return if local_suite_files.empty?
|
99
|
-
|
100
|
-
ruby = "#{config[:ruby_bindir]}/ruby"
|
101
|
-
gem = sudo("#{config[:ruby_bindir]}/gem")
|
102
|
-
busser = sudo(config[:busser_bin])
|
103
|
-
|
104
|
-
cmd = <<-CMD.gsub(/^ {8}/, "")
|
105
|
-
#{busser_setup_env}
|
106
|
-
gem_bindir=`#{ruby} -rrubygems -e "puts Gem.bindir"`
|
107
|
-
|
108
|
-
if ! #{gem} list busser -i >/dev/null; then
|
109
|
-
#{gem} install #{gem_install_args}
|
110
|
-
fi
|
111
|
-
#{sudo("${gem_bindir}")}/busser setup
|
112
|
-
#{busser} plugin install #{plugins.join(" ")}
|
113
|
-
CMD
|
114
|
-
Util.wrap_command(cmd)
|
115
|
-
end
|
116
|
-
|
117
|
-
# Returns a command string which transfers all suite test files to the
|
118
|
-
# instance.
|
119
|
-
#
|
120
|
-
# If no work needs to be performed, for example if there are no tests for
|
121
|
-
# the given suite, then `nil` will be returned.
|
122
|
-
#
|
123
|
-
# @return [String] a command string to transfer all suite test files, or
|
124
|
-
# nil if no work needs to be performed.
|
125
|
-
def sync_cmd
|
126
|
-
return if local_suite_files.empty?
|
127
|
-
|
128
|
-
cmd = <<-CMD.gsub(/^ {8}/, "")
|
129
|
-
#{busser_setup_env}
|
130
|
-
|
131
|
-
#{sudo(config[:busser_bin])} suite cleanup
|
132
|
-
|
133
|
-
CMD
|
134
|
-
local_suite_files.each do |f|
|
135
|
-
cmd << stream_file(f, remote_file(f, config[:suite_name])).concat("\n")
|
136
|
-
end
|
137
|
-
helper_files.each do |f|
|
138
|
-
cmd << stream_file(f, remote_file(f, "helpers")).concat("\n")
|
139
|
-
end
|
140
|
-
|
141
|
-
Util.wrap_command(cmd)
|
142
|
-
end
|
143
|
-
|
144
|
-
# Returns a command string which runs all Busser suite tests for the suite.
|
145
|
-
#
|
146
|
-
# If no work needs to be performed, for example if there are no tests for
|
147
|
-
# the given suite, then `nil` will be returned.
|
148
|
-
#
|
149
|
-
# @return [String] a command string to run the test suites, or nil if no
|
150
|
-
# work needs to be performed
|
151
|
-
def run_cmd
|
152
|
-
return if local_suite_files.empty?
|
153
|
-
|
154
|
-
cmd = <<-CMD.gsub(/^ {8}/, "")
|
155
|
-
#{busser_setup_env}
|
156
|
-
|
157
|
-
#{sudo(config[:busser_bin])} test
|
158
|
-
CMD
|
159
|
-
|
160
|
-
Util.wrap_command(cmd)
|
161
|
-
end
|
162
|
-
|
163
|
-
private
|
164
|
-
|
165
|
-
DEFAULT_RUBY_BINDIR = "/opt/chef/embedded/bin".freeze
|
166
|
-
DEFAULT_ROOT_PATH = "/tmp/busser".freeze
|
167
|
-
|
168
|
-
# @return [Hash] a configuration hash
|
169
|
-
# @api private
|
170
|
-
attr_reader :config
|
171
|
-
|
172
|
-
# Ensures that the object is internally consistent and otherwise raising
|
173
|
-
# an exception.
|
174
|
-
#
|
175
|
-
# @param suite_name [String] the suite name
|
176
|
-
# @raise [ClientError] if a suite name is missing
|
177
|
-
# @raise [UserError] if the suite name is invalid
|
178
|
-
# @api private
|
179
|
-
def validate_options(suite_name)
|
180
|
-
if suite_name.nil?
|
181
|
-
raise ClientError, "Busser#new requires a suite_name"
|
182
|
-
end
|
183
|
-
|
184
|
-
if suite_name == "helper"
|
185
|
-
raise UserError,
|
186
|
-
"Suite name invalid: 'helper' is a reserved directory name."
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
# Returns a uniquely sorted Array of Busser plugin gems that need to
|
191
|
-
# be installed for the related suite.
|
192
|
-
#
|
193
|
-
# @return [Array<String>] a lexically sorted, unique item array of Busser
|
194
|
-
# plugin gem names
|
195
|
-
# @api private
|
196
|
-
def plugins
|
197
|
-
non_suite_dirs = %w[data data_bags environments nodes roles]
|
198
|
-
glob = File.join(config[:test_base_path], config[:suite_name], "*")
|
199
|
-
Dir.glob(glob).reject { |d|
|
200
|
-
!File.directory?(d) || non_suite_dirs.include?(File.basename(d))
|
201
|
-
}.map { |d| "busser-#{File.basename(d)}" }.sort.uniq
|
202
|
-
end
|
203
|
-
|
204
|
-
# Returns an Array of test suite filenames for the related suite currently
|
205
|
-
# residing on the local workstation. Any special provisioner-specific
|
206
|
-
# directories (such as a Chef roles/ directory) are excluded.
|
207
|
-
#
|
208
|
-
# @return [Array<String>] array of suite files
|
209
|
-
# @api private
|
210
|
-
def local_suite_files
|
211
|
-
base = File.join(config[:test_base_path], config[:suite_name])
|
212
|
-
glob = File.join(base, "*/**/*")
|
213
|
-
Dir.glob(glob).reject do |f|
|
214
|
-
chef_data_dir?(base, f) || File.directory?(f)
|
215
|
-
end
|
216
|
-
end
|
217
|
-
|
218
|
-
# Determines whether or not a local workstation file exists under a
|
219
|
-
# Chef-related directory.
|
220
|
-
#
|
221
|
-
# @return [truthy,falsey] whether or not a given file is some kind of
|
222
|
-
# Chef-related file
|
223
|
-
# @api private
|
224
|
-
def chef_data_dir?(base, file)
|
225
|
-
file =~ %r{^#{base}/(data|data_bags|environments|nodes|roles)/}
|
226
|
-
end
|
227
|
-
|
228
|
-
# Returns an Array of common helper filenames currently residing on the
|
229
|
-
# local workstation.
|
230
|
-
#
|
231
|
-
# @return [Array<String>] array of helper files
|
232
|
-
# @api private
|
233
|
-
def helper_files
|
234
|
-
glob = File.join(config[:test_base_path], "helpers", "*/**/*")
|
235
|
-
Dir.glob(glob).reject { |f| File.directory?(f) }
|
236
|
-
end
|
237
|
-
|
238
|
-
# Returns a command string that will, once evaluated, result in the
|
239
|
-
# fully qualified destination path of a file on an instance.
|
240
|
-
#
|
241
|
-
# @param file [String] absolute path to the local file
|
242
|
-
# @param dir [String] suite directory or helper directory name
|
243
|
-
# @return [String] command string
|
244
|
-
# @api private
|
245
|
-
def remote_file(file, dir)
|
246
|
-
local_prefix = File.join(config[:test_base_path], dir)
|
247
|
-
"`#{sudo(config[:busser_bin])} suite path`/".
|
248
|
-
concat(file.sub(%r{^#{local_prefix}/}, ""))
|
249
|
-
end
|
250
|
-
|
251
|
-
# Returns a command string that will, once evaluated, result in the copying
|
252
|
-
# of a local file to a remote instance.
|
253
|
-
#
|
254
|
-
# @param local_path [String] the path to a local source file for copying
|
255
|
-
# @param remote_path [String] the destrination path on the remote instance
|
256
|
-
# @return [String] command string
|
257
|
-
# @api private
|
258
|
-
def stream_file(local_path, remote_path)
|
259
|
-
local_file = IO.read(local_path)
|
260
|
-
encoded_file = Base64.encode64(local_file).gsub("\n", "")
|
261
|
-
md5 = Digest::MD5.hexdigest(local_file)
|
262
|
-
perms = format("%o", File.stat(local_path).mode)[2, 4]
|
263
|
-
stream_cmd = [
|
264
|
-
sudo(config[:busser_bin]),
|
265
|
-
"deserialize",
|
266
|
-
"--destination=#{remote_path}",
|
267
|
-
"--md5sum=#{md5}",
|
268
|
-
"--perms=#{perms}"
|
269
|
-
].join(" ")
|
270
|
-
|
271
|
-
[
|
272
|
-
%{echo "Uploading #{remote_path} (mode=#{perms})"},
|
273
|
-
%{echo "#{encoded_file}" | #{stream_cmd}}
|
274
|
-
].join("\n").concat("\n")
|
275
|
-
end
|
276
|
-
|
277
|
-
# Conditionally prefixes a command with a sudo command.
|
278
|
-
#
|
279
|
-
# @param command [String] command to be prefixed
|
280
|
-
# @return [String] the command, conditionaly prefixed with sudo
|
281
|
-
# @api private
|
282
|
-
def sudo(command)
|
283
|
-
config[:sudo] ? "sudo -E #{command}" : command
|
284
|
-
end
|
285
|
-
|
286
|
-
# Returns a command string that sets appropriate environment variables for
|
287
|
-
# busser commands.
|
288
|
-
#
|
289
|
-
# @return [String] command string
|
290
|
-
# @api private
|
291
|
-
def busser_setup_env
|
292
|
-
[
|
293
|
-
%{BUSSER_ROOT="#{config[:root_path]}"},
|
294
|
-
%{GEM_HOME="#{config[:root_path]}/gems"},
|
295
|
-
%{GEM_PATH="#{config[:root_path]}/gems"},
|
296
|
-
%{GEM_CACHE="#{config[:root_path]}/gems/cache"},
|
297
|
-
%{\nexport BUSSER_ROOT GEM_HOME GEM_PATH GEM_CACHE}
|
298
|
-
].join(" ")
|
299
|
-
end
|
300
|
-
|
301
|
-
# Returns arguments to a `gem install` command, suitable to install the
|
302
|
-
# Busser gem.
|
303
|
-
#
|
304
|
-
# @return [String] arguments string
|
305
|
-
# @api private
|
306
|
-
def gem_install_args
|
307
|
-
gem, version = config[:version].split("@")
|
308
|
-
gem, version = "busser", gem if gem =~ /^\d+\.\d+\.\d+/
|
309
|
-
|
310
|
-
args = gem
|
311
|
-
args += " --version #{version}" if version
|
312
|
-
args += " --no-rdoc --no-ri"
|
313
|
-
args
|
314
|
-
end
|
315
|
-
end
|
316
|
-
end
|