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.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/.cane +2 -0
  3. data/.gitignore +4 -0
  4. data/CHANGELOG.md +45 -0
  5. data/Rakefile +15 -0
  6. data/features/kitchen_action_commands.feature +12 -9
  7. data/features/kitchen_defaults.feature +38 -0
  8. data/features/kitchen_init_command.feature +0 -1
  9. data/features/kitchen_list_command.feature +2 -2
  10. data/features/kitchen_login_command.feature +7 -1
  11. data/features/kitchen_test_command.feature +4 -4
  12. data/lib/kitchen.rb +40 -11
  13. data/lib/kitchen/cli.rb +38 -22
  14. data/lib/kitchen/command/list.rb +5 -2
  15. data/lib/kitchen/config.rb +45 -18
  16. data/lib/kitchen/configurable.rb +137 -1
  17. data/lib/kitchen/data_munger.rb +248 -17
  18. data/lib/kitchen/driver.rb +1 -1
  19. data/lib/kitchen/driver/base.rb +1 -83
  20. data/lib/kitchen/driver/dummy.rb +0 -5
  21. data/lib/kitchen/driver/ssh_base.rb +177 -22
  22. data/lib/kitchen/instance.rb +140 -20
  23. data/lib/kitchen/logger.rb +43 -8
  24. data/lib/kitchen/login_command.rb +14 -5
  25. data/lib/kitchen/platform.rb +19 -0
  26. data/lib/kitchen/provisioner.rb +5 -3
  27. data/lib/kitchen/provisioner/base.rb +46 -48
  28. data/lib/kitchen/provisioner/chef/common_sandbox.rb +322 -0
  29. data/lib/kitchen/provisioner/chef_base.rb +179 -286
  30. data/lib/kitchen/provisioner/chef_solo.rb +11 -5
  31. data/lib/kitchen/provisioner/chef_zero.rb +108 -94
  32. data/lib/kitchen/provisioner/dummy.rb +47 -0
  33. data/lib/kitchen/provisioner/shell.rb +45 -12
  34. data/lib/kitchen/rake_tasks.rb +1 -1
  35. data/lib/kitchen/ssh.rb +1 -1
  36. data/lib/kitchen/thor_tasks.rb +1 -1
  37. data/lib/kitchen/transport.rb +54 -0
  38. data/lib/kitchen/transport/base.rb +146 -0
  39. data/lib/kitchen/transport/dummy.rb +75 -0
  40. data/lib/kitchen/transport/ssh.rb +325 -0
  41. data/lib/kitchen/transport/winrm.rb +508 -0
  42. data/lib/kitchen/transport/winrm/command_executor.rb +188 -0
  43. data/lib/kitchen/transport/winrm/file_transporter.rb +454 -0
  44. data/lib/kitchen/transport/winrm/logging.rb +50 -0
  45. data/lib/kitchen/transport/winrm/template.rb +74 -0
  46. data/lib/kitchen/transport/winrm/tmp_zip.rb +187 -0
  47. data/lib/kitchen/verifier.rb +55 -0
  48. data/lib/kitchen/verifier/base.rb +191 -0
  49. data/lib/kitchen/verifier/busser.rb +266 -0
  50. data/lib/kitchen/verifier/dummy.rb +75 -0
  51. data/lib/kitchen/version.rb +1 -1
  52. data/spec/kitchen/cli_spec.rb +56 -0
  53. data/spec/kitchen/config_spec.rb +61 -20
  54. data/spec/kitchen/configurable_spec.rb +327 -1
  55. data/spec/kitchen/data_munger_spec.rb +777 -14
  56. data/spec/kitchen/driver/base_spec.rb +7 -38
  57. data/spec/kitchen/driver/dummy_spec.rb +0 -29
  58. data/spec/kitchen/driver/ssh_base_spec.rb +580 -236
  59. data/spec/kitchen/driver_spec.rb +1 -0
  60. data/spec/kitchen/instance_spec.rb +383 -83
  61. data/spec/kitchen/login_command_spec.rb +29 -10
  62. data/spec/kitchen/platform_spec.rb +58 -2
  63. data/spec/kitchen/provisioner/base_spec.rb +170 -18
  64. data/spec/kitchen/provisioner/chef_base_spec.rb +454 -104
  65. data/spec/kitchen/provisioner/chef_solo_spec.rb +307 -104
  66. data/spec/kitchen/provisioner/chef_zero_spec.rb +561 -230
  67. data/spec/kitchen/provisioner/dummy_spec.rb +91 -0
  68. data/spec/kitchen/provisioner/shell_spec.rb +158 -56
  69. data/spec/kitchen/provisioner_spec.rb +37 -0
  70. data/spec/kitchen/ssh_spec.rb +19 -19
  71. data/spec/kitchen/transport/base_spec.rb +89 -0
  72. data/spec/kitchen/transport/ssh_spec.rb +1147 -0
  73. data/spec/kitchen/transport/winrm/command_executor_spec.rb +400 -0
  74. data/spec/kitchen/transport/winrm/file_transporter_spec.rb +876 -0
  75. data/spec/kitchen/transport/winrm/logging_spec.rb +92 -0
  76. data/spec/kitchen/transport/winrm/template_spec.rb +51 -0
  77. data/spec/kitchen/transport/winrm/tmp_zip_spec.rb +132 -0
  78. data/spec/kitchen/transport/winrm_spec.rb +1069 -0
  79. data/spec/kitchen/transport_spec.rb +112 -0
  80. data/spec/kitchen/verifier/base_spec.rb +310 -0
  81. data/spec/kitchen/verifier/busser_spec.rb +540 -0
  82. data/spec/kitchen/verifier/dummy_spec.rb +91 -0
  83. data/spec/kitchen/verifier_spec.rb +120 -0
  84. data/spec/kitchen_spec.rb +7 -0
  85. data/spec/spec_helper.rb +8 -0
  86. data/spec/support/powershell_max_size_spec.rb +40 -0
  87. data/support/busser_install_command.ps1 +14 -0
  88. data/support/busser_install_command.sh +15 -0
  89. data/support/check_files.ps1.erb +48 -0
  90. data/support/chef_base_init_command.ps1 +18 -0
  91. data/support/chef_base_init_command.sh +2 -0
  92. data/support/chef_base_install_command.ps1 +76 -0
  93. data/support/chef_base_install_command.sh +137 -0
  94. data/support/chef_zero_prepare_command_legacy.ps1 +9 -0
  95. data/support/chef_zero_prepare_command_legacy.sh +10 -0
  96. data/support/decode_files.ps1.erb +61 -0
  97. data/test-kitchen.gemspec +2 -0
  98. metadata +97 -8
  99. data/lib/kitchen/busser.rb +0 -316
  100. data/spec/kitchen/busser_spec.rb +0 -490
  101. 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.3.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-01-16 00:00:00.000000000 Z
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/busser_spec.rb
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/chef_helpers.sh
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: '0'
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/busser_spec.rb
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:
@@ -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