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,91 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2015, 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_relative "../../spec_helper"
20
+
21
+ require "logger"
22
+ require "stringio"
23
+
24
+ require "kitchen/verifier/dummy"
25
+
26
+ describe Kitchen::Verifier::Dummy do
27
+
28
+ let(:logged_output) { StringIO.new }
29
+ let(:logger) { Logger.new(logged_output) }
30
+ let(:platform) { stub(:os_type => nil, :shell_type => nil) }
31
+ let(:suite) { stub(:name => "fries") }
32
+ let(:state) { Hash.new }
33
+
34
+ let(:config) do
35
+ { :test_base_path => "/basist", :kitchen_root => "/rooty" }
36
+ end
37
+
38
+ let(:instance) do
39
+ stub(
40
+ :name => "coolbeans",
41
+ :to_str => "instance",
42
+ :logger => logger,
43
+ :suite => suite,
44
+ :platform => platform
45
+ )
46
+ end
47
+
48
+ let(:verifier) do
49
+ Kitchen::Verifier::Dummy.new(config).finalize_config!(instance)
50
+ end
51
+
52
+ describe "configuration" do
53
+
54
+ it "sets :sleep to 0 by default" do
55
+ verifier[:sleep].must_equal 0
56
+ end
57
+
58
+ it "sets :random_failure to false by default" do
59
+ verifier[:random_failure].must_equal false
60
+ end
61
+ end
62
+
63
+ describe "#call" do
64
+
65
+ it "calls sleep if :sleep value is greater than 0" do
66
+ config[:sleep] = 12.5
67
+ verifier.expects(:sleep).with(12.5).returns(true)
68
+
69
+ verifier.call(state)
70
+ end
71
+
72
+ it "raises ActionFailed if :fail is set" do
73
+ config[:fail] = true
74
+
75
+ proc { verifier.call(state) }.must_raise Kitchen::ActionFailed
76
+ end
77
+
78
+ it "randomly raises ActionFailed if :random_failure is set" do
79
+ config[:random_failure] = true
80
+ verifier.stubs(:randomly_fail?).returns(true)
81
+
82
+ proc { verifier.call(state) }.must_raise Kitchen::ActionFailed
83
+ end
84
+
85
+ it "logs a converge event to INFO" do
86
+ verifier.call(state)
87
+
88
+ logged_output.string.must_match(/^.+ INFO .+ \[Dummy\] Verify on .+$/)
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,120 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2015, 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_relative "../spec_helper"
20
+
21
+ require "kitchen/verifier"
22
+
23
+ require "kitchen/configurable"
24
+ module Kitchen
25
+ module Verifier
26
+ class Base
27
+ include Configurable
28
+ def initialize(config = {})
29
+ init_config(config)
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ module Kitchen
36
+
37
+ module Verifier
38
+
39
+ class Coolbeans < Kitchen::Verifier::Base
40
+ end
41
+
42
+ class ItDepends < Kitchen::Verifier::Base
43
+
44
+ attr_reader :verify_call_count
45
+
46
+ def initialize(config = {})
47
+ @verify_call_count = 0
48
+ super
49
+ end
50
+
51
+ def verify_dependencies
52
+ @verify_call_count += 1
53
+ end
54
+ end
55
+
56
+ class UnstableDepends < Kitchen::Verifier::Base
57
+
58
+ def verify_dependencies
59
+ raise UserError, "Oh noes, you don't have software!"
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ describe Kitchen::Verifier do
66
+
67
+ describe ".for_plugin" do
68
+
69
+ before do
70
+ Kitchen::Verifier.stubs(:require).returns(true)
71
+ end
72
+
73
+ it "returns a verifier object of the correct class" do
74
+ verifier = Kitchen::Verifier.for_plugin("coolbeans", {})
75
+
76
+ verifier.must_be_kind_of Kitchen::Verifier::Coolbeans
77
+ end
78
+
79
+ it "returns a verifier initialized with its config" do
80
+ verifier = Kitchen::Verifier.for_plugin("coolbeans", :foo => "bar")
81
+
82
+ verifier[:foo].must_equal "bar"
83
+ end
84
+
85
+ it "calls #verify_dependencies on the transport object" do
86
+ verifier = Kitchen::Verifier.for_plugin("it_depends", {})
87
+
88
+ verifier.verify_call_count.must_equal 1
89
+ end
90
+
91
+ it "calls #verify_dependencies once per verifier require" do
92
+ Kitchen::Verifier.stubs(:require).returns(true, false)
93
+ verifier1 = Kitchen::Verifier.for_plugin("it_depends", {})
94
+ verifier1.verify_call_count.must_equal 1
95
+ verifier2 = Kitchen::Verifier.for_plugin("it_depends", {})
96
+
97
+ verifier2.verify_call_count.must_equal 0
98
+ end
99
+
100
+ it "raises ClientError if the verifier could not be required" do
101
+ Kitchen::Verifier.stubs(:require).raises(LoadError)
102
+
103
+ proc { Kitchen::Verifier.for_plugin("coolbeans", {}) }.
104
+ must_raise Kitchen::ClientError
105
+ end
106
+
107
+ it "raises ClientError if the verifier's class constant was not found" do
108
+ # pretend require worked
109
+ Kitchen::Verifier.stubs(:require).returns(true)
110
+
111
+ proc { Kitchen::Verifier.for_plugin("nope", {}) }.
112
+ must_raise Kitchen::ClientError
113
+ end
114
+
115
+ it "raises UserError if #verify_dependencies failes" do
116
+ proc { Kitchen::Verifier.for_plugin("unstable_depends", {}) }.
117
+ must_raise Kitchen::UserError
118
+ end
119
+ end
120
+ end
data/spec/kitchen_spec.rb CHANGED
@@ -97,6 +97,13 @@ describe "Kitchen" do
97
97
  must_match %r{ -- Kitchen: uhoh$}
98
98
  end
99
99
 
100
+ it ".default_file_logger accepts a level and log_overwrite" do
101
+ l = Kitchen.default_file_logger(:error, false)
102
+
103
+ l.level.must_equal 3
104
+ l.log_overwrite.must_equal false
105
+ end
106
+
100
107
  it "sets Kitchen.logger to a Kitchen::Logger" do
101
108
  Kitchen.default_logger.must_be_instance_of Kitchen::Logger
102
109
  end
data/spec/spec_helper.rb CHANGED
@@ -46,3 +46,11 @@ class IO
46
46
  File.open(args[0], "rb") { |f| f.read(args[1]) }
47
47
  end
48
48
  end
49
+
50
+ def with_fake_fs
51
+ FakeFS.activate!
52
+ FileUtils.mkdir_p("/tmp")
53
+ yield
54
+ FakeFS.deactivate!
55
+ FakeFS::FileSystem.clear
56
+ end
@@ -0,0 +1,40 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2014, 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_relative "../spec_helper"
20
+
21
+ # There is some double Base64 encoding going on when a PowerShell script is
22
+ # given to a CMD to invoke. We're in a battle with Windows' CMD max length and
23
+ # that what these specs are trying to ensure. This does lead to some less than
24
+ # ideal "code golfing" to reduce the code payload, but at the end of the day
25
+ # it's easier to see the entire context of the code vs. uploading partial code
26
+ # fragements and calling them on the remote side (not to mention more expensive
27
+ # in terms of PowerShell invocations).
28
+
29
+ describe "PowerShell script max size" do
30
+
31
+ MAX_POWERSHELL_SIZE = 3010
32
+
33
+ Dir.glob(File.join(File.dirname(__FILE__), "../../support/*.ps1*")).each do|script|
34
+ base = File.basename(script)
35
+
36
+ it "support/#{base} size must be less than #{MAX_POWERSHELL_SIZE} bytes" do
37
+ (IO.read(script).size < MAX_POWERSHELL_SIZE).must_equal true
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,14 @@
1
+ if ((& "$ruby" "$gem" list busser -i) -ne "true") {
2
+ Write-Host "-----> Installing Busser ($version)`n"
3
+ & "$ruby" "$gem" install $gem_install_args.Split() 2>&1
4
+ } else {
5
+ Write-Host "-----> Busser installation detected ($version)`n"
6
+ }
7
+
8
+ if (-Not (Test-Path "$busser")) {
9
+ $gem_bindir = & "$ruby" -rrubygems -e "puts Gem.bindir.dup.gsub('/', '\\')"
10
+ & "$ruby" "$gem_bindir\busser" setup --type bat 2>&1
11
+ }
12
+
13
+ Write-Host " Installing Busser plugins: $plugins`n"
14
+ & "$busser" plugin install $plugins.Split() 2>&1
@@ -0,0 +1,15 @@
1
+ $gem list busser -i 2>&1 >/dev/null
2
+ if test $? -ne 0; then
3
+ echo "-----> Installing Busser ($version)"
4
+ $gem install $gem_install_args
5
+ else
6
+ echo "-----> Busser installation detected ($version)"
7
+ fi
8
+
9
+ if test ! -f "$BUSSER_ROOT/bin/busser"; then
10
+ gem_bindir=`$ruby -rrubygems -e "puts Gem.bindir"`
11
+ $gem_bindir/busser setup
12
+ fi
13
+
14
+ echo " Installing Busser plugins: $plugins"
15
+ $busser plugin install $plugins
@@ -0,0 +1,48 @@
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 Check-Files($h) {
18
+ return $h.GetEnumerator() | ForEach-Object {
19
+ $dst = Unresolve-Path $_.Key
20
+ New-Object psobject -Property @{
21
+ chk_exists = ($exists = Test-Path $dst -PathType Leaf)
22
+ src_md5 = ($sMd5 = $_.Value)
23
+ dst_md5 = ($dMd5 = if ($exists) { Get-MD5Sum $dst } else { $null })
24
+ chk_dirty = ($dirty = if ($sMd5 -ne $dMd5) { $true } else { $false })
25
+ verifies = if ($dirty -eq $false) { $true } else { $false }
26
+ }
27
+ } | Select-Object -Property chk_exists,src_md5,dst_md5,chk_dirty,verifies
28
+ }
29
+
30
+ Function Get-MD5Sum($src) {
31
+ Try {
32
+ $c = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
33
+ $bytes = $c.ComputeHash(($in = (Get-Item $src).OpenRead()))
34
+ return ([System.BitConverter]::ToString($bytes)).Replace("-", "").ToLower()
35
+ } Finally { Cleanup $c; Cleanup $in }
36
+ }
37
+
38
+ Function Invoke-Input($in) {
39
+ $in = Unresolve-Path $in
40
+ Decode-Base64File $in ($decoded = "$($in).ps1")
41
+ $expr = Get-Content $decoded | Out-String
42
+ Remove-Item $in,$decoded -Force
43
+ return Invoke-Expression "$expr"
44
+ }
45
+
46
+ Function Unresolve-Path($p) { if ($p -eq $null) { return $null } else { return $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($p) } }
47
+
48
+ Check-Files (Invoke-Input $hash_file) | ConvertTo-Csv -NoTypeInformation
@@ -0,0 +1,18 @@
1
+ Function Delete-AllDirs($dirs) {
2
+ $dirs | ForEach-Object {
3
+ if (Test-Path ($path = Unresolve-Path $_)) { Remove-Item $path -Recurse -Force }
4
+ }
5
+ }
6
+
7
+ Function Unresolve-Path($p) {
8
+ if ($p -eq $null) { return $null }
9
+ else { return $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($p) }
10
+ }
11
+
12
+ Function Make-RootPath($p) {
13
+ $p = Unresolve-Path $p
14
+ if (-Not (Test-Path $p)) { New-Item $p -ItemType directory | Out-Null }
15
+ }
16
+
17
+ Delete-AllDirs $dirs
18
+ Make-RootPath $root_path
@@ -0,0 +1,2 @@
1
+ $sudo_rm -rf $dirs
2
+ mkdir -p $root_path
@@ -0,0 +1,76 @@
1
+ Function Check-UpdateChef($root, $version) {
2
+ if (-Not (Test-Path $root)) { return $true }
3
+ elseif ("$version" -eq "true") { return $false }
4
+ elseif ("$version" -eq "latest") { return $true }
5
+
6
+ Try { $chef_version = (& $root\bin\chef-solo.bat -v).split(" ", 2)[1] }
7
+ Catch { $chef_version = "" }
8
+
9
+ if ($chef_version.StartsWith($version)) { return $false }
10
+ else { return $true }
11
+ }
12
+
13
+ Function Get-ChefMetadata($url) {
14
+ Try { $response = ($c = Make-WebClient).DownloadString($url) }
15
+ Finally { if ($c -ne $null) { $c.Dispose() } }
16
+
17
+ $md = ConvertFrom-StringData $response.Replace("`t", "=")
18
+ return @($md.url, $md.md5)
19
+ }
20
+
21
+ Function Get-MD5Sum($src) {
22
+ Try {
23
+ $c = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
24
+ $bytes = $c.ComputeHash(($in = (Get-Item $src).OpenRead()))
25
+ return ([System.BitConverter]::ToString($bytes)).Replace("-", "").ToLower()
26
+ } Finally { if (($c -ne $null) -and ($c.GetType().GetMethod("Dispose") -ne $null)) { $c.Dispose() }; if ($in -ne $null) { $in.Dispose() } }
27
+ }
28
+
29
+ Function Download-Chef($md_url, $dst) {
30
+ $url, $md5 = Get-ChefMetadata $md_url
31
+
32
+ Try {
33
+ Log "Downloading package from $url"
34
+ ($c = Make-WebClient).DownloadFile($url, $dst)
35
+ Log "Download complete."
36
+ } Finally { if ($c -ne $null) { $c.Dispose() } }
37
+
38
+ if (($dmd5 = Get-MD5Sum $dst) -eq $md5) { Log "Successfully verified $dst" }
39
+ else { throw "MD5 for $dst $dmd5 does not match $md5" }
40
+ }
41
+
42
+ Function Install-Chef($msi) {
43
+ Log "Installing Chef Omnibus package $msi"
44
+ $p = Start-Process -FilePath "msiexec.exe" -ArgumentList "/qn /i $msi" -Passthru -Wait
45
+
46
+ if ($p.ExitCode -ne 0) { throw "msiexec was not successful. Received exit code $($p.ExitCode)" }
47
+
48
+ Remove-Item $msi -Force
49
+ Log "Installation complete"
50
+ }
51
+
52
+ Function Log($m) { Write-Host " $m`n" }
53
+
54
+ Function Make-WebClient {
55
+ $proxy = New-Object -TypeName System.Net.WebProxy
56
+ $proxy.Address = $env:http_proxy
57
+ $client = New-Object -TypeName System.Net.WebClient
58
+ $client.Proxy = $proxy
59
+ return $client
60
+ }
61
+
62
+ Function Unresolve-Path($p) {
63
+ if ($p -eq $null) { return $null }
64
+ else { return $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($p) }
65
+ }
66
+
67
+ $chef_omnibus_root = Unresolve-Path $chef_omnibus_root
68
+ $msi = Unresolve-Path $msi
69
+
70
+ if (Check-UpdateChef $chef_omnibus_root $version) {
71
+ Write-Host "-----> Installing Chef Omnibus ($pretty_version)`n"
72
+ Download-Chef "$chef_metadata_url" $msi
73
+ Install-Chef $msi
74
+ } else {
75
+ Write-Host "-----> Chef Omnibus installation detected ($pretty_version)`n"
76
+ }