summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThom May <thom@may.lt>2018-03-09 11:02:46 +0000
committerGitHub <noreply@github.com>2018-03-09 11:02:46 +0000
commit7208ed1e9713933f2c29b8a7accb83752c77f2de (patch)
tree151797dae1d3d9ca6ebc59dc3e0c741c836af62e
parent27de91563e5311cf17fdb53e7542db553787ec2f (diff)
parente3bbbb4cbe7f8d0a6f15416f4b9bf86e3ea83dbb (diff)
downloadchef-7208ed1e9713933f2c29b8a7accb83752c77f2de.tar.gz
Merge pull request #6941 from chef/sp/powershell_exec
New interop between Chef and PowerShell 4.0 (or higher)
-rw-r--r--.gitattributes1
-rw-r--r--RELEASE_NOTES.md6
-rw-r--r--appveyor.yml1
-rw-r--r--appveyor_registry.reg29
-rw-r--r--distro/powershell/chef/Chef.PowerShell.dllbin0 -> 6144 bytes
-rw-r--r--distro/powershell/chef/Newtonsoft.Json.dllbin0 -> 664576 bytes
-rw-r--r--lib/chef/dsl/universal.rb2
-rw-r--r--lib/chef/mixin/powershell_exec.rb36
-rw-r--r--lib/chef/powershell.rb55
-rw-r--r--omnibus/Gemfile2
-rw-r--r--omnibus/Gemfile.lock2
-rw-r--r--omnibus/resources/chef/msi/source.wxs.erb30
-rw-r--r--spec/unit/mixin/powershell_exec_spec.rb43
13 files changed, 205 insertions, 2 deletions
diff --git a/.gitattributes b/.gitattributes
index bb9914a8b6..3122278bd5 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -4,3 +4,4 @@ distro/common/html/* merge=ignore
distro/common/man/man1/* merge=ignore
distro/common/man/man8/* merge=ignore
lib/chef/version.rb merge=ignore
+*.reg text eol=crlf \ No newline at end of file
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index 71f1909145..15e95c736a 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -2,6 +2,12 @@ _This file holds "in progress" release notes for the current release under devel
# Unreleased
+# Chef Client Release Notes 14.TBC:
+
+## New Windows PowerShell mixin `powershell_exec`
+
+Since our supported Windows platforms can all run .NET Framework 4.0 and PowerShell 4.0 we have taken time to add a new interop that will allow faster and safer interactions with the system PowerShell. You will be able to use the `powershell_exec` mixin in most places where you would have previously used `powershell_out`.
+
# Chef Client Release Notes 13.7:
## The `windows_task` Resource should be better behaved
diff --git a/appveyor.yml b/appveyor.yml
index ddc6009bf8..19b127fa98 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -23,6 +23,7 @@ branches:
install:
- systeminfo
- winrm quickconfig -q
+ - regedit /s c:\projects\chef\appveyor_registry.reg
- SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
- echo %PATH%
- appveyor DownloadFile http://curl.haxx.se/ca/cacert.pem -FileName C:\cacert.pem
diff --git a/appveyor_registry.reg b/appveyor_registry.reg
new file mode 100644
index 0000000000..293e98dd07
--- /dev/null
+++ b/appveyor_registry.reg
@@ -0,0 +1,29 @@
+REGEDIT4
+
+[HKEY_CLASSES_ROOT\Chef.PowerShell]
+@="Chef.PowerShell"
+
+[HKEY_CLASSES_ROOT\Chef.PowerShell\CLSID]
+@="{9008CA83-83E4-41FF-9C07-696E2CC47B52}"
+
+[HKEY_CLASSES_ROOT\CLSID\{9008CA83-83E4-41FF-9C07-696E2CC47B52}]
+@="Chef.PowerShell"
+
+[HKEY_CLASSES_ROOT\CLSID\{9008CA83-83E4-41FF-9C07-696E2CC47B52}\InprocServer32]
+@="c:\\windows\\system32\\mscoree.dll"
+"ThreadingModel"="Both"
+"Class"="Chef.PowerShell"
+"Assembly"="Chef.PowerShell, Version=1.0.14.0, Culture=neutral, PublicKeyToken=7def9f799d039a95"
+"RuntimeVersion"="v4.0.30319"
+"CodeBase"="file:///C:/projects/chef/distro/powershell/chef/Chef.PowerShell.dll"
+
+[HKEY_CLASSES_ROOT\CLSID\{9008CA83-83E4-41FF-9C07-696E2CC47B52}\InprocServer32\1.0.0.0]
+"Class"="Chef.PowerShell"
+"Assembly"="Chef.PowerShell, Version=1.0.14.0, Culture=neutral, PublicKeyToken=7def9f799d039a95"
+"RuntimeVersion"="v4.0.30319"
+"CodeBase"="file:///C:/projects/chef/distro/powershell/chef/Chef.PowerShell.dll"
+
+[HKEY_CLASSES_ROOT\CLSID\{9008CA83-83E4-41FF-9C07-696E2CC47B52}\ProgId]
+@="Chef.PowerShell"
+
+[HKEY_CLASSES_ROOT\CLSID\{9008CA83-83E4-41FF-9C07-696E2CC47B52}\Implemented Categories\{62C8FE65-4EBB-45E7-B440-6E39B2CDBF29}]
diff --git a/distro/powershell/chef/Chef.PowerShell.dll b/distro/powershell/chef/Chef.PowerShell.dll
new file mode 100644
index 0000000000..9aa1c62850
--- /dev/null
+++ b/distro/powershell/chef/Chef.PowerShell.dll
Binary files differ
diff --git a/distro/powershell/chef/Newtonsoft.Json.dll b/distro/powershell/chef/Newtonsoft.Json.dll
new file mode 100644
index 0000000000..1971a35679
--- /dev/null
+++ b/distro/powershell/chef/Newtonsoft.Json.dll
Binary files differ
diff --git a/lib/chef/dsl/universal.rb b/lib/chef/dsl/universal.rb
index 6e3d162b6f..f3b79b1d60 100644
--- a/lib/chef/dsl/universal.rb
+++ b/lib/chef/dsl/universal.rb
@@ -18,6 +18,7 @@
#
require "chef/dsl/platform_introspection"
+require "chef/mixin/powershell_exec"
require "chef/mixin/powershell_out"
require "chef/mixin/shell_out"
@@ -43,6 +44,7 @@ class Chef
#
module Universal
include Chef::DSL::PlatformIntrospection
+ include Chef::Mixin::PowershellExec
include Chef::Mixin::PowershellOut
include Chef::Mixin::ShellOut
end
diff --git a/lib/chef/mixin/powershell_exec.rb b/lib/chef/mixin/powershell_exec.rb
new file mode 100644
index 0000000000..4e276b307d
--- /dev/null
+++ b/lib/chef/mixin/powershell_exec.rb
@@ -0,0 +1,36 @@
+#
+# Author:: Stuart Preston (<stuart@chef.io>)
+# Copyright:: Copyright 2018, Chef Software, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+require "chef/powershell"
+
+class Chef
+ module Mixin
+ module PowershellExec
+ # Run a command under PowerShell via a managed (.NET) COM interop API.
+ # This implementation requires the managed dll to be registered on the
+ # target machine.
+ #
+ # Requires: .NET Framework 4.0 or higher on the target machine.
+ #
+ # @param script [String] script to run
+ # @return [Chef::PowerShell] output
+ def powershell_exec(script)
+ Chef::PowerShell.new(script)
+ end
+ end
+ end
+end
diff --git a/lib/chef/powershell.rb b/lib/chef/powershell.rb
new file mode 100644
index 0000000000..0d3f82590a
--- /dev/null
+++ b/lib/chef/powershell.rb
@@ -0,0 +1,55 @@
+#
+# Author:: Stuart Preston (<stuart@chef.io>)
+# Copyright:: Copyright 2018, Chef Software, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+require "chef/json_compat"
+require "win32ole" if RUBY_PLATFORM =~ /mswin|mingw32|windows/
+
+class Chef
+ class PowerShell
+
+ attr_reader :result
+ attr_reader :errors
+
+ # Run a command under PowerShell via a managed (.NET) COM interop API.
+ # This implementation requires the managed dll to be registered on the
+ # target machine.
+ #
+ # Requires: .NET Framework 4.0 or higher on the target machine.
+ #
+ # @param script [String] script to run
+ # @return [Object] output
+ def initialize(script)
+ raise "Chef::PowerShell can only be used on the Windows platform." unless RUBY_PLATFORM =~ /mswin|mingw32|windows/
+ exec(script)
+ end
+
+ def error?
+ return true if errors.count > 0
+ false
+ end
+
+ private
+
+ def exec(script)
+ ps = WIN32OLE.new("Chef.PowerShell")
+ outcome = ps.ExecuteScript(script)
+ hashed_outcome = Chef::JSONCompat.parse(outcome)
+ @result = Chef::JSONCompat.parse(hashed_outcome["result"])
+ @errors = hashed_outcome["errors"]
+ end
+ end
+end
diff --git a/omnibus/Gemfile b/omnibus/Gemfile
index 0de03a5ea2..5457f0f40b 100644
--- a/omnibus/Gemfile
+++ b/omnibus/Gemfile
@@ -18,7 +18,7 @@ group :development do
# Use Test Kitchen with Vagrant for converging the build environment
gem "test-kitchen", "~> 1.13"
- gem "kitchen-vagrant", "~> 0.19.0"
+ gem "kitchen-vagrant", "~> 1.3.1"
gem "winrm-fs", "~> 1.0"
gem "pry"
gem "pry-byebug"
diff --git a/omnibus/Gemfile.lock b/omnibus/Gemfile.lock
index 1c6856f758..4ca8eb4536 100644
--- a/omnibus/Gemfile.lock
+++ b/omnibus/Gemfile.lock
@@ -258,7 +258,7 @@ PLATFORMS
DEPENDENCIES
berkshelf (~> 4.0)
- kitchen-vagrant (~> 0.19.0)
+ kitchen-vagrant (~> 1.3.1)
ohai (~> 13.0)
omnibus!
omnibus-software!
diff --git a/omnibus/resources/chef/msi/source.wxs.erb b/omnibus/resources/chef/msi/source.wxs.erb
index 2249262b1f..5977e9283b 100644
--- a/omnibus/resources/chef/msi/source.wxs.erb
+++ b/omnibus/resources/chef/msi/source.wxs.erb
@@ -151,6 +151,35 @@
<Environment Id="ChefPSModulePathEnvironment"
Name="PSModulePath" Action="set" Part="last" System="yes" Value="[PSMODULES]" />
</Component>
+ <Component Id="ChefPowerShellRegistryEntries" Guid="{3715B7AB-C3CA-4C69-8FAF-79C8CF58FD89}">
+ <RegistryKey Root="HKCR" Key="Chef.PowerShell">
+ <RegistryValue Type="string" Value="Chef.PowerShell" />
+ </RegistryKey>
+ <RegistryKey Root="HKCR" Key="Chef.PowerShell\CLSID">
+ <RegistryValue Type="string" Value="{9008CA83-83E4-41FF-9C07-696E2CC47B52}" />
+ </RegistryKey>
+ <RegistryKey Root="HKCR" Key="CLSID\{9008CA83-83E4-41FF-9C07-696E2CC47B52}">
+ <RegistryValue Type="string" Value="Chef.PowerShell" />
+ </RegistryKey>
+ <RegistryKey Root="HKCR" Key="CLSID\{9008CA83-83E4-41FF-9C07-696E2CC47B52}\InprocServer32">
+ <RegistryValue Type="string" Value="[System64Folder]mscoree.dll" />
+ <RegistryValue Type="string" Name="ThreadingModel" Value="Both" />
+ <RegistryValue Type="string" Name="Class" Value="Chef.PowerShell" />
+ <RegistryValue Type="string" Name="Assembly" Value="Chef.PowerShell, Version=1.0.14.0, Culture=neutral, PublicKeyToken=7def9f799d039a95" />
+ <RegistryValue Type="string" Name="RuntimeVersion" Value="v4.0.30319" />
+ <RegistryValue Type="string" Name="CodeBase" Value="[PSMODULES]chef\Chef.PowerShell.dll" />
+ </RegistryKey>
+ <RegistryKey Root="HKCR" Key="CLSID\{9008CA83-83E4-41FF-9C07-696E2CC47B52}\InprocServer32\1.0.0.0">
+ <RegistryValue Type="string" Name="Class" Value="Chef.PowerShell" />
+ <RegistryValue Type="string" Name="Assembly" Value="Chef.PowerShell, Version=1.0.14.0, Culture=neutral, PublicKeyToken=7def9f799d039a95" />
+ <RegistryValue Type="string" Name="RuntimeVersion" Value="v4.0.30319" />
+ <RegistryValue Type="string" Name="CodeBase" Value="[PSMODULES]chef\Chef.PowerShell.dll" />
+ </RegistryKey>
+ <RegistryKey Root="HKCR" Key="CLSID\{9008CA83-83E4-41FF-9C07-696E2CC47B52}\ProgId">
+ <RegistryValue Type="string" Value="Chef.PowerShell" />
+ </RegistryKey>
+ <RegistryKey Root="HKCR" Key="CLSID\{9008CA83-83E4-41FF-9C07-696E2CC47B52}\Implemented Categories\{62C8FE65-4EBB-45E7-B440-6E39B2CDBF29}" />
+ </Component>
</Directory>
<Directory Id="EMBEDDED" Name="embedded" >
<Directory Id="EMBEDDEDBIN" Name="bin" >
@@ -197,6 +226,7 @@
<ComponentRef Id="ChefClientPath" />
<ComponentRef Id="CONFIGLOCATIONDIR" />
<ComponentRef Id="ChefClientLog" />
+ <ComponentRef Id="ChefPowerShellRegistryEntries" />
</Feature>
<Feature Id="ChefPSModuleFeature" Title="!(loc.FeaturePSModuleName)" Level="1000" AllowAdvertise="no">
diff --git a/spec/unit/mixin/powershell_exec_spec.rb b/spec/unit/mixin/powershell_exec_spec.rb
new file mode 100644
index 0000000000..72619bdc8a
--- /dev/null
+++ b/spec/unit/mixin/powershell_exec_spec.rb
@@ -0,0 +1,43 @@
+#
+# Author:: Stuart Preston (<stuart@chef.io>)
+# Copyright:: Copyright 2018, Chef Software, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require "spec_helper"
+require "chef/mixin/powershell_exec"
+
+describe Chef::Mixin::PowershellExec, :windows_only do
+ let(:powershell_mixin) { Class.new { include Chef::Mixin::PowershellExec } }
+ subject(:object) { powershell_mixin.new }
+
+ describe "#powershell_exec" do
+ it "runs a basic command and returns a Chef::PowerShell object" do
+ expect(object.powershell_exec("$PSVersionTable")).to be_kind_of(Chef::PowerShell)
+ end
+
+ it "runs a command that fails with a non-terminating error and can trap the error via .error?" do
+ execution = object.powershell_exec("this-should-error")
+ expect(execution.error?).to eql(true)
+ end
+
+ it "runs a command that fails with a non-terminating error and can list the errors" do
+ execution = object.powershell_exec("this-should-error")
+ expect(execution.errors).to be_a_kind_of(Array)
+ expect(execution.errors[0]).to be_a_kind_of(String)
+ expect(execution.errors[0]).to include("CommandNotFoundException")
+ end
+ end
+end