diff options
173 files changed, 2449 insertions, 1712 deletions
diff --git a/.travis.yml b/.travis.yml index 36fd343809..84d8c71543 100644 --- a/.travis.yml +++ b/.travis.yml @@ -132,7 +132,7 @@ matrix: - cat .kitchen/logs/kitchen.log env: - AMAZON=2 - - KITCHEN_YAML=.kitchen.travis.yml + - KITCHEN_YAML=kitchen.travis.yml - rvm: 2.4.4 services: docker sudo: required @@ -149,7 +149,7 @@ matrix: - cat .kitchen/logs/kitchen.log env: - AMAZON=201X - - KITCHEN_YAML=.kitchen.travis.yml + - KITCHEN_YAML=kitchen.travis.yml - rvm: 2.4.4 services: docker sudo: required @@ -166,7 +166,7 @@ matrix: - cat .kitchen/logs/kitchen.log env: - UBUNTU=14.04 - - KITCHEN_YAML=.kitchen.travis.yml + - KITCHEN_YAML=kitchen.travis.yml - rvm: 2.4.4 services: docker sudo: required @@ -183,7 +183,7 @@ matrix: - cat .kitchen/logs/kitchen.log env: - UBUNTU=16.04 - - KITCHEN_YAML=.kitchen.travis.yml + - KITCHEN_YAML=kitchen.travis.yml - rvm: 2.4.4 services: docker sudo: required @@ -200,7 +200,7 @@ matrix: - cat .kitchen/logs/kitchen.log env: - UBUNTU=18.04 - - KITCHEN_YAML=.kitchen.travis.yml + - KITCHEN_YAML=kitchen.travis.yml - rvm: 2.4.4 services: docker sudo: required @@ -217,7 +217,7 @@ matrix: - cat .kitchen/logs/kitchen.log env: - DEBIAN=8 - - KITCHEN_YAML=.kitchen.travis.yml + - KITCHEN_YAML=kitchen.travis.yml - rvm: 2.4.4 services: docker sudo: required @@ -234,7 +234,7 @@ matrix: - cat .kitchen/logs/kitchen.log env: - DEBIAN=9 - - KITCHEN_YAML=.kitchen.travis.yml + - KITCHEN_YAML=kitchen.travis.yml - rvm: 2.4.4 services: docker sudo: required @@ -251,7 +251,7 @@ matrix: - cat .kitchen/logs/kitchen.log env: - CENTOS=6 - - KITCHEN_YAML=.kitchen.travis.yml + - KITCHEN_YAML=kitchen.travis.yml - rvm: 2.4.4 services: docker sudo: required @@ -268,7 +268,7 @@ matrix: - cat .kitchen/logs/kitchen.log env: - CENTOS=7 - - KITCHEN_YAML=.kitchen.travis.yml + - KITCHEN_YAML=kitchen.travis.yml - rvm: 2.4.4 services: docker sudo: required @@ -285,7 +285,7 @@ matrix: - cat .kitchen/logs/kitchen.log env: - FEDORA=latest - - KITCHEN_YAML=.kitchen.travis.yml + - KITCHEN_YAML=kitchen.travis.yml - rvm: 2.4.4 services: docker sudo: required @@ -302,42 +302,7 @@ matrix: - cat .kitchen/logs/kitchen.log env: - OPENSUSELEAP=42 - - KITCHEN_YAML=.kitchen.travis.yml -# - rvm: 2.4.4 -# services: docker -# sudo: required -# gemfile: kitchen-tests/Gemfile -# before_install: -# - gem update --system $(grep rubygems omnibus_overrides.rb | cut -d'"' -f2) -# - gem install bundler -v $(grep :bundler omnibus_overrides.rb | cut -d'"' -f2) -# before_script: -# - sudo iptables -L DOCKER || ( echo "DOCKER iptables chain missing" ; sudo iptables -N DOCKER ) -# - cd kitchen-tests -# script: -# - bundle exec kitchen test awesome-customers-ubuntu-ubuntu-1404 -# after_failure: -# - cat .kitchen/logs/kitchen.log -# env: -# - AWESOME_CUSTOMERS_UBUNTU=1 -# - KITCHEN_YAML=.kitchen.travis.yml -# - rvm: 2.4.4 -# services: docker -# sudo: required -# gemfile: kitchen-tests/Gemfile -# before_install: -# - gem update --system $(grep rubygems omnibus_overrides.rb | cut -d'"' -f2) -# - gem install bundler -v $(grep :bundler omnibus_overrides.rb | cut -d'"' -f2) -# before_script: -# - sudo iptables -L DOCKER || ( echo "DOCKER iptables chain missing" ; sudo iptables -N DOCKER ) -# - cd kitchen-tests -# script: -# - bundle exec kitchen test awesome-customers-rhel-centos-7 -# after_failure: -# - cat .kitchen/logs/kitchen.log -# env: -# - AWESOME_CUSTOMERS_RHEL=1 -# - KITCHEN_YAML=.kitchen.travis.yml -# ### END TEST KITCHEN ONLY ### + - KITCHEN_YAML=kitchen.travis.yml - rvm: 2.5.1 sudo: required before_install: diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f377e8957..a8e991af61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,15 +1,39 @@ <!-- usage documentation: http://expeditor-docs.es.chef.io/configuration/changelog/ --> -<!-- latest_release 14.2.2 --> -## [v14.2.2](https://github.com/chef/chef/tree/v14.2.2) (2018-06-07) +<!-- latest_release 14.3.18 --> +## [v14.3.18](https://github.com/chef/chef/tree/v14.3.18) (2018-06-19) #### Merged Pull Requests -- Expand development docs with branch/backport + more [#7343](https://github.com/chef/chef/pull/7343) ([tas50](https://github.com/tas50)) +- Unification of shell_out APIs [#7372](https://github.com/chef/chef/pull/7372) ([lamont-granquist](https://github.com/lamont-granquist)) +- Remove the unused audit test cookbook [#7378](https://github.com/chef/chef/pull/7378) ([tas50](https://github.com/tas50)) <!-- latest_release --> <!-- release_rollup since=14.2.0 --> ### Changes since 14.2.0 release #### Merged Pull Requests +- Unification of shell_out APIs [#7372](https://github.com/chef/chef/pull/7372) ([lamont-granquist](https://github.com/lamont-granquist)) <!-- 14.3.18 --> +- Remove the unused audit test cookbook [#7378](https://github.com/chef/chef/pull/7378) ([tas50](https://github.com/tas50)) <!-- 14.3.17 --> +- Silence deprecation warnings [#7375](https://github.com/chef/chef/pull/7375) ([coderanger](https://github.com/coderanger)) <!-- 14.3.17 --> +- Remove awesome customers testing and update kitchen configs [#7377](https://github.com/chef/chef/pull/7377) ([tas50](https://github.com/tas50)) <!-- 14.3.16 --> +- windows_task: Fix for task is not idempotent when task name includes parent folder [#7293](https://github.com/chef/chef/pull/7293) ([Vasu1105](https://github.com/Vasu1105)) <!-- 14.3.16 --> +- windows_task: Don't allow bad username/password to be provided to a task which will fail later [#7288](https://github.com/chef/chef/pull/7288) ([Vasu1105](https://github.com/Vasu1105)) <!-- 14.3.15 --> +- Pull in win32-taskscheduler 1.0.2 [#7371](https://github.com/chef/chef/pull/7371) ([tas50](https://github.com/tas50)) <!-- 14.3.14 --> +- removing mwrock from client maintainers [#7369](https://github.com/chef/chef/pull/7369) ([mwrock](https://github.com/mwrock)) <!-- 14.3.13 --> +- Add more property descriptions to resources [#7358](https://github.com/chef/chef/pull/7358) ([tas50](https://github.com/tas50)) <!-- 14.3.12 --> +- windows_feature_dism: Fix errors when specifying the source [#7370](https://github.com/chef/chef/pull/7370) ([tas50](https://github.com/tas50)) <!-- 14.3.11 --> +- package: Make sure to use the package_name name properties [#7365](https://github.com/chef/chef/pull/7365) ([tas50](https://github.com/tas50)) <!-- 14.3.10 --> +- Add missing chef/resource requires in resource [#7364](https://github.com/chef/chef/pull/7364) ([tas50](https://github.com/tas50)) <!-- 14.3.9 --> +- Update to the latest inspec and liblzma [#7355](https://github.com/chef/chef/pull/7355) ([tas50](https://github.com/tas50)) <!-- 14.3.8 --> +- Mount: Fix errors on Windows when using the mount_point property [#7284](https://github.com/chef/chef/pull/7284) ([dheerajd-msys](https://github.com/dheerajd-msys)) <!-- 14.3.7 --> +- Add kernel_module resource from the kernel_module cookbook [#7165](https://github.com/chef/chef/pull/7165) ([tas50](https://github.com/tas50)) <!-- 14.3.6 --> +- Add ssh_known_hosts_entry resource from ssh_known_hosts cookbook [#7161](https://github.com/chef/chef/pull/7161) ([tas50](https://github.com/tas50)) <!-- 14.3.5 --> +- Update help link in Add/Remove Programs on Windows [#7345](https://github.com/chef/chef/pull/7345) ([stuartpreston](https://github.com/stuartpreston)) <!-- 14.3.4 --> +- Implement rfc107: NodeMap locking for resource and provider handlers [#7224](https://github.com/chef/chef/pull/7224) ([coderanger](https://github.com/coderanger)) <!-- 14.3.4 --> +- Add whyrun message when installing a local file on Windows [#7351](https://github.com/chef/chef/pull/7351) ([josh-barker](https://github.com/josh-barker)) <!-- 14.3.3 --> +- Make shell_out_compact automatically pull timeouts off the resource + remove uses of shell_out_compact_timeout [#7330](https://github.com/chef/chef/pull/7330) ([lamont-granquist](https://github.com/lamont-granquist)) <!-- 14.3.2 --> +- Deprecated the Chef::Provider::Package::Freebsd::Pkg provider [#7350](https://github.com/chef/chef/pull/7350) ([tas50](https://github.com/tas50)) <!-- 14.3.1 --> +- Bump the version to 14.3.0 [#7346](https://github.com/chef/chef/pull/7346) ([tas50](https://github.com/tas50)) <!-- 14.3.0 --> +- Support windows_feature_powershell on Windows 2008 R2 [#7349](https://github.com/chef/chef/pull/7349) ([tas50](https://github.com/tas50)) <!-- 14.2.3 --> - Add skip_publisher_check property to powershell_package [#7259](https://github.com/chef/chef/pull/7259) ([Happycoil](https://github.com/Happycoil)) <!-- 14.2.1 --> - Expand development docs with branch/backport + more [#7343](https://github.com/chef/chef/pull/7343) ([tas50](https://github.com/tas50)) <!-- 14.2.2 --> <!-- release_rollup --> diff --git a/Gemfile.lock b/Gemfile.lock index 35c5e1ce65..12a8de2e2a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -9,10 +9,10 @@ GIT PATH remote: . specs: - chef (14.2.2) + chef (14.3.18) addressable bundler (>= 1.10) - chef-config (= 14.2.2) + chef-config (= 14.3.18) chef-zero (>= 13.0) diff-lcs (~> 1.2, >= 1.2.4) erubis (~> 2.7) @@ -40,10 +40,10 @@ PATH specinfra (~> 2.10) syslog-logger (~> 1.6) uuidtools (~> 2.1.5) - chef (14.2.2-universal-mingw32) + chef (14.3.18-universal-mingw32) addressable bundler (>= 1.10) - chef-config (= 14.2.2) + chef-config (= 14.3.18) chef-zero (>= 13.0) diff-lcs (~> 1.2, >= 1.2.4) erubis (~> 2.7) @@ -79,14 +79,14 @@ PATH win32-mutex (~> 0.4.2) win32-process (~> 0.8.2) win32-service (~> 0.8.7) - win32-taskscheduler (~> 0.4.0) + win32-taskscheduler (~> 1.0.0) windows-api (~> 0.4.4) wmi-lite (~> 1.0) PATH remote: chef-config specs: - chef-config (14.2.2) + chef-config (14.3.18) addressable fuzzyurl mixlib-config (~> 2.0) @@ -149,7 +149,7 @@ GEM highline (1.7.10) htmlentities (4.3.4) iniparse (1.4.4) - inspec-core (2.1.84) + inspec-core (2.2.10) addressable (~> 2.4) faraday (>= 0.9.0) hashie (~> 3.4) @@ -175,11 +175,11 @@ GEM addressable (~> 2.3) libyajl2 (1.2.0) method_source (0.9.0) - mixlib-archive (0.4.6) + mixlib-archive (0.4.7) mixlib-log - mixlib-authentication (2.1.0) + mixlib-authentication (2.1.1) mixlib-cli (1.7.0) - mixlib-config (2.2.6) + mixlib-config (2.2.8) tomlrb mixlib-log (2.0.4) mixlib-shellout (2.3.2) @@ -221,7 +221,7 @@ GEM ast (~> 2.4.0) parslet (1.8.2) plist (3.4.0) - powerpack (0.1.1) + powerpack (0.1.2) proxifier (1.0.3) pry (0.11.3) coderay (~> 1.1.0) @@ -299,7 +299,7 @@ GEM syslog-logger (1.6.8) systemu (2.6.5) thor (0.20.0) - tomlrb (1.2.6) + tomlrb (1.2.7) train-core (1.4.11) json (>= 1.8, < 3.0) mixlib-shellout (~> 2.0) @@ -314,7 +314,7 @@ GEM typhoeus (~> 0.6, >= 0.6.8) typhoeus (0.8.0) ethon (>= 0.8.0) - unicode-display_width (1.3.3) + unicode-display_width (1.4.0) uuidtools (2.1.5) webmock (3.4.2) addressable (>= 2.3.6) @@ -339,7 +339,7 @@ GEM win32-service (0.8.10) ffi ffi-win32-extensions - win32-taskscheduler (0.4.1) + win32-taskscheduler (1.0.2) ffi structured_warnings windows-api (0.4.4) @@ -377,4 +377,4 @@ DEPENDENCIES yard BUNDLED WITH - 1.16.1 + 1.16.2 diff --git a/MAINTAINERS.md b/MAINTAINERS.md index 536d9b6629..d0acb37daf 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -40,7 +40,6 @@ To mention the team, use @chef/client-core * [Joshua Timberman](https://github.com/jtimberman) * [Lamont Granquist](https://github.com/lamont-granquist) * [Claire McQuin](https://github.com/mcquin) -* [Matt Wrock](https://github.com/mwrock) * [Ranjib Dey](https://github.com/ranjib) * [Steven Murawski](https://github.com/smurawski) * [Steven Danna](https://github.com/stevendanna) diff --git a/MAINTAINERS.toml b/MAINTAINERS.toml index ce4f514d89..1d0888eb6e 100644 --- a/MAINTAINERS.toml +++ b/MAINTAINERS.toml @@ -46,7 +46,6 @@ Maintainers for the Chef client, Ohai, mixlibs, ChefDK, ChefSpec, Foodcritic, ch "jtimberman", "lamont-granquist", "mcquin", - "mwrock", "ranjib", "smurawski", "stevendanna", diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index d9747c80df..85181821c6 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,54 @@ This file holds "in progress" release notes for the current release under development and is intended for consumption by the Chef Documentation team. Please see <https://docs.chef.io/release_notes.html> for the official Chef release notes. +## Silencing deprecation warnings + +While deprecation warnings have been great for the Chef community to ensure +cookbooks are kept up-to-date and to prepare for major version upgrades, sometimes +you just can't fix a deprecation right now. This is often compounded by the +recommendation to enable `treat_deprecation_warnings_as_errors` mode in your +Test Kitchen integration tests, which doesn't understand the difference between +deprecations from community cookbooks and those from your own code. + +Two new options are provided for silencing deprecation warnings: `silence_deprecation_warnings` +and inline `chef:silence_deprecation` comments. + +The `silence_deprecation_warnings` configuration value can be set in your +`client.rb` or `solo.rb` config file, either to `true` to silence all deprecation +warnings or to an array of deprecations to silence. You can specify which to +silence either by the deprecation key name (e.g. `"internal_api"`), the numeric +deprecation ID (e.g. `25` or `"CHEF-25"`), or by specifying the filename and +line number where the deprecation is being raised from (e.g. `"default.rb:67"`). + +An example of setting the `silence_deprecation_warnings` option in your `client.rb` +or `solo.rb`: + +```ruby +silence_deprecation_warnings %w{deploy_resource chef-23 recipes/install.rb:22} +``` + +or in your `kitchen.yml`: + +```yaml +provisioner: + name: chef_solo + solo_rb: + treat_deprecation_warnings_as_errors: true + silence_deprecation_warnings: + - deploy_resource + - chef-23 + - recipes/install.rb:22 +``` + +You can also silence deprecations using a comment on the line that is raising +the warning: + +```ruby +erl_call 'something' do # chef:silence_deprecation +``` + +We advise caution in the use of this feature, as excessive or prolonged silencing +can lead to difficulty upgrading when the next major release of Chef comes out. + # Chef Client Release Notes 14.2: ## `ssh-agent` support for user keys @@ -1 +1 @@ -14.2.2
\ No newline at end of file +14.3.18
\ No newline at end of file diff --git a/acceptance/data-collector/.acceptance/data-collector-test/.gitignore b/acceptance/data-collector/.acceptance/data-collector-test/.gitignore index ec2a890bd3..f0c21602ee 100644 --- a/acceptance/data-collector/.acceptance/data-collector-test/.gitignore +++ b/acceptance/data-collector/.acceptance/data-collector-test/.gitignore @@ -13,4 +13,4 @@ bin/* .bundle/* .kitchen/ -.kitchen.local.yml +kitchen.local.yml diff --git a/chef-config/lib/chef-config/config.rb b/chef-config/lib/chef-config/config.rb index 82f25f4139..ed8fab9ee4 100644 --- a/chef-config/lib/chef-config/config.rb +++ b/chef-config/lib/chef-config/config.rb @@ -715,6 +715,11 @@ module ChefConfig ENV.key?("CHEF_TREAT_DEPRECATION_WARNINGS_AS_ERRORS") end + # Which deprecations warnings to silence. Can be set to `true` to silence + # all warnings, or an array of strings like either `"deprecation_type"` or + # `"filename.rb:lineno"`. + default :silence_deprecation_warnings, [] + # Whether the resource count should be updated for log resource # on running chef-client default :count_log_resource_updates, true diff --git a/chef-config/lib/chef-config/version.rb b/chef-config/lib/chef-config/version.rb index a9cae3a2da..7f6f6f1347 100644 --- a/chef-config/lib/chef-config/version.rb +++ b/chef-config/lib/chef-config/version.rb @@ -21,7 +21,7 @@ module ChefConfig CHEFCONFIG_ROOT = File.expand_path("../..", __FILE__) - VERSION = "14.2.2" + VERSION = "14.3.18" end # diff --git a/chef-universal-mingw32.gemspec b/chef-universal-mingw32.gemspec index a4949db712..05877d19b3 100644 --- a/chef-universal-mingw32.gemspec +++ b/chef-universal-mingw32.gemspec @@ -14,7 +14,7 @@ gemspec.add_dependency "win32-process", "~> 0.8.2" gemspec.add_dependency "win32-service", "~> 0.8.7" gemspec.add_dependency "windows-api", "~> 0.4.4" gemspec.add_dependency "wmi-lite", "~> 1.0" -gemspec.add_dependency "win32-taskscheduler", "~> 0.4.0" +gemspec.add_dependency "win32-taskscheduler", "~> 1.0.0" gemspec.extensions << "ext/win32-eventlog/Rakefile" gemspec.files += %w{ext/win32-eventlog/Rakefile ext/win32-eventlog/chef-log.man} diff --git a/kitchen-tests/Berksfile b/kitchen-tests/Berksfile index 22f838d83e..ea45042a2e 100644 --- a/kitchen-tests/Berksfile +++ b/kitchen-tests/Berksfile @@ -1,9 +1,3 @@ source "https://supermarket.chef.io" cookbook "base", path: "cookbooks/base" - -# Disabled pending updating these test cases for Chef 13. -# cookbook "awesome_customers_ubuntu_wrapper", path: "cookbooks/awesome_customers_ubuntu_wrapper" -# cookbook "awesome_customers_ubuntu", github: "lamont-granquist/awesome_customers_ubuntu", branch: "lcg/bump-mysql-version" -# cookbook "awesome_customers_rhel_wrapper", path: "cookbooks/awesome_customers_rhel_wrapper" -# cookbook "awesome_customers_rhel", github: "lamont-granquist/awesome_customers_rhel", branch: "lcg/bump-mysql-version" diff --git a/kitchen-tests/Gemfile b/kitchen-tests/Gemfile index 9cc63fb7d6..3505c5f32e 100644 --- a/kitchen-tests/Gemfile +++ b/kitchen-tests/Gemfile @@ -2,8 +2,7 @@ source "https://rubygems.org" gem "rake" # required to build some native extensions gem "chef", path: ".." -# remove this ohai pin once we ship the 14 gem -gem "ohai", git: "https://github.com/chef/ohai.git", branch: "master" +gem "ohai", git: "https://github.com/chef/ohai.git", branch: "master" # avoids failures when we bump chef major gem "berkshelf", git: "https://github.com/berkshelf/berkshelf.git", branch: "master" gem "kitchen-appbundle-updater", git: "https://github.com/chef/kitchen-appbundle-updater", branch: "master" gem "kitchen-dokken", "< 2.0" # 2.x fails atm: https://travis-ci.org/chef/chef/jobs/199125787 diff --git a/kitchen-tests/README.md b/kitchen-tests/README.md index 2d03b19b62..8dcf9702a5 100644 --- a/kitchen-tests/README.md +++ b/kitchen-tests/README.md @@ -1,18 +1,16 @@ # End-To-End Testing for Chef Client -Here we seek to provide end-to-end testing of Chef Client through cookbooks which -exercise many of the available resources, providers, and common patterns. The cookbooks -here are designed to ensure certain capabilities remain functional with updates -to the client code base. + +Here we seek to provide end-to-end testing of Chef Client through cookbooks which exercise many of the available resources, providers, and common patterns. The cookbooks here are designed to ensure certain capabilities remain functional with updates to the client code base. ## Getting started + All the gems needed to run these tests can be installed with Bundler. ```shell chef/kitchen-tests$ bundle install ``` -To ensure everything is working properly, and to see which platforms can have tests -executed on them, run +To ensure everything is working properly, and to see which platforms can have tests executed on them, run ```shell chef/kitchen-tests$ bundle exec kitchen list @@ -21,69 +19,55 @@ chef/kitchen-tests$ bundle exec kitchen list You should see output similar to ```shell -Instance Driver Provisioner Last Action -webapp-ubuntu-1204 Vagrant ChefSolo <Not Created> +Instance Driver Provisioner Verifier Transport Last Action Last Error +base-amazonlinux Vagrant ChefGithub Inspec Ssh <Not Created> <None> ``` ## Testing -We use Test Kitchen to build instances, test client code, and destroy instances. If -you are unfamiliar with Test Kitchen we recommend checking out the [tutorial](http://kitchen.ci/) -along with the `kitchen-vagrant` [driver documentation](https://github.com/test-kitchen/kitchen-vagrant). -Test Kitchen is configured to manipulate instances using [Vagrant](http://www.vagrantup.com/) -when testing locally, and [Amazon EC2](http://aws.amazon.com/ec2/) when testing -pull requests on [Travis CI](https://travis-ci.com). + +We use Test Kitchen to build instances, test client code, and destroy instances. If you are unfamiliar with Test Kitchen we recommend checking out the [tutorial](http://kitchen.ci/) along with the `kitchen-vagrant` [driver documentation](https://github.com/test-kitchen/kitchen-vagrant). Test Kitchen is configured to manipulate instances using [Vagrant](https://www.vagrantup.com/) when testing locally, and Docker via [kitchen-dokken](https://github.com/someara/kitchen-dokken/) when testing pull requests on [Travis CI](https://travis-ci.com/). ### Commands -Kitchen instances are led through a series of states. The instance states, and the actions -taken to transition into each state, are in order: -* `destroy`: Delete all information for and terminate one or more instances. - * This is equivalent to running `vagrant destroy` to stop and delete a Vagrant machine. -* `create`: Start one or more instances. - * This is equivalent to running `vagrant up --no-provision` to start a Vagrant instance. -* `converge`: Use a provisioner to configure one or more instances. - * By default, Test Kitchen is configured to use the `ChefSolo` provisioner which: - * Prepares local files for transfer, - * Installs the latest release of Chef Omnibus, - * Downloads Chef Client source code from the prescribed GitHub repository and reference, - * Builds and installs a `chef` gem from the downloaded source, - * Runs `chef-client`. -* `setup`: Prepare to run automated tests. Installs `busser` and related gems on one or more instances. -* `verify`: Run automated tests on one or more instances. - -When transitioning between states, actions for any and all intermediate states will performed. -Executing the `create` then the `verify` commands is equivalent to executing `create`, `converge`, -`setup`, and `verify` one-by-one and in order. The only exception is `destroy`, which will -immediately transfer that machine's state to destroyed. - -The `test` command takes one or more instances through all the states, in order: `destroy`, `create`, -`converge`, `setup`, `verify`, `destroy`. - -To see a list of available commands, type `bundle exec kitchen help`. To see more information -about a particular command, type `bundle exec kitchen help <command>`. + +Kitchen instances are led through a series of states. The instance states, and the actions taken to transition into each state, are in order: + +- `destroy`: Delete all information for and terminate one or more instances. + - This is equivalent to running `vagrant destroy` to stop and delete a Vagrant machine. +- `create`: Start one or more instances. + - This is equivalent to running `vagrant up --no-provision` to start a Vagrant instance. +- `converge`: Use a provisioner to configure one or more instances. + - By default, Test Kitchen is configured to use the `ChefSolo` provisioner which: + - Prepares local files for transfer, + - Installs the latest release of Chef Omnibus, + - Downloads Chef Client source code from the prescribed GitHub repository and reference, + - Builds and installs a `chef` gem from the downloaded source, + - Runs `chef-client`. +- `setup`: Prepare the instance to run automated tests. +- `verify`: Run automated tests on one or more instances. + +When transitioning between states, actions for any and all intermediate states will performed. Executing the `create` then the `verify` commands is equivalent to executing `create`, `converge`, `setup`, and `verify` one-by-one and in order. The only exception is `destroy`, which will immediately transfer that machine's state to destroyed. + +The `test` command takes one or more instances through all the states, in order: `destroy`, `create`, `converge`, `setup`, `verify`, `destroy`. + +To see a list of available commands, type `bundle exec kitchen help`. To see more information about a particular command, type `bundle exec kitchen help <command>`. ### Configuring your tests -Test Kitchen is configured for local testing in the `.kitchen.yml` file which resides in this directory. -You will need to configure the provisioner before running the tests. -The provisioner can be configured to pull client source code from a GitHub repository using any -valid Git reference. You are encouraged to modify any of these settings, but please return them -to their original values before submitting a pull request for review (unless, of course, your -changes are enhancements to the default provisioner settings). +Test Kitchen is configured for local testing in the `kitchen.yml` file which resides in this directory. You will need to configure the provisioner before running the tests. + +The provisioner can be configured to pull client source code from a GitHub repository using any valid Git reference. You are encouraged to modify any of these settings, but please return them to their original values before submitting a pull request for review (unless, of course, your changes are enhancements to the default provisioner settings). -By default, the provisioner is configured to pull your most recent commit to `opscode/chef`. You -can change this by modifying the `github` and `branch` provisioner options: -* `github`: Set this to `"<your_username>/<your_chef_repo>"`. The default is `"opscode/chef"`. -* `branch`: This can be any valid git reference (e.g., branch name, tag, or commit SHA). If omitted, it defaults to `master`. +By default, the provisioner is configured to pull your most recent commit to `chef/chef`. You can change this by modifying the `github` and `branch` provisioner options: + +- `github`: Set this to `"<your_username>/<your_chef_repo>"`. The default is `"chef/chef"`. +- `branch`: This can be any valid git reference (e.g., branch name, tag, or commit SHA). If omitted, it defaults to `master`. The branch you choose must be accessible on GitHub. You cannot use a local commit at this time. ### Testing pull requests -These end-to-end tests are also configured to run with Travis on EC2 instances when you submit a pull request -to `opscode/chef`. Kitchen is configured to pull chef client source code from the branch it is testing. There -is no need to modify `.kitchen.travis.yml` unless you are contributing tests. + +These end-to-end tests are also configured to run on Travis-CI with docker containers when you submit a pull request to `chef/chef`. Kitchen is configured to pull chef client source code from the branch it is testing. There is no need to modify `kitchen.travis.yml` unless you are contributing tests. ## Contributing -We would love to fill out our end-to-end testing coverage! If you have cookbooks and tests that you would -like to see become a part of client testing, we encourage you to submit a pull request with your additions. -We request that you do not add platforms to `.kitchen.travis.yml`. Please file a request to add a -platform under [Issues](https://github.com/opscode/chef/issues). + +We would love to fill out our end-to-end testing coverage! If you have cookbooks and tests that you would like to see become a part of client testing, we encourage you to submit a pull request with your additions. We request that you do not add platforms to `kitchen.travis.yml`. Please file a request to add a platform under [Issues](https://github.com/chef/chef/issues). diff --git a/kitchen-tests/cookbooks/audit_test/.kitchen.yml b/kitchen-tests/cookbooks/audit_test/.kitchen.yml deleted file mode 100644 index be11e33081..0000000000 --- a/kitchen-tests/cookbooks/audit_test/.kitchen.yml +++ /dev/null @@ -1,16 +0,0 @@ ---- -driver: - name: vagrant - -provisioner: - name: chef_zero - -platforms: - - name: ubuntu-12.04 - - name: centos-6.5 - -suites: - - name: default - run_list: - - recipe[audit_test::default] - attributes: diff --git a/kitchen-tests/cookbooks/audit_test/Berksfile b/kitchen-tests/cookbooks/audit_test/Berksfile deleted file mode 100644 index 967b9a78b6..0000000000 --- a/kitchen-tests/cookbooks/audit_test/Berksfile +++ /dev/null @@ -1,3 +0,0 @@ -source "https://supermarket.chef.io" - -metadata diff --git a/kitchen-tests/cookbooks/audit_test/Berksfile.lock b/kitchen-tests/cookbooks/audit_test/Berksfile.lock deleted file mode 100644 index ef9f28a3be..0000000000 --- a/kitchen-tests/cookbooks/audit_test/Berksfile.lock +++ /dev/null @@ -1,7 +0,0 @@ -DEPENDENCIES - audit_test - path: . - metadata: true - -GRAPH - audit_test (0.1.0) diff --git a/kitchen-tests/cookbooks/audit_test/README.md b/kitchen-tests/cookbooks/audit_test/README.md deleted file mode 100644 index 75e2f44808..0000000000 --- a/kitchen-tests/cookbooks/audit_test/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# audit_test - -This cookbook has some basic recipes to test audit mode. - -In order to run these tests on your dev box: - -``` -$ bundle install -$ bundle exec chef-client -c kitchen-tests/.chef/client.rb -z -o audit_test::default -l debug -``` - -Expected JSON output for the tests will be printed to `debug` log. diff --git a/kitchen-tests/cookbooks/audit_test/metadata.rb b/kitchen-tests/cookbooks/audit_test/metadata.rb deleted file mode 100644 index 2b34ce28d0..0000000000 --- a/kitchen-tests/cookbooks/audit_test/metadata.rb +++ /dev/null @@ -1,7 +0,0 @@ -name "audit_test" -maintainer "The Authors" -maintainer_email "you@example.com" -license "Apache-2.0" -description "Installs/Configures audit_test" -long_description "Installs/Configures audit_test" -version "0.1.0" diff --git a/kitchen-tests/cookbooks/audit_test/recipes/default.rb b/kitchen-tests/cookbooks/audit_test/recipes/default.rb deleted file mode 100644 index 886c2cd0ac..0000000000 --- a/kitchen-tests/cookbooks/audit_test/recipes/default.rb +++ /dev/null @@ -1,26 +0,0 @@ -# -# Cookbook Name:: audit_test -# Recipe:: default -# -# Copyright 2014-2016, The Authors, All Rights Reserved. - -control_group "basic control group" do - control "basic math" do - it "should pass" do - expect(2 - 2).to eq(0) - end - end -end - -control_group "control group without top level control" do - it "should pass" do - expect(2 - 2).to eq(0) - end -end - -control_group "control group with empty control" do - control "empty" -end - -control_group "empty control group with block" do -end diff --git a/kitchen-tests/cookbooks/audit_test/recipes/error_duplicate_control_groups.rb b/kitchen-tests/cookbooks/audit_test/recipes/error_duplicate_control_groups.rb deleted file mode 100644 index 2b5b8b5d22..0000000000 --- a/kitchen-tests/cookbooks/audit_test/recipes/error_duplicate_control_groups.rb +++ /dev/null @@ -1,17 +0,0 @@ -# -# Cookbook Name:: audit_test -# Recipe:: error_duplicate_control_groups -# -# Copyright 2014-2016, The Authors, All Rights Reserved. - -control_group "basic control group" do - it "should pass" do - expect(2 - 2).to eq(0) - end -end - -control_group "basic control group" do - it "should pass" do - expect(2 - 2).to eq(0) - end -end diff --git a/kitchen-tests/cookbooks/audit_test/recipes/error_no_block.rb b/kitchen-tests/cookbooks/audit_test/recipes/error_no_block.rb deleted file mode 100644 index e4c444e8bc..0000000000 --- a/kitchen-tests/cookbooks/audit_test/recipes/error_no_block.rb +++ /dev/null @@ -1,7 +0,0 @@ -# -# Cookbook Name:: audit_test -# Recipe:: error_no_block -# -# Copyright 2014-2016, The Authors, All Rights Reserved. - -control_group "empty control group without block" diff --git a/kitchen-tests/cookbooks/audit_test/recipes/error_orphan_control.rb b/kitchen-tests/cookbooks/audit_test/recipes/error_orphan_control.rb deleted file mode 100644 index 61d809a7c0..0000000000 --- a/kitchen-tests/cookbooks/audit_test/recipes/error_orphan_control.rb +++ /dev/null @@ -1,13 +0,0 @@ -# -# Cookbook Name:: audit_test -# Recipe:: error_orphan_control -# -# Copyright 2014-2016, The Authors, All Rights Reserved. - -control_group "basic control group" do - it "should pass" do - expect(2 - 2).to eq(0) - end -end - -control "orphan control" diff --git a/kitchen-tests/cookbooks/audit_test/recipes/failed_specs.rb b/kitchen-tests/cookbooks/audit_test/recipes/failed_specs.rb deleted file mode 100644 index 9e6adfe2e9..0000000000 --- a/kitchen-tests/cookbooks/audit_test/recipes/failed_specs.rb +++ /dev/null @@ -1,14 +0,0 @@ -# -# Cookbook Name:: audit_test -# Recipe:: failed_specs -# -# Copyright 2014-2016, The Authors, All Rights Reserved. - -control_group "basic control group" do - control "basic math" do - # Can not write a good control :( - it "should pass" do - expect(2 - 0).to eq(0) - end - end -end diff --git a/kitchen-tests/cookbooks/audit_test/recipes/serverspec_collision.rb b/kitchen-tests/cookbooks/audit_test/recipes/serverspec_collision.rb deleted file mode 100644 index 36dd714cef..0000000000 --- a/kitchen-tests/cookbooks/audit_test/recipes/serverspec_collision.rb +++ /dev/null @@ -1,31 +0,0 @@ -# -# Cookbook Name:: audit_test -# Recipe:: serverspec_collision -# -# Copyright 2014-2016, The Authors, All Rights Reserved. - -file "/tmp/audit_test_file" do - action :create - content "Welcome to audit mode." -end - -control_group "file auditing" do - describe "test file" do - it "says welcome" do - expect(file("/tmp/audit_test_file")).to contain("Welcome") - end - end -end - -file "/tmp/audit_test_file_2" do - action :create - content "Bye to audit mode." -end - -control_group "end file auditing" do - describe "end file" do - it "says bye" do - expect(file("/tmp/audit_test_file_2")).to contain("Bye") - end - end -end diff --git a/kitchen-tests/cookbooks/audit_test/recipes/serverspec_support.rb b/kitchen-tests/cookbooks/audit_test/recipes/serverspec_support.rb deleted file mode 100644 index fc44fb334e..0000000000 --- a/kitchen-tests/cookbooks/audit_test/recipes/serverspec_support.rb +++ /dev/null @@ -1,37 +0,0 @@ -# -# Cookbook Name:: audit_test -# Recipe:: serverspec_support -# -# Copyright 2014-2016, The Authors, All Rights Reserved. - -file "/tmp/audit_test_file" do - action :create - content "Welcome to audit mode." -end - -# package "curl" do -# action :install -# end - -control_group "serverspec helpers with types" do - control "file helper" do - it "says welcome" do - expect(file("/tmp/audit_test_file")).to contain("Welcome") - end - end - - control service("com.apple.CoreRAID") do - it { is_expected.to be_enabled } - it { is_expected.not_to be_running } - end - - # describe "package helper" do - # it "works" do - # expect(package("curl")).to be_installed - # end - # end - - control package("postgresql") do - it { is_expected.to_not be_installed } - end -end diff --git a/kitchen-tests/cookbooks/audit_test/recipes/with_include_recipe.rb b/kitchen-tests/cookbooks/audit_test/recipes/with_include_recipe.rb deleted file mode 100644 index 7727c573c7..0000000000 --- a/kitchen-tests/cookbooks/audit_test/recipes/with_include_recipe.rb +++ /dev/null @@ -1,16 +0,0 @@ -# -# Cookbook Name:: audit_test -# Recipe:: with_include_recipe -# -# Copyright 2014-2016, The Authors, All Rights Reserved. - -include_recipe "audit_test::serverspec_collision" - -control_group "basic example" do - it "should pass" do - expect(2 - 2).to eq(0) - end -end - -include_recipe "audit_test::serverspec_collision" -include_recipe "audit_test::default" diff --git a/kitchen-tests/cookbooks/awesome_customers_rhel_wrapper/metadata.rb b/kitchen-tests/cookbooks/awesome_customers_rhel_wrapper/metadata.rb deleted file mode 100644 index 49dbb50869..0000000000 --- a/kitchen-tests/cookbooks/awesome_customers_rhel_wrapper/metadata.rb +++ /dev/null @@ -1,9 +0,0 @@ -name "awesome_customers_rhel_wrapper" -maintainer "The Authors" -maintainer_email "you@example.com" -license "Apache-2.0" -description "Installs/Configures awesome_customers_rhel" -long_description "Installs/Configures awesome_customers_rhel" -version "0.1.0" - -depends "awesome_customers_rhel" diff --git a/kitchen-tests/cookbooks/awesome_customers_rhel_wrapper/recipes/default.rb b/kitchen-tests/cookbooks/awesome_customers_rhel_wrapper/recipes/default.rb deleted file mode 100644 index c58db5fe29..0000000000 --- a/kitchen-tests/cookbooks/awesome_customers_rhel_wrapper/recipes/default.rb +++ /dev/null @@ -1,8 +0,0 @@ -# -# Cookbook:: awesome_customers_rhel -# Recipe:: default -# -# Copyright:: 2014-2017, Chef Software, Inc. -# - -include_recipe "awesome_customers_rhel::default" diff --git a/kitchen-tests/cookbooks/awesome_customers_ubuntu_wrapper/metadata.rb b/kitchen-tests/cookbooks/awesome_customers_ubuntu_wrapper/metadata.rb deleted file mode 100644 index d07a2c2c13..0000000000 --- a/kitchen-tests/cookbooks/awesome_customers_ubuntu_wrapper/metadata.rb +++ /dev/null @@ -1,9 +0,0 @@ -name "awesome_customers_ubuntu_wrapper" -maintainer "The Authors" -maintainer_email "you@example.com" -license "Apache-2.0" -description "Installs/Configures awesome_customers_ubuntu" -long_description "Installs/Configures awesome_customers_ubuntu" -version "0.1.0" - -depends "awesome_customers_ubuntu" diff --git a/kitchen-tests/cookbooks/awesome_customers_ubuntu_wrapper/recipes/default.rb b/kitchen-tests/cookbooks/awesome_customers_ubuntu_wrapper/recipes/default.rb deleted file mode 100644 index f6fd388f16..0000000000 --- a/kitchen-tests/cookbooks/awesome_customers_ubuntu_wrapper/recipes/default.rb +++ /dev/null @@ -1,8 +0,0 @@ -# -# Cookbook:: awesome_customers_ubuntu -# Recipe:: default -# -# Copyright:: 2016-2017, Chef Software, Inc. -# - -include_recipe "awesome_customers_ubuntu::default" diff --git a/kitchen-tests/cookbooks/base/recipes/default.rb b/kitchen-tests/cookbooks/base/recipes/default.rb index ea0215ca96..9175bfbd26 100644 --- a/kitchen-tests/cookbooks/base/recipes/default.rb +++ b/kitchen-tests/cookbooks/base/recipes/default.rb @@ -38,6 +38,9 @@ users_manage "sysadmin" do action [:create] end +ssh_known_hosts_entry "github.com" +ssh_known_hosts_entry "travis.org" + sudo "sysadmins" do group ["sysadmin", "%superadmin"] nopasswd true diff --git a/kitchen-tests/data_bags/passwords/mysql.json b/kitchen-tests/data_bags/passwords/mysql.json deleted file mode 100644 index af02a6a858..0000000000 --- a/kitchen-tests/data_bags/passwords/mysql.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "id": "mysql", - "server_root_password": "ilikerandompasswordstoo", - "server_repl_password": "itoolikerandompasswords" -} diff --git a/kitchen-tests/.kitchen.travis.yml b/kitchen-tests/kitchen.travis.yml index 7f1cc94667..7daf95195f 100644 --- a/kitchen-tests/.kitchen.travis.yml +++ b/kitchen-tests/kitchen.travis.yml @@ -121,11 +121,3 @@ suites: - name: base run_list: - recipe[base::default] - - name: awesome_customers_ubuntu - includes: [ubuntu-14.04, ubuntu-16.04, ubuntu-18.04] - run_list: - - recipe[awesome_customers_ubuntu_wrapper::default] - - name: awesome_customers_rhel - includes: [centos-6, centos-7] - run_list: - - recipe[awesome_customers_rhel_wrapper::default] diff --git a/kitchen-tests/.kitchen.yml b/kitchen-tests/kitchen.yml index b449265ce7..9133401c7c 100644 --- a/kitchen-tests/.kitchen.yml +++ b/kitchen-tests/kitchen.yml @@ -31,16 +31,9 @@ platforms: - name: opensuse-leap-42 - name: ubuntu-14.04 - name: ubuntu-16.04 + - name: ubuntu-18.04 suites: - name: base run_list: - recipe[base::default] - - name: awesome_customers_ubuntu - includes: [ubuntu-14.04, ubuntu-16.04] - run_list: - - recipe[awesome_customers_ubuntu_wrapper::default] - - name: awesome_customers_rhel - includes: [centos-6, centos-7] - run_list: - - recipe[awesome_customers_rhel_wrapper::default] diff --git a/lib/chef/chef_class.rb b/lib/chef/chef_class.rb index bfea51609a..95b03f1c5c 100644 --- a/lib/chef/chef_class.rb +++ b/lib/chef/chef_class.rb @@ -200,13 +200,14 @@ class Chef # # Emit a deprecation message. # - # @param [Symbol] type The message to send. This should refer to a class + # @param type [Symbol] The message to send. This should refer to a class # defined in Chef::Deprecated - # @param message An explicit message to display, rather than the generic one - # associated with the deprecation. - # @param location The location. Defaults to the caller who called you (since - # generally the person who triggered the check is the one that needs to be - # fixed). + # @param message [String, nil] An explicit message to display, rather than + # the generic one associated with the deprecation. + # @param location [String, nil] The location. Defaults to the caller who + # called you (since generally the person who triggered the check is the one + # that needs to be fixed). + # @return [void] # # @example # Chef.deprecated(:my_deprecation, message: "This is deprecated!") @@ -220,11 +221,18 @@ class Chef # run. If we are not yet in a run, print to `Chef::Log`. if run_context && run_context.events run_context.events.deprecation(deprecation, location) - else - Chef::Log.deprecation(deprecation, location) + elsif !deprecation.silenced? + Chef::Log.deprecation(deprecation.to_s) end end + # Log a generic deprecation warning that doesn't have a specific class in + # Chef::Deprecated. + # + # This should generally not be used, as the user will not be given a link + # to get more infomration on fixing the deprecation warning. + # + # @see #deprecated def log_deprecation(message, location = nil) location ||= Chef::Log.caller_location Chef.deprecated(:generic, message, location) diff --git a/lib/chef/client.rb b/lib/chef/client.rb index 7218c3bb49..33d625c54e 100644 --- a/lib/chef/client.rb +++ b/lib/chef/client.rb @@ -275,6 +275,9 @@ class Chef do_windows_admin_check + Chef.resource_handler_map.lock! + Chef.provider_handler_map.lock! + run_context = setup_run_context load_required_recipe(@rest, run_context) unless Chef::Config[:solo_legacy_mode] diff --git a/lib/chef/deprecated.rb b/lib/chef/deprecated.rb index 792df69f71..d9a8df7b83 100644 --- a/lib/chef/deprecated.rb +++ b/lib/chef/deprecated.rb @@ -24,266 +24,196 @@ class Chef class << self include Chef::Mixin::ConvertToClassName - def create(type, message = nil, location = nil) - Chef::Deprecated.const_get(convert_to_class_name(type.to_s)).send(:new, message, location) + def create(type, message, location) + Chef::Deprecated.const_get(convert_to_class_name(type.to_s)).new(message, location) end end class Base BASE_URL = "https://docs.chef.io/deprecations_" - attr_accessor :message, :location + attr_reader :message, :location def initialize(msg = nil, location = nil) - @message = msg if msg - @location = location if location + @message = msg + @location = location end def link "Please see #{url} for further details and information on how to correct this problem." end + # Render the URL for the deprecation documentation page. + # + # @return [String] def url - "#{BASE_URL}#{target}" - end - - # We know that the only time this gets called is by Chef::Log.deprecation, - # so special case - def <<(location) - @location = location - end - - def inspect - "#{message} (CHEF-#{id})#{location}.\n#{link}" - end - - def id - raise NotImplementedError, "subclasses of Chef::Deprecated::Base should define #id with a unique number" - end - - def target - raise NotImplementedError, "subclasses of Chef::Deprecated::Base should define #target" + "#{BASE_URL}#{self.class.doc_page}" + end + + # Render the user-visible message for this deprecation. + # + # @return [String] + def to_s + "Deprecation CHEF-#{self.class.deprecation_id} from #{location}\n\n #{message}\n\n#{link}" + end + + # Check if this deprecation has been silenced. + # + # @return [Boolean] + def silenced? + # Check if all warnings have been silenced. + return true if Chef::Config[:silence_deprecation_warnings] == true + # Check if this warning has been silenced by the config. + return true if Chef::Config[:silence_deprecation_warnings].any? do |silence_spec| + # Just in case someone uses a symbol in the config by mistake. + silence_spec = silence_spec.to_s + # Check for a silence by deprecation name, or by location. + self.class.deprecation_key == silence_spec || self.class.deprecation_id.to_s == silence_spec || "chef-#{self.class.deprecation_id}" == silence_spec.downcase || location.include?(silence_spec) + end + # check if this warning has been silenced by inline comment. + return true if location =~ /^(.*?):(\d+):in/ && begin + # Don't buffer the whole file in memory, so read it one line at a time. + line_no = $2.to_i + location_file = ::File.open($1) + (line_no - 1).times { location_file.readline } # Read all the lines we don't care about. + relevant_line = location_file.readline + relevant_line.match?(/#.*chef:silence_deprecation($|[^:]|:#{self.class.deprecation_key})/) + end + false + end + + class << self + attr_reader :deprecation_id, :doc_page + + # Return the deprecation key as would be used with {Chef::Deprecated.create}. + # + # @return [String] + def deprecation_key + Chef::Mixin::ConvertToClassName.convert_to_snake_case(name, "Chef::Deprecated") + end + + # Set the ID and documentation page path for this deprecation. + # + # Used in subclasses to set the data for each type of deprecation. + # + # @example + # class MyDeprecation < Base + # target 123, "my_deprecation.html" + # end + # @param id [Integer] Deprecation ID number. This must be unique among + # all deprecations. + # @param page [String, nil] Optional documentation page path. If not + # specified, the deprecation key is used. + # @return [void] + def target(id, page = nil) + @deprecation_id = id + @doc_page = page || "#{deprecation_key}.html" + end end end class InternalApi < Base - def id - 0 - end - - def target - "internal_api.html" - end + target 0 end class JsonAutoInflate < Base - def id - 1 - end - - def target - "json_auto_inflate.html" - end + target 1 end class ExitCode < Base - def id - 2 - end - - def target - "exit_code.html" - end + target 2 end # id 3 has been deleted class Attributes < Base - def id - 4 - end - - def target - "attributes.html" - end + target 4 end class CustomResource < Base - def id - 5 - end - - def target - "custom_resource_cleanups.html" - end + target 5, "custom_resource_cleanups.html" end class EasyInstall < Base - def id - 6 - end - - def target - "easy_install.html" - end + target 6 end class VerifyFile < Base - def id - 7 - end - - def target - "verify_file.html" - end + target 7 end class SupportsProperty < Base - def id - 8 - end - - def target - "supports_property.html" - end + target 8 end class ChefRest < Base - def id - 9 - end - - def target - "chef_rest.html" - end + target 9 end class DnfPackageAllowDowngrade < Base - def id - 10 - end - - def target - "dnf_package_allow_downgrade.html" - end + target 10 end class PropertyNameCollision < Base - def id - 11 - end - - def target - "property_name_collision.html" - end + target 11 end class LaunchdHashProperty < Base - def id - 12 - end - - def target - "launchd_hash_property.html" - end + target 12 end class ChefPlatformMethods < Base - def id - 13 - end - - def target - "chef_platform_methods.html" - end + target 13 end class RunCommand < Base - def id - 14 - end - - def target - "run_command.html" - end + target 14 end class PackageMisc < Base - def id - 15 - end - - def target - "package_misc.html" - end + target 15 end class MultiresourceMatch < Base - def id - 16 - end - - def target - "multiresource_match.html" - end + target 16 end class UseInlineResources < Base - def id - 17 - end - - def target - "use_inline_resources.html" - end + target 17 end class LocalListen < Base - def id - 18 - end - - def target - "local_listen.html" - end + target 18 end class NamespaceCollisions < Base - def id - 19 - end - - def target - "namespace_collisions.html" - end + target 19 end class DeployResource < Base - def id - 21 - end - - def target - "deploy_resource.html" - end + target 21 end class ErlResource < Base - def id - 22 - end + target 22 + end - def target - "erl_resource.html" - end + class FreebsdPkgProvider < Base + target 23 + end + + class MapCollision < Base + target 25 end # id 3694 was deleted # Returned when using the deprecated option on a property class Property < Base - def inspect - "#{message}\n#{location}" + target 24 + + def to_s + "Deprecated resource property used from #{location}\n\n #{message}\n\nPlease consult the resource documentation for more information." end end @@ -292,8 +222,8 @@ class Chef "https://docs.chef.io/chef_deprecations_client.html" end - def inspect - "#{message}\nThis is a generic error message and should be updated to have a proper deprecation class. #{location}\nPlease see #{url} for an overview of Chef deprecations." + def to_s + "Deprecation from #{location}\n\n #{message}\n\n#{link}" end end diff --git a/lib/chef/formatters/base.rb b/lib/chef/formatters/base.rb index 0b27b55048..997577aa7b 100644 --- a/lib/chef/formatters/base.rb +++ b/lib/chef/formatters/base.rb @@ -212,14 +212,13 @@ class Chef file_load_failed(path, exception) end - def deprecation(message, location = caller(2..2)[0]) - out = if is_structured_deprecation?(message) - message.inspect - else - "#{message} at #{location}" - end - - Chef::Log.deprecation(out) + # Log a deprecation warning object. + # + # @param deprecation [Chef::Deprecated::Base] Deprecation object to log. + # In previous versions, this could be a string. Don't do that anymore. + # @param location [Object] Unused, present only for compatbility. + def deprecation(deprecation, _location = nil) + Chef::Log.deprecation(deprecation.to_s) unless deprecation.silenced? end def is_structured_deprecation?(deprecation) diff --git a/lib/chef/formatters/doc.rb b/lib/chef/formatters/doc.rb index 0c51cc2cfb..d47ab73a30 100644 --- a/lib/chef/formatters/doc.rb +++ b/lib/chef/formatters/doc.rb @@ -414,19 +414,15 @@ class Chef end end - def deprecation(message, location = caller(2..2)[0]) + # (see Base#deprecation) + def deprecation(deprecation, _location = nil) if Chef::Config[:treat_deprecation_warnings_as_errors] super + elsif !deprecation.silenced? + # Save non-silenced deprecations to the screen until the end. + deprecations[deprecation.message] ||= { url: deprecation.url, locations: Set.new } + deprecations[deprecation.message][:locations] << deprecation.location end - - # Save deprecations to the screen until the end - if is_structured_deprecation?(message) - url = message.url - message = message.message - end - - deprecations[message] ||= { url: url, locations: Set.new } - deprecations[message][:locations] << location end def indent diff --git a/lib/chef/log.rb b/lib/chef/log.rb index 10c9f0f20d..3f77158579 100644 --- a/lib/chef/log.rb +++ b/lib/chef/log.rb @@ -46,19 +46,21 @@ class Chef # def self.caller_location # Pick the first caller that is *not* part of the Chef gem, that's the - # thing the user wrote. + # thing the user wrote. Or failing that, the most recent caller. chef_gem_path = File.expand_path("../..", __FILE__) - caller(0..20).find { |c| !c.start_with?(chef_gem_path) } + caller(0..20).find { |c| !c.start_with?(chef_gem_path) } || caller(0..1)[0] end - def self.deprecation(msg = nil, location = caller(2..2)[0], &block) - if msg - msg << " at #{Array(location).join("\n")}" - msg = msg.join("") if msg.respond_to?(:join) - end + # Log a deprecation warning. + # + # If the treat_deprecation_warnings_as_errors config option is set, this + # will raise an exception instead. + # + # @param msg [String] Deprecation message to display. + def self.deprecation(msg, &block) if Chef::Config[:treat_deprecation_warnings_as_errors] error(msg, &block) - raise Chef::Exceptions::DeprecatedFeatureError.new(msg.inspect) + raise Chef::Exceptions::DeprecatedFeatureError.new(msg) else warn(msg, &block) end diff --git a/lib/chef/mixin/shell_out.rb b/lib/chef/mixin/shell_out.rb index 236ef844b1..2c67d34630 100644 --- a/lib/chef/mixin/shell_out.rb +++ b/lib/chef/mixin/shell_out.rb @@ -21,89 +21,126 @@ require "chef/mixin/path_sanity" class Chef module Mixin module ShellOut - include Chef::Mixin::PathSanity + extend Chef::Mixin::PathSanity # PREFERRED APIS: # - # shell_out_compact and shell_out_compact! flatten their array arguments and remove nils and pass - # the resultant array to shell_out. this actually eliminates spaces-in-args bugs because this: + # all consumers should now call shell_out!/shell_out. # - # shell_out!("command #{arg}") + # on unix the shell_out API supports the clean_array() kind of syntax (below) so that + # array args are flat/compact/to_s'd. on windows, array args aren't supported to its + # up to the caller to join(" ") on arrays of strings. # - # becomes two arguments if arg has spaces and requires quotations: + # the shell_out_compacted/shell_out_compacted! APIs are private but are intended for use + # in rspec tests, and should ideally always be used to make code refactorings that do not + # change behavior easier: # - # shell_out!("command '#{arg}'") + # allow(provider).to receive(:shell_out_compacted!).with("foo", "bar", "baz") + # provider.shell_out!("foo", [ "bar", nil, "baz"]) + # provider.shell_out!(["foo", nil, "bar" ], ["baz"]) # - # using shell_out_compact! this becomes: - # - # shell_out_compact!("command", arg) - # - # and spaces in the arg just works and it does not become two arguments (and the shell quoting around - # the argument must actually be removed). - # - # there's also an implicit join between all the array elements, and nested arrays are flattened which - # means that odd where-do-i-put-the-spaces options handling just works, and instead of this: - # - # opts = "" # needs to be empty string for when foo and bar are both missing - # opts << " -foo" if needs_foo? # needs the leading space on both of these - # opts << " -bar" if needs_bar? - # shell_out!("cmd#{opts}") # have to think way too hard about why there's no space here - # - # becomes: - # - # opts = [] - # opts << "-foo" if needs_foo? - # opts << "-bar" if needs_bar? - # shell_out_compact!("cmd", opts) - # - # and opts can be an empty array or nil and it'll work out fine. - # - # generally its best to use shell_out_compact! in code and setup expectations on shell_out! in tests + # note that shell_out_compacted also includes adding the magical timeout option to force + # people to setup expectations on that value explicitly. it does not include the default_env + # mangling in order to avoid users having to setup an expectation on anything other than + # setting `default_env: false` and allow us to make tweak to the default_env without breaking + # a thousand unit tests. # - def shell_out_compact(*args, **options) + def shell_out_compact(*args, **options) # FIXME: deprecate if options.empty? - shell_out(*clean_array(*args)) + shell_out(*args) else - shell_out(*clean_array(*args), **options) + shell_out(*args, **options) end end - def shell_out_compact!(*args, **options) + def shell_out_compact!(*args, **options) # FIXME: deprecate if options.empty? - shell_out!(*clean_array(*args)) + shell_out!(*args) else - shell_out!(*clean_array(*args), **options) + shell_out!(*args, **options) end end - # helper sugar for resources that support passing timeouts to shell_out + def shell_out_compact_timeout(*args, **options) # FIXME: deprecate + if options.empty? + shell_out(*args) + else + shell_out(*args, **options) + end + end + + def shell_out_compact_timeout!(*args, **options) # FIXME: deprecate + if options.empty? + shell_out!(*args) + else + shell_out!(*args, **options) + end + end - def shell_out_compact_timeout(*args, **options) - raise "object is not a resource that supports timeouts" unless respond_to?(:new_resource) && new_resource.respond_to?(:timeout) - options_dup = options.dup - options_dup[:timeout] = new_resource.timeout if new_resource.timeout - options_dup[:timeout] = 900 unless options_dup.key?(:timeout) - shell_out_compact(*args, **options_dup) + def shell_out_with_systems_locale(*args, **options) # FIXME: deprecate + if options.empty? + shell_out(*args, default_env: false) + else + shell_out(*args, default_env: false, **options) + end end - def shell_out_compact_timeout!(*args, **options) - raise "object is not a resource that supports timeouts" unless respond_to?(:new_resource) && new_resource.respond_to?(:timeout) - options_dup = options.dup - options_dup[:timeout] = new_resource.timeout if new_resource.timeout - options_dup[:timeout] = 900 unless options_dup.key?(:timeout) - shell_out_compact!(*args, **options_dup) + def shell_out_with_systems_locale!(*args, **options) # FIXME: deprecate + if options.empty? + shell_out!(*args, default_env: false) + else + shell_out!(*args, default_env: false, **options) + end end - # shell_out! runs a command on the system and will raise an error if the command fails, which is what you want - # for debugging, shell_out and shell_out! both will display command output to the tty when the log level is debug - # Generally speaking, 'extend Chef::Mixin::ShellOut' in your recipes and include 'Chef::Mixin::ShellOut' in your LWRPs - # You can also call Mixlib::Shellout.new directly, but you lose all of the above functionality + def a_to_s(*args) # FIXME: deprecate + # can't quite deprecate this yet + #Chef.deprecated(:package_misc, "a_to_s is deprecated use shell_out_compact or shell_out_compact_timeout instead") + args.flatten.reject { |i| i.nil? || i == "" }.map(&:to_s).join(" ") + end - # we use 'en_US.UTF-8' by default because we parse localized strings in English as an API and - # generally must support UTF-8 unicode. def shell_out(*args, **options) options = options.dup + options = Chef::Mixin::ShellOut.maybe_add_timeout(self, options) + if options.empty? + shell_out_compacted(*Chef::Mixin::ShellOut.clean_array(*args)) + else + shell_out_compacted(*Chef::Mixin::ShellOut.clean_array(*args), **options) + end + end + + def shell_out!(*args, **options) + options = options.dup + options = Chef::Mixin::ShellOut.maybe_add_timeout(self, options) + if options.empty? + shell_out_compacted!(*Chef::Mixin::ShellOut.clean_array(*args)) + else + shell_out_compacted!(*Chef::Mixin::ShellOut.clean_array(*args), **options) + end + end + + # helper sugar for resources that support passing timeouts to shell_out + # + # module method to not pollute namespaces, but that means we need self injected as an arg + # @api private + def self.maybe_add_timeout(obj, options) + # note that we can't define an empty Chef::Resource::LWRPBase because that breaks descendants tracker, so we'd have to instead require the file here, which would pull in half + # of chef, so instead convert to using strings. once descendants tracker is gone, we can just declare the empty classes instead and use `is_a?` against the symbols. + # (be nice if ruby supported strings in `is_a?` for looser coupling). + if obj.class.ancestors.map(&:to_s).include?("Chef::Provider") && !obj.class.ancestors.map(&:to_s).include?("Chef::Resource::LWRPBase") && obj.new_resource.respond_to?(:timeout) && !options.key?(:timeout) + options = options.dup + # historically resources have not properly declared defaults on their timeouts, so a default default of 900s was enforced here + options[:timeout] = obj.new_resource.timeout ? obj.new_resource.timeout.to_f : 900 + end + options + end + + # helper function to mangle options when `default_env` is true + # + # @api private + def self.apply_default_env(options) + options = options.dup default_env = options.delete(:default_env) default_env = true if default_env.nil? if default_env @@ -115,34 +152,37 @@ class Chef env_path => sanitized_path, }.update(options[env_key] || {}) end - shell_out_command(*args, **options) + options end - # call shell_out (using en_US.UTF-8) and raise errors - def shell_out!(*command_args) - cmd = shell_out(*command_args) - cmd.error! - cmd - end - - def shell_out_with_systems_locale(*args, **options) # FIXME: deprecate - shell_out(*args, default_env: false, **options) - end + private - def shell_out_with_systems_locale!(*args, **options) # FIXME: deprecate - shell_out!(*args, default_env: false, **options) + # this SHOULD be used for setting up expectations in rspec, see banner comment at top. + # + # the private constraint is meant to avoid code calling this directly, rspec expectations are fine. + # + def shell_out_compacted(*args, **options) + options = Chef::Mixin::ShellOut.apply_default_env(options) + if options.empty? + Chef::Mixin::ShellOut.shell_out_command(*args) + else + Chef::Mixin::ShellOut.shell_out_command(*args, **options) + end end - # Helper for subclasses to convert an array of string args into a string. It - # will compact nil or empty strings in the array and will join the array elements - # with spaces, without introducing any double spaces for nil/empty elements. + # this SHOULD be used for setting up expectations in rspec, see banner comment at top. # - # @param args [String] variable number of string arguments - # @return [String] nicely concatenated string or empty string - def a_to_s(*args) - # can't quite deprecate this yet - #Chef.deprecated(:package_misc, "a_to_s is deprecated use shell_out_compact or shell_out_compact_timeout instead") - args.flatten.reject { |i| i.nil? || i == "" }.map(&:to_s).join(" ") + # the private constraint is meant to avoid code calling this directly, rspec expectations are fine. + # + def shell_out_compacted!(*args, **options) + options = Chef::Mixin::ShellOut.apply_default_env(options) + cmd = if options.empty? + Chef::Mixin::ShellOut.shell_out_command(*args) + else + Chef::Mixin::ShellOut.shell_out_command(*args, **options) + end + cmd.error! + cmd end # Helper for subclasses to reject nil out of an array. It allows @@ -161,20 +201,23 @@ class Chef # # @param args [String] variable number of string arguments # @return [Array] array of strings with nil and null string rejection - def clean_array(*args) + + def self.clean_array(*args) args.flatten.compact.map(&:to_s) end - private - - def shell_out_command(*command_args) - cmd = Mixlib::ShellOut.new(*command_args) + def self.shell_out_command(*args, **options) + cmd = if options.empty? + Mixlib::ShellOut.new(*args) + else + Mixlib::ShellOut.new(*args, **options) + end cmd.live_stream ||= io_for_live_stream cmd.run_command cmd end - def io_for_live_stream + def self.io_for_live_stream if STDOUT.tty? && !Chef::Config[:daemon] && Chef::Log.debug? STDOUT else @@ -182,7 +225,7 @@ class Chef end end - def env_path + def self.env_path if Chef::Platform.windows? "Path" else diff --git a/lib/chef/node_map.rb b/lib/chef/node_map.rb index 0406b3c1d6..c0066bfce5 100644 --- a/lib/chef/node_map.rb +++ b/lib/chef/node_map.rb @@ -37,6 +37,21 @@ # class Chef class NodeMap + COLLISION_WARNING_14 = <<-EOH.gsub(/\s+/, " ").strip +%{type_caps} %{key} has been loaded from a cookbook. The %{type} %{key} is now +included in Chef and will take precedence over the existing cookbook %{type} in the +next major release of Chef (15.0, April 2019). You may be able to remove this cookbook dependency from +your runlist if you do not use other recipes/resources/libraries from the cookbook. +Alternatively there may be a newer version of this cookbook without the %{key} %{type}. +EOH + + COLLISION_WARNING_15 = <<-EOH.gsub(/\s+/, " ").strip +%{type_caps} %{key} attempted to load from a cookbook. The %{type} %{key} is now +included in Chef and takes precedence over the existing cookbook %{type} +which will be ignored. You may be able to remove this cookbook dependency from +your runlist if you do not use other recipes/resources/libraries from the cookbook. +Alternatively there may be a newer version of this cookbook without the %{key} %{type}. +EOH # # Set a key/value pair on the map with a filter. The filter must be true @@ -45,12 +60,18 @@ class Chef # @param key [Object] Key to store # @param value [Object] Value associated with the key # @param filters [Hash] Node filter options to apply to key retrieval + # @param allow_cookbook_override [Boolean, String] Allow a cookbook to add + # to this key even in locked mode. If a string is given, it should be a + # Gem::Requirement-compatible value indicating for which Chef versions an + # override from cookbooks is allowed. + # @param __core_override__ [Boolean] Advanced-mode override to add to a key + # even in locked mode. # # @yield [node] Arbitrary node filter as a block which takes a node argument # # @return [NodeMap] Returns self for possible chaining # - def set(key, klass, platform: nil, platform_version: nil, platform_family: nil, os: nil, canonical: nil, override: nil, &block) + def set(key, klass, platform: nil, platform_version: nil, platform_family: nil, os: nil, canonical: nil, override: nil, allow_cookbook_override: false, __core_override__: false, &block) # rubocop:disable Lint/UnderscorePrefixedVariableName new_matcher = { klass: klass } new_matcher[:platform] = platform if platform new_matcher[:platform_version] = platform_version if platform_version @@ -59,6 +80,31 @@ class Chef new_matcher[:block] = block if block new_matcher[:canonical] = canonical if canonical new_matcher[:override] = override if override + new_matcher[:cookbook_override] = allow_cookbook_override + new_matcher[:core_override] = __core_override__ + + # Check if the key is already present and locked, unless the override is allowed. + # The checks to see if we should reject, in order: + # 1. Core override mode is not set. + # 2. The key exists. + # 3. At least one previous `provides` is now locked. + # 4. No previous `provides` had `allow_cookbook_override`, either set to + # true or with a string version matcher that still matches Chef::VERSION + if !__core_override__ && map[key] && map[key].any? { |matcher| matcher[:locked] } && !map[key].any? { |matcher| matcher[:cookbook_override].is_a?(String) ? Chef::VERSION =~ matcher[:cookbook_override] : matcher[:cookbook_override] } + # If we ever use locked mode on things other than the resource and provider handler maps, this probably needs a tweak. + type_of_thing = if klass < Chef::Resource + "resource" + elsif klass < Chef::Provider + "provider" + else + klass.superclass.to_s + end + # For now, only log the warning. + Chef.deprecated(:map_collision, COLLISION_WARNING_14 % { type: type_of_thing, key: key, type_caps: type_of_thing.capitalize }) + # In 15.0, uncomment this and remove the log above. + # Chef.deprecated(:map_collision, COLLISION_WARNING_15 % {type: type_of_thing, key: key, type_caps: type_of_thing.capitalize})) + # return + end # The map is sorted in order of preference already; we just need to find # our place in it (just before the first value with the same preference level). @@ -159,6 +205,34 @@ class Chef remaining end + # Check if this map has been locked. + # + # @api internal + # @since 14.2 + # @return [Boolean] + def locked? + if defined?(@locked) + @locked + else + false + end + end + + # Set this map to locked mode. This is used to prevent future overwriting + # of existing names. + # + # @api internal + # @since 14.2 + # @return [void] + def lock! + map.each do |key, matchers| + matchers.each do |matcher| + matcher[:locked] = true + end + end + @locked = true + end + private # diff --git a/lib/chef/platform/query_helpers.rb b/lib/chef/platform/query_helpers.rb index b49010efc0..448885dfbc 100644 --- a/lib/chef/platform/query_helpers.rb +++ b/lib/chef/platform/query_helpers.rb @@ -20,6 +20,12 @@ class Chef class Platform class << self + # a simple helper to determine if we're on a windows release pre-2012 / 8 + # @return [Boolean] Is the system older than Windows 8 / 2012 + def older_than_win_2012_or_8? + node["platform_version"].to_f < 6.2 + end + def windows? ChefConfig.windows? end diff --git a/lib/chef/provider/group/aix.rb b/lib/chef/provider/group/aix.rb index 5c500e2753..7da07b8006 100644 --- a/lib/chef/provider/group/aix.rb +++ b/lib/chef/provider/group/aix.rb @@ -32,33 +32,33 @@ class Chef end def create_group - shell_out_compact!("mkgroup", set_options, new_resource.group_name) + shell_out!("mkgroup", set_options, new_resource.group_name) modify_group_members end def manage_group options = set_options if options.size > 0 - shell_out_compact!("chgroup", options, new_resource.group_name) + shell_out!("chgroup", options, new_resource.group_name) end modify_group_members end def remove_group - shell_out_compact!("rmgroup", new_resource.group_name) + shell_out!("rmgroup", new_resource.group_name) end def add_member(member) - shell_out_compact!("chgrpmem", "-m", "+", member, new_resource.group_name) + shell_out!("chgrpmem", "-m", "+", member, new_resource.group_name) end def set_members(members) return if members.empty? - shell_out_compact!("chgrpmem", "-m", "=", members.join(","), new_resource.group_name) + shell_out!("chgrpmem", "-m", "=", members.join(","), new_resource.group_name) end def remove_member(member) - shell_out_compact!("chgrpmem", "-m", "-", member, new_resource.group_name) + shell_out!("chgrpmem", "-m", "-", member, new_resource.group_name) end def set_options diff --git a/lib/chef/provider/group/dscl.rb b/lib/chef/provider/group/dscl.rb index 81c7d66aa8..a5c4d27ddb 100644 --- a/lib/chef/provider/group/dscl.rb +++ b/lib/chef/provider/group/dscl.rb @@ -27,7 +27,7 @@ class Chef argdup = args.dup cmd = argdup.shift shellcmd = [ "dscl", ".", "-#{cmd}", argdup ] - status = shell_out_compact(shellcmd) + status = shell_out(shellcmd) stdout_result = "" stderr_result = "" status.stdout.each_line { |line| stdout_result << line } diff --git a/lib/chef/provider/group/gpasswd.rb b/lib/chef/provider/group/gpasswd.rb index d8aff10d5b..a5d6a378c0 100644 --- a/lib/chef/provider/group/gpasswd.rb +++ b/lib/chef/provider/group/gpasswd.rb @@ -39,18 +39,18 @@ class Chef def set_members(members) if members.empty? - shell_out_compact!("gpasswd", "-M", "", new_resource.group_name) + shell_out!("gpasswd", "-M", "", new_resource.group_name) else - shell_out_compact!("gpasswd", "-M", members.join(","), new_resource.group_name) + shell_out!("gpasswd", "-M", members.join(","), new_resource.group_name) end end def add_member(member) - shell_out_compact!("gpasswd", "-a", member, new_resource.group_name) + shell_out!("gpasswd", "-a", member, new_resource.group_name) end def remove_member(member) - shell_out_compact!("gpasswd", "-d", member, new_resource.group_name) + shell_out!("gpasswd", "-d", member, new_resource.group_name) end end end diff --git a/lib/chef/provider/group/groupadd.rb b/lib/chef/provider/group/groupadd.rb index 7d7fac146c..fb8f306034 100644 --- a/lib/chef/provider/group/groupadd.rb +++ b/lib/chef/provider/group/groupadd.rb @@ -44,19 +44,19 @@ class Chef # Create the group def create_group - shell_out_compact!("groupadd", set_options, groupadd_options) + shell_out!("groupadd", set_options, groupadd_options) modify_group_members end # Manage the group when it already exists def manage_group - shell_out_compact!("groupmod", set_options) + shell_out!("groupmod", set_options) modify_group_members end # Remove the group def remove_group - shell_out_compact!("groupdel", new_resource.group_name) + shell_out!("groupdel", new_resource.group_name) end def modify_group_members diff --git a/lib/chef/provider/group/groupmod.rb b/lib/chef/provider/group/groupmod.rb index 13f83db4c4..ac033e607d 100644 --- a/lib/chef/provider/group/groupmod.rb +++ b/lib/chef/provider/group/groupmod.rb @@ -32,7 +32,7 @@ class Chef # Create the group def create_group - shell_out_compact!("group", "add", set_options) + shell_out!("group", "add", set_options) add_group_members(new_resource.members) end @@ -79,14 +79,14 @@ class Chef # Remove the group def remove_group - shell_out_compact!("group", "del", new_resource.group_name) + shell_out!("group", "del", new_resource.group_name) end # Adds a list of usernames to the group using `user mod` def add_group_members(members) logger.trace("#{new_resource} adding members #{members.join(', ')}") unless members.empty? members.each do |user| - shell_out_compact!("user", "mod", "-G", new_resource.group_name, user) + shell_out!("user", "mod", "-G", new_resource.group_name, user) end end @@ -94,11 +94,11 @@ class Chef # "<name>_bak", create a new group with the same GID and # "<name>", then set correct members on that group def reset_group_membership - shell_out_compact!("group", "mod", "-n", "#{new_resource.group_name}_bak", new_resource.group_name) + shell_out!("group", "mod", "-n", "#{new_resource.group_name}_bak", new_resource.group_name) - shell_out_compact!("group", "add", set_options(overwrite_gid: true)) + shell_out!("group", "add", set_options(overwrite_gid: true)) - shell_out_compact!("group", "del", "#{new_resource.group_name}_bak") + shell_out!("group", "del", "#{new_resource.group_name}_bak") end # Little bit of magic as per Adam's useradd provider to pull and assign the command line flags diff --git a/lib/chef/provider/group/pw.rb b/lib/chef/provider/group/pw.rb index b0393a147e..2a1f294bde 100644 --- a/lib/chef/provider/group/pw.rb +++ b/lib/chef/provider/group/pw.rb @@ -48,24 +48,24 @@ class Chef command += [ "-M", new_resource.members.join(",") ] end - shell_out_compact!(command) + shell_out!(command) end # Manage the group when it already exists def manage_group member_options = set_members_options if member_options.empty? - shell_out_compact!("pw", "groupmod", set_options) + shell_out!("pw", "groupmod", set_options) else member_options.each do |option| - shell_out_compact!("pw", "groupmod", set_options, option) + shell_out!("pw", "groupmod", set_options, option) end end end # Remove the group def remove_group - shell_out_compact!("pw", "groupdel", new_resource.group_name) + shell_out!("pw", "groupdel", new_resource.group_name) end # Little bit of magic as per Adam's useradd provider to pull and assign the command line flags diff --git a/lib/chef/provider/group/suse.rb b/lib/chef/provider/group/suse.rb index 0790d2c2d9..7e8473c901 100644 --- a/lib/chef/provider/group/suse.rb +++ b/lib/chef/provider/group/suse.rb @@ -66,7 +66,7 @@ class Chef end def add_member(member) - shell_out_compact!("groupmod", "-A", member, new_resource.group_name) + shell_out!("groupmod", "-A", member, new_resource.group_name) end def to_remove(members) @@ -74,7 +74,7 @@ class Chef end def remove_member(member) - shell_out_compact!("groupmod", "-R", member, new_resource.group_name) + shell_out!("groupmod", "-R", member, new_resource.group_name) end end diff --git a/lib/chef/provider/group/usermod.rb b/lib/chef/provider/group/usermod.rb index 3874f7b4de..6b040b7190 100644 --- a/lib/chef/provider/group/usermod.rb +++ b/lib/chef/provider/group/usermod.rb @@ -66,7 +66,7 @@ class Chef end def add_member(member) - shell_out_compact!("usermod", append_flags, new_resource.group_name, member) + shell_out!("usermod", append_flags, new_resource.group_name, member) end def remove_member(member) diff --git a/lib/chef/provider/ifconfig.rb b/lib/chef/provider/ifconfig.rb index 243c8ee9c3..f3d65d7c7c 100644 --- a/lib/chef/provider/ifconfig.rb +++ b/lib/chef/provider/ifconfig.rb @@ -163,7 +163,7 @@ class Chef unless new_resource.device == loopback_device command = add_command converge_by("run #{command.join(' ')} to add #{new_resource}") do - shell_out_compact!(command) + shell_out!(command) logger.info("#{new_resource} added") end end @@ -179,7 +179,7 @@ class Chef return if new_resource.device == loopback_device command = enable_command converge_by("run #{command.join(' ')} to enable #{new_resource}") do - shell_out_compact!(command) + shell_out!(command) logger.info("#{new_resource} enabled") end end @@ -189,7 +189,7 @@ class Chef if current_resource.device command = delete_command converge_by("run #{command.join(' ')} to delete #{new_resource}") do - shell_out_compact!(command) + shell_out!(command) logger.info("#{new_resource} deleted") end else @@ -204,7 +204,7 @@ class Chef if current_resource.device command = disable_command converge_by("run #{command.join(' ')} to disable #{new_resource}") do - shell_out_compact!(command) + shell_out!(command) logger.info("#{new_resource} disabled") end else diff --git a/lib/chef/provider/ifconfig/aix.rb b/lib/chef/provider/ifconfig/aix.rb index b68c5d5364..f9ecc1f22e 100644 --- a/lib/chef/provider/ifconfig/aix.rb +++ b/lib/chef/provider/ifconfig/aix.rb @@ -31,7 +31,7 @@ class Chef found_interface = false interface = {} - @status = shell_out_compact("ifconfig", "-a") + @status = shell_out("ifconfig", "-a") @status.stdout.each_line do |line| if !found_interface if line =~ /^(\S+):\sflags=(\S+)/ diff --git a/lib/chef/provider/mount/windows.rb b/lib/chef/provider/mount/windows.rb index 1bd932729d..590b2bfa52 100644 --- a/lib/chef/provider/mount/windows.rb +++ b/lib/chef/provider/mount/windows.rb @@ -40,9 +40,9 @@ class Chef def load_current_resource if is_volume(@new_resource.device) - @mount = Chef::Util::Windows::Volume.new(@new_resource.name) + @mount = Chef::Util::Windows::Volume.new(@new_resource.mount_point) else #assume network drive - @mount = Chef::Util::Windows::NetUse.new(@new_resource.name) + @mount = Chef::Util::Windows::NetUse.new(@new_resource.mount_point) end @current_resource = Chef::Resource::Mount.new(@new_resource.name) diff --git a/lib/chef/provider/package.rb b/lib/chef/provider/package.rb index 133f87dad9..ddd2fa5dd6 100644 --- a/lib/chef/provider/package.rb +++ b/lib/chef/provider/package.rb @@ -307,7 +307,7 @@ class Chef # used by subclasses. deprecated. use #a_to_s instead. def expand_options(options) # its deprecated but still work to do to deprecate it fully - #Chef.deprecated(:package_misc, "expand_options is deprecated, use shell_out_compact or shell_out_compact_timeout instead") + #Chef.deprecated(:package_misc, "expand_options is deprecated, use shell_out instead") if options " #{options.is_a?(Array) ? Shellwords.join(options) : options}" else @@ -668,17 +668,17 @@ class Chef end end - def shell_out_with_timeout(*command_args) + def shell_out_with_timeout(*command_args) # FIXME: deprecated shell_out(*add_timeout_option(command_args)) end - def shell_out_with_timeout!(*command_args) + def shell_out_with_timeout!(*command_args) # FIXME: deprecated shell_out!(*add_timeout_option(command_args)) end def add_timeout_option(command_args) # this is deprecated but its not quite done yet - #Chef.deprecated(:package_misc, "shell_out_with_timeout and add_timeout_option are deprecated methods, use shell_out_compact_timeout instead") + #Chef.deprecated(:package_misc, "shell_out_with_timeout and add_timeout_option are deprecated methods, use shell_out instead") args = command_args.dup if args.last.is_a?(Hash) options = args.pop.dup diff --git a/lib/chef/provider/package/apt.rb b/lib/chef/provider/package/apt.rb index 798abf4680..f245e481a3 100644 --- a/lib/chef/provider/package/apt.rb +++ b/lib/chef/provider/package/apt.rb @@ -81,7 +81,7 @@ class Chef def locked_packages @locked_packages ||= begin - locked = shell_out_compact_timeout!("apt-mark", "showhold") + locked = shell_out!("apt-mark", "showhold") locked.stdout.each_line.map do |line| line.strip end @@ -140,9 +140,9 @@ class Chef # # @return [Integer] 1 if v1 > v2. 0 if they're equal. -1 if v1 < v2 def version_compare(v1, v2) - if !shell_out_compact_timeout("dpkg", "--compare-versions", v1.to_s, "gt", v2.to_s).error? + if !shell_out("dpkg", "--compare-versions", v1.to_s, "gt", v2.to_s).error? 1 - elsif !shell_out_compact_timeout("dpkg", "--compare-versions", v1.to_s, "eq", v2.to_s).error? + elsif !shell_out("dpkg", "--compare-versions", v1.to_s, "eq", v2.to_s).error? 0 else -1 @@ -153,7 +153,7 @@ class Chef # interactive prompts. Command is run with default localization rather # than forcing locale to "C", so command output may not be stable. def run_noninteractive(*args) - shell_out_compact_timeout!(*args, env: { "DEBIAN_FRONTEND" => "noninteractive" }) + shell_out!(*args, env: { "DEBIAN_FRONTEND" => "noninteractive" }) end def default_release_options diff --git a/lib/chef/provider/package/bff.rb b/lib/chef/provider/package/bff.rb index 44fadd92df..652fad447b 100644 --- a/lib/chef/provider/package/bff.rb +++ b/lib/chef/provider/package/bff.rb @@ -34,11 +34,11 @@ class Chef super requirements.assert(:install) do |a| a.assertion { new_resource.source } - a.failure_message Chef::Exceptions::Package, "Source for package #{new_resource.name} required for action install" + a.failure_message Chef::Exceptions::Package, "Source for package #{new_resource.package_name} required for action install" end requirements.assert(:all_actions) do |a| a.assertion { !new_resource.source || package_source_found? } - a.failure_message Chef::Exceptions::Package, "Package #{new_resource.name} not found: #{new_resource.source}" + a.failure_message Chef::Exceptions::Package, "Package #{new_resource.package_name} not found: #{new_resource.source}" a.whyrun "would assume #{new_resource.source} would be have previously been made available" end end @@ -49,7 +49,7 @@ class Chef if package_source_found? logger.trace("#{new_resource} checking pkg status") - ret = shell_out_compact_timeout("installp", "-L", "-d", new_resource.source) + ret = shell_out("installp", "-L", "-d", new_resource.source) ret.stdout.each_line do |line| case line when /:#{new_resource.package_name}:/ @@ -65,7 +65,7 @@ class Chef end logger.trace("#{new_resource} checking install state") - ret = shell_out_compact_timeout("lslpp", "-lcq", current_resource.package_name) + ret = shell_out("lslpp", "-lcq", current_resource.package_name) ret.stdout.each_line do |line| case line when /#{current_resource.package_name}/ @@ -85,7 +85,7 @@ class Chef def candidate_version return @candidate_version if @candidate_version if package_source_found? - ret = shell_out_compact_timeout("installp", "-L", "-d", new_resource.source) + ret = shell_out("installp", "-L", "-d", new_resource.source) ret.stdout.each_line do |line| case line when /\w:#{Regexp.escape(new_resource.package_name)}:(.*)/ @@ -112,10 +112,10 @@ class Chef def install_package(name, version) logger.trace("#{new_resource} package install options: #{options}") if options.nil? - shell_out_compact_timeout!("installp", "-aYF", "-d", new_resource.source, new_resource.package_name) + shell_out!("installp", "-aYF", "-d", new_resource.source, new_resource.package_name) logger.trace("#{new_resource} installed version #{new_resource.version} from: #{new_resource.source}") else - shell_out_compact_timeout!("installp", "-aYF", options, "-d", new_resource.source, new_resource.package_name) + shell_out!("installp", "-aYF", options, "-d", new_resource.source, new_resource.package_name) logger.trace("#{new_resource} installed version #{new_resource.version} from: #{new_resource.source}") end end @@ -124,10 +124,10 @@ class Chef def remove_package(name, version) if options.nil? - shell_out_compact_timeout!("installp", "-u", name) + shell_out!("installp", "-u", name) logger.trace("#{new_resource} removed version #{new_resource.version}") else - shell_out_compact_timeout!("installp", "-u", options, name) + shell_out!("installp", "-u", options, name) logger.trace("#{new_resource} removed version #{new_resource.version}") end end diff --git a/lib/chef/provider/package/chocolatey.rb b/lib/chef/provider/package/chocolatey.rb index a6abdd5b46..c60483d0dc 100644 --- a/lib/chef/provider/package/chocolatey.rb +++ b/lib/chef/provider/package/chocolatey.rb @@ -171,7 +171,7 @@ EOS # @param args [String] variable number of string arguments # @return [Mixlib::ShellOut] object returned from shell_out! def choco_command(*args) - shell_out_with_timeout!(args_to_string(choco_exe, *args), returns: new_resource.returns) + shell_out!(args_to_string(choco_exe, *args), returns: new_resource.returns) end # Use the available_packages Hash helper to create an array suitable for diff --git a/lib/chef/provider/package/dnf.rb b/lib/chef/provider/package/dnf.rb index b18a284116..2339b4cabe 100644 --- a/lib/chef/provider/package/dnf.rb +++ b/lib/chef/provider/package/dnf.rb @@ -121,7 +121,7 @@ class Chef private def resolve_source_to_version_obj - shell_out_with_timeout!("rpm -qp --queryformat '%{NAME} %{EPOCH} %{VERSION} %{RELEASE} %{ARCH}\n' #{new_resource.source}").stdout.each_line do |line| + shell_out!("rpm -qp --queryformat '%{NAME} %{EPOCH} %{VERSION} %{RELEASE} %{ARCH}\n' #{new_resource.source}").stdout.each_line do |line| # this is another case of committing the sin of doing some lightweight mangling of RPM versions in ruby -- but the output of the rpm command # does not match what the dnf library accepts. case line @@ -167,7 +167,7 @@ class Chef end def dnf(*args) - shell_out_compact_timeout!("dnf", *args) + shell_out!("dnf", *args) end def safe_version_array diff --git a/lib/chef/provider/package/dpkg.rb b/lib/chef/provider/package/dpkg.rb index aa53f6145f..de5b2858e7 100644 --- a/lib/chef/provider/package/dpkg.rb +++ b/lib/chef/provider/package/dpkg.rb @@ -113,9 +113,9 @@ class Chef # # @return [Integer] 1 if v1 > v2. 0 if they're equal. -1 if v1 < v2 def version_compare(v1, v2) - if !shell_out_compact_timeout("dpkg", "--compare-versions", v1.to_s, "gt", v2.to_s).error? + if !shell_out("dpkg", "--compare-versions", v1.to_s, "gt", v2.to_s).error? 1 - elsif !shell_out_compact_timeout("dpkg", "--compare-versions", v1.to_s, "eq", v2.to_s).error? + elsif !shell_out("dpkg", "--compare-versions", v1.to_s, "eq", v2.to_s).error? 0 else -1 @@ -124,7 +124,7 @@ class Chef def read_current_version_of_package(package_name) logger.trace("#{new_resource} checking install state of #{package_name}") - status = shell_out_compact_timeout!("dpkg", "-s", package_name, returns: [0, 1]) + status = shell_out!("dpkg", "-s", package_name, returns: [0, 1]) package_installed = false status.stdout.each_line do |line| case line @@ -149,10 +149,10 @@ class Chef end end - # Runs command via shell_out_with_timeout with magic environment to disable + # Runs command via shell_out with magic environment to disable # interactive prompts. def run_noninteractive(*command) - shell_out_compact_timeout!(*command, env: { "DEBIAN_FRONTEND" => "noninteractive" }) + shell_out!(*command, env: { "DEBIAN_FRONTEND" => "noninteractive" }) end # Returns true if all sources exist. Returns false if any do not, or if no @@ -192,7 +192,7 @@ class Chef begin pkginfos = resolved_source_array.map do |src| logger.trace("#{new_resource} checking #{src} dpkg status") - status = shell_out_compact_timeout!("dpkg-deb", "-W", src) + status = shell_out!("dpkg-deb", "-W", src) status.stdout end Hash[*package_name_array.zip(pkginfos).flatten] diff --git a/lib/chef/provider/package/freebsd/base.rb b/lib/chef/provider/package/freebsd/base.rb index fc62fa7cc0..bf704a5cae 100644 --- a/lib/chef/provider/package/freebsd/base.rb +++ b/lib/chef/provider/package/freebsd/base.rb @@ -47,7 +47,7 @@ class Chef # Otherwise look up the path to the ports directory using 'whereis' else - whereis = shell_out_compact_timeout!("whereis", "-s", port, env: nil) + whereis = shell_out!("whereis", "-s", port, env: nil) unless path = whereis.stdout[/^#{Regexp.escape(port)}:\s+(.+)$/, 1] raise Chef::Exceptions::Package, "Could not find port with the name #{port}" end @@ -57,7 +57,7 @@ class Chef def makefile_variable_value(variable, dir = nil) options = dir ? { cwd: dir } : {} - make_v = shell_out_compact_timeout!("make", "-V", variable, options.merge!(env: nil, returns: [0, 1])) + make_v = shell_out!("make", "-V", variable, options.merge!(env: nil, returns: [0, 1])) make_v.exitstatus == 0 ? make_v.stdout.strip.split($OUTPUT_RECORD_SEPARATOR).first : nil # $\ is the line separator, i.e. newline. end end diff --git a/lib/chef/provider/package/freebsd/pkg.rb b/lib/chef/provider/package/freebsd/pkg.rb index 04e6e5c427..c847ae5658 100644 --- a/lib/chef/provider/package/freebsd/pkg.rb +++ b/lib/chef/provider/package/freebsd/pkg.rb @@ -34,24 +34,24 @@ class Chef case new_resource.source when /^http/, /^ftp/ if new_resource.source =~ /\/$/ - shell_out_compact_timeout!("pkg_add", "-r", package_name, env: { "PACKAGESITE" => new_resource.source, "LC_ALL" => nil }).status + shell_out!("pkg_add", "-r", package_name, env: { "PACKAGESITE" => new_resource.source, "LC_ALL" => nil }).status else - shell_out_compact_timeout!("pkg_add", "-r", package_name, env: { "PACKAGEROOT" => new_resource.source, "LC_ALL" => nil }).status + shell_out!("pkg_add", "-r", package_name, env: { "PACKAGEROOT" => new_resource.source, "LC_ALL" => nil }).status end logger.trace("#{new_resource} installed from: #{new_resource.source}") when /^\// - shell_out_compact_timeout!("pkg_add", file_candidate_version_path, env: { "PKG_PATH" => new_resource.source, "LC_ALL" => nil }).status + shell_out!("pkg_add", file_candidate_version_path, env: { "PKG_PATH" => new_resource.source, "LC_ALL" => nil }).status logger.trace("#{new_resource} installed from: #{new_resource.source}") else - shell_out_compact_timeout!("pkg_add", "-r", latest_link_name, env: nil).status + shell_out!("pkg_add", "-r", latest_link_name, env: nil).status end end end def remove_package(name, version) - shell_out_compact_timeout!("pkg_delete", "#{package_name}-#{version || current_resource.version}", env: nil).status + shell_out!("pkg_delete", "#{package_name}-#{version || current_resource.version}", env: nil).status end # The name of the package (without the version number) as understood by pkg_add and pkg_info. @@ -72,7 +72,7 @@ class Chef end def current_installed_version - pkg_info = shell_out_compact_timeout!("pkg_info", "-E", "#{package_name}*", env: nil, returns: [0, 1]) + pkg_info = shell_out!("pkg_info", "-E", "#{package_name}*", env: nil, returns: [0, 1]) pkg_info.stdout[/^#{Regexp.escape(package_name)}-(.+)/, 1] end diff --git a/lib/chef/provider/package/freebsd/pkgng.rb b/lib/chef/provider/package/freebsd/pkgng.rb index c9c0947f9b..250baf0fac 100644 --- a/lib/chef/provider/package/freebsd/pkgng.rb +++ b/lib/chef/provider/package/freebsd/pkgng.rb @@ -28,21 +28,21 @@ class Chef unless current_resource.version case new_resource.source when /^(http|ftp|\/)/ - shell_out_compact_timeout!("pkg", "add", options, new_resource.source, env: { "LC_ALL" => nil }).status + shell_out!("pkg", "add", options, new_resource.source, env: { "LC_ALL" => nil }).status logger.trace("#{new_resource} installed from: #{new_resource.source}") else - shell_out_compact_timeout!("pkg", "install", "-y", options, name, env: { "LC_ALL" => nil }).status + shell_out!("pkg", "install", "-y", options, name, env: { "LC_ALL" => nil }).status end end end def remove_package(name, version) options_dup = options && options.map { |str| str.sub(repo_regex, "") }.reject!(&:empty?) - shell_out_compact_timeout!("pkg", "delete", "-y", options_dup, "#{name}#{version ? '-' + version : ''}", env: nil).status + shell_out!("pkg", "delete", "-y", options_dup, "#{name}#{version ? '-' + version : ''}", env: nil).status end def current_installed_version - pkg_info = shell_out_compact_timeout!("pkg", "info", new_resource.package_name, env: nil, returns: [0, 70]) + pkg_info = shell_out!("pkg", "info", new_resource.package_name, env: nil, returns: [0, 70]) pkg_info.stdout[/^Version +: (.+)$/, 1] end @@ -61,7 +61,7 @@ class Chef options = $1.split(" ") end - pkg_query = shell_out_compact_timeout!("pkg", "rquery", options, "%v", new_resource.package_name, env: nil) + pkg_query = shell_out!("pkg", "rquery", options, "%v", new_resource.package_name, env: nil) pkg_query.exitstatus == 0 ? pkg_query.stdout.strip.split(/\n/).last : nil end diff --git a/lib/chef/provider/package/freebsd/port.rb b/lib/chef/provider/package/freebsd/port.rb index e87be4d304..7a46bbaf97 100644 --- a/lib/chef/provider/package/freebsd/port.rb +++ b/lib/chef/provider/package/freebsd/port.rb @@ -26,18 +26,18 @@ class Chef include PortsHelper def install_package(name, version) - shell_out_compact_timeout!("make", "-DBATCH", "install", "clean", timeout: 1800, env: nil, cwd: port_dir).status + shell_out!("make", "-DBATCH", "install", "clean", timeout: 1800, env: nil, cwd: port_dir).status end def remove_package(name, version) - shell_out_compact_timeout!("make", "deinstall", timeout: 300, env: nil, cwd: port_dir).status + shell_out!("make", "deinstall", timeout: 300, env: nil, cwd: port_dir).status end def current_installed_version pkg_info = if new_resource.supports_pkgng? - shell_out_compact_timeout!("pkg", "info", new_resource.package_name, env: nil, returns: [0, 70]) + shell_out!("pkg", "info", new_resource.package_name, env: nil, returns: [0, 70]) else - shell_out_compact_timeout!("pkg_info", "-E", "#{new_resource.package_name}*", env: nil, returns: [0, 1]) + shell_out!("pkg_info", "-E", "#{new_resource.package_name}*", env: nil, returns: [0, 1]) end pkg_info.stdout[/^#{Regexp.escape(new_resource.package_name)}-(.+)/, 1] end diff --git a/lib/chef/provider/package/homebrew.rb b/lib/chef/provider/package/homebrew.rb index 643faf23c6..1a7407486b 100644 --- a/lib/chef/provider/package/homebrew.rb +++ b/lib/chef/provider/package/homebrew.rb @@ -128,7 +128,7 @@ class Chef logger.trace "Executing '#{command.join(' ')}' as user '#{homebrew_user.name}'" # FIXME: this 1800 second default timeout should be deprecated - output = shell_out_compact_timeout!(*command, timeout: 1800, user: homebrew_uid, environment: { "HOME" => homebrew_user.dir, "RUBYOPT" => nil, "TMPDIR" => nil }) + output = shell_out!(*command, timeout: 1800, user: homebrew_uid, environment: { "HOME" => homebrew_user.dir, "RUBYOPT" => nil, "TMPDIR" => nil }) output.stdout.chomp end diff --git a/lib/chef/provider/package/ips.rb b/lib/chef/provider/package/ips.rb index cabc7fc68b..f7fdb95e4d 100644 --- a/lib/chef/provider/package/ips.rb +++ b/lib/chef/provider/package/ips.rb @@ -1,7 +1,7 @@ # # Author:: Jason J. W. Williams (<williamsjj@digitar.com>) # Author:: Stephen Nelson-Smith (<sns@chef.io>) -# Copyright:: Copyright 2011-2017, Chef Software Inc. +# Copyright:: Copyright 2011-2018, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -42,14 +42,14 @@ class Chef end def get_current_version - shell_out_compact_timeout("pkg", "info", new_resource.package_name).stdout.each_line do |line| + shell_out("pkg", "info", new_resource.package_name).stdout.each_line do |line| return $1.split[0] if line =~ /^\s+Version: (.*)/ end nil end def get_candidate_version - shell_out_compact_timeout!("pkg", "info", "-r", new_resource.package_name).stdout.each_line do |line| + shell_out!("pkg", "info", "-r", new_resource.package_name).stdout.each_line do |line| return $1.split[0] if line =~ /Version: (.*)/ end nil @@ -58,7 +58,7 @@ class Chef def load_current_resource @current_resource = Chef::Resource::IpsPackage.new(new_resource.name) current_resource.package_name(new_resource.package_name) - logger.trace("Checking package status for #{new_resource.name}") + logger.trace("Checking package status for #{new_resource.package_name}") current_resource.version(get_current_version) @candidate_version = get_candidate_version current_resource @@ -68,7 +68,7 @@ class Chef command = [ "pkg", options, "install", "-q" ] command << "--accept" if new_resource.accept_license command << "#{name}@#{version}" - shell_out_compact_timeout!(command) + shell_out!(command) end def upgrade_package(name, version) @@ -77,7 +77,7 @@ class Chef def remove_package(name, version) package_name = "#{name}@#{version}" - shell_out_compact_timeout!( "pkg", options, "uninstall", "-q", package_name ) + shell_out!( "pkg", options, "uninstall", "-q", package_name ) end end end diff --git a/lib/chef/provider/package/macports.rb b/lib/chef/provider/package/macports.rb index ddaf19a76f..384435778d 100644 --- a/lib/chef/provider/package/macports.rb +++ b/lib/chef/provider/package/macports.rb @@ -16,7 +16,7 @@ class Chef @candidate_version = macports_candidate_version if !new_resource.version && !@candidate_version - raise Chef::Exceptions::Package, "Could not get a candidate version for this package -- #{new_resource.name} does not seem to be a valid package!" + raise Chef::Exceptions::Package, "Could not get a candidate version for this package -- #{new_resource.package_name} does not seem to be a valid package!" end logger.trace("#{new_resource} candidate version is #{@candidate_version}") if @candidate_version @@ -49,21 +49,21 @@ class Chef unless current_resource.version == version command = [ "port", options, "install", name ] command << "@#{version}" if version && !version.empty? - shell_out_compact_timeout!(command) + shell_out!(command) end end def purge_package(name, version) command = [ "port", options, "uninstall", name ] command << "@#{version}" if version && !version.empty? - shell_out_compact_timeout!(command) + shell_out!(command) end def remove_package(name, version) command = [ "port", options, "deactivate", name ] command << "@#{version}" if version && !version.empty? - shell_out_compact_timeout!(command) + shell_out!(command) end def upgrade_package(name, version) @@ -76,7 +76,7 @@ class Chef # that hasn't been installed. install_package(name, version) elsif current_version != version - shell_out_compact_timeout!( "port", options, "upgrade", name, "@#{version}" ) + shell_out!( "port", options, "upgrade", name, "@#{version}" ) end end @@ -84,7 +84,7 @@ class Chef def get_response_from_command(command) output = nil - status = shell_out_compact_timeout(command) + status = shell_out(command) begin output = status.stdout rescue Exception diff --git a/lib/chef/provider/package/msu.rb b/lib/chef/provider/package/msu.rb index c4e53a0fdf..9dbea31c82 100644 --- a/lib/chef/provider/package/msu.rb +++ b/lib/chef/provider/package/msu.rb @@ -125,7 +125,7 @@ class Chef def extract_msu_contents(msu_file, destination) with_os_architecture(nil) do - shell_out_with_timeout!("#{ENV['SYSTEMROOT']}\\system32\\expand.exe -f:* #{msu_file} #{destination}") + shell_out!("#{ENV['SYSTEMROOT']}\\system32\\expand.exe -f:* #{msu_file} #{destination}") end end diff --git a/lib/chef/provider/package/openbsd.rb b/lib/chef/provider/package/openbsd.rb index f528c48f08..3408aef944 100644 --- a/lib/chef/provider/package/openbsd.rb +++ b/lib/chef/provider/package/openbsd.rb @@ -72,7 +72,7 @@ class Chef if parts = name.match(/^(.+?)--(.+)/) # use double-dash for stems with flavors, see man page for pkg_add name = parts[1] end - shell_out_compact_timeout!("pkg_add", "-r", package_string(name, version), env: { "PKG_PATH" => pkg_path }).status + shell_out!("pkg_add", "-r", package_string(name, version), env: { "PKG_PATH" => pkg_path }).status logger.trace("#{new_resource.package_name} installed") end end @@ -81,7 +81,7 @@ class Chef if parts = name.match(/^(.+?)--(.+)/) name = parts[1] end - shell_out_compact_timeout!("pkg_delete", package_string(name, version), env: nil).status + shell_out!("pkg_delete", package_string(name, version), env: nil).status end private @@ -92,7 +92,7 @@ class Chef else new_resource.package_name end - pkg_info = shell_out_compact_timeout!("pkg_info", "-e", "#{name}->0", env: nil, returns: [0, 1]) + pkg_info = shell_out!("pkg_info", "-e", "#{name}->0", env: nil, returns: [0, 1]) result = pkg_info.stdout[/^inst:#{Regexp.escape(name)}-(.+?)\s/, 1] logger.trace("installed_version of '#{new_resource.package_name}' is '#{result}'") result @@ -101,7 +101,7 @@ class Chef def candidate_version @candidate_version ||= begin results = [] - shell_out_compact_timeout!("pkg_info", "-I", package_string(new_resource.package_name, new_resource.version), env: nil, returns: [0, 1]).stdout.each_line do |line| + shell_out!("pkg_info", "-I", package_string(new_resource.package_name, new_resource.version), env: nil, returns: [0, 1]).stdout.each_line do |line| results << if parts = new_resource.package_name.match(/^(.+?)--(.+)/) line[/^#{Regexp.escape(parts[1])}-(.+?)\s/, 1] else @@ -116,7 +116,7 @@ class Chef when 1 results[0] else - raise Chef::Exceptions::Package, "#{new_resource.name} has multiple matching candidates. Please use a more specific name" if results.length > 1 + raise Chef::Exceptions::Package, "#{new_resource.package_name} has multiple matching candidates. Please use a more specific name" if results.length > 1 end end end diff --git a/lib/chef/provider/package/pacman.rb b/lib/chef/provider/package/pacman.rb index f6dde66219..4a3b795700 100644 --- a/lib/chef/provider/package/pacman.rb +++ b/lib/chef/provider/package/pacman.rb @@ -32,7 +32,7 @@ class Chef current_resource.package_name(new_resource.package_name) logger.trace("#{new_resource} checking pacman for #{new_resource.package_name}") - status = shell_out_compact_timeout("pacman", "-Qi", new_resource.package_name) + status = shell_out("pacman", "-Qi", new_resource.package_name) status.stdout.each_line do |line| case line when /^Version(\s?)*: (.+)$/ @@ -60,7 +60,7 @@ class Chef package_repos = repos.map { |r| Regexp.escape(r) }.join("|") - status = shell_out_compact_timeout("pacman", "-Sl") + status = shell_out("pacman", "-Sl") status.stdout.each_line do |line| case line when /^(#{package_repos}) #{Regexp.escape(new_resource.package_name)} (.+)$/ @@ -82,7 +82,7 @@ class Chef end def install_package(name, version) - shell_out_compact_timeout!( "pacman", "--sync", "--noconfirm", "--noprogressbar", options, name) + shell_out!( "pacman", "--sync", "--noconfirm", "--noprogressbar", options, name) end def upgrade_package(name, version) @@ -90,7 +90,7 @@ class Chef end def remove_package(name, version) - shell_out_compact_timeout!( "pacman", "--remove", "--noconfirm", "--noprogressbar", options, name ) + shell_out!( "pacman", "--remove", "--noconfirm", "--noprogressbar", options, name ) end def purge_package(name, version) diff --git a/lib/chef/provider/package/paludis.rb b/lib/chef/provider/package/paludis.rb index f6274d7553..3550b155d5 100644 --- a/lib/chef/provider/package/paludis.rb +++ b/lib/chef/provider/package/paludis.rb @@ -35,7 +35,7 @@ class Chef installed = false re = Regexp.new("(.*)[[:blank:]](.*)[[:blank:]](.*)$") - shell_out_compact!("cave", "-L", "warning", "print-ids", "-M", "none", "-m", new_resource.package_name, "-f", "%c/%p %v %r\n").stdout.each_line do |line| + shell_out!("cave", "-L", "warning", "print-ids", "-M", "none", "-m", new_resource.package_name, "-f", "%c/%p %v %r\n").stdout.each_line do |line| res = re.match(line) next if res.nil? case res[3] @@ -58,7 +58,7 @@ class Chef else new_resource.package_name.to_s end - shell_out_compact_timeout!("cave", "-L", "warning", "resolve", "-x", options, pkg) + shell_out!("cave", "-L", "warning", "resolve", "-x", options, pkg) end def upgrade_package(name, version) @@ -72,7 +72,7 @@ class Chef new_resource.package_name.to_s end - shell_out_compact!("cave", "-L", "warning", "uninstall", "-x", options, pkg) + shell_out!("cave", "-L", "warning", "uninstall", "-x", options, pkg) end def purge_package(name, version) diff --git a/lib/chef/provider/package/portage.rb b/lib/chef/provider/package/portage.rb index fecbba9dc9..11cbe99d18 100644 --- a/lib/chef/provider/package/portage.rb +++ b/lib/chef/provider/package/portage.rb @@ -1,6 +1,6 @@ # # Author:: Ezra Zygmuntowicz (<ezra@engineyard.com>) -# Copyright:: Copyright 2008-2016, Chef Software Inc. +# Copyright:: Copyright 2008-2018, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -31,7 +31,7 @@ class Chef PACKAGE_NAME_PATTERN = %r{(?:([^/]+)/)?([^/]+)} def load_current_resource - @current_resource = Chef::Resource::Package.new(new_resource.name) + @current_resource = Chef::Resource::PortagePackage.new(new_resource.name) current_resource.package_name(new_resource.package_name) category, pkg = /^#{PACKAGE_NAME_PATTERN}$/.match(new_resource.package_name)[1, 2] @@ -66,7 +66,7 @@ class Chef def candidate_version return @candidate_version if @candidate_version - pkginfo = shell_out_compact("portageq", "best_visible", "/", new_resource.package_name) + pkginfo = shell_out("portageq", "best_visible", "/", new_resource.package_name) if pkginfo.exitstatus != 0 pkginfo.stderr.each_line do |line| @@ -106,7 +106,7 @@ class Chef pkg = "~#{name}-#{$1}" end - shell_out_compact!( "emerge", "-g", "--color", "n", "--nospinner", "--quiet", options, pkg ) + shell_out!( "emerge", "-g", "--color", "n", "--nospinner", "--quiet", options, pkg ) end def upgrade_package(name, version) @@ -120,7 +120,7 @@ class Chef new_resource.package_name.to_s end - shell_out_compact!( "emerge", "--unmerge", "--color", "n", "--nospinner", "--quiet", options, pkg ) + shell_out!( "emerge", "--unmerge", "--color", "n", "--nospinner", "--quiet", options, pkg ) end def purge_package(name, version) diff --git a/lib/chef/provider/package/rpm.rb b/lib/chef/provider/package/rpm.rb index 9d4f2f3c23..3d070cee17 100644 --- a/lib/chef/provider/package/rpm.rb +++ b/lib/chef/provider/package/rpm.rb @@ -33,13 +33,13 @@ class Chef requirements.assert(:all_actions) do |a| a.assertion { @package_source_exists } - a.failure_message Chef::Exceptions::Package, "Package #{new_resource.name} not found: #{new_resource.source}" - a.whyrun "Assuming package #{new_resource.name} would have been made available." + a.failure_message Chef::Exceptions::Package, "Package #{new_resource.package_name} not found: #{new_resource.source}" + a.whyrun "Assuming package #{new_resource.package_name} would have been made available." end requirements.assert(:all_actions) do |a| a.assertion { !@rpm_status.nil? && (@rpm_status.exitstatus == 0 || @rpm_status.exitstatus == 1) } a.failure_message Chef::Exceptions::Package, "Unable to determine current version due to RPM failure. Detail: #{@rpm_status.inspect}" - a.whyrun "Assuming current version would have been determined for package#{new_resource.name}." + a.whyrun "Assuming current version would have been determined for package #{new_resource.package_name}." end end @@ -57,7 +57,7 @@ class Chef end logger.trace("#{new_resource} checking rpm status") - shell_out_compact_timeout!("rpm", "-qp", "--queryformat", "%{NAME} %{VERSION}-%{RELEASE}\n", new_resource.source).stdout.each_line do |line| + shell_out!("rpm", "-qp", "--queryformat", "%{NAME} %{VERSION}-%{RELEASE}\n", new_resource.source).stdout.each_line do |line| case line when /^(\S+)\s(\S+)$/ current_resource.package_name($1) @@ -73,7 +73,7 @@ class Chef end logger.trace("#{new_resource} checking install state") - @rpm_status = shell_out_compact_timeout("rpm", "-q", "--queryformat", "%{NAME} %{VERSION}-%{RELEASE}\n", current_resource.package_name) + @rpm_status = shell_out("rpm", "-q", "--queryformat", "%{NAME} %{VERSION}-%{RELEASE}\n", current_resource.package_name) @rpm_status.stdout.each_line do |line| case line when /^(\S+)\s(\S+)$/ @@ -88,12 +88,12 @@ class Chef def install_package(name, version) if current_resource.version if allow_downgrade - shell_out_compact_timeout!("rpm", options, "-U", "--oldpackage", new_resource.source) + shell_out!("rpm", options, "-U", "--oldpackage", new_resource.source) else - shell_out_compact_timeout!("rpm", options, "-U", new_resource.source) + shell_out!("rpm", options, "-U", new_resource.source) end else - shell_out_compact_timeout!("rpm", options, "-i", new_resource.source) + shell_out!("rpm", options, "-i", new_resource.source) end end @@ -101,9 +101,9 @@ class Chef def remove_package(name, version) if version - shell_out_compact_timeout!("rpm", options, "-e", "#{name}-#{version}") + shell_out!("rpm", options, "-e", "#{name}-#{version}") else - shell_out_compact_timeout!("rpm", options, "-e", name) + shell_out!("rpm", options, "-e", name) end end diff --git a/lib/chef/provider/package/rubygems.rb b/lib/chef/provider/package/rubygems.rb index 6b04af547b..d99dce8972 100644 --- a/lib/chef/provider/package/rubygems.rb +++ b/lib/chef/provider/package/rubygems.rb @@ -547,9 +547,9 @@ class Chef end src_str = src.empty? ? "" : " #{src.join(" ")}" if !version.nil? && !version.empty? - shell_out_with_timeout!("#{gem_binary_path} install #{name} -q --no-rdoc --no-ri -v \"#{version}\"#{src_str}#{opts}", env: nil) + shell_out!("#{gem_binary_path} install #{name} -q --no-rdoc --no-ri -v \"#{version}\"#{src_str}#{opts}", env: nil) else - shell_out_with_timeout!("#{gem_binary_path} install \"#{name}\" -q --no-rdoc --no-ri #{src_str}#{opts}", env: nil) + shell_out!("#{gem_binary_path} install \"#{name}\" -q --no-rdoc --no-ri #{src_str}#{opts}", env: nil) end end @@ -573,9 +573,9 @@ class Chef def uninstall_via_gem_command(name, version) if version - shell_out_with_timeout!("#{gem_binary_path} uninstall #{name} -q -x -I -v \"#{version}\"#{opts}", env: nil) + shell_out!("#{gem_binary_path} uninstall #{name} -q -x -I -v \"#{version}\"#{opts}", env: nil) else - shell_out_with_timeout!("#{gem_binary_path} uninstall #{name} -q -x -I -a#{opts}", env: nil) + shell_out!("#{gem_binary_path} uninstall #{name} -q -x -I -a#{opts}", env: nil) end end diff --git a/lib/chef/provider/package/smartos.rb b/lib/chef/provider/package/smartos.rb index 5c637814a6..4623196c13 100644 --- a/lib/chef/provider/package/smartos.rb +++ b/lib/chef/provider/package/smartos.rb @@ -43,7 +43,7 @@ class Chef def check_package_state(name) logger.trace("#{new_resource} checking package #{name}") version = nil - info = shell_out_compact_timeout!("/opt/local/sbin/pkg_info", "-E", "#{name}*", env: nil, returns: [0, 1]) + info = shell_out!("/opt/local/sbin/pkg_info", "-E", "#{name}*", env: nil, returns: [0, 1]) if info.stdout version = info.stdout[/^#{new_resource.package_name}-(.+)/, 1] @@ -58,7 +58,7 @@ class Chef return @candidate_version if @candidate_version name = nil version = nil - pkg = shell_out_compact_timeout!("/opt/local/bin/pkgin", "se", new_resource.package_name, env: nil, returns: [0, 1]) + pkg = shell_out!("/opt/local/bin/pkgin", "se", new_resource.package_name, env: nil, returns: [0, 1]) pkg.stdout.each_line do |line| case line when /^#{new_resource.package_name}/ @@ -72,7 +72,7 @@ class Chef def install_package(name, version) logger.trace("#{new_resource} installing package #{name} version #{version}") package = "#{name}-#{version}" - out = shell_out_compact_timeout!("/opt/local/bin/pkgin", "-y", "install", package, env: nil) + out = shell_out!("/opt/local/bin/pkgin", "-y", "install", package, env: nil) end def upgrade_package(name, version) @@ -83,7 +83,7 @@ class Chef def remove_package(name, version) logger.trace("#{new_resource} removing package #{name} version #{version}") package = name.to_s - out = shell_out_compact_timeout!("/opt/local/bin/pkgin", "-y", "remove", package, env: nil) + out = shell_out!("/opt/local/bin/pkgin", "-y", "remove", package, env: nil) end end diff --git a/lib/chef/provider/package/solaris.rb b/lib/chef/provider/package/solaris.rb index 9c75c76929..01958df1ee 100644 --- a/lib/chef/provider/package/solaris.rb +++ b/lib/chef/provider/package/solaris.rb @@ -38,11 +38,11 @@ class Chef super requirements.assert(:install) do |a| a.assertion { new_resource.source } - a.failure_message Chef::Exceptions::Package, "Source for package #{new_resource.name} required for action install" + a.failure_message Chef::Exceptions::Package, "Source for package #{new_resource.package_name} required for action install" end requirements.assert(:all_actions) do |a| a.assertion { !new_resource.source || @package_source_found } - a.failure_message Chef::Exceptions::Package, "Package #{new_resource.name} not found: #{new_resource.source}" + a.failure_message Chef::Exceptions::Package, "Package #{new_resource.package_name} not found: #{new_resource.source}" a.whyrun "would assume #{new_resource.source} would be have previously been made available" end end @@ -55,7 +55,7 @@ class Chef @package_source_found = ::File.exist?(new_resource.source) if @package_source_found logger.trace("#{new_resource} checking pkg status") - shell_out_compact_timeout("pkginfo", "-l", "-d", new_resource.source, new_resource.package_name).stdout.each_line do |line| + shell_out("pkginfo", "-l", "-d", new_resource.source, new_resource.package_name).stdout.each_line do |line| case line when /VERSION:\s+(.+)/ new_resource.version($1) @@ -65,7 +65,7 @@ class Chef end logger.trace("#{new_resource} checking install state") - status = shell_out_compact_timeout("pkginfo", "-l", current_resource.package_name) + status = shell_out("pkginfo", "-l", current_resource.package_name) status.stdout.each_line do |line| case line when /VERSION:\s+(.+)/ @@ -83,7 +83,7 @@ class Chef def candidate_version return @candidate_version if @candidate_version - status = shell_out_compact_timeout("pkginfo", "-l", "-d", new_resource.source, new_resource.package_name) + status = shell_out("pkginfo", "-l", "-d", new_resource.source, new_resource.package_name) status.stdout.each_line do |line| case line when /VERSION:\s+(.+)/ @@ -106,7 +106,7 @@ class Chef else [ "pkgadd", "-n", "-d", new_resource.source, "all" ] end - shell_out_compact_timeout!(command) + shell_out!(command) logger.trace("#{new_resource} installed version #{new_resource.version} from: #{new_resource.source}") else command = if ::File.directory?(new_resource.source) # CHEF-4469 @@ -114,7 +114,7 @@ class Chef else [ "pkgadd", "-n", options, "-d", new_resource.source, "all" ] end - shell_out_compact_timeout!(*command) + shell_out!(*command) logger.trace("#{new_resource} installed version #{new_resource.version} from: #{new_resource.source}") end end @@ -123,10 +123,10 @@ class Chef def remove_package(name, version) if options.nil? - shell_out_compact_timeout!( "pkgrm", "-n", name ) + shell_out!( "pkgrm", "-n", name ) logger.trace("#{new_resource} removed version #{new_resource.version}") else - shell_out_compact_timeout!( "pkgrm", "-n", options, name ) + shell_out!( "pkgrm", "-n", options, name ) logger.trace("#{new_resource} removed version #{new_resource.version}") end end diff --git a/lib/chef/provider/package/windows.rb b/lib/chef/provider/package/windows.rb index 8958bff068..d203adafe2 100644 --- a/lib/chef/provider/package/windows.rb +++ b/lib/chef/provider/package/windows.rb @@ -37,13 +37,14 @@ class Chef def define_resource_requirements requirements.assert(:install) do |a| a.assertion { new_resource.source || msi? } - a.failure_message Chef::Exceptions::NoWindowsPackageSource, "Source for package #{new_resource.name} must be specified in the resource's source property for package to be installed because the package_name property is used to test for the package installation state for this package type." + a.failure_message Chef::Exceptions::NoWindowsPackageSource, "Source for package #{new_resource.package_name} must be specified in the resource's source property for package to be installed because the package_name property is used to test for the package installation state for this package type." end unless uri_scheme?(new_resource.source) requirements.assert(:install) do |a| a.assertion { ::File.exist?(new_resource.source) } - a.failure_message Chef::Exceptions::Package, "Source for package #{new_resource.name} does not exist" + a.failure_message Chef::Exceptions::Package, "Source for package #{new_resource.package_name} does not exist" + a.whyrun "Assuming source file #{new_resource.source} would have been created." end end end @@ -120,7 +121,7 @@ class Chef if basename == "setup.exe" :installshield else - raise Chef::Exceptions::CannotDetermineWindowsInstallerType, "Installer type for Windows Package '#{new_resource.name}' not specified and cannot be determined from file extension '#{file_extension}'" + raise Chef::Exceptions::CannotDetermineWindowsInstallerType, "Installer type for Windows Package '#{new_resource.package_name}' not specified and cannot be determined from file extension '#{file_extension}'" end end end diff --git a/lib/chef/provider/package/yum.rb b/lib/chef/provider/package/yum.rb index 1c18e4bfc4..42dd11b43f 100644 --- a/lib/chef/provider/package/yum.rb +++ b/lib/chef/provider/package/yum.rb @@ -210,7 +210,7 @@ class Chef end def resolve_source_to_version_obj - shell_out_with_timeout!("rpm -qp --queryformat '%{NAME} %{EPOCH} %{VERSION} %{RELEASE} %{ARCH}\n' #{new_resource.source}").stdout.each_line do |line| + shell_out!("rpm -qp --queryformat '%{NAME} %{EPOCH} %{VERSION} %{RELEASE} %{ARCH}\n' #{new_resource.source}").stdout.each_line do |line| # this is another case of committing the sin of doing some lightweight mangling of RPM versions in ruby -- but the output of the rpm command # does not match what the yum library accepts. case line @@ -260,7 +260,7 @@ class Chef end def yum(*args) - shell_out_compact_timeout!(yum_binary, *args) + shell_out!(yum_binary, *args) end def safe_version_array diff --git a/lib/chef/provider/package/zypper.rb b/lib/chef/provider/package/zypper.rb index c2638fbfc1..058fcf1a6b 100644 --- a/lib/chef/provider/package/zypper.rb +++ b/lib/chef/provider/package/zypper.rb @@ -35,7 +35,7 @@ class Chef candidate_version = current_version = nil is_installed = false logger.trace("#{new_resource} checking zypper") - status = shell_out_compact_timeout!("zypper", "--non-interactive", "info", package_name) + status = shell_out!("zypper", "--non-interactive", "info", package_name) status.stdout.each_line do |line| case line when /^Version *: (.+) *$/ @@ -86,7 +86,7 @@ class Chef def locked_packages @locked_packages ||= begin - locked = shell_out_compact_timeout!("zypper", "locks") + locked = shell_out!("zypper", "locks") locked.stdout.each_line.map do |line| line.split("|").shift(2).last.strip end @@ -144,9 +144,9 @@ class Chef def zypper_package(command, *options, names, versions) zipped_names = zip(names, versions) if zypper_version < 1.0 - shell_out_compact_timeout!("zypper", gpg_checks, command, *options, "-y", names) + shell_out!("zypper", gpg_checks, command, *options, "-y", names) else - shell_out_compact_timeout!("zypper", "--non-interactive", gpg_checks, command, *options, zipped_names) + shell_out!("zypper", "--non-interactive", gpg_checks, command, *options, zipped_names) end end diff --git a/lib/chef/provider/route.rb b/lib/chef/provider/route.rb index b23d0307cc..2195abfe29 100644 --- a/lib/chef/provider/route.rb +++ b/lib/chef/provider/route.rb @@ -133,7 +133,7 @@ class Chef else command = generate_command(:add) converge_by("run #{command.join(' ')} to add route") do - shell_out_compact!(command) + shell_out!(command) logger.info("#{new_resource} added") end end @@ -146,7 +146,7 @@ class Chef if is_running command = generate_command(:delete) converge_by("run #{command.join(' ')} to delete route ") do - shell_out_compact!(command) + shell_out!(command) logger.info("#{new_resource} removed") end else diff --git a/lib/chef/provider/service/simple.rb b/lib/chef/provider/service/simple.rb index 3270deb781..9bfcbb1410 100644 --- a/lib/chef/provider/service/simple.rb +++ b/lib/chef/provider/service/simple.rb @@ -163,6 +163,7 @@ class Chef end def ps_cmd + # XXX: magic attributes are a shitty api, need something better here and deprecate this attribute @run_context.node[:command] && @run_context.node[:command][:ps] end end diff --git a/lib/chef/provider/user/aix.rb b/lib/chef/provider/user/aix.rb index be6ff9d750..aca0511e41 100644 --- a/lib/chef/provider/user/aix.rb +++ b/lib/chef/provider/user/aix.rb @@ -24,7 +24,7 @@ class Chef provides :aix_user def create_user - shell_out_compact!("useradd", universal_options, useradd_options, new_resource.username) + shell_out!("useradd", universal_options, useradd_options, new_resource.username) add_password end @@ -32,11 +32,11 @@ class Chef add_password manage_home return if universal_options.empty? && usermod_options.empty? - shell_out_compact!("usermod", universal_options, usermod_options, new_resource.username) + shell_out!("usermod", universal_options, usermod_options, new_resource.username) end def remove_user - shell_out_compact!("userdel", userdel_options, new_resource.username) + shell_out!("userdel", userdel_options, new_resource.username) end # Aix does not support -r like other unix, sytem account is created by adding to 'system' group @@ -66,7 +66,7 @@ class Chef end def check_lock - lock_info = shell_out_compact!("lsuser", "-a", "account_locked", new_resource.username) + lock_info = shell_out!("lsuser", "-a", "account_locked", new_resource.username) if whyrun_mode? && passwd_s.stdout.empty? && lock_info.stderr.match(/does not exist/) # if we're in whyrun mode and the user is not yet created we assume it would be return false @@ -85,11 +85,11 @@ class Chef end def lock_user - shell_out_compact!("chuser", "account_locked=true", new_resource.username) + shell_out!("chuser", "account_locked=true", new_resource.username) end def unlock_user - shell_out_compact!("chuser", "account_locked=false", new_resource.username) + shell_out!("chuser", "account_locked=false", new_resource.username) end def universal_options diff --git a/lib/chef/provider/user/dscl.rb b/lib/chef/provider/user/dscl.rb index 67fe8f3762..c22329d0d6 100644 --- a/lib/chef/provider/user/dscl.rb +++ b/lib/chef/provider/user/dscl.rb @@ -326,7 +326,7 @@ user password using shadow hash.") end def ditto_home - shell_out_compact!("/usr/sbin/createhomedir", "-c", "-u", "#{new_resource.username}") + shell_out!("/usr/sbin/createhomedir", "-c", "-u", "#{new_resource.username}") end def move_home @@ -364,7 +364,7 @@ user password using shadow hash.") # Shadow info is saved as binary plist. Convert the info to binary plist. shadow_info_binary = StringIO.new - shell_out_compact("plutil", "-convert", "binary1", "-o", "-", "-", + shell_out("plutil", "-convert", "binary1", "-o", "-", "-", input: shadow_info.to_plist, live_stream: shadow_info_binary) if user_info.nil? @@ -586,7 +586,7 @@ user password using shadow hash.") # We flush the cache here in order to make sure that we read fresh information # for the user. - shell_out_compact("dscacheutil", "-flushcache") # FIXME: this is MacOS version dependent + shell_out("dscacheutil", "-flushcache") # FIXME: this is MacOS version dependent begin user_plist_file = "#{USER_PLIST_DIRECTORY}/#{new_resource.username}.plist" @@ -654,7 +654,7 @@ user password using shadow hash.") end def run_dscl(*args) - result = shell_out_compact("dscl", ".", "-#{args[0]}", args[1..-1]) + result = shell_out("dscl", ".", "-#{args[0]}", args[1..-1]) return "" if ( args.first =~ /^delete/ ) && ( result.exitstatus != 0 ) raise(Chef::Exceptions::DsclCommandFailed, "dscl error: #{result.inspect}") unless result.exitstatus == 0 raise(Chef::Exceptions::DsclCommandFailed, "dscl error: #{result.inspect}") if result.stdout =~ /No such key: / @@ -662,7 +662,7 @@ user password using shadow hash.") end def run_plutil(*args) - result = shell_out_compact("plutil", "-#{args[0]}", args[1..-1]) + result = shell_out("plutil", "-#{args[0]}", args[1..-1]) raise(Chef::Exceptions::PlistUtilCommandFailed, "plutil error: #{result.inspect}") unless result.exitstatus == 0 if result.stdout.encoding == Encoding::ASCII_8BIT result.stdout.encode("utf-8", "binary", undef: :replace, invalid: :replace, replace: "?") @@ -672,7 +672,7 @@ user password using shadow hash.") end def convert_binary_plist_to_xml(binary_plist_string) - shell_out_compact("plutil", "-convert", "xml1", "-o", "-", "-", input: binary_plist_string).stdout + shell_out("plutil", "-convert", "xml1", "-o", "-", "-", input: binary_plist_string).stdout end def convert_to_binary(string) diff --git a/lib/chef/provider/user/linux.rb b/lib/chef/provider/user/linux.rb index a846d2657a..7d3a3c1163 100644 --- a/lib/chef/provider/user/linux.rb +++ b/lib/chef/provider/user/linux.rb @@ -24,23 +24,23 @@ class Chef provides :user, os: "linux" def create_user - shell_out_compact!("useradd", universal_options, useradd_options, new_resource.username) + shell_out!("useradd", universal_options, useradd_options, new_resource.username) end def manage_user - shell_out_compact!("usermod", universal_options, usermod_options, new_resource.username) + shell_out!("usermod", universal_options, usermod_options, new_resource.username) end def remove_user - shell_out_compact!("userdel", userdel_options, new_resource.username) + shell_out!("userdel", userdel_options, new_resource.username) end def lock_user - shell_out_compact!("usermod", "-L", new_resource.username) + shell_out!("usermod", "-L", new_resource.username) end def unlock_user - shell_out_compact!("usermod", "-U", new_resource.username) + shell_out!("usermod", "-U", new_resource.username) end # common to usermod and useradd @@ -88,7 +88,7 @@ class Chef def check_lock # there's an old bug in rhel (https://bugzilla.redhat.com/show_bug.cgi?id=578534) # which means that both 0 and 1 can be success. - passwd_s = shell_out_compact("passwd", "-S", new_resource.username, returns: [ 0, 1 ]) + passwd_s = shell_out("passwd", "-S", new_resource.username, returns: [ 0, 1 ]) # checking "does not exist" has to come before exit code handling since centos and ubuntu differ in exit codes if passwd_s.stderr =~ /does not exist/ diff --git a/lib/chef/provider/user/pw.rb b/lib/chef/provider/user/pw.rb index 695dbfd539..42d44bab51 100644 --- a/lib/chef/provider/user/pw.rb +++ b/lib/chef/provider/user/pw.rb @@ -31,19 +31,19 @@ class Chef end def create_user - shell_out_compact!("pw", "useradd", set_options) + shell_out!("pw", "useradd", set_options) modify_password end def manage_user - shell_out_compact!("pw", "usermod", set_options) + shell_out!("pw", "usermod", set_options) modify_password end def remove_user command = [ "pw", "userdel", new_resource.username ] command << "-r" if new_resource.manage_home - shell_out_compact!(command) + shell_out!(command) end def check_lock @@ -57,11 +57,11 @@ class Chef end def lock_user - shell_out_compact!("pw", "lock", new_resource.username) + shell_out!("pw", "lock", new_resource.username) end def unlock_user - shell_out_compact!("pw", "unlock", new_resource.username) + shell_out!("pw", "unlock", new_resource.username) end def set_options diff --git a/lib/chef/provider/user/solaris.rb b/lib/chef/provider/user/solaris.rb index 1abe660cfd..38e7f8cb31 100644 --- a/lib/chef/provider/user/solaris.rb +++ b/lib/chef/provider/user/solaris.rb @@ -30,18 +30,18 @@ class Chef PASSWORD_FILE = "/etc/shadow" def create_user - shell_out_compact!("useradd", universal_options, useradd_options, new_resource.username) + shell_out!("useradd", universal_options, useradd_options, new_resource.username) manage_password end def manage_user manage_password return if universal_options.empty? && usermod_options.empty? - shell_out_compact!("usermod", universal_options, usermod_options, new_resource.username) + shell_out!("usermod", universal_options, usermod_options, new_resource.username) end def remove_user - shell_out_compact!("userdel", userdel_options, new_resource.username) + shell_out!("userdel", userdel_options, new_resource.username) end def check_lock @@ -56,11 +56,11 @@ class Chef end def lock_user - shell_out_compact!("passwd", "-l", new_resource.username) + shell_out!("passwd", "-l", new_resource.username) end def unlock_user - shell_out_compact!("passwd", "-u", new_resource.username) + shell_out!("passwd", "-u", new_resource.username) end private diff --git a/lib/chef/provider/user/useradd.rb b/lib/chef/provider/user/useradd.rb index c09cc0d3a5..855da325a0 100644 --- a/lib/chef/provider/user/useradd.rb +++ b/lib/chef/provider/user/useradd.rb @@ -36,7 +36,7 @@ class Chef useradd.concat(universal_options) useradd.concat(useradd_options) end - shell_out_compact!(command) + shell_out!(command) end def manage_user @@ -44,7 +44,7 @@ class Chef command = compile_command("usermod") do |u| u.concat(universal_options) end - shell_out_compact!(command) + shell_out!(command) end def remove_user @@ -52,13 +52,13 @@ class Chef command << "-r" if new_resource.manage_home command << "-f" if new_resource.force command << new_resource.username - shell_out_compact!(command) + shell_out!(command) end def check_lock # we can get an exit code of 1 even when it's successful on # rhel/centos (redhat bug 578534). See additional error checks below. - passwd_s = shell_out_compact!("passwd", "-S", new_resource.username, returns: [0, 1]) + passwd_s = shell_out!("passwd", "-S", new_resource.username, returns: [0, 1]) if whyrun_mode? && passwd_s.stdout.empty? && passwd_s.stderr.match(/does not exist/) # if we're in whyrun mode and the user is not yet created we assume it would be return false @@ -79,7 +79,7 @@ class Chef unless passwd_s.exitstatus == 0 raise_lock_error = false if %w{redhat centos}.include?(node[:platform]) - passwd_version_check = shell_out_compact!("rpm", "-q", "passwd") + passwd_version_check = shell_out!("rpm", "-q", "passwd") passwd_version = passwd_version_check.stdout.chomp unless passwd_version == "passwd-0.73-1" @@ -96,11 +96,11 @@ class Chef end def lock_user - shell_out_compact!("usermod", "-L", new_resource.username) + shell_out!("usermod", "-L", new_resource.username) end def unlock_user - shell_out_compact!("usermod", "-U", new_resource.username) + shell_out!("usermod", "-U", new_resource.username) end def compile_command(base_command) diff --git a/lib/chef/provider/windows_task.rb b/lib/chef/provider/windows_task.rb index 0bb28c66c6..1676ec3f6b 100644 --- a/lib/chef/provider/windows_task.rb +++ b/lib/chef/provider/windows_task.rb @@ -100,15 +100,13 @@ class Chef def load_current_resource @current_resource = Chef::Resource::WindowsTask.new(new_resource.name) - task = TaskScheduler.new - if task.exists?(new_resource.task_name) - @current_resource.exists = true + task = TaskScheduler.new(new_resource.task_name, nil, "\\", false) + @current_resource.exists = task.exists?(new_resource.task_name) + if @current_resource.exists task.get_task(new_resource.task_name) @current_resource.task = task pathed_task_name = new_resource.task_name.start_with?('\\') ? new_resource.task_name : "\\#{new_resource.task_name}" @current_resource.task_name(pathed_task_name) - else - @current_resource.exists = false end @current_resource end @@ -133,10 +131,10 @@ class Chef converge_by("#{new_resource} task created") do task = TaskScheduler.new if new_resource.frequency == :none - task.new_work_item(new_resource.task_name, {}) + task.new_work_item(new_resource.task_name, {}, { user: new_resource.user, password: new_resource.password }) task.activate(new_resource.task_name) else - task.new_work_item(new_resource.task_name, trigger) + task.new_work_item(new_resource.task_name, trigger, { user: new_resource.user, password: new_resource.password }) end task.application_name = new_resource.command task.parameters = new_resource.command_arguments if new_resource.command_arguments diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb index 05349b80e7..478637ff4e 100644 --- a/lib/chef/resource.rb +++ b/lib/chef/resource.rb @@ -1161,6 +1161,22 @@ class Chef end end + # Set or return if this resource is in preview mode. + # + # This is used in Chef core as part of the process of migrating resources + # from a cookbook into core. It should be set to `true` when a cookbook + # resource is added to core, and then removed (set to `false`) in the next + # major release. + # + # @param value [nil, Boolean] If nil, get the current value. If not nil, set + # the value of the flag. + # @return [Boolean] + def self.preview_resource(value = nil) + @preview_resource = false unless defined?(@preview_resource) + @preview_resource = value unless value.nil? + @preview_resource + end + # # Internal Resource Interface (for Chef) # @@ -1305,6 +1321,12 @@ class Chef remove_canonical_dsl end + # If a resource is in preview mode, set allow_cookbook_override on all its + # mappings by default. + if preview_resource && !options.include?(:allow_cookbook_override) + options[:allow_cookbook_override] = true + end + result = Chef.resource_handler_map.set(name, self, options, &block) Chef::DSL::Resources.add_resource_dsl(name) result diff --git a/lib/chef/resource/chef_handler.rb b/lib/chef/resource/chef_handler.rb index ceed235840..6d55f882bd 100644 --- a/lib/chef/resource/chef_handler.rb +++ b/lib/chef/resource/chef_handler.rb @@ -15,6 +15,8 @@ # limitations under the License. # +require "chef/resource" + class Chef class Resource class ChefHandler < Chef::Resource diff --git a/lib/chef/resource/dsc_script.rb b/lib/chef/resource/dsc_script.rb index d10113be56..f3fa5d0314 100644 --- a/lib/chef/resource/dsc_script.rb +++ b/lib/chef/resource/dsc_script.rb @@ -16,6 +16,7 @@ # limitations under the License. # +require "chef/resource" require "chef/exceptions" require "chef/dsl/powershell" diff --git a/lib/chef/resource/freebsd_package.rb b/lib/chef/resource/freebsd_package.rb index d16355d027..e85a75e906 100644 --- a/lib/chef/resource/freebsd_package.rb +++ b/lib/chef/resource/freebsd_package.rb @@ -46,7 +46,7 @@ class Chef # # @return [Boolean] do we support pkgng def supports_pkgng? - ships_with_pkgng? || !!shell_out_compact!("make", "-V", "WITH_PKGNG", :env => nil).stdout.match(/yes/i) + ships_with_pkgng? || !!shell_out!("make", "-V", "WITH_PKGNG", :env => nil).stdout.match(/yes/i) end private @@ -63,6 +63,8 @@ class Chef elsif supports_pkgng? Chef::Provider::Package::Freebsd::Pkgng else + Chef.deprecated(:freebsd_package_provider, "The freebsd_package provider for pkg (Chef::Provider::Package::Freebsd::Pkg) is deprecated and will be removed from Chef core in 15.0 (April 2019).") + Chef::Provider::Package::Freebsd::Pkg end end diff --git a/lib/chef/resource/homebrew_package.rb b/lib/chef/resource/homebrew_package.rb index dee132a1b4..9d8c7b2596 100644 --- a/lib/chef/resource/homebrew_package.rb +++ b/lib/chef/resource/homebrew_package.rb @@ -30,7 +30,8 @@ class Chef description "Use the homebrew_package resource to manage packages for the macOS platform." introduced "12.0" - property :homebrew_user, [ String, Integer ] + property :homebrew_user, [ String, Integer ], + description: "The name of the Homebrew owner to be used by the chef-client when executing a command." end end diff --git a/lib/chef/resource/hostname.rb b/lib/chef/resource/hostname.rb index 878f502dae..02996f4464 100644 --- a/lib/chef/resource/hostname.rb +++ b/lib/chef/resource/hostname.rb @@ -1,3 +1,19 @@ +# +# 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/resource" + class Chef class Resource # Sets the hostname and updates /etc/hosts on *nix systems diff --git a/lib/chef/resource/http_request.rb b/lib/chef/resource/http_request.rb index f209e419dd..3493cec9db 100644 --- a/lib/chef/resource/http_request.rb +++ b/lib/chef/resource/http_request.rb @@ -32,8 +32,11 @@ class Chef default_action :get allowed_actions :get, :patch, :put, :post, :delete, :head, :options - property :url, String, identity: true - property :headers, Hash, default: lazy { Hash.new } + property :url, String, identity: true, + description: "The URL to which an HTTP request is sent." + + property :headers, Hash, default: lazy { Hash.new }, + description: "A Hash of custom headers." def initialize(name, run_context = nil) super diff --git a/lib/chef/resource/ifconfig.rb b/lib/chef/resource/ifconfig.rb index 579a4eeedb..84ee249ec4 100644 --- a/lib/chef/resource/ifconfig.rb +++ b/lib/chef/resource/ifconfig.rb @@ -35,23 +35,63 @@ class Chef default_action :add allowed_actions :add, :delete, :enable, :disable - property :target, String, name_property: true - property :hwaddr, String - property :mask, String - property :family, String, default: "inet" - property :inet_addr, String - property :bcast, String - property :mtu, String - property :metric, String - property :device, String, identity: true - property :onboot, String - property :network, String - property :bootproto, String - property :onparent, String - property :ethtool_opts, String - property :bonding_opts, String - property :master, String - property :slave, String + property :target, String, + name_property: true, + description: "The IP address that is to be assigned to the network interface. If not specified we'll use the resource's name." + + property :hwaddr, String, + description: "The hardware address for the network interface." + + property :mask, String, + description: "The decimal representation of the network mask. For example: 255.255.255.0." + + property :family, String, + default: "inet", introduced: "14.0", + description: "Networking family option for Debian-based systems. For example: inet or inet6." + + property :inet_addr, String, + description: "The Internet host address for the network interface." + + property :bcast, String, + description: "The broadcast address for a network interface. On some platforms this property is not set using ifconfig, but instead is added to the startup configuration file for the network interface." + + property :mtu, String, + description: "The maximum transmission unit (MTU) for the network interface." + + property :metric, String, + description: "The routing metric for the interface." + + property :device, String, + identity: true, + description: "The network interface to be configured." + + property :onboot, String, + description: "Bring up the network interface on boot." + + property :network, String, + description: "The address for the network interface." + + property :bootproto, String, + description: "The boot protocol used by a network interface." + + property :onparent, String, + description: "Bring up the network interface when its parent interface is brought up." + + property :ethtool_opts, String, + introduced: "13.4", + description: "Options to be passed to ethtool(8). For example: -A eth0 autoneg off rx off tx off" + + property :bonding_opts, String, + introduced: "13.4", + description: "Bonding options to pass via BONDING_OPTS on RHEL and CentOS. For example: mode=active-backup miimon=100" + + property :master, String, + introduced: "13.4", + description: "Specifies the channel bonding interface to which the Ethernet interface is linked." + + property :slave, String, + introduced: "13.4", + description: "When set to yes, this device is controlled by the channel bonding interface that is specified via the master property." end end end diff --git a/lib/chef/resource/ips_package.rb b/lib/chef/resource/ips_package.rb index 70e3bfee81..ff154e8bd8 100644 --- a/lib/chef/resource/ips_package.rb +++ b/lib/chef/resource/ips_package.rb @@ -30,7 +30,9 @@ class Chef allowed_actions :install, :remove, :upgrade - property :accept_license, [TrueClass, FalseClass], default: false, desired_state: false + property :accept_license, [TrueClass, FalseClass], + default: false, desired_state: false, + description: "Accept an end-user license agreement, automatically." end end end diff --git a/lib/chef/resource/kernel_module.rb b/lib/chef/resource/kernel_module.rb new file mode 100644 index 0000000000..bea56dedc2 --- /dev/null +++ b/lib/chef/resource/kernel_module.rb @@ -0,0 +1,129 @@ +# +# Resource:: kernel_module +# +# The MIT License (MIT) +# +# Copyright 2016-2018, Shopify Inc. +# Copyright 2018, Chef Software, Inc. + +require "chef/resource" + +class Chef + class Resource + class KernelModule < Chef::Resource + preview_resource true + resource_name :kernel_module + + description "Use the kernel_module resource to manage kernel modules on Linux systems. This resource can load, unload, blacklist, install, and uninstall modules." + introduced "14.3" + + property :modname, String, + description: "The name of the kernel module.", + name_property: true, identity: true + + property :load_dir, String, + description: "The directory to load modules from.", + default: "/etc/modules-load.d" + + property :unload_dir, String, + description: "The modprobe.d directory.", + default: "/etc/modprobe.d" + + action :install do + description "Load kernel module, and ensure it loads on reboot" + + # load the module first before installing + new_resource.run_action(:load) + + directory new_resource.load_dir do + recursive true + end + + file "#{new_resource.load_dir}/#{new_resource.modname}.conf" do + content "#{new_resource.modname}\n" + notifies :run, "execute[update initramfs]" + end + + execute "update initramfs" do + command initramfs_command + action :nothing + end + end + + action :uninstall do + description "Unload a kernel module and remove module config, so it doesn't load on reboot." + + file "#{new_resource.load_dir}/#{new_resource.modname}.conf" do + action :delete + notifies :run, "execute[update initramfs]" + end + + file "#{new_resource.unload_dir}/blacklist_#{new_resource.modname}.conf" do + action :delete + notifies :run, "execute[update initramfs]" + end + + execute "update initramfs" do + command initramfs_command + action :nothing + end + + new_resource.run_action(:unload) + end + + action :blacklist do + description "Blacklist a kernel module." + + file "#{new_resource.unload_dir}/blacklist_#{new_resource.modname}.conf" do + content "blacklist #{new_resource.modname}" + notifies :run, "execute[update initramfs]" + end + + execute "update initramfs" do + command initramfs_command + action :nothing + end + + new_resource.run_action(:unload) + end + + action :load do + description "Load a kernel module." + + unless module_loaded? + converge_by("load kernel module #{new_resource.modname}") do + shell_out!("modprobe #{new_resource.modname}") + end + end + end + + action :unload do + description "Unload kernel module" + + if module_loaded? + converge_by("unload kernel module #{new_resource.modname}") do + shell_out!("modprobe -r #{new_resource.modname}") + end + end + end + + action_class do + # determine the correct command to regen the initramfs based on platform + # @return [String] + def initramfs_command + if platform_family?("debian") + "update-initramfs -u" + else + "dracut -f" + end + end + + # see if the module is listed in /proc/modules or not + # @return [Boolean] + def module_loaded? + /^#{new_resource.modname}/.match?(::File.read("/proc/modules")) + end + end + end + end +end diff --git a/lib/chef/resource/launchd.rb b/lib/chef/resource/launchd.rb index 9161efa6ea..df01675de1 100644 --- a/lib/chef/resource/launchd.rb +++ b/lib/chef/resource/launchd.rb @@ -30,16 +30,39 @@ class Chef default_action :create allowed_actions :create, :create_if_missing, :delete, :enable, :disable, :restart - property :label, String, identity: true, name_property: true - property :backup, [Integer, FalseClass], desired_state: false - property :cookbook, String, desired_state: false - property :group, [String, Integer] - property :plist_hash, Hash - property :mode, [String, Integer] - property :owner, [String, Integer] - property :path, String - property :source, String - property :session_type, String + property :label, String, + identity: true, name_property: true, + description: "The unique identifier for the job." + + property :backup, [Integer, FalseClass], + desired_state: false, + description: "The number of backups to be kept in /var/chef/backup. Set to false to prevent backups from being kept." + + property :cookbook, String, + desired_state: false, + description: "The name of the cookbook in which the source files are located." + + property :group, [String, Integer], + description: "When launchd is run as the root user, the group to run the job as. If the username property is specified and this property is not, this value is set to the default group for the user." + + property :plist_hash, Hash, + introduced: "12.19", + description: "A Hash of key value pairs used to create the launchd property list." + + property :mode, [String, Integer], + description: "A quoted 3-5 character string that defines the octal mode. For example: '755', '0755', or 00755." + + property :owner, [String, Integer], + description: "A string or ID that identifies the group owner by user name, including fully qualified user names such as domain_user or user@domain. If this value is not specified, existing owners remain unchanged and new owner assignments use the current user (when necessary)." + + property :path, String, + description: "The path to the directory. Using a fully qualified path is recommended, but is not always required." + + property :source, String, + description: "The path to the launchd property list." + + property :session_type, String, + description: "The type of launchd plist to be created. Possible values: system (default) or user." # StartCalendarInterval has some gotchas so we coerce it to help sanity # check. According to `man 5 launchd.plist`: @@ -50,96 +73,180 @@ class Chef # this means that an entry like: # { "Hour"=>0, "Weekday"=>"6-7"} # will not just run on midnight of Sat and Sun, rather it will run _every_ midnight. - property :start_calendar_interval, [Hash, Array], coerce: proc { |type| - # Coerce into an array of hashes to make validation easier - array = if type.is_a?(Array) - type - else - [type] - end - - # Check to make sure that our array only has hashes - unless array.all? { |obj| obj.is_a?(Hash) } - error_msg = "start_calendar_interval must be a single hash or an array of hashes!" - raise Chef::Exceptions::ValidationFailed, error_msg - end - - # Make sure the hashes don't have any incorrect keys/values - array.each do |entry| - allowed_keys = %w{Minute Hour Day Weekday Month} - unless entry.keys.all? { |key| allowed_keys.include?(key) } - failed_keys = entry.keys.reject { |k| allowed_keys.include?(k) }.join(", ") - error_msg = "The following key(s): #{failed_keys} are invalid for start_calendar_interval, must be one of: #{allowed_keys.join(", ")}" - raise Chef::Exceptions::ValidationFailed, error_msg - end - - unless entry.values.all? { |val| val.is_a?(Integer) } - failed_values = entry.values.reject { |val| val.is_a?(Integer) }.join(", ") - error_msg = "Invalid value(s) (#{failed_values}) for start_calendar_interval item. Values must be integers!" - raise Chef::Exceptions::ValidationFailed, error_msg - end - end - - # Don't return array if we only have one entry - if array.size == 1 - array.first - else - array - end - } - - property :type, String, default: "daemon", coerce: proc { |type| - type = type ? type.downcase : "daemon" - types = %w{daemon agent} - - unless types.include?(type) - error_msg = "type must be daemon or agent" - raise Chef::Exceptions::ValidationFailed, error_msg - end - type - } + property :start_calendar_interval, [Hash, Array], + description: "A Hash (similar to crontab) that defines the calendar frequency at which a job is started or an Array.", + coerce: proc { |type| + # Coerce into an array of hashes to make validation easier + array = if type.is_a?(Array) + type + else + [type] + end + + # Check to make sure that our array only has hashes + unless array.all? { |obj| obj.is_a?(Hash) } + error_msg = "start_calendar_interval must be a single hash or an array of hashes!" + raise Chef::Exceptions::ValidationFailed, error_msg + end + + # Make sure the hashes don't have any incorrect keys/values + array.each do |entry| + allowed_keys = %w{Minute Hour Day Weekday Month} + unless entry.keys.all? { |key| allowed_keys.include?(key) } + failed_keys = entry.keys.reject { |k| allowed_keys.include?(k) }.join(", ") + error_msg = "The following key(s): #{failed_keys} are invalid for start_calendar_interval, must be one of: #{allowed_keys.join(", ")}" + raise Chef::Exceptions::ValidationFailed, error_msg + end + + unless entry.values.all? { |val| val.is_a?(Integer) } + failed_values = entry.values.reject { |val| val.is_a?(Integer) }.join(", ") + error_msg = "Invalid value(s) (#{failed_values}) for start_calendar_interval item. Values must be integers!" + raise Chef::Exceptions::ValidationFailed, error_msg + end + end + + # Don't return array if we only have one entry + if array.size == 1 + array.first + else + array + end + } + + property :type, String, + description: "The type of resource. Possible values: daemon (default), agent.", + default: "daemon", coerce: proc { |type| + type = type ? type.downcase : "daemon" + types = %w{daemon agent} + + unless types.include?(type) + error_msg = "type must be daemon or agent" + raise Chef::Exceptions::ValidationFailed, error_msg + end + type + } # Apple LaunchD Keys - property :abandon_process_group, [ TrueClass, FalseClass ] - property :debug, [ TrueClass, FalseClass ] - property :disabled, [ TrueClass, FalseClass ], default: false - property :enable_globbing, [ TrueClass, FalseClass ] - property :enable_transactions, [ TrueClass, FalseClass ] - property :environment_variables, Hash - property :exit_timeout, Integer - property :hard_resource_limits, Hash - property :inetd_compatibility, Hash - property :init_groups, [ TrueClass, FalseClass ] - property :keep_alive, [ TrueClass, FalseClass, Hash ] - property :launch_only_once, [ TrueClass, FalseClass ] - property :ld_group, String - property :limit_load_from_hosts, Array - property :limit_load_to_hosts, Array - property :limit_load_to_session_type, [ Array, String ] - property :low_priority_io, [ TrueClass, FalseClass ] - property :mach_services, Hash - property :nice, Integer - property :on_demand, [ TrueClass, FalseClass ] - property :process_type, String - property :program, String - property :program_arguments, Array - property :queue_directories, Array - property :root_directory, String - property :run_at_load, [ TrueClass, FalseClass ] - property :sockets, Hash - property :soft_resource_limits, Array - property :standard_error_path, String - property :standard_in_path, String - property :standard_out_path, String - property :start_interval, Integer - property :start_on_mount, [ TrueClass, FalseClass ] - property :throttle_interval, Integer - property :time_out, Integer - property :umask, Integer - property :username, String - property :wait_for_debugger, [ TrueClass, FalseClass ] - property :watch_paths, Array - property :working_directory, String + property :abandon_process_group, [ TrueClass, FalseClass ], + description: "If a job dies, all remaining processes with the same process ID may be kept running. Set to true to kill all remaining processes." + + property :debug, [ TrueClass, FalseClass ], + description: "Sets the log mask to LOG_DEBUG for this job." + + property :disabled, [ TrueClass, FalseClass ], default: false, + description: "Hints to launchctl to not submit this job to launchd." + + property :enable_globbing, [ TrueClass, FalseClass ], + description: "Update program arguments before invocation." + + property :enable_transactions, [ TrueClass, FalseClass ], + description: "Track in-progress transactions; if none, then send the SIGKILL signal." + + property :environment_variables, Hash, + description: "Additional environment variables to set before running a job." + + property :exit_timeout, Integer, + description: "The amount of time (in seconds) launchd waits before sending a SIGKILL signal." + + property :hard_resource_limits, Hash, + description: "A Hash of resource limits to be imposed on a job." + + property :inetd_compatibility, Hash, + description: "Specifies if a daemon expects to be run as if it were launched from inetd. Set to wait => true to pass standard input, output, and error file descriptors. Set to wait => false to call the accept system call on behalf of the job, and then pass standard input, output, and error file descriptors." + + property :init_groups, [ TrueClass, FalseClass ], + description: "Specify if initgroups is called before running a job." + + property :keep_alive, [ TrueClass, FalseClass, Hash ], + introduced: "12.14", + description: "Keep a job running continuously (true) or allow demand and conditions on the node to determine if the job keeps running (false)." + + property :launch_only_once, [ TrueClass, FalseClass ], + description: "Specify if a job can be run only one time. Set this value to true if a job cannot be restarted without a full machine reboot." + + property :ld_group, String, + description: "The group name." + + property :limit_load_from_hosts, Array, + description: "An array of hosts to which this configuration file does not apply, i.e. 'apply this configuration file to all hosts not specified in this array'." + + property :limit_load_to_hosts, Array, + description: "An array of hosts to which this configuration file applies." + + property :limit_load_to_session_type, [ Array, String ], + description: "The session type(s) to which this configuration file applies." + + property :low_priority_io, [ TrueClass, FalseClass ], + description: "Specify if the kernel on the node should consider this daemon to be low priority during file system I/O." + + property :mach_services, Hash, + description: "Specify services to be registered with the bootstrap subsystem." + + property :nice, Integer, + description: "The program scheduling priority value in the range -20 to 20." + + property :on_demand, [ TrueClass, FalseClass ], + description: "Keep a job alive. Only applies to macOS version 10.4 (and earlier); use keep_alive instead for newer versions." + + property :process_type, String, + description: "The intended purpose of the job: Adaptive, Background, Interactive, or Standard." + + property :program, String, + description: "The first argument of execvp, typically the file name associated with the file to be executed. This value must be specified if program_arguments is not specified, and vice-versa." + + property :program_arguments, Array, + description: "The second argument of execvp. If program is not specified, this property must be specified and will be handled as if it were the first argument." + + property :queue_directories, Array, + description: "An array of non-empty directories which, if any are modified, will cause a job to be started." + + property :root_directory, String, + description: "chroot to this directory, and then run the job." + + property :run_at_load, [ TrueClass, FalseClass ], + description: "Launch a job once (at the time it is loaded)." + + property :sockets, Hash, + description: "A Hash of on-demand sockets that notify launchd when a job should be run." + + property :soft_resource_limits, Array, + description: "A Hash of resource limits to be imposed on a job." + + property :standard_error_path, String, + description: "The file to which standard error (stderr) is sent." + + property :standard_in_path, String, + description: "The file to which standard input (stdin) is sent." + + property :standard_out_path, String, + description: "The file to which standard output (stdout) is sent." + + property :start_interval, Integer, + description: "The frequency (in seconds) at which a job is started." + + property :start_on_mount, [ TrueClass, FalseClass ], + description: "Start a job every time a file system is mounted." + + property :throttle_interval, Integer, + description: "The frequency (in seconds) at which jobs are allowed to spawn." + + property :time_out, Integer, + description: "The amount of time (in seconds) a job may be idle before it times out. If no value is specified, the default timeout value for launchd will be used." + + property :umask, Integer, + description: "A decimal value to pass to umask before running a job." + + property :username, String, + description: "When launchd is run as the root user, the user to run the job as." + + property :wait_for_debugger, [ TrueClass, FalseClass ], + description: "Specify if launchd has a job wait for a debugger to attach before executing code." + + property :watch_paths, Array, + description: "An array of paths which, if any are modified, will cause a job to be started." + + property :working_directory, String, + description: "Chdir to this directory, and then run the job." end end end diff --git a/lib/chef/resource/log.rb b/lib/chef/resource/log.rb index a9dea6b104..b97b5c9e66 100644 --- a/lib/chef/resource/log.rb +++ b/lib/chef/resource/log.rb @@ -37,8 +37,13 @@ class Chef " entry that is not built into the resource collection, use Chef::Log instead"\ " of the log resource.)" - property :message, String, name_property: true, identity: true - property :level, Symbol, equal_to: [ :debug, :info, :warn, :error, :fatal ], default: :info + property :message, String, + name_property: true, identity: true, + description: "The message to be added to a log file. If not specified we'll use the resource's name instead." + + property :level, Symbol, + equal_to: [ :debug, :info, :warn, :error, :fatal ], default: :info, + description: "The logging level to display this message at." allowed_actions :write default_action :write diff --git a/lib/chef/resource/mdadm.rb b/lib/chef/resource/mdadm.rb index 3b54a53e98..3fc5b7c338 100644 --- a/lib/chef/resource/mdadm.rb +++ b/lib/chef/resource/mdadm.rb @@ -32,14 +32,35 @@ class Chef default_action :create allowed_actions :create, :assemble, :stop - property :chunk, Integer, default: 16 - property :devices, Array, default: lazy { [] } - property :exists, [ TrueClass, FalseClass ], default: false - property :level, Integer, default: 1 - property :metadata, String, default: "0.90" - property :bitmap, String - property :raid_device, String, identity: true, name_property: true - property :layout, String + property :chunk, Integer, + default: 16, + description: "The chunk size. This property should not be used for a RAID 1 mirrored pair (i.e. when the level property is set to 1)." + + property :devices, Array, + default: lazy { [] }, + description: "The devices to be part of a RAID array." + + property :exists, [ TrueClass, FalseClass ], + default: false, + description: "Indicates whether the RAID array exists." + + property :level, Integer, + default: 1, + description: "The RAID level." + + property :metadata, String, + default: "0.90", + description: "The superblock type for RAID metadata." + + property :bitmap, String, + description: "The path to a file in which a write-intent bitmap is stored." + + property :raid_device, String, + identity: true, name_property: true, + description: "The name of the RAID device. We'll use the resource's name if this isn't specified." + + property :layout, String, + description: "The RAID5 parity algorithm. Possible values: left-asymmetric (or la), left-symmetric (or ls), right-asymmetric (or ra), or right-symmetric (or rs)." end end end diff --git a/lib/chef/resource/ohai.rb b/lib/chef/resource/ohai.rb index a84d521333..b286412434 100644 --- a/lib/chef/resource/ohai.rb +++ b/lib/chef/resource/ohai.rb @@ -17,6 +17,8 @@ # limitations under the License. # +require "chef/resource" + class Chef class Resource class Ohai < Chef::Resource diff --git a/lib/chef/resource/ohai_hint.rb b/lib/chef/resource/ohai_hint.rb index 6eb36aea13..f485222ec6 100644 --- a/lib/chef/resource/ohai_hint.rb +++ b/lib/chef/resource/ohai_hint.rb @@ -15,6 +15,8 @@ # limitations under the License. # +require "chef/resource" + class Chef class Resource class OhaiHint < Chef::Resource diff --git a/lib/chef/resource/paludis_package.rb b/lib/chef/resource/paludis_package.rb index 15378cd2e5..722163254f 100644 --- a/lib/chef/resource/paludis_package.rb +++ b/lib/chef/resource/paludis_package.rb @@ -1,6 +1,6 @@ # # Author:: Vasiliy Tolstov (<v.tolstov@selfip.ru>) -# Copyright:: Copyright 2014-2016, Chef Software Inc. +# Copyright:: Copyright 2014-2018, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/lib/chef/resource/portage_package.rb b/lib/chef/resource/portage_package.rb index 6936f5129f..43b0cfc74d 100644 --- a/lib/chef/resource/portage_package.rb +++ b/lib/chef/resource/portage_package.rb @@ -25,6 +25,8 @@ class Chef provides :portage_package description "Use the portage_package resource to manage packages for the Gentoo platform." + + property :timeout, default: 3600 end end end diff --git a/lib/chef/resource/powershell_package.rb b/lib/chef/resource/powershell_package.rb index 1056a8011c..ae6e410f21 100644 --- a/lib/chef/resource/powershell_package.rb +++ b/lib/chef/resource/powershell_package.rb @@ -37,7 +37,7 @@ class Chef property :package_name, [String, Array], coerce: proc { |x| [x].flatten } property :version, [String, Array], coerce: proc { |x| [x].flatten } property :source, [String] - property :skip_publisher_check, [true, false], default: false, introduced: "14.2", description: "Skip validating module author" + property :skip_publisher_check, [true, false], default: false, introduced: "14.3", description: "Skip validating module author" end end end diff --git a/lib/chef/resource/ssh_known_hosts_entry.rb b/lib/chef/resource/ssh_known_hosts_entry.rb new file mode 100644 index 0000000000..07e35587b7 --- /dev/null +++ b/lib/chef/resource/ssh_known_hosts_entry.rb @@ -0,0 +1,146 @@ +# +# Author:: Seth Vargo (<sethvargo@gmail.com>) +# +# Copyright:: 2013-2018, Seth Vargo +# Copyright:: 2017-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/resource" + +class Chef + class Resource + class SshKnownHostsEntry < Chef::Resource + preview_resource true + resource_name :ssh_known_hosts_entry + + description "Use the ssh_known_hosts_entry resource to append an entry for the specified host in /etc/ssh/ssh_known_hosts or a user's known hosts file if specified." + introduced "14.3" + + property :host, String, + description: "The host to add to the known hosts file.", + name_property: true + + property :key, String, + description: "An optional key for the host. If not provided this will be automatically determined." + + property :key_type, String, + description: "The type of key to store.", + default: "rsa" + + property :port, Integer, + description: "The server port that the ssh-keyscan command will use to gather the public key.", + default: 22 + + property :timeout, Integer, + description: "The timeout in seconds for ssh-keyscan.", + default: 30 + + property :mode, String, + description: "The file mode for the ssh_known_hosts file.", + default: "0644" + + property :owner, String, + description: "The file owner for the ssh_known_hosts file.", + default: "root" + + property :group, String, + description: "The file group for the ssh_known_hosts file.", + default: lazy { node["root_group"] } + + property :hash_entries, [TrueClass, FalseClass], + description: "Hash the hostname and addresses in the ssh_known_hosts file for privacy.", + default: false + + property :file_location, String, + description: "The location of the ssh known hosts file. Change this to set a known host file for a particular user.", + default: "/etc/ssh/ssh_known_hosts" + + action :create do + description "Create an entry in the ssh_known_hosts file." + + key = + if new_resource.key + hoststr = (new_resource.port != 22) ? "[#{new_resource.host}]:#{new_resource.port}" : new_resource.host + "#{hoststr} #{type_string(new_resource.key_type)} #{new_resource.key}" + else + keyscan_cmd = ["ssh-keyscan", "-t#{new_resource.key_type}", "-p #{new_resource.port}"] + keyscan_cmd << "-H" if new_resource.hash_entries + keyscan_cmd << new_resource.host + keyscan = shell_out!(keyscan_cmd.join(" "), timeout: new_resource.timeout) + keyscan.stdout + end + + key.sub!(/^#{new_resource.host}/, "[#{new_resource.host}]:#{new_resource.port}") if new_resource.port != 22 + + comment = key.split("\n").first || "" + + r = with_run_context :root do + find_resource(:template, "update ssh known hosts file #{new_resource.file_location}") do + source ::File.expand_path("../support/ssh_known_hosts.erb", __FILE__) + local true + path new_resource.file_location + owner new_resource.owner + group new_resource.group + mode new_resource.mode + action :nothing + delayed_action :create + backup false + variables(entries: []) + end + end + + keys = r.variables[:entries].reject(&:empty?) + + if key_exists?(keys, key, comment) + Chef::Log.debug "Known hosts key for #{new_resource.name} already exists - skipping" + else + r.variables[:entries].push(key) + end + end + + # all this does is send an immediate run_action(:create) to the template resource + action :flush do + description "Immediately flush the entries to the config file. Without this the actual writing of the file is delayed in the Chef run so all entries can be accumulated before writing the file out." + + with_run_context :root do + # if you haven't ever called ssh_known_hosts_entry before you're definitely doing it wrong so we blow up hard. + find_resource!(:template, "update ssh known hosts file #{new_resource.file_location}").run_action(:create) + # it is the user's responsibility to only call this *after* all the ssh_known_hosts_entry resources have been called. + # if you call this too early in your run_list you will get a partial known_host file written to disk, and the resource + # behavior will not be idempotent (template resources will flap and never show 0 resources updated on converged boxes). + Chef::Log.warn "flushed ssh_known_hosts entries to file, later ssh_known_hosts_entry resources will not have been written" + end + end + + action_class do + def key_exists?(keys, key, comment) + keys.any? do |line| + line.match(/#{Regexp.escape(comment)}|#{Regexp.escape(key)}/) + end + end + + def type_string(key_type) + type_map = { + "rsa" => "ssh-rsa", + "dsa" => "ssh-dss", + "ecdsa" => "ecdsa-sha2-nistp256", + "ed25519" => "ssh-ed25519", + } + type_map[key_type] || key_type + end + end + end + end +end diff --git a/lib/chef/resource/support/ssh_known_hosts.erb b/lib/chef/resource/support/ssh_known_hosts.erb new file mode 100644 index 0000000000..0073b250ff --- /dev/null +++ b/lib/chef/resource/support/ssh_known_hosts.erb @@ -0,0 +1,3 @@ +<% @entries.sort.each do |entry| -%> +<%= entry %> +<% end -%> diff --git a/lib/chef/resource/windows_feature_dism.rb b/lib/chef/resource/windows_feature_dism.rb index ebd52c4db7..fd076ffad3 100644 --- a/lib/chef/resource/windows_feature_dism.rb +++ b/lib/chef/resource/windows_feature_dism.rb @@ -17,6 +17,7 @@ # require "chef/resource" +require "chef/platform/query_helpers" class Chef class Resource @@ -30,7 +31,7 @@ class Chef property :feature_name, [Array, String], description: "The name of the feature/role(s) to install if it differs from the resource name.", - coerce: proc { |x| to_lowercase_array(x) }, + coerce: proc { |x| to_formatted_array(x) }, name_property: true property :source, String, @@ -44,12 +45,12 @@ class Chef description: "Specifies a timeout (in seconds) for feature install.", default: 600 - def to_lowercase_array(x) + # @return [Array] lowercase the array unless we're on < Windows 2012 + def to_formatted_array(x) x = x.split(/\s*,\s*/) if x.is_a?(String) # split multiple forms of a comma separated list - # dism on windows < 2012 is case sensitive so only downcase when on 2012+ - # @todo when we're really ready to remove support for Windows 2008 R2 this check can go away - node["platform_version"].to_f < 6.2 ? x : x.map(&:downcase) + # feature installs on windows < 2012 are case sensitive so only downcase when on 2012+ + Chef::Platform.older_than_win_2012_or_8? ? x : x.map(&:downcase) end action :install do @@ -116,7 +117,7 @@ class Chef def features_to_install @install ||= begin # disabled features are always available to install - available_for_install = node["dism_features_cache"]["disabled"] + available_for_install = node["dism_features_cache"]["disabled"].dup # if the user passes a source then removed features are also available for installation available_for_install.concat(node["dism_features_cache"]["removed"]) if new_resource.source @@ -200,7 +201,7 @@ class Chef # dism on windows 2012+ isn't case sensitive so it's best to compare # lowercase lists so the user input doesn't need to be case sensitive # @todo when we're ready to remove windows 2008R2 the gating here can go away - feature_details.downcase! unless node["platform_version"].to_f < 6.2 + feature_details.downcase! unless Chef::Platform.older_than_win_2012_or_8? node.override["dism_features_cache"][feature_type] << feature_details end @@ -208,7 +209,7 @@ class Chef # @return [void] def fail_if_removed return if new_resource.source # if someone provides a source then all is well - if node["platform_version"].to_f > 6.2 + if node["platform_version"].to_f > 6.2 # 2012R2 or later return if registry_key_exists?('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Servicing') && registry_value_exists?('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Servicing', name: "LocalSourcePath") # if source is defined in the registry, still fine end removed = new_resource.feature_name & node["dism_features_cache"]["removed"] @@ -218,7 +219,7 @@ class Chef # Fail unless we're on windows 8+ / 2012+ where deleting a feature is supported # @return [void] def raise_if_delete_unsupported - raise Chef::Exceptions::UnsupportedAction, "#{self} :delete action not support on Windows releases before Windows 8/2012. Cannot continue!" unless node["platform_version"].to_f >= 6.2 + raise Chef::Exceptions::UnsupportedAction, "#{self} :delete action not supported on Windows releases before Windows 8/2012. Cannot continue!" if Chef::Platform.older_than_win_2012_or_8? end end end diff --git a/lib/chef/resource/windows_feature_powershell.rb b/lib/chef/resource/windows_feature_powershell.rb index 82713e3438..daee0e9d34 100644 --- a/lib/chef/resource/windows_feature_powershell.rb +++ b/lib/chef/resource/windows_feature_powershell.rb @@ -19,6 +19,7 @@ require "chef/mixin/powershell_out" require "chef/json_compat" require "chef/resource" +require "chef/platform/query_helpers" class Chef class Resource @@ -35,7 +36,7 @@ class Chef property :feature_name, [Array, String], description: "The name of the feature/role(s) to install if it differs from the resource name.", - coerce: proc { |x| to_lowercase_array(x) }, + coerce: proc { |x| to_formatted_array(x) }, name_property: true property :source, String, @@ -54,9 +55,13 @@ class Chef description: "", default: false - def to_lowercase_array(x) + # Converts strings of features into an Array. Array objects are lowercased unless we're on < 8/2k12+. + # @return [Array] array of features + def to_formatted_array(x) x = x.split(/\s*,\s*/) if x.is_a?(String) # split multiple forms of a comma separated list - x.map(&:downcase) + + # feature installs on windows < 8/2012 are case sensitive so only downcase when on 2012+ + Chef::Platform.older_than_win_2012_or_8? ? x : x.map(&:downcase) end include Chef::Mixin::PowershellOut @@ -73,8 +78,8 @@ class Chef converge_by("install Windows feature#{'s' if features_to_install.count > 1} #{features_to_install.join(',')}") do install_command = "#{install_feature_cmdlet} #{features_to_install.join(',')}" install_command << " -IncludeAllSubFeature" if new_resource.all - if node["platform_version"].to_f < 6.2 && (new_resource.source || new_resource.management_tools) - Chef::Log.warn("The 'source' and 'management_tools' properties are not available on Windows 2012R2 or great. Skipping these properties!") + if Chef::Platform.older_than_win_2012_or_8? && (new_resource.source || new_resource.management_tools) + Chef::Log.warn("The 'source' and 'management_tools' properties are only available on Windows 8/2012 or greater. Skipping these properties!") else install_command << " -Source \"#{new_resource.source}\"" if new_resource.source install_command << " -IncludeManagementTools" if new_resource.management_tools @@ -148,12 +153,16 @@ class Chef raise "The windows_feature_powershell resource requires PowerShell 3.0 or later. Please install PowerShell 3.0+ before running this resource." if powershell_version < 3 end + # The appropriate cmdlet to install a windows feature based on windows release + # @return [String] def install_feature_cmdlet - node["platform_version"].to_f < 6.2 ? "Import-Module ServerManager; Add-WindowsFeature" : "Install-WindowsFeature" + Chef::Platform.older_than_win_2012_or_8? ? "Add-WindowsFeature" : "Install-WindowsFeature" end + # The appropriate cmdlet to remove a windows feature based on windows release + # @return [String] def remove_feature_cmdlet - node["platform_version"].to_f < 6.2 ? "Import-Module ServerManager; Remove-WindowsFeature" : "Uninstall-WindowsFeature" + Chef::Platform.older_than_win_2012_or_8? ? "Remove-WindowsFeature" : "Uninstall-WindowsFeature" end # @return [Array] features the user has requested to install which need installation @@ -220,8 +229,9 @@ class Chef # fetch the list of available feature names and state in JSON and parse the JSON def parsed_feature_list # Grab raw feature information from dism command line - raw_list_of_features = if node["platform_version"].to_f < 6.2 - powershell_out!("Import-Module ServerManager; Get-WindowsFeature | Select-Object -Property Name,InstallState | ConvertTo-Json -Compress", timeout: new_resource.timeout).stdout + # Windows < 2012 doesn't present a state value so we have to check if the feature is installed or not + raw_list_of_features = if Chef::Platform.older_than_win_2012_or_8? # make the older format look like the new format, warts and all + powershell_out!('Get-WindowsFeature | Select-Object -Property Name, @{Name=\"InstallState\"; Expression = {If ($_.Installed) { 1 } Else { 0 }}} | ConvertTo-Json -Compress', timeout: new_resource.timeout).stdout else powershell_out!("Get-WindowsFeature | Select-Object -Property Name,InstallState | ConvertTo-Json -Compress", timeout: new_resource.timeout).stdout end @@ -232,14 +242,15 @@ class Chef # add the features values to the appropriate array # @return [void] def add_to_feature_mash(feature_type, feature_details) - node.override["powershell_features_cache"][feature_type] << feature_details.downcase # lowercase so we can compare properly + # add the lowercase feature name to the mash unless we're on < 2012 where they're case sensitive + node.override["powershell_features_cache"][feature_type] << (Chef::Platform.older_than_win_2012_or_8? ? feature_details : feature_details.downcase) end # Fail if any of the packages are in a removed state # @return [void] def fail_if_removed return if new_resource.source # if someone provides a source then all is well - if node["platform_version"].to_f > 6.2 + if node["platform_version"].to_f > 6.2 # 2012R2 or later return if registry_key_exists?('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Servicing') && registry_value_exists?('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Servicing', name: "LocalSourcePath") # if source is defined in the registry, still fine end removed = new_resource.feature_name & node["powershell_features_cache"]["removed"] @@ -248,7 +259,7 @@ class Chef # Fail unless we're on windows 8+ / 2012+ where deleting a feature is supported def raise_if_delete_unsupported - raise Chef::Exceptions::UnsupportedAction, "#{self} :delete action not support on Windows releases before Windows 8/2012. Cannot continue!" unless node["platform_version"].to_f >= 6.2 + raise Chef::Exceptions::UnsupportedAction, "#{self} :delete action not supported on Windows releases before Windows 8/2012. Cannot continue!" if Chef::Platform.older_than_win_2012_or_8? end end end diff --git a/lib/chef/resource_inspector.rb b/lib/chef/resource_inspector.rb index bbec03ffd6..10fa42c842 100644 --- a/lib/chef/resource_inspector.rb +++ b/lib/chef/resource_inspector.rb @@ -43,6 +43,7 @@ module ResourceInspector data[:actions] = resource.allowed_actions data[:examples] = resource.examples data[:introduced] = resource.introduced + data[:preview] = resource.preview_resource properties = unless complete resource.properties.reject { |_, k| k.options[:declared_in] == Chef::Resource } diff --git a/lib/chef/resources.rb b/lib/chef/resources.rb index cc1af2a5df..b21f2fe6f7 100644 --- a/lib/chef/resources.rb +++ b/lib/chef/resources.rb @@ -49,6 +49,7 @@ require "chef/resource/homebrew_cask" require "chef/resource/homebrew_package" require "chef/resource/homebrew_tap" require "chef/resource/ifconfig" +require "chef/resource/kernel_module" require "chef/resource/ksh" require "chef/resource/launchd" require "chef/resource/link" @@ -93,6 +94,7 @@ require "chef/resource/sudo" require "chef/resource/sysctl" require "chef/resource/swap_file" require "chef/resource/systemd_unit" +require "chef/resource/ssh_known_hosts_entry" require "chef/resource/windows_service" require "chef/resource/subversion" require "chef/resource/smartos_package" diff --git a/lib/chef/util/selinux.rb b/lib/chef/util/selinux.rb index 0d973b0376..fb0c98cff5 100644 --- a/lib/chef/util/selinux.rb +++ b/lib/chef/util/selinux.rb @@ -52,7 +52,7 @@ class Chef restorecon_flags << "-r" if recursive restorecon_flags << file_path Chef::Log.trace("Restoring selinux security content with #{restorecon_path}") - shell_out_compact!(restorecon_path, restorecon_flags) + shell_out!(restorecon_path, restorecon_flags) else Chef::Log.warn "Can not find 'restorecon' on the system. Skipping selinux security context restore." end diff --git a/lib/chef/version.rb b/lib/chef/version.rb index 6b7512dda9..4348c4d952 100644 --- a/lib/chef/version.rb +++ b/lib/chef/version.rb @@ -23,7 +23,7 @@ require "chef/version_string" class Chef CHEF_ROOT = File.expand_path("../..", __FILE__) - VERSION = Chef::VersionString.new("14.2.2") + VERSION = Chef::VersionString.new("14.3.18") end # diff --git a/omnibus/.gitignore b/omnibus/.gitignore index 1a2c556f8d..a959250f6e 100644 --- a/omnibus/.gitignore +++ b/omnibus/.gitignore @@ -1,6 +1,6 @@ vendor/bundle pkg/* -.kitchen.local.yml +kitchen.local.yml bin/* files/chef-server-cookbooks/cache/ files/msi/ChefClient-Config.wxi diff --git a/omnibus/Gemfile b/omnibus/Gemfile index 5457f0f40b..1876755d84 100644 --- a/omnibus/Gemfile +++ b/omnibus/Gemfile @@ -17,7 +17,7 @@ group :development do gem "ohai", "~> 13.0" # Use Test Kitchen with Vagrant for converging the build environment - gem "test-kitchen", "~> 1.13" + gem "test-kitchen", "~> 1.21" gem "kitchen-vagrant", "~> 1.3.1" gem "winrm-fs", "~> 1.0" gem "pry" diff --git a/omnibus/Gemfile.lock b/omnibus/Gemfile.lock index 1b241b0ed7..fd190ca04a 100644 --- a/omnibus/Gemfile.lock +++ b/omnibus/Gemfile.lock @@ -18,7 +18,7 @@ GIT GIT remote: https://github.com/chef/omnibus-software - revision: 0cb3a8dfb6cebd56684c1d4609a676959389e4c5 + revision: 88ce7ac44a6be8a36b6582fa6f50150ed38a87c7 branch: master specs: omnibus-software (4.0.0) @@ -31,13 +31,13 @@ GEM addressable (2.5.2) public_suffix (>= 2.0.2, < 4.0) awesome_print (1.8.0) - aws-sdk (2.11.33) - aws-sdk-resources (= 2.11.33) - aws-sdk-core (2.11.33) + aws-sdk (2.11.70) + aws-sdk-resources (= 2.11.70) + aws-sdk-core (2.11.70) aws-sigv4 (~> 1.0) jmespath (~> 1.0) - aws-sdk-resources (2.11.33) - aws-sdk-core (= 2.11.33) + aws-sdk-resources (2.11.70) + aws-sdk-core (= 2.11.70) aws-sigv4 (1.0.2) berkshelf (4.3.5) addressable (~> 2.3, >= 2.3.4) @@ -78,7 +78,7 @@ GEM celluloid-io (0.16.2) celluloid (>= 0.16.0) nio4r (>= 1.1.0) - chef-config (13.8.5) + chef-config (13.9.4) addressable fuzzyurl mixlib-config (~> 2.0) @@ -92,9 +92,9 @@ GEM erubis (2.7.0) faraday (0.9.2) multipart-post (>= 1.2, < 3) - ffi (1.9.23) - ffi (1.9.23-x64-mingw32) - ffi (1.9.23-x86-mingw32) + ffi (1.9.25) + ffi (1.9.25-x64-mingw32) + ffi (1.9.25-x86-mingw32) ffi-yajl (2.3.1) libyajl2 (~> 1.2) fuzzyurl (0.9.0) @@ -103,17 +103,18 @@ GEM gyoku (1.3.1) builder (>= 2.1.2) hashie (3.5.7) - hitimes (1.2.6) - hitimes (1.2.6-x86-mingw32) + hitimes (1.3.0) + hitimes (1.3.0-x64-mingw32) + hitimes (1.3.0-x86-mingw32) httpclient (2.7.2) iostruct (0.0.4) ipaddress (0.8.3) jmespath (1.4.0) json (2.1.0) - kitchen-vagrant (1.3.1) + kitchen-vagrant (1.3.2) test-kitchen (~> 1.4) libyajl2 (1.2.0) - license_scout (1.0.2) + license_scout (1.0.10) ffi-yajl (~> 2.2) mixlib-shellout (~> 2.2) toml-rb (~> 1.0) @@ -123,13 +124,13 @@ GEM multi_json (~> 1.10) method_source (0.9.0) minitar (0.6.1) - mixlib-archive (0.4.1) + mixlib-archive (0.4.7) mixlib-log - mixlib-authentication (2.0.0) + mixlib-authentication (2.1.1) mixlib-cli (1.7.0) - mixlib-config (2.2.6) + mixlib-config (2.2.8) tomlrb - mixlib-install (3.9.3) + mixlib-install (3.10.0) mixlib-shellout mixlib-versioning thor @@ -147,11 +148,11 @@ GEM net-ssh (4.2.0) net-ssh-gateway (1.3.0) net-ssh (>= 2.6.5) - nio4r (2.3.0) + nio4r (2.3.1) nori (2.6.0) - octokit (4.8.0) + octokit (4.9.0) sawyer (~> 0.8.0, >= 0.5.3) - ohai (13.9.0) + ohai (13.9.2) chef-config (>= 12.5.0.alpha.1, < 14) ffi (~> 1.9) ffi-yajl (~> 2.2) @@ -211,22 +212,22 @@ GEM molinillo (~> 0.4.2) semverse (~> 1.1) systemu (2.6.5) - test-kitchen (1.21.0) + test-kitchen (1.21.2) mixlib-install (~> 3.6) mixlib-shellout (>= 1.2, < 3.0) net-scp (~> 1.1) net-ssh (>= 2.9, < 5.0) net-ssh-gateway (~> 1.2) - thor (~> 0.19, < 0.19.2) + thor (~> 0.19) winrm (~> 2.0) winrm-elevated (~> 1.0) winrm-fs (~> 1.1) - thor (0.19.1) + thor (0.20.0) timers (4.0.4) hitimes toml-rb (1.1.1) citrus (~> 3.0, > 3.0) - tomlrb (1.2.6) + tomlrb (1.2.7) varia_model (0.4.1) buff-extensions (~> 1.0) hashie (>= 2.0.2, < 4.0.0) @@ -267,8 +268,8 @@ DEPENDENCIES pry pry-byebug pry-stack_explorer - test-kitchen (~> 1.13) + test-kitchen (~> 1.21) winrm-fs (~> 1.0) BUNDLED WITH - 1.16.1 + 1.16.2 diff --git a/omnibus/README.md b/omnibus/README.md index 5f325aa164..50c28779be 100644 --- a/omnibus/README.md +++ b/omnibus/README.md @@ -1,22 +1,21 @@ -Client Tools Omnibus project -============================ +# Client Tools Omnibus project + This project creates full-stack platform-specific packages for the following projects: -* AngryChef -* Chef -* Chef with FIPS enabled +- AngryChef +- Chef +- Chef with FIPS enabled + +## Installation -Installation ------------- -You must have a sane Ruby 1.9+ environment with Bundler installed. Ensure all -the required gems are installed: +You must have a sane Ruby environment with Bundler installed. Ensure all the required gems are installed: ```shell $ bundle install --without development ``` -Usage ------ +## Usage + ### Build You create a platform-specific package using the `build project` command: @@ -25,23 +24,17 @@ You create a platform-specific package using the `build project` command: $ bundle exec omnibus build <PROJECT> ``` -The platform/architecture type of the package created will match the platform -where the `build project` command is invoked. For example, running this command -on a MacBook Pro will generate a Mac OS X package. After the build completes -packages will be available in the `pkg/` folder. +The platform/architecture type of the package created will match the platform where the `build project` command is invoked. For example, running this command on a MacBook Pro will generate a Mac OS X package. After the build completes packages will be available in the `pkg/` folder. ### Clean -You can clean up all temporary files generated during the build process with -the `clean` command: +You can clean up all temporary files generated during the build process with the `clean` command: ```shell $ bundle exec omnibus clean <PROJECT> ``` -Adding the `--purge` purge option removes __ALL__ files generated during the -build including the project install directory (`/opt/chef`) and -the package cache directory (`/var/cache/omnibus/pkg`): +Adding the `--purge` purge option removes **ALL** files generated during the build including the project install directory (`/opt/chef`) and the package cache directory (`/var/cache/omnibus/pkg`): ```shell $ bundle exec omnibus clean <PROJECT> --purge @@ -49,9 +42,7 @@ $ bundle exec omnibus clean <PROJECT> --purge ### Publish -Omnibus has a built-in mechanism for releasing to a variety of "backends", such -as Amazon S3 and Artifactory. You must set the proper credentials in your `omnibus.rb` -config file or specify them via the command line. +Omnibus has a built-in mechanism for releasing to a variety of "backends", such as Amazon S3 and Artifactory. You must set the proper credentials in your `omnibus.rb` config file or specify them via the command line. ```shell $ bundle exec omnibus publish path/to/*.deb --backend s3 @@ -59,40 +50,27 @@ $ bundle exec omnibus publish path/to/*.deb --backend s3 ### Help -Full help for the Omnibus command line interface can be accessed with the -`help` command: +Full help for the Omnibus command line interface can be accessed with the `help` command: ```shell $ bundle exec omnibus help ``` -Kitchen-based Build Environment -------------------------------- -Every Omnibus project ships will a project-specific -[Berksfile](http://berkshelf.com/) that will allow you to build your omnibus projects on all of the projects listed -in the `.kitchen.yml`. You can add/remove additional platforms as needed by -changing the list found in the `.kitchen.yml` `platforms` YAML stanza. +## Kitchen-based Build Environment -This build environment is designed to get you up-and-running quickly. However, -there is nothing that restricts you to building on other platforms. Simply use -the [omnibus cookbook](https://github.com/chef-cookbooks/omnibus) to setup -your desired platform and execute the build steps listed above. +Every Omnibus project ships will a project-specific [Berksfile](https://docs.chef.io/berkshelf.html/) that will allow you to build your omnibus projects on all of the projects listed in the `kitchen.yml`. You can add/remove additional platforms as needed by changing the list found in the `kitchen.yml` `platforms` YAML stanza. -The default build environment requires Test Kitchen and VirtualBox for local -development. Test Kitchen also exposes the ability to provision instances using -various cloud providers like AWS, DigitalOcean, or OpenStack. For more -information, please see the [Test Kitchen documentation](http://kitchen.ci). +This build environment is designed to get you up-and-running quickly. However, there is nothing that restricts you to building on other platforms. Simply use the [omnibus cookbook](https://github.com/chef-cookbooks/omnibus) to setup your desired platform and execute the build steps listed above. -Once you have tweaked your `.kitchen.yml` (or `.kitchen.local.yml`) to your -liking, you can bring up an individual build environment using the `kitchen` -command. +The default build environment requires Test Kitchen and VirtualBox for local development. Test Kitchen also exposes the ability to provision instances using various cloud providers like AWS, DigitalOcean, or OpenStack. For more information, please see the [Test Kitchen documentation](http://kitchen.ci). + +Once you have tweaked your `kitchen.yml` (or `kitchen.local.yml`) to your liking, you can bring up an individual build environment using the `kitchen` command. ```shell $ bundle exec kitchen converge chef-ubuntu-1404 ``` -Then login to the instance and build the project as described in the Usage -section: +Then login to the instance and build the project as described in the Usage section: ```shell $ bundle exec kitchen login <PROJECT>-ubuntu-1204 @@ -101,6 +79,7 @@ $ bundle exec kitchen login <PROJECT>-ubuntu-1204 [vagrant@ubuntu...] $ ... [vagrant@ubuntu...] $ bundle exec omnibus build <PROJECT> -l internal ``` + ```shell $ kitchen login chef-ubuntu-1404 [vagrant@ubuntu...] $ source load-omnibus-toolchain.sh @@ -110,10 +89,7 @@ $ kitchen login chef-ubuntu-1404 [vagrant@ubuntu...] $ bundle exec omnibus build chef -l internal ``` -You can also login to Windows instances but will have to manually call the -`load-omnibus-toolchain.bat` script which initializes the build environment. -Please note the mounted code directory is also at `C:\home\vagrant\chef\omnibus` -as opposed to `C:\Users\vagrant\chef\omnibus`. +You can also login to Windows instances but will have to manually call the `load-omnibus-toolchain.bat` script which initializes the build environment. Please note the mounted code directory is also at `C:\home\vagrant\chef\omnibus` as opposed to `C:\Users\vagrant\chef\omnibus`. ```shell $ bundle exec kitchen login <PROJECT>-windows-81-professional @@ -130,13 +106,12 @@ C:\vagrant\code\chef\omnibus>bundle install --without development C:\vagrant\code\chef\omnibus>bundle exec omnibus build chef -l internal ``` -For a complete list of all commands and platforms, run `kitchen list` or -`kitchen help`. +For a complete list of all commands and platforms, run `kitchen list` or `kitchen help`. + +## License -License -------- ```text -Copyright 2012-2016, Chef Software, Inc. +Copyright 2012-2018, Chef Software, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/omnibus/.kitchen.vmware.yml b/omnibus/kitchen.vmware.yml index 69f001ef97..69f001ef97 100644 --- a/omnibus/.kitchen.vmware.yml +++ b/omnibus/kitchen.vmware.yml diff --git a/omnibus/.kitchen.yml b/omnibus/kitchen.yml index 56b11de3c3..2e889a789a 100644 --- a/omnibus/.kitchen.yml +++ b/omnibus/kitchen.yml @@ -33,25 +33,21 @@ provisioner: chef_omnibus_root: /opt/angrychef platforms: - - name: centos-5.11 + - name: centos-6 run_list: yum-epel::default - - name: centos-6.7 + - name: centos-7 run_list: yum-epel::default - - name: centos-7.2 - run_list: yum-epel::default - - name: debian-8.2 + - name: debian-8 run_list: apt::default - - name: freebsd-9.3 - run_list: - - freebsd::portsnap - - freebsd::pkgng - - name: freebsd-10.2 + - name: freebsd-10 + run_list: freebsd::portsnap + - name: freebsd-11 run_list: freebsd::portsnap - - name: ubuntu-10.04 + - name: ubuntu-14.04 run_list: apt::default - - name: ubuntu-12.04 + - name: ubuntu-16.04 run_list: apt::default - - name: ubuntu-14.04 + - name: ubuntu-18.04 run_list: apt::default # The following (private) boxes are shared via Atlas and are only # available to users working for Chef. Sorry, it's about software licensing. @@ -64,10 +60,10 @@ platforms: # the private boxes. # # The Mac OS X boxes are VMware only also. You can enable VMware Fusion - # by activating the `.kitchen.vmware.yml` file with the `KITCHEN_LOCAL_YAML` + # by activating the `kitchen.vmware.yml` file with the `KITCHEN_LOCAL_YAML` # environment variable: # - # KITCHEN_LOCAL_YAML=.kitchen.vmware.yml kitchen converge chefdk-macosx-109 + # KITCHEN_LOCAL_YAML=kitchen.vmware.yml kitchen converge chefdk-macosx-109 # # OSX diff --git a/omnibus/resources/chef/msi/source.wxs.erb b/omnibus/resources/chef/msi/source.wxs.erb index c87c400624..f07050e13d 100644 --- a/omnibus/resources/chef/msi/source.wxs.erb +++ b/omnibus/resources/chef/msi/source.wxs.erb @@ -266,7 +266,7 @@ --> <Icon Id="oc.ico" SourceFile="Resources\assets\oc_16x16.ico"/> <Property Id="ARPPRODUCTICON" Value="oc.ico" /> - <Property Id="ARPHELPLINK" Value="http://www.getchef.com/support/" /> + <Property Id="ARPHELPLINK" Value="https://www.chef.io/support/" /> <Property Id="WIXUI_INSTALLDIR" Value="INSTALLLOCATION" /> <UIRef Id="ChefClientUI_InstallDir"/> diff --git a/omnibus_overrides.rb b/omnibus_overrides.rb index 1d2b46bdbe..cbb2edd6cf 100644 --- a/omnibus_overrides.rb +++ b/omnibus_overrides.rb @@ -6,7 +6,7 @@ override :bundler, version: "1.16.1" override "nokogiri", version: "1.8.2" override "libffi", version: "3.2.1" override "libiconv", version: "1.15" -override "liblzma", version: "5.2.3" +override "liblzma", version: "5.2.4" override "libtool", version: "2.4.2" override "libxml2", version: "2.9.7" override "libxslt", version: "1.1.30" diff --git a/spec/functional/resource/windows_task_spec.rb b/spec/functional/resource/windows_task_spec.rb index 65a396cf56..46fbfe2e82 100644 --- a/spec/functional/resource/windows_task_spec.rb +++ b/spec/functional/resource/windows_task_spec.rb @@ -1109,6 +1109,60 @@ describe Chef::Resource::WindowsTask, :windows_only do end end + context "task_name with parent folder" do + describe "task_name with path '\\foo\\chef-client-functional-test' " do + let(:task_name) { "\\foo\\chef-client-functional-test" } + after { delete_task } + subject do + new_resource = Chef::Resource::WindowsTask.new(task_name, run_context) + new_resource.command task_name + new_resource.run_level :highest + new_resource.frequency :once + new_resource.execution_time_limit = 259200 / 60 # converting "PT72H" into minutes and passing here since win32-taskscheduler accespts this + new_resource + end + + it "creates the scheduled task with task name 'chef-client-functional-test' inside path '\\foo'" do + call_for_create_action + current_resource = call_for_load_current_resource + expect(current_resource.exists).to eq(true) + expect(current_resource.task.application_name).to eq(task_name) + end + + it "does not converge the resource if it is already converged" do + subject.run_action(:create) + subject.run_action(:create) + expect(subject).not_to be_updated_by_last_action + end + end + + describe "task_name with path '\\foo\\bar\\chef-client-functional-test' " do + let(:task_name) { "\\foo\\bar\\chef-client-functional-test" } + after { delete_task } + subject do + new_resource = Chef::Resource::WindowsTask.new(task_name, run_context) + new_resource.command task_name + new_resource.run_level :highest + new_resource.frequency :once + new_resource.execution_time_limit = 259200 / 60 # converting "PT72H" into minutes and passing here since win32-taskscheduler accespts this + new_resource + end + + it "creates the scheduled task with task with name 'chef-client-functional-test' inside path '\\foo\\bar' " do + call_for_create_action + current_resource = call_for_load_current_resource + expect(current_resource.exists).to eq(true) + expect(current_resource.task.application_name).to eq(task_name) + end + + it "does not converge the resource if it is already converged" do + subject.run_action(:create) + subject.run_action(:create) + expect(subject).not_to be_updated_by_last_action + end + end + end + describe "Examples of idempotent checks for each frequency" do after { delete_task } context "For frequency :once" do diff --git a/spec/integration/knife/common_options_spec.rb b/spec/integration/knife/common_options_spec.rb index 6b6b83aafe..da1409456b 100644 --- a/spec/integration/knife/common_options_spec.rb +++ b/spec/integration/knife/common_options_spec.rb @@ -28,7 +28,7 @@ describe "knife common options", :workstation do Chef::Config.treat_deprecation_warnings_as_errors(false) end - let(:local_listen_warning) { /\Awarn:.*local.*listen.*$/i } + let(:local_listen_warning) { /\Awarn:.*local.*listen.*$/im } when_the_repository "has a node" do before { file "nodes/x.json", {} } diff --git a/spec/support/shared/unit/provider/useradd_based_user_provider.rb b/spec/support/shared/unit/provider/useradd_based_user_provider.rb index e123e8e0e2..caa76e4ad6 100644 --- a/spec/support/shared/unit/provider/useradd_based_user_provider.rb +++ b/spec/support/shared/unit/provider/useradd_based_user_provider.rb @@ -160,7 +160,7 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option "-d", "/Users/mud", "-m", "adam" ]) - expect(provider).to receive(:shell_out!).with(*command).and_return(true) + expect(provider).to receive(:shell_out_compacted!).with(*command).and_return(true) provider.create_user end @@ -181,7 +181,7 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option "-u", "1000", "-r", "-m", "adam" ]) - expect(provider).to receive(:shell_out!).with(*command).and_return(true) + expect(provider).to receive(:shell_out_compacted!).with(*command).and_return(true) provider.create_user end @@ -204,7 +204,7 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option "-d", "/Users/mud", "-m", "adam" ] - expect(provider).to receive(:shell_out!).with(*command).and_return(true) + expect(provider).to receive(:shell_out_compacted!).with(*command).and_return(true) provider.manage_user end @@ -215,7 +215,7 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option "-d", "/Users/mud", "-m", "adam" ] - expect(provider).to receive(:shell_out!).with(*command).and_return(true) + expect(provider).to receive(:shell_out_compacted!).with(*command).and_return(true) provider.manage_user end @@ -224,7 +224,7 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option command = ["usermod", "-g", "23", "adam" ] - expect(provider).to receive(:shell_out!).with(*command).and_return(true) + expect(provider).to receive(:shell_out_compacted!).with(*command).and_return(true) provider.manage_user end end @@ -232,24 +232,24 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option describe "when removing a user" do it "should run userdel with the new resources user name" do - expect(provider).to receive(:shell_out!).with("userdel", @new_resource.username).and_return(true) + expect(provider).to receive(:shell_out_compacted!).with("userdel", @new_resource.username).and_return(true) provider.remove_user end it "should run userdel with the new resources user name and -r if manage_home is true" do @new_resource.manage_home true - expect(provider).to receive(:shell_out!).with("userdel", "-r", @new_resource.username).and_return(true) + expect(provider).to receive(:shell_out_compacted!).with("userdel", "-r", @new_resource.username).and_return(true) provider.remove_user end it "should run userdel with the new resources user name if non_unique is true" do - expect(provider).to receive(:shell_out!).with("userdel", @new_resource.username).and_return(true) + expect(provider).to receive(:shell_out_compacted!).with("userdel", @new_resource.username).and_return(true) provider.remove_user end it "should run userdel with the new resources user name and -f if force is true" do @new_resource.force(true) - expect(provider).to receive(:shell_out!).with("userdel", "-f", @new_resource.username).and_return(true) + expect(provider).to receive(:shell_out_compacted!).with("userdel", "-f", @new_resource.username).and_return(true) provider.remove_user end end @@ -335,14 +335,14 @@ shared_examples_for "a useradd-based user provider" do |supported_useradd_option describe "when locking the user" do it "should run usermod -L with the new resources username" do - expect(provider).to receive(:shell_out!).with("usermod", "-L", @new_resource.username) + expect(provider).to receive(:shell_out_compacted!).with("usermod", "-L", @new_resource.username) provider.lock_user end end describe "when unlocking the user" do it "should run usermod -L with the new resources username" do - expect(provider).to receive(:shell_out!).with("usermod", "-U", @new_resource.username) + expect(provider).to receive(:shell_out_compacted!).with("usermod", "-U", @new_resource.username) provider.unlock_user end end diff --git a/spec/unit/chef_class_spec.rb b/spec/unit/chef_class_spec.rb index 21987c01ab..2f370388fa 100644 --- a/spec/unit/chef_class_spec.rb +++ b/spec/unit/chef_class_spec.rb @@ -107,4 +107,124 @@ describe "Chef class" do end.to raise_error(Chef::Exceptions::InvalidEventType) end end + + describe "Deprecation system" do + context "with treat_deprecation_warnings_as_errors false" do + before { Chef::Config[:treat_deprecation_warnings_as_errors] = false } + + it "displays a simple deprecation warning" do + expect(Chef::Log).to receive(:warn).with(%r{spec/unit/chef_class_spec\.rb.*?I'm a little teapot.*?Please see}m) + Chef.deprecated(:generic, "I'm a little teapot.") + end + + it "allows silencing all warnings" do + Chef::Config[:silence_deprecation_warnings] = true + expect(Chef::Log).to_not receive(:warn) + Chef.deprecated(:generic, "I'm a little teapot.") + Chef.deprecated(:internal_api, "Short and stout.") + Chef.deprecated(:generic, "This is my handle.") + end + + it "allows silencing specific types" do + Chef::Config[:silence_deprecation_warnings] = [:internal_api] + expect(Chef::Log).to receive(:warn).with(/I'm a little teapot/).once + expect(Chef::Log).to receive(:warn).with(/This is my handle/).once + Chef.deprecated(:generic, "I'm a little teapot.") + Chef.deprecated(:internal_api, "Short and stout.") + Chef.deprecated(:generic, "This is my handle.") + end + + it "allows silencing specific IDs" do + Chef::Config[:silence_deprecation_warnings] = [0] + expect(Chef::Log).to receive(:warn).with(/I'm a little teapot/).once + expect(Chef::Log).to receive(:warn).with(/This is my handle/).once + Chef.deprecated(:generic, "I'm a little teapot.") + Chef.deprecated(:internal_api, "Short and stout.") + Chef.deprecated(:generic, "This is my handle.") + end + + it "allows silencing specific IDs using the CHEF- syntax" do + Chef::Config[:silence_deprecation_warnings] = ["CHEF-0"] + expect(Chef::Log).to receive(:warn).with(/I'm a little teapot/).once + expect(Chef::Log).to receive(:warn).with(/This is my handle/).once + Chef.deprecated(:generic, "I'm a little teapot.") + Chef.deprecated(:internal_api, "Short and stout.") + Chef.deprecated(:generic, "This is my handle.") + end + + it "allows silencing specific IDs using the chef- syntax" do + Chef::Config[:silence_deprecation_warnings] = ["chef-0"] + expect(Chef::Log).to receive(:warn).with(/I'm a little teapot/).once + expect(Chef::Log).to receive(:warn).with(/This is my handle/).once + Chef.deprecated(:generic, "I'm a little teapot.") + Chef.deprecated(:internal_api, "Short and stout.") + Chef.deprecated(:generic, "This is my handle.") + end + + it "allows silencing specific lines" do + Chef::Config[:silence_deprecation_warnings] = ["chef_class_spec.rb:#{__LINE__ + 4}"] + expect(Chef::Log).to receive(:warn).with(/I'm a little teapot/).once + expect(Chef::Log).to receive(:warn).with(/This is my handle/).once + Chef.deprecated(:generic, "I'm a little teapot.") + Chef.deprecated(:generic, "Short and stout.") + Chef.deprecated(:internal_api, "This is my handle.") + end + + it "allows silencing all via inline comments" do + expect(Chef::Log).to receive(:warn).with(/I'm a little teapot/).once + expect(Chef::Log).to receive(:warn).with(/This is my handle/).once + Chef.deprecated(:generic, "I'm a little teapot.") + Chef.deprecated(:generic, "Short and stout.") # chef:silence_deprecation + Chef.deprecated(:internal_api, "This is my handle.") + end + + it "allows silencing specific types via inline comments" do + expect(Chef::Log).to receive(:warn).with(/I'm a little teapot/).once + expect(Chef::Log).to receive(:warn).with(/This is my handle/).once + Chef.deprecated(:generic, "I'm a little teapot.") + Chef.deprecated(:generic, "Short and stout.") # chef:silence_deprecation:generic + Chef.deprecated(:internal_api, "This is my handle.") + end + + it "does not silence via inline comments when the types don't match" do + expect(Chef::Log).to receive(:warn).with(/I'm a little teapot/).once + expect(Chef::Log).to receive(:warn).with(/Short and stout/).once + expect(Chef::Log).to receive(:warn).with(/This is my handle/).once + Chef.deprecated(:generic, "I'm a little teapot.") + Chef.deprecated(:internal_api, "Short and stout.") # chef:silence_deprecation:generic + Chef.deprecated(:internal_api, "This is my handle.") + end + + it "allows silencing all via inline comments with other stuff in the comment" do + expect(Chef::Log).to receive(:warn).with(/I'm a little teapot/).once + expect(Chef::Log).to receive(:warn).with(/This is my handle/).once + Chef.deprecated(:generic, "I'm a little teapot.") + Chef.deprecated(:generic, "Short and stout.") # rubocop:something chef:silence_deprecation other stuff + Chef.deprecated(:internal_api, "This is my handle.") + end + + it "handles multiple silence configurations at the same time" do + Chef::Config[:silence_deprecation_warnings] = ["exit_code", "chef_class_spec.rb:#{__LINE__ + 6}"] + expect(Chef::Log).to receive(:warn).with(/I'm a little teapot/).once + expect(Chef::Log).to receive(:warn).with(/This is my spout/).once + expect(Chef::Log).to receive(:warn).with(/Hear me shout/).once + Chef.deprecated(:generic, "I'm a little teapot.") + Chef.deprecated(:generic, "Short and stout.") # chef:silence_deprecation + Chef.deprecated(:internal_api, "This is my handle.") + Chef.deprecated(:internal_api, "This is my spout.") + Chef.deprecated(:exit_code, "When I get all steamed up.") + Chef.deprecated(:generic, "Hear me shout.") + end + end + + context "with treat_deprecation_warnings_as_errors true" do + # This is already turned on globally for Chef's unit tests, but just for clarity do it here too. + before { Chef::Config[:treat_deprecation_warnings_as_errors] = true } + + it "displays a simple deprecation error" do + expect(Chef::Log).to receive(:error).with(%r{spec/unit/chef_class_spec\.rb.*?I'm a little teapot.*?Please see}m) + expect { Chef.deprecated(:generic, "I'm a little teapot.") }.to raise_error(/I'm a little teapot./) + end + end + end end diff --git a/spec/unit/deprecated_spec.rb b/spec/unit/deprecated_spec.rb index 4eba764b63..9c60080cef 100644 --- a/spec/unit/deprecated_spec.rb +++ b/spec/unit/deprecated_spec.rb @@ -20,40 +20,46 @@ require "chef/deprecated" describe Chef::Deprecated do class TestDeprecation < Chef::Deprecated::Base - def id; 999; end - - def target; "test.html"; end - - def link; "#{Chef::Deprecated::Base::BASE_URL}test.html"; end + target 999, "test.html" end context "loading a deprecation class" do it "loads the correct class" do - expect(Chef::Deprecated.create(:test_deprecation)).to be_an_instance_of(TestDeprecation) + expect(Chef::Deprecated.create(:test_deprecation, nil, nil)).to be_an_instance_of(TestDeprecation) end - it "optionally sets a message" do - deprecation = Chef::Deprecated.create(:test_deprecation, "A test message") + it "sets a message" do + deprecation = Chef::Deprecated.create(:test_deprecation, "A test message", nil) expect(deprecation.message).to eql("A test message") end - it "optionally sets the location" do + it "sets the location" do deprecation = Chef::Deprecated.create(:test_deprecation, nil, "A test location") expect(deprecation.location).to eql("A test location") end end context "formatting deprecation warnings" do - let(:base_url) { Chef::Deprecated::Base::BASE_URL } let(:message) { "A test message" } let(:location) { "the location" } it "displays the full URL" do - expect(TestDeprecation.new().url).to eql("#{base_url}test.html") + expect(TestDeprecation.new().url).to eql("https://docs.chef.io/deprecations_test.html") end it "formats a complete deprecation message" do - expect(TestDeprecation.new(message, location).inspect).to eql("#{message} (CHEF-999)#{location}.\nhttps://docs.chef.io/deprecations_test.html") + expect(TestDeprecation.new(message, location).to_s).to eql("Deprecation CHEF-999 from the location\n\n A test message\n\nPlease see https://docs.chef.io/deprecations_test.html for further details and information on how to correct this problem.") + end + end + + it "has no overlapping deprecation IDs" do + id_map = {} + ObjectSpace.each_object(Class).select { |cls| cls < Chef::Deprecated::Base }.each do |cls| + (id_map[cls.deprecation_id] ||= []) << cls + end + collisions = id_map.select { |k, v| v.size != 1 } + unless collisions.empty? + raise "Found deprecation ID collisions:\n#{collisions.map { |k, v| "* #{k} #{v.map(&:name).join(', ')}" }.join("\n")}" end end end diff --git a/spec/unit/lwrp_spec.rb b/spec/unit/lwrp_spec.rb index 4423ccf64e..b42ac3af1e 100644 --- a/spec/unit/lwrp_spec.rb +++ b/spec/unit/lwrp_spec.rb @@ -1,6 +1,6 @@ # # Author:: Christopher Walters (<cw@chef.io>) -# Copyright:: Copyright 2009-2017, Chef Software Inc. +# Copyright:: Copyright 2009-2018, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/spec/unit/mixin/shell_out_spec.rb b/spec/unit/mixin/shell_out_spec.rb index 66dfbd3491..df35960cc9 100644 --- a/spec/unit/mixin/shell_out_spec.rb +++ b/spec/unit/mixin/shell_out_spec.rb @@ -48,128 +48,130 @@ describe Chef::Mixin::ShellOut do ENV.update(@original_env) end + let(:retobj) { instance_double(Mixlib::ShellOut, "error!" => false) } let(:cmd) { "echo '#{rand(1000)}'" } - describe "#shell_out" do - - describe "when the last argument is a Hash" do - describe "and environment is an option" do - it "should not change environment language settings when they are set to nil" do - options = { :environment => { "LC_ALL" => nil, "LANGUAGE" => nil, "LANG" => nil, env_path => nil } } - expect(shell_out_obj).to receive(:shell_out_command).with(cmd, options).and_return(true) - shell_out_obj.shell_out(cmd, options) + [ :shell_out, :shell_out_compact, :shell_out_compact_timeout, :shell_out!, :shell_out_compact!, :shell_out_compact_timeout! ].each do |method| + describe "##{method}" do + + describe "when the last argument is a Hash" do + describe "and environment is an option" do + it "should not change environment language settings when they are set to nil" do + options = { :environment => { "LC_ALL" => nil, "LANGUAGE" => nil, "LANG" => nil, env_path => nil } } + expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, options).and_return(retobj) + shell_out_obj.send(method, cmd, options) + end + + it "should not change environment language settings when they are set to non-nil" do + options = { :environment => { "LC_ALL" => "en_US.UTF-8", "LANGUAGE" => "en_US.UTF-8", "LANG" => "en_US.UTF-8", env_path => "foo:bar:baz" } } + expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, options).and_return(retobj) + shell_out_obj.send(method, cmd, options) + end + + it "should set environment language settings to the configured internal locale when they are not present" do + options = { :environment => { "HOME" => "/Users/morty" } } + expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, { + :environment => { + "HOME" => "/Users/morty", + "LC_ALL" => Chef::Config[:internal_locale], + "LANG" => Chef::Config[:internal_locale], + "LANGUAGE" => Chef::Config[:internal_locale], + env_path => sanitized_path, + }, + }).and_return(retobj) + shell_out_obj.send(method, cmd, options) + end + + it "should not mutate the options hash when it adds language settings" do + options = { :environment => { "HOME" => "/Users/morty" } } + expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, { + :environment => { + "HOME" => "/Users/morty", + "LC_ALL" => Chef::Config[:internal_locale], + "LANG" => Chef::Config[:internal_locale], + "LANGUAGE" => Chef::Config[:internal_locale], + env_path => sanitized_path, + }, + }).and_return(retobj) + shell_out_obj.send(method, cmd, options) + expect(options[:environment].has_key?("LC_ALL")).to be false + end end - it "should not change environment language settings when they are set to non-nil" do - options = { :environment => { "LC_ALL" => "en_US.UTF-8", "LANGUAGE" => "en_US.UTF-8", "LANG" => "en_US.UTF-8", env_path => "foo:bar:baz" } } - expect(shell_out_obj).to receive(:shell_out_command).with(cmd, options).and_return(true) - shell_out_obj.shell_out(cmd, options) + describe "and env is an option" do + it "should not change env when langauge options are set to nil" do + options = { :env => { "LC_ALL" => nil, "LANG" => nil, "LANGUAGE" => nil, env_path => nil } } + expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, options).and_return(retobj) + shell_out_obj.send(method, cmd, options) + end + + it "should not change env when language options are set to non-nil" do + options = { :env => { "LC_ALL" => "de_DE.UTF-8", "LANG" => "de_DE.UTF-8", "LANGUAGE" => "de_DE.UTF-8", env_path => "foo:bar:baz" } } + expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, options).and_return(retobj) + shell_out_obj.send(method, cmd, options) + end + + it "should set environment language settings to the configured internal locale when they are not present" do + options = { :env => { "HOME" => "/Users/morty" } } + expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, { + :env => { + "HOME" => "/Users/morty", + "LC_ALL" => Chef::Config[:internal_locale], + "LANG" => Chef::Config[:internal_locale], + "LANGUAGE" => Chef::Config[:internal_locale], + env_path => sanitized_path, + }, + }).and_return(retobj) + shell_out_obj.send(method, cmd, options) + end + + it "should not mutate the options hash when it adds language settings" do + options = { :env => { "HOME" => "/Users/morty" } } + expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, { + :env => { + "HOME" => "/Users/morty", + "LC_ALL" => Chef::Config[:internal_locale], + "LANG" => Chef::Config[:internal_locale], + "LANGUAGE" => Chef::Config[:internal_locale], + env_path => sanitized_path, + }, + }).and_return(retobj) + shell_out_obj.send(method, cmd, options) + expect(options[:env].has_key?("LC_ALL")).to be false + end end - it "should set environment language settings to the configured internal locale when they are not present" do - options = { :environment => { "HOME" => "/Users/morty" } } - expect(shell_out_obj).to receive(:shell_out_command).with(cmd, { - :environment => { - "HOME" => "/Users/morty", - "LC_ALL" => Chef::Config[:internal_locale], - "LANG" => Chef::Config[:internal_locale], - "LANGUAGE" => Chef::Config[:internal_locale], - env_path => sanitized_path, - }, - }).and_return(true) - shell_out_obj.shell_out(cmd, options) - end - - it "should not mutate the options hash when it adds language settings" do - options = { :environment => { "HOME" => "/Users/morty" } } - expect(shell_out_obj).to receive(:shell_out_command).with(cmd, { - :environment => { - "HOME" => "/Users/morty", - "LC_ALL" => Chef::Config[:internal_locale], - "LANG" => Chef::Config[:internal_locale], - "LANGUAGE" => Chef::Config[:internal_locale], - env_path => sanitized_path, - }, - }).and_return(true) - shell_out_obj.shell_out(cmd, options) - expect(options[:environment].has_key?("LC_ALL")).to be false - end - end - - describe "and env is an option" do - it "should not change env when langauge options are set to nil" do - options = { :env => { "LC_ALL" => nil, "LANG" => nil, "LANGUAGE" => nil, env_path => nil } } - expect(shell_out_obj).to receive(:shell_out_command).with(cmd, options).and_return(true) - shell_out_obj.shell_out(cmd, options) - end - - it "should not change env when language options are set to non-nil" do - options = { :env => { "LC_ALL" => "de_DE.UTF-8", "LANG" => "de_DE.UTF-8", "LANGUAGE" => "de_DE.UTF-8", env_path => "foo:bar:baz" } } - expect(shell_out_obj).to receive(:shell_out_command).with(cmd, options).and_return(true) - shell_out_obj.shell_out(cmd, options) - end - - it "should set environment language settings to the configured internal locale when they are not present" do - options = { :env => { "HOME" => "/Users/morty" } } - expect(shell_out_obj).to receive(:shell_out_command).with(cmd, { - :env => { - "HOME" => "/Users/morty", - "LC_ALL" => Chef::Config[:internal_locale], - "LANG" => Chef::Config[:internal_locale], - "LANGUAGE" => Chef::Config[:internal_locale], - env_path => sanitized_path, - }, - }).and_return(true) - shell_out_obj.shell_out(cmd, options) - end - - it "should not mutate the options hash when it adds language settings" do - options = { :env => { "HOME" => "/Users/morty" } } - expect(shell_out_obj).to receive(:shell_out_command).with(cmd, { - :env => { - "HOME" => "/Users/morty", - "LC_ALL" => Chef::Config[:internal_locale], - "LANG" => Chef::Config[:internal_locale], - "LANGUAGE" => Chef::Config[:internal_locale], - env_path => sanitized_path, - }, - }).and_return(true) - shell_out_obj.shell_out(cmd, options) - expect(options[:env].has_key?("LC_ALL")).to be false - end - end - - describe "and no env/environment option is present" do - it "should set environment language settings to the configured internal locale" do - options = { :user => "morty" } - expect(shell_out_obj).to receive(:shell_out_command).with(cmd, { - :user => "morty", - :environment => { - "LC_ALL" => Chef::Config[:internal_locale], - "LANG" => Chef::Config[:internal_locale], - "LANGUAGE" => Chef::Config[:internal_locale], - env_path => sanitized_path, - }, - }).and_return(true) - shell_out_obj.shell_out(cmd, options) + describe "and no env/environment option is present" do + it "should set environment language settings to the configured internal locale" do + options = { :user => "morty" } + expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, { + :user => "morty", + :environment => { + "LC_ALL" => Chef::Config[:internal_locale], + "LANG" => Chef::Config[:internal_locale], + "LANGUAGE" => Chef::Config[:internal_locale], + env_path => sanitized_path, + }, + }).and_return(retobj) + shell_out_obj.send(method, cmd, options) + end end end end describe "when the last argument is not a Hash" do it "should set environment language settings to the configured internal locale" do - expect(shell_out_obj).to receive(:shell_out_command).with(cmd, { + expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, { :environment => { "LC_ALL" => Chef::Config[:internal_locale], "LANG" => Chef::Config[:internal_locale], "LANGUAGE" => Chef::Config[:internal_locale], env_path => sanitized_path, }, - }).and_return(true) - shell_out_obj.shell_out(cmd) + }).and_return(retobj) + shell_out_obj.send(method, cmd) end end - end describe "#shell_out_with_systems_locale" do @@ -178,19 +180,19 @@ describe Chef::Mixin::ShellOut do describe "and environment is an option" do it "should not change environment['LC_ALL'] when set to nil" do options = { :environment => { "LC_ALL" => nil } } - expect(shell_out_obj).to receive(:shell_out_command).with(cmd, options).and_return(true) + expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, options).and_return(true) shell_out_obj.shell_out_with_systems_locale(cmd, options) end it "should not change environment['LC_ALL'] when set to non-nil" do options = { :environment => { "LC_ALL" => "en_US.UTF-8" } } - expect(shell_out_obj).to receive(:shell_out_command).with(cmd, options).and_return(true) + expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, options).and_return(true) shell_out_obj.shell_out_with_systems_locale(cmd, options) end it "should no longer set environment['LC_ALL'] to nil when 'LC_ALL' not present" do options = { :environment => { "HOME" => "/Users/morty" } } - expect(shell_out_obj).to receive(:shell_out_command).with(cmd, options).and_return(true) + expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, options).and_return(true) shell_out_obj.shell_out_with_systems_locale(cmd, options) end end @@ -198,19 +200,19 @@ describe Chef::Mixin::ShellOut do describe "and env is an option" do it "should not change env when set to nil" do options = { :env => { "LC_ALL" => nil } } - expect(shell_out_obj).to receive(:shell_out_command).with(cmd, options).and_return(true) + expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, options).and_return(true) shell_out_obj.shell_out_with_systems_locale(cmd, options) end it "should not change env when set to non-nil" do options = { :env => { "LC_ALL" => "en_US.UTF-8" } } - expect(shell_out_obj).to receive(:shell_out_command).with(cmd, options).and_return(true) + expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, options).and_return(true) shell_out_obj.shell_out_with_systems_locale(cmd, options) end it "should no longer set env['LC_ALL'] to nil when 'LC_ALL' not present" do options = { :env => { "HOME" => "/Users/morty" } } - expect(shell_out_obj).to receive(:shell_out_command).with(cmd, options).and_return(true) + expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, options).and_return(true) shell_out_obj.shell_out_with_systems_locale(cmd, options) end end @@ -218,7 +220,7 @@ describe Chef::Mixin::ShellOut do describe "and no env/environment option is present" do it "should no longer add environment option and set environment['LC_ALL'] to nil" do options = { :user => "morty" } - expect(shell_out_obj).to receive(:shell_out_command).with(cmd, options).and_return(true) + expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, options).and_return(true) shell_out_obj.shell_out_with_systems_locale(cmd, options) end end @@ -226,7 +228,7 @@ describe Chef::Mixin::ShellOut do describe "when the last argument is not a Hash" do it "should no longer add environment options and set environment['LC_ALL'] to nil" do - expect(shell_out_obj).to receive(:shell_out_command).with(cmd, {}).and_return(true) + expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd).and_return(true) shell_out_obj.shell_out_with_systems_locale(cmd) end end @@ -238,19 +240,19 @@ describe Chef::Mixin::ShellOut do describe "and environment is an option" do it "should not change environment['LC_ALL'] when set to nil" do options = { :environment => { "LC_ALL" => nil } } - expect(shell_out_obj).to receive(:shell_out_command).with(cmd, options).and_return(true) + expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, options).and_return(true) shell_out_obj.shell_out(cmd, **options, default_env: false) end it "should not change environment['LC_ALL'] when set to non-nil" do options = { :environment => { "LC_ALL" => "en_US.UTF-8" } } - expect(shell_out_obj).to receive(:shell_out_command).with(cmd, options).and_return(true) + expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, options).and_return(true) shell_out_obj.shell_out(cmd, **options, default_env: false) end it "should no longer set environment['LC_ALL'] to nil when 'LC_ALL' not present" do options = { :environment => { "HOME" => "/Users/morty" } } - expect(shell_out_obj).to receive(:shell_out_command).with(cmd, options).and_return(true) + expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, options).and_return(true) shell_out_obj.shell_out(cmd, **options, default_env: false) end end @@ -258,19 +260,19 @@ describe Chef::Mixin::ShellOut do describe "and env is an option" do it "should not change env when set to nil" do options = { :env => { "LC_ALL" => nil } } - expect(shell_out_obj).to receive(:shell_out_command).with(cmd, options).and_return(true) + expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, options).and_return(true) shell_out_obj.shell_out(cmd, **options, default_env: false) end it "should not change env when set to non-nil" do options = { :env => { "LC_ALL" => "en_US.UTF-8" } } - expect(shell_out_obj).to receive(:shell_out_command).with(cmd, options).and_return(true) + expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, options).and_return(true) shell_out_obj.shell_out(cmd, **options, default_env: false) end it "should no longer set env['LC_ALL'] to nil when 'LC_ALL' not present" do options = { :env => { "HOME" => "/Users/morty" } } - expect(shell_out_obj).to receive(:shell_out_command).with(cmd, options).and_return(true) + expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, options).and_return(true) shell_out_obj.shell_out(cmd, **options, default_env: false) end end @@ -278,7 +280,7 @@ describe Chef::Mixin::ShellOut do describe "and no env/environment option is present" do it "should no longer add environment option and set environment['LC_ALL'] to nil" do options = { :user => "morty" } - expect(shell_out_obj).to receive(:shell_out_command).with(cmd, options).and_return(true) + expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd, options).and_return(true) shell_out_obj.shell_out(cmd, **options, default_env: false) end end @@ -286,7 +288,7 @@ describe Chef::Mixin::ShellOut do describe "when the last argument is not a Hash" do it "should no longer add environment options and set environment['LC_ALL'] to nil" do - expect(shell_out_obj).to receive(:shell_out_command).with(cmd, {}).and_return(true) + expect(Chef::Mixin::ShellOut).to receive(:shell_out_command).with(cmd).and_return(true) shell_out_obj.shell_out(cmd, default_env: false) end end diff --git a/spec/unit/node_map_spec.rb b/spec/unit/node_map_spec.rb index 24f3bebe2a..253486438b 100644 --- a/spec/unit/node_map_spec.rb +++ b/spec/unit/node_map_spec.rb @@ -22,6 +22,12 @@ require "chef/node_map" class Foo; end class Bar; end +class FooResource < Chef::Resource; end +class BarResource < Chef::Resource; end + +class FooProvider < Chef::Provider; end +class BarProvider < Chef::Provider; end + describe Chef::NodeMap do let(:node_map) { Chef::NodeMap.new } @@ -139,14 +145,14 @@ describe Chef::NodeMap do describe "deleting classes" do it "deletes a class and removes the mapping completely" do node_map.set(:thing, Bar) - expect( node_map.delete_class(Bar) ).to eql({ :thing => [{ :klass => Bar }] }) + expect( node_map.delete_class(Bar) ).to include({ :thing => [{ :klass => Bar, :cookbook_override => false, :core_override => false }] }) expect( node_map.get(node, :thing) ).to eql(nil) end it "deletes a class and leaves the mapping that still has an entry" do node_map.set(:thing, Bar) node_map.set(:thing, Foo) - expect( node_map.delete_class(Bar) ).to eql({ :thing => [{ :klass => Bar }] }) + expect( node_map.delete_class(Bar) ).to eql({ :thing => [{ :klass => Bar, :cookbook_override => false, :core_override => false }] }) expect( node_map.get(node, :thing) ).to eql(Foo) end @@ -154,7 +160,7 @@ describe Chef::NodeMap do node_map.set(:thing1, Bar) node_map.set(:thing2, Bar) node_map.set(:thing2, Foo) - expect( node_map.delete_class(Bar) ).to eql({ :thing1 => [{ :klass => Bar }], :thing2 => [{ :klass => Bar }] }) + expect( node_map.delete_class(Bar) ).to eql({ :thing1 => [{ :klass => Bar, :cookbook_override => false, :core_override => false }], :thing2 => [{ :klass => Bar, :cookbook_override => false, :core_override => false }] }) expect( node_map.get(node, :thing1) ).to eql(nil) expect( node_map.get(node, :thing2) ).to eql(Foo) end @@ -204,4 +210,66 @@ describe Chef::NodeMap do end end + describe "locked mode" do + context "while unlocked" do + it "allows setting the same key twice" do + expect(Chef).to_not receive(:deprecated) + node_map.set(:foo, FooResource) + node_map.set(:foo, BarResource) + expect(node_map.get(node, :foo)).to eql(BarResource) + end + end + + context "while locked" do + # Uncomment the commented `expect`s in 15.0. + it "rejects setting the same key twice" do + expect(Chef).to receive(:deprecated).with(:map_collision, /resource foo/) + node_map.set(:foo, FooResource) + node_map.lock! + node_map.set(:foo, BarResource) + # expect(node_map.get(node, :foo)).to eql(FooResource) + end + + it "allows setting the same key twice when the first has allow_cookbook_override" do + expect(Chef).to_not receive(:deprecated) + node_map.set(:foo, FooResource, allow_cookbook_override: true) + node_map.lock! + node_map.set(:foo, BarResource) + expect(node_map.get(node, :foo)).to eql(BarResource) + end + + it "allows setting the same key twice when the first has allow_cookbook_override with a future version" do + expect(Chef).to_not receive(:deprecated) + node_map.set(:foo, FooResource, allow_cookbook_override: "< 100") + node_map.lock! + node_map.set(:foo, BarResource) + expect(node_map.get(node, :foo)).to eql(BarResource) + end + + it "rejects setting the same key twice when the first has allow_cookbook_override with a past version" do + expect(Chef).to receive(:deprecated).with(:map_collision, /resource foo/) + node_map.set(:foo, FooResource, allow_cookbook_override: "< 1") + node_map.lock! + node_map.set(:foo, BarResource) + # expect(node_map.get(node, :foo)).to eql(FooResource) + end + + it "allows setting the same key twice when the second has __core_override__" do + expect(Chef).to_not receive(:deprecated) + node_map.set(:foo, FooResource) + node_map.lock! + node_map.set(:foo, BarResource, __core_override__: true) + expect(node_map.get(node, :foo)).to eql(BarResource) + end + + it "rejects setting the same key twice for a provider" do + expect(Chef).to receive(:deprecated).with(:map_collision, /provider foo/) + node_map.set(:foo, FooProvider) + node_map.lock! + node_map.set(:foo, BarProvider) + # expect(node_map.get(node, :foo)).to eql(FooProvider) + end + end + end + end diff --git a/spec/unit/provider/group/dscl_spec.rb b/spec/unit/provider/group/dscl_spec.rb index 6e40e41579..b6748fd5f8 100644 --- a/spec/unit/provider/group/dscl_spec.rb +++ b/spec/unit/provider/group/dscl_spec.rb @@ -32,11 +32,11 @@ describe Chef::Provider::Group::Dscl do @provider.current_resource = @current_resource @status = double(stdout: "\n", stderr: "", exitstatus: 0) - allow(@provider).to receive(:shell_out).and_return(@status) + allow(@provider).to receive(:shell_out_compacted).and_return(@status) end it "should run shell_out with the supplied array of arguments appended to the dscl command" do - expect(@provider).to receive(:shell_out).with("dscl", ".", "-cmd", "/Path", "arg1", "arg2") + expect(@provider).to receive(:shell_out_compacted).with("dscl", ".", "-cmd", "/Path", "arg1", "arg2") @provider.dscl("cmd", "/Path", "arg1", "arg2") end diff --git a/spec/unit/provider/group/gpasswd_spec.rb b/spec/unit/provider/group/gpasswd_spec.rb index 287951a1a9..506c7b642a 100644 --- a/spec/unit/provider/group/gpasswd_spec.rb +++ b/spec/unit/provider/group/gpasswd_spec.rb @@ -69,7 +69,7 @@ describe Chef::Provider::Group::Gpasswd, "modify_group_members" do it "logs a message and sets group's members to 'none'" do expect(logger).to receive(:trace).with("group[wheel] setting group members to: none") - expect(@provider).to receive(:shell_out!).with("gpasswd", "-M", "", "wheel") + expect(@provider).to receive(:shell_out_compacted!).with("gpasswd", "-M", "", "wheel") @provider.modify_group_members end end @@ -81,7 +81,7 @@ describe Chef::Provider::Group::Gpasswd, "modify_group_members" do end it "does not modify group membership" do - expect(@provider).not_to receive(:shell_out!) + expect(@provider).not_to receive(:shell_out_compacted!) @provider.modify_group_members end end @@ -89,12 +89,12 @@ describe Chef::Provider::Group::Gpasswd, "modify_group_members" do describe "when the resource specifies group members" do it "should log an appropriate debug message" do expect(logger).to receive(:trace).with("group[wheel] setting group members to: lobster, rage, fist") - allow(@provider).to receive(:shell_out!) + allow(@provider).to receive(:shell_out_compacted!) @provider.modify_group_members end it "should run gpasswd with the members joined by ',' followed by the target group" do - expect(@provider).to receive(:shell_out!).with("gpasswd", "-M", "lobster,rage,fist", "wheel") + expect(@provider).to receive(:shell_out_compacted!).with("gpasswd", "-M", "lobster,rage,fist", "wheel") @provider.modify_group_members end @@ -107,9 +107,9 @@ describe Chef::Provider::Group::Gpasswd, "modify_group_members" do it "should run gpasswd individually for each user when the append option is set" do @new_resource.append(true) - expect(@provider).to receive(:shell_out!).with("gpasswd", "-a", "lobster", "wheel") - expect(@provider).to receive(:shell_out!).with("gpasswd", "-a", "rage", "wheel") - expect(@provider).to receive(:shell_out!).with("gpasswd", "-a", "fist", "wheel") + expect(@provider).to receive(:shell_out_compacted!).with("gpasswd", "-a", "lobster", "wheel") + expect(@provider).to receive(:shell_out_compacted!).with("gpasswd", "-a", "rage", "wheel") + expect(@provider).to receive(:shell_out_compacted!).with("gpasswd", "-a", "fist", "wheel") @provider.modify_group_members end end diff --git a/spec/unit/provider/group/groupadd_spec.rb b/spec/unit/provider/group/groupadd_spec.rb index ded1bc76f1..1aae4fc7f1 100644 --- a/spec/unit/provider/group/groupadd_spec.rb +++ b/spec/unit/provider/group/groupadd_spec.rb @@ -108,14 +108,14 @@ describe Chef::Provider::Group::Groupadd do describe "#create_group" do before do - allow(provider).to receive(:shell_out!).and_return(true) + allow(provider).to receive(:shell_out_compacted!).and_return(true) allow(provider).to receive(:set_options).and_return("monkey") allow(provider).to receive(:groupadd_options).and_return([]) allow(provider).to receive(:modify_group_members).and_return(true) end it "should run groupadd with the return of set_options" do - expect(provider).to receive(:shell_out!).with("groupadd", "monkey").and_return(true) + expect(provider).to receive(:shell_out_compacted!).with("groupadd", "monkey").and_return(true) provider.create_group end @@ -127,13 +127,13 @@ describe Chef::Provider::Group::Groupadd do describe "#manage_group" do before do - allow(provider).to receive(:shell_out!).and_return(true) + allow(provider).to receive(:shell_out_compacted!).and_return(true) allow(provider).to receive(:set_options).and_return("monkey") end it "should run groupmod with the return of set_options" do allow(provider).to receive(:modify_group_members).and_return(true) - expect(provider).to receive(:shell_out!).with("groupmod", "monkey").and_return(true) + expect(provider).to receive(:shell_out_compacted!).with("groupmod", "monkey").and_return(true) provider.manage_group end @@ -145,12 +145,12 @@ describe Chef::Provider::Group::Groupadd do describe "#remove_group" do before do - allow(provider).to receive(:shell_out!).and_return(true) + allow(provider).to receive(:shell_out_compacted!).and_return(true) allow(provider).to receive(:set_options).and_return("monkey") end it "should run groupdel with the new resources group name" do - expect(provider).to receive(:shell_out!).with("groupdel", "aj").and_return(true) + expect(provider).to receive(:shell_out_compacted!).with("groupdel", "aj").and_return(true) provider.remove_group end end @@ -163,7 +163,7 @@ describe Chef::Provider::Group::Groupadd do describe "#load_current_resource" do before do - allow(provider).to receive(:shell_out!).and_return(true) + allow(provider).to receive(:shell_out_compacted!).and_return(true) allow(provider).to receive(:set_options).and_return("monkey") end diff --git a/spec/unit/provider/group/groupmod_spec.rb b/spec/unit/provider/group/groupmod_spec.rb index 3f36a5b8a6..60965f2d47 100644 --- a/spec/unit/provider/group/groupmod_spec.rb +++ b/spec/unit/provider/group/groupmod_spec.rb @@ -65,9 +65,9 @@ describe Chef::Provider::Group::Groupmod do it "logs a message and sets group's members to 'none', then removes existing group members" do expect(logger).to receive(:trace).with("group[wheel] setting group members to: none") - expect(@provider).to receive(:shell_out!).with("group", "mod", "-n", "wheel_bak", "wheel") - expect(@provider).to receive(:shell_out!).with("group", "add", "-g", "123", "-o", "wheel") - expect(@provider).to receive(:shell_out!).with("group", "del", "wheel_bak") + expect(@provider).to receive(:shell_out_compacted!).with("group", "mod", "-n", "wheel_bak", "wheel") + expect(@provider).to receive(:shell_out_compacted!).with("group", "add", "-g", "123", "-o", "wheel") + expect(@provider).to receive(:shell_out_compacted!).with("group", "del", "wheel_bak") @provider.manage_group end end @@ -80,7 +80,7 @@ describe Chef::Provider::Group::Groupmod do it "logs a message and does not modify group membership" do expect(logger).to receive(:trace).with("group[wheel] not changing group members, the group has no members to add") - expect(@provider).not_to receive(:shell_out!) + expect(@provider).not_to receive(:shell_out_compacted!) @provider.manage_group end end @@ -93,10 +93,10 @@ describe Chef::Provider::Group::Groupmod do it "updates group membership correctly" do allow(logger).to receive(:trace) - expect(@provider).to receive(:shell_out!).with("group", "mod", "-n", "wheel_bak", "wheel") - expect(@provider).to receive(:shell_out!).with("user", "mod", "-G", "wheel", "lobster") - expect(@provider).to receive(:shell_out!).with("group", "add", "-g", "123", "-o", "wheel") - expect(@provider).to receive(:shell_out!).with("group", "del", "wheel_bak") + expect(@provider).to receive(:shell_out_compacted!).with("group", "mod", "-n", "wheel_bak", "wheel") + expect(@provider).to receive(:shell_out_compacted!).with("user", "mod", "-G", "wheel", "lobster") + expect(@provider).to receive(:shell_out_compacted!).with("group", "add", "-g", "123", "-o", "wheel") + expect(@provider).to receive(:shell_out_compacted!).with("group", "del", "wheel_bak") @provider.manage_group end end @@ -111,10 +111,10 @@ describe Chef::Provider::Group::Groupmod do end it "should run a group add command and some user mod commands" do - expect(@provider).to receive(:shell_out!).with("group", "add", "-g", "123", "wheel") - expect(@provider).to receive(:shell_out!).with("user", "mod", "-G", "wheel", "lobster") - expect(@provider).to receive(:shell_out!).with("user", "mod", "-G", "wheel", "rage") - expect(@provider).to receive(:shell_out!).with("user", "mod", "-G", "wheel", "fist") + expect(@provider).to receive(:shell_out_compacted!).with("group", "add", "-g", "123", "wheel") + expect(@provider).to receive(:shell_out_compacted!).with("user", "mod", "-G", "wheel", "lobster") + expect(@provider).to receive(:shell_out_compacted!).with("user", "mod", "-G", "wheel", "rage") + expect(@provider).to receive(:shell_out_compacted!).with("user", "mod", "-G", "wheel", "fist") @provider.create_group end end @@ -128,7 +128,7 @@ describe Chef::Provider::Group::Groupmod do end it "should run a group del command" do - expect(@provider).to receive(:shell_out!).with("group", "del", "wheel") + expect(@provider).to receive(:shell_out_compacted!).with("group", "del", "wheel") @provider.remove_group end end diff --git a/spec/unit/provider/group/pw_spec.rb b/spec/unit/provider/group/pw_spec.rb index 736ba0671b..fc42a64566 100644 --- a/spec/unit/provider/group/pw_spec.rb +++ b/spec/unit/provider/group/pw_spec.rb @@ -52,7 +52,7 @@ describe Chef::Provider::Group::Pw do describe "when creating a group" do it "should run pw groupadd with the return of set_options and set_members_option" do @new_resource.gid(23) - expect(@provider).to receive(:shell_out!).with("pw", "groupadd", "wheel", "-g", "23", "-M", "root,aj").and_return(true) + expect(@provider).to receive(:shell_out_compacted!).with("pw", "groupadd", "wheel", "-g", "23", "-M", "root,aj").and_return(true) @provider.create_group end end @@ -62,8 +62,8 @@ describe Chef::Provider::Group::Pw do it "should run pw groupmod with the return of set_options" do @new_resource.gid(42) @new_resource.members(["someone"]) - expect(@provider).to receive(:shell_out!).with("pw", "groupmod", "wheel", "-g", "42", "-m", "someone").and_return(true) - expect(@provider).to receive(:shell_out!).with("pw", "groupmod", "wheel", "-g", "42", "-d", "root,aj").and_return(true) + expect(@provider).to receive(:shell_out_compacted!).with("pw", "groupmod", "wheel", "-g", "42", "-m", "someone").and_return(true) + expect(@provider).to receive(:shell_out_compacted!).with("pw", "groupmod", "wheel", "-g", "42", "-d", "root,aj").and_return(true) @provider.manage_group end @@ -71,7 +71,7 @@ describe Chef::Provider::Group::Pw do describe "when removing the group" do it "should run pw groupdel with the new resources group name" do - expect(@provider).to receive(:shell_out!).with("pw", "groupdel", "wheel").and_return(true) + expect(@provider).to receive(:shell_out_compacted!).with("pw", "groupdel", "wheel").and_return(true) @provider.remove_group end end diff --git a/spec/unit/provider/group/suse_spec.rb b/spec/unit/provider/group/suse_spec.rb index e61d865b6d..29d8f4c58c 100644 --- a/spec/unit/provider/group/suse_spec.rb +++ b/spec/unit/provider/group/suse_spec.rb @@ -76,14 +76,14 @@ describe Chef::Provider::Group::Suse do describe "#add_member" do it "should call out to groupmod to add user" do - expect(provider).to receive(:shell_out!).with("groupmod", "-A", "new_user", "new_group") + expect(provider).to receive(:shell_out_compacted!).with("groupmod", "-A", "new_user", "new_group") provider.add_member("new_user") end end describe "#remove_member" do it "should call out to groupmod to remove user" do - expect(provider).to receive(:shell_out!).with("groupmod", "-R", "new_user", "new_group") + expect(provider).to receive(:shell_out_compacted!).with("groupmod", "-R", "new_user", "new_group") provider.remove_member("new_user") end end diff --git a/spec/unit/provider/group/usermod_spec.rb b/spec/unit/provider/group/usermod_spec.rb index da2c20b7da..e34949f839 100644 --- a/spec/unit/provider/group/usermod_spec.rb +++ b/spec/unit/provider/group/usermod_spec.rb @@ -39,7 +39,7 @@ describe Chef::Provider::Group::Usermod do end it "should log an appropriate message" do - expect(@provider).not_to receive(:shell_out!) + expect(@provider).not_to receive(:shell_out_compacted!) @provider.modify_group_members end end @@ -85,9 +85,9 @@ describe Chef::Provider::Group::Usermod do @provider.current_resource = current_resource @node.automatic_attrs[:platform] = platform @new_resource.append(true) - expect(@provider).to receive(:shell_out!).with("usermod", *flags, "wheel", "all") - expect(@provider).to receive(:shell_out!).with("usermod", *flags, "wheel", "your") - expect(@provider).to receive(:shell_out!).with("usermod", *flags, "wheel", "base") + expect(@provider).to receive(:shell_out_compacted!).with("usermod", *flags, "wheel", "all") + expect(@provider).to receive(:shell_out_compacted!).with("usermod", *flags, "wheel", "your") + expect(@provider).to receive(:shell_out_compacted!).with("usermod", *flags, "wheel", "base") @provider.modify_group_members end end diff --git a/spec/unit/provider/ifconfig/aix_spec.rb b/spec/unit/provider/ifconfig/aix_spec.rb index 7f316c952b..3eb4228c51 100644 --- a/spec/unit/provider/ifconfig/aix_spec.rb +++ b/spec/unit/provider/ifconfig/aix_spec.rb @@ -49,7 +49,7 @@ IFCONFIG describe "#load_current_resource" do before do @status = double(stdout: @ifconfig_output, exitstatus: 0) - allow(@provider).to receive(:shell_out).and_return(@status) + allow(@provider).to receive(:shell_out_compacted).and_return(@status) @new_resource.device "en0" end @@ -72,7 +72,7 @@ IFCONFIG @provider.instance_variable_set("@current_resource", Chef::Resource::Ifconfig.new("10.0.0.1", @run_context)) end command = "chdev -l #{@new_resource.device} -a netaddr=#{@new_resource.name}" - expect(@provider).to receive(:shell_out!).with(*command.split(" ")) + expect(@provider).to receive(:shell_out_compacted!).with(*command.split(" ")) @provider.run_action(:add) expect(@new_resource).to be_updated @@ -98,7 +98,7 @@ IFCONFIG @provider.instance_variable_set("@current_resource", Chef::Resource::Ifconfig.new("10.0.0.1", @run_context)) end command = "ifconfig #{@new_resource.device} #{@new_resource.name}" - expect(@provider).to receive(:shell_out!).with(*command.split(" ")) + expect(@provider).to receive(:shell_out_compacted!).with(*command.split(" ")) @provider.run_action(:enable) expect(@new_resource).to be_updated @@ -114,7 +114,7 @@ IFCONFIG @provider.instance_variable_set("@current_resource", Chef::Resource::Ifconfig.new("10.0.0.1", @run_context)) end - expect(@provider).not_to receive(:shell_out!) + expect(@provider).not_to receive(:shell_out_compacted!) @provider.run_action(:disable) expect(@new_resource).not_to be_updated @@ -133,7 +133,7 @@ IFCONFIG it "should disable an interface if it exists" do command = "ifconfig #{@new_resource.device} down" - expect(@provider).to receive(:shell_out!).with(*command.split(" ")) + expect(@provider).to receive(:shell_out_compacted!).with(*command.split(" ")) @provider.run_action(:disable) expect(@new_resource).to be_updated @@ -151,7 +151,7 @@ IFCONFIG @provider.instance_variable_set("@current_resource", Chef::Resource::Ifconfig.new("10.0.0.1", @run_context)) end - expect(@provider).not_to receive(:shell_out!) + expect(@provider).not_to receive(:shell_out_compacted!) @provider.run_action(:delete) expect(@new_resource).not_to be_updated @@ -170,7 +170,7 @@ IFCONFIG it "should delete an interface if it exists" do command = "chdev -l #{@new_resource.device} -a state=down" - expect(@provider).to receive(:shell_out!).with(*command.split(" ")) + expect(@provider).to receive(:shell_out_compacted!).with(*command.split(" ")) @provider.run_action(:delete) expect(@new_resource).to be_updated diff --git a/spec/unit/provider/ifconfig_spec.rb b/spec/unit/provider/ifconfig_spec.rb index 3732d75cc9..748b4d897e 100644 --- a/spec/unit/provider/ifconfig_spec.rb +++ b/spec/unit/provider/ifconfig_spec.rb @@ -48,9 +48,9 @@ EOS before do ifconfig = double(stdout: "", exitstatus: 1) - allow(@provider).to receive(:shell_out).and_return(ifconfig) + allow(@provider).to receive(:shell_out_compacted).and_return(ifconfig) ifconfig_version = double(stdout: "", stderr: net_tools_version, exitstatus: 4) - allow(@provider).to receive(:shell_out).with("ifconfig --version").and_return(ifconfig_version) + allow(@provider).to receive(:shell_out_compacted).with("ifconfig --version").and_return(ifconfig_version) @provider.load_current_resource end it "should track state of ifconfig failure" do @@ -67,7 +67,7 @@ EOS allow(@provider).to receive(:load_current_resource) @current_resource.inet_addr nil command = "ifconfig eth0 10.0.0.1 netmask 255.255.254.0 metric 1 mtu 1500" - expect(@provider).to receive(:shell_out!).with(*command.split(" ")) + expect(@provider).to receive(:shell_out_compacted!).with(*command.split(" ")) expect(@provider).to receive(:generate_config) @provider.run_action(:add) @@ -78,7 +78,7 @@ EOS allow(@provider).to receive(:load_current_resource) @new_resource.target "172.16.32.2" command = "ifconfig eth0 172.16.32.2 netmask 255.255.254.0 metric 1 mtu 1500" - expect(@provider).to receive(:shell_out!).with(*command.split(" ")) + expect(@provider).to receive(:shell_out_compacted!).with(*command.split(" ")) @provider.run_action(:add) expect(@new_resource).to be_updated @@ -86,7 +86,7 @@ EOS it "should not add an interface if it already exists" do allow(@provider).to receive(:load_current_resource) - expect(@provider).not_to receive(:shell_out!) + expect(@provider).not_to receive(:shell_out_compacted!) @current_resource.inet_addr "10.0.0.1" expect(@provider).to receive(:generate_config) @@ -105,7 +105,7 @@ EOS allow(@provider).to receive(:load_current_resource) @current_resource.inet_addr nil command = "ifconfig eth0 10.0.0.1 netmask 255.255.254.0 metric 1 mtu 1500" - expect(@provider).to receive(:shell_out!).with(*command.split(" ")) + expect(@provider).to receive(:shell_out_compacted!).with(*command.split(" ")) expect(@provider).not_to receive(:generate_config) @provider.run_action(:enable) @@ -116,7 +116,7 @@ EOS allow(@provider).to receive(:load_current_resource) @new_resource.target "172.16.32.2" command = "ifconfig eth0 172.16.32.2 netmask 255.255.254.0 metric 1 mtu 1500" - expect(@provider).to receive(:shell_out!).with(*command.split(" ")) + expect(@provider).to receive(:shell_out_compacted!).with(*command.split(" ")) @provider.run_action(:enable) expect(@new_resource).to be_updated @@ -139,7 +139,7 @@ EOS allow(@provider).to receive(:load_current_resource) @current_resource.device "eth0" command = "ifconfig #{@new_resource.device} down" - expect(@provider).to receive(:shell_out!).with(*command.split(" ")) + expect(@provider).to receive(:shell_out_compacted!).with(*command.split(" ")) expect(@provider).to receive(:delete_config) @provider.run_action(:delete) @@ -148,7 +148,7 @@ EOS it "should not delete interface if it does not exist" do allow(@provider).to receive(:load_current_resource) - expect(@provider).not_to receive(:shell_out!) + expect(@provider).not_to receive(:shell_out_compacted!) expect(@provider).to receive(:delete_config) @provider.run_action(:delete) @@ -162,7 +162,7 @@ EOS allow(@provider).to receive(:load_current_resource) @current_resource.device "eth0" command = "ifconfig #{@new_resource.device} down" - expect(@provider).to receive(:shell_out!).with(*command.split(" ")) + expect(@provider).to receive(:shell_out_compacted!).with(*command.split(" ")) expect(@provider).not_to receive(:delete_config) @provider.run_action(:disable) @@ -171,7 +171,7 @@ EOS it "should not delete interface if it does not exist" do allow(@provider).to receive(:load_current_resource) - expect(@provider).not_to receive(:shell_out!) + expect(@provider).not_to receive(:shell_out_compacted!) expect(@provider).not_to receive(:delete_config) @provider.run_action(:disable) @@ -185,7 +185,7 @@ EOS allow(@provider).to receive(:load_current_resource) @current_resource.device "eth0" command = "ifconfig #{@new_resource.device} down" - expect(@provider).to receive(:shell_out!).with(*command.split(" ")) + expect(@provider).to receive(:shell_out_compacted!).with(*command.split(" ")) expect(@provider).to receive(:delete_config) @provider.run_action(:delete) @@ -196,7 +196,7 @@ EOS # This is so that our fake values do not get overwritten allow(@provider).to receive(:load_current_resource) # This is so that nothing actually runs - expect(@provider).not_to receive(:shell_out!) + expect(@provider).not_to receive(:shell_out_compacted!) expect(@provider).to receive(:delete_config) @provider.run_action(:delete) diff --git a/spec/unit/provider/package/apt_spec.rb b/spec/unit/provider/package/apt_spec.rb index 0700f69eb4..f15929880d 100644 --- a/spec/unit/provider/package/apt_spec.rb +++ b/spec/unit/provider/package/apt_spec.rb @@ -1,6 +1,6 @@ # # Author:: Adam Jacob (<adam@chef.io>) -# Copyright:: Copyright 2008-2017, Chef Software Inc. +# Copyright:: Copyright 2008-2018, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -50,7 +50,7 @@ irssi: describe "when loading current resource" do it "should create a current resource with the name of the new_resource" do - expect(@provider).to receive(:shell_out!).with( + expect(@provider).to receive(:shell_out_compacted!).with( "apt-cache", "policy", @new_resource.package_name, :env => { "DEBIAN_FRONTEND" => "noninteractive" }, :timeout => @timeout @@ -77,7 +77,7 @@ sudo: 1.7.2p1-1ubuntu5 0 500 http://us.archive.ubuntu.com/ubuntu/ lucid/main Packages INSTALLED - expect(@provider).to receive(:shell_out!).and_return(@shell_out) + expect(@provider).to receive(:shell_out_compacted!).and_return(@shell_out) @provider.load_current_resource expect(@provider.current_resource.version).to eq(["1.7.2p1-1ubuntu5.3"]) expect(@provider.candidate_version).to eql(["1.7.2p1-1ubuntu5.3"]) @@ -90,7 +90,7 @@ sudo: N: Unable to locate package conic-smarms POLICY_STDOUT policy = double(:stdout => policy_out, :exitstatus => 0) - expect(@provider).to receive(:shell_out!).with( + expect(@provider).to receive(:shell_out_compacted!).with( "apt-cache", "policy", "conic-smarms", :env => { "DEBIAN_FRONTEND" => "noninteractive" }, :timeout => @timeout @@ -99,7 +99,7 @@ N: Unable to locate package conic-smarms N: Unable to locate package conic-smarms SHOWPKG_STDOUT showpkg = double(:stdout => showpkg_out, :exitstatus => 0) - expect(@provider).to receive(:shell_out!).with( + expect(@provider).to receive(:shell_out_compacted!).with( "apt-cache", "showpkg", "conic-smarms", :env => { "DEBIAN_FRONTEND" => "noninteractive" }, :timeout => @timeout @@ -118,7 +118,7 @@ libmysqlclient15-dev: Version table: VPKG_STDOUT virtual_package = double(:stdout => virtual_package_out, :exitstatus => 0) - expect(@provider).to receive(:shell_out!).with( + expect(@provider).to receive(:shell_out_compacted!).with( "apt-cache", "policy", "libmysqlclient15-dev", :env => { "DEBIAN_FRONTEND" => "noninteractive" }, :timeout => @timeout @@ -142,7 +142,7 @@ libmysqlclient-dev 5.1.41-3ubuntu12.10 libmysqlclient-dev 5.1.41-3ubuntu12 SHOWPKG_STDOUT showpkg = double(:stdout => showpkg_out, :exitstatus => 0) - expect(@provider).to receive(:shell_out!).with( + expect(@provider).to receive(:shell_out_compacted!).with( "apt-cache", "showpkg", "libmysqlclient15-dev", :env => { "DEBIAN_FRONTEND" => "noninteractive" }, :timeout => @timeout @@ -161,7 +161,7 @@ libmysqlclient-dev: 500 http://us.archive.ubuntu.com/ubuntu/ lucid/main Packages RPKG_STDOUT real_package = double(:stdout => real_package_out, :exitstatus => 0) - expect(@provider).to receive(:shell_out!).with( + expect(@provider).to receive(:shell_out_compacted!).with( "apt-cache", "policy", "libmysqlclient-dev", :env => { "DEBIAN_FRONTEND" => "noninteractive" }, :timeout => @timeout @@ -178,7 +178,7 @@ mp3-decoder: Version table: VPKG_STDOUT virtual_package = double(:stdout => virtual_package_out, :exitstatus => 0) - expect(@provider).to receive(:shell_out!).with( + expect(@provider).to receive(:shell_out_compacted!).with( "apt-cache", "policy", "mp3-decoder", :env => { "DEBIAN_FRONTEND" => "noninteractive" }, :timeout => @timeout @@ -205,7 +205,7 @@ mpg321 0.2.10.6 mpg123 1.12.1-0ubuntu1 SHOWPKG_STDOUT showpkg = double(:stdout => showpkg_out, :exitstatus => 0) - expect(@provider).to receive(:shell_out!).with( + expect(@provider).to receive(:shell_out_compacted!).with( "apt-cache", "showpkg", "mp3-decoder", :env => { "DEBIAN_FRONTEND" => "noninteractive" }, :timeout => @timeout @@ -219,7 +219,7 @@ mpg123 1.12.1-0ubuntu1 @new_resource.default_release("lenny-backports") @new_resource.provider(nil) - expect(@provider).to receive(:shell_out!).with( + expect(@provider).to receive(:shell_out_compacted!).with( "apt-cache", "-o", "APT::Default-Release=lenny-backports", "policy", "irssi", :env => { "DEBIAN_FRONTEND" => "noninteractive" }, :timeout => @timeout @@ -229,7 +229,7 @@ mpg123 1.12.1-0ubuntu1 it "raises an exception if a source is specified (CHEF-5113)" do @new_resource.source "pluto" - expect(@provider).to receive(:shell_out!).with( + expect(@provider).to receive(:shell_out_compacted!).with( "apt-cache", "policy", @new_resource.package_name, :env => { "DEBIAN_FRONTEND" => "noninteractive" } , :timeout => @timeout @@ -258,7 +258,7 @@ mpg123 1.12.1-0ubuntu1 describe "install_package" do it "should run apt-get install with the package name and version" do - expect(@provider).to receive(:shell_out!). with( + expect(@provider).to receive(:shell_out_compacted!). with( "apt-get", "-q", "-y", "-o", "Dpkg::Options::=--force-confdef", "-o", "Dpkg::Options::=--force-confold", "install", "irssi=0.8.12-7", :env => { "DEBIAN_FRONTEND" => "noninteractive" }, :timeout => @timeout @@ -267,7 +267,7 @@ mpg123 1.12.1-0ubuntu1 end it "should run apt-get install with the package name and version and options if specified" do - expect(@provider).to receive(:shell_out!).with( + expect(@provider).to receive(:shell_out_compacted!).with( "apt-get", "-q", "-y", "-o", "Dpkg::Options::=--force-confdef", "-o", "Dpkg::Options::=--force-confold", "--force-yes", "install", "irssi=0.8.12-7", :env => { "DEBIAN_FRONTEND" => "noninteractive" }, :timeout => @timeout @@ -283,7 +283,7 @@ mpg123 1.12.1-0ubuntu1 @new_resource.provider = nil @provider.new_resource = @new_resource - expect(@provider).to receive(:shell_out!).with( + expect(@provider).to receive(:shell_out_compacted!).with( "apt-get", "-q", "-y", "-o", "Dpkg::Options::=--force-confdef", "-o", "Dpkg::Options::=--force-confold", "-o", "APT::Default-Release=lenny-backports", "install", "irssi=0.8.12-7", :env => { "DEBIAN_FRONTEND" => "noninteractive" }, :timeout => @timeout @@ -293,7 +293,7 @@ mpg123 1.12.1-0ubuntu1 end it "should run apt-get install with the package name and quotes options if specified" do - expect(@provider).to receive(:shell_out!).with( + expect(@provider).to receive(:shell_out_compacted!).with( "apt-get", "-q", "-y", "--force-yes", "-o", "Dpkg::Options::=--force-confdef", "-o", "Dpkg::Options::=--force-confnew", "install", "irssi=0.8.12-7", :env => { "DEBIAN_FRONTEND" => "noninteractive" }, :timeout => @timeout @@ -314,7 +314,7 @@ mpg123 1.12.1-0ubuntu1 describe Chef::Resource::AptPackage, "remove_package" do it "should run apt-get remove with the package name" do - expect(@provider).to receive(:shell_out!).with( + expect(@provider).to receive(:shell_out_compacted!).with( "apt-get", "-q", "-y", "remove", "irssi", :env => { "DEBIAN_FRONTEND" => "noninteractive" }, :timeout => @timeout @@ -323,7 +323,7 @@ mpg123 1.12.1-0ubuntu1 end it "should run apt-get remove with the package name and options if specified" do - expect(@provider).to receive(:shell_out!).with( + expect(@provider).to receive(:shell_out_compacted!).with( "apt-get", "-q", "-y", "--force-yes", "remove", "irssi", :env => { "DEBIAN_FRONTEND" => "noninteractive" }, :timeout => @timeout @@ -337,7 +337,7 @@ mpg123 1.12.1-0ubuntu1 describe "when purging a package" do it "should run apt-get purge with the package name" do - expect(@provider).to receive(:shell_out!).with( + expect(@provider).to receive(:shell_out_compacted!).with( "apt-get", "-q", "-y", "purge", "irssi", :env => { "DEBIAN_FRONTEND" => "noninteractive" }, :timeout => @timeout @@ -346,7 +346,7 @@ mpg123 1.12.1-0ubuntu1 end it "should run apt-get purge with the package name and options if specified" do - expect(@provider).to receive(:shell_out!).with( + expect(@provider).to receive(:shell_out_compacted!).with( "apt-get", "-q", "-y", "--force-yes", "purge", "irssi", :env => { "DEBIAN_FRONTEND" => "noninteractive" }, :timeout => @timeout @@ -365,7 +365,7 @@ mpg123 1.12.1-0ubuntu1 it "should get the full path to the preseed response file" do file = "/tmp/irssi-0.8.12-7.seed" - expect(@provider).to receive(:shell_out!).with( + expect(@provider).to receive(:shell_out_compacted!).with( "debconf-set-selections", "/tmp/irssi-0.8.12-7.seed", :env => { "DEBIAN_FRONTEND" => "noninteractive" }, :timeout => @timeout @@ -375,7 +375,7 @@ mpg123 1.12.1-0ubuntu1 end it "should run debconf-set-selections on the preseed file if it has changed" do - expect(@provider).to receive(:shell_out!).with( + expect(@provider).to receive(:shell_out_compacted!).with( "debconf-set-selections", "/tmp/irssi-0.8.12-7.seed", :env => { "DEBIAN_FRONTEND" => "noninteractive" }, :timeout => @timeout @@ -389,14 +389,14 @@ mpg123 1.12.1-0ubuntu1 @current_resource.version "0.8.11" @new_resource.response_file "/tmp/file" allow(@provider).to receive(:get_preseed_file).and_return(false) - expect(@provider).not_to receive(:shell_out!) + expect(@provider).not_to receive(:shell_out_compacted!) @provider.run_action(:reconfig) end end describe "when reconfiguring a package" do it "should run dpkg-reconfigure package" do - expect(@provider).to receive(:shell_out!).with( + expect(@provider).to receive(:shell_out_compacted!).with( "dpkg-reconfigure", "irssi", :env => { "DEBIAN_FRONTEND" => "noninteractive" }, :timeout => @timeout @@ -407,7 +407,7 @@ mpg123 1.12.1-0ubuntu1 describe "when locking a package" do it "should run apt-mark hold package" do - expect(@provider).to receive(:shell_out!).with( + expect(@provider).to receive(:shell_out_compacted!).with( "apt-mark", "hold", "irssi", :env => { "DEBIAN_FRONTEND" => "noninteractive" }, :timeout => @timeout @@ -415,8 +415,8 @@ mpg123 1.12.1-0ubuntu1 @provider.lock_package("irssi", "0.8.12-7") end it "should not lock if the package is already locked" do - allow(@provider).to receive(:shell_out_compact_timeout!).with( - "apt-mark", "showhold" + allow(@provider).to receive(:shell_out_compacted!).with( + "apt-mark", "showhold", timeout: 900 ).and_return(instance_double( Mixlib::ShellOut, stdout: "irssi") ) @@ -428,7 +428,7 @@ mpg123 1.12.1-0ubuntu1 describe "when unlocking a package" do it "should run apt-mark unhold package" do - expect(@provider).to receive(:shell_out!).with( + expect(@provider).to receive(:shell_out_compacted!).with( "apt-mark", "unhold", "irssi", :env => { "DEBIAN_FRONTEND" => "noninteractive" }, :timeout => @timeout @@ -436,8 +436,8 @@ mpg123 1.12.1-0ubuntu1 @provider.unlock_package("irssi", "0.8.12-7") end it "should not unlock if the package is already unlocked" do - allow(@provider).to receive(:shell_out_compact_timeout!).with( - "apt-mark", "showhold" + allow(@provider).to receive(:shell_out_compacted!).with( + "apt-mark", "showhold", timeout: 900 ).and_return(instance_double( Mixlib::ShellOut, stdout: "") ) @@ -450,7 +450,7 @@ mpg123 1.12.1-0ubuntu1 describe "when installing a virtual package" do it "should install the package without specifying a version" do @provider.package_data["libmysqlclient15-dev"][:virtual] = true - expect(@provider).to receive(:shell_out!).with( + expect(@provider).to receive(:shell_out_compacted!).with( "apt-get", "-q", "-y", "-o", "Dpkg::Options::=--force-confdef", "-o", "Dpkg::Options::=--force-confold", "install", "libmysqlclient15-dev", :env => { "DEBIAN_FRONTEND" => "noninteractive" }, :timeout => @timeout @@ -462,7 +462,7 @@ mpg123 1.12.1-0ubuntu1 describe "when removing a virtual package" do it "should remove the resolved name instead of the virtual package name" do expect(@provider).to receive(:resolve_virtual_package_name).with("libmysqlclient15-dev").and_return("libmysqlclient-dev") - expect(@provider).to receive(:shell_out!).with( + expect(@provider).to receive(:shell_out_compacted!).with( "apt-get", "-q", "-y", "remove", "libmysqlclient-dev", :env => { "DEBIAN_FRONTEND" => "noninteractive" }, :timeout => @timeout @@ -474,7 +474,7 @@ mpg123 1.12.1-0ubuntu1 describe "when purging a virtual package" do it "should purge the resolved name instead of the virtual package name" do expect(@provider).to receive(:resolve_virtual_package_name).with("libmysqlclient15-dev").and_return("libmysqlclient-dev") - expect(@provider).to receive(:shell_out!).with( + expect(@provider).to receive(:shell_out_compacted!).with( "apt-get", "-q", "-y", "purge", "libmysqlclient-dev", :env => { "DEBIAN_FRONTEND" => "noninteractive" }, :timeout => @timeout @@ -486,7 +486,7 @@ mpg123 1.12.1-0ubuntu1 describe "when installing multiple packages" do it "can install a virtual package followed by a non-virtual package" do # https://github.com/chef/chef/issues/2914 - expect(@provider).to receive(:shell_out!).with( + expect(@provider).to receive(:shell_out_compacted!).with( "apt-get", "-q", "-y", "-o", "Dpkg::Options::=--force-confdef", "-o", "Dpkg::Options::=--force-confold", "install", "libmysqlclient15-dev", "irssi=0.8.12-7", :env => { "DEBIAN_FRONTEND" => "noninteractive" }, :timeout => @timeout @@ -499,8 +499,8 @@ mpg123 1.12.1-0ubuntu1 it "should run dpkg to compare versions if an existing version is installed" do allow(@provider).to receive(:get_current_versions).and_return("1.4.0") allow(@new_resource).to receive(:allow_downgrade).and_return(false) - expect(@provider).to receive(:shell_out_compact_timeout).with( - "dpkg", "--compare-versions", "1.4.0", "gt", "0.8.12-7" + expect(@provider).to receive(:shell_out_compacted).with( + "dpkg", "--compare-versions", "1.4.0", "gt", "0.8.12-7", timeout: 900 ).and_return(double(error?: false)) @provider.run_action(:upgrade) end @@ -509,7 +509,7 @@ mpg123 1.12.1-0ubuntu1 allow(@provider).to receive(:get_current_versions).and_return("0.4.0") allow(@new_resource).to receive(:allow_downgrade).and_return(false) expect(@provider).to receive(:version_compare).and_return(-1) - expect(@provider).to receive(:shell_out!).with( + expect(@provider).to receive(:shell_out_compacted!).with( "apt-get", "-q", "-y", "-o", "Dpkg::Options::=--force-confdef", "-o", "Dpkg::Options::=--force-confold", "install", "irssi=0.8.12-7", :env => { "DEBIAN_FRONTEND" => "noninteractive" }, :timeout => @timeout @@ -521,7 +521,7 @@ mpg123 1.12.1-0ubuntu1 allow(@provider).to receive(:get_current_versions).and_return(nil) allow(@new_resource).to receive(:allow_downgrade).and_return(false) expect(@provider).not_to receive(:version_compare) - expect(@provider).to receive(:shell_out!).with( + expect(@provider).to receive(:shell_out_compacted!).with( "apt-get", "-q", "-y", "-o", "Dpkg::Options::=--force-confdef", "-o", "Dpkg::Options::=--force-confold", "install", "irssi=0.8.12-7", :env => { "DEBIAN_FRONTEND" => "noninteractive" }, :timeout => @timeout diff --git a/spec/unit/provider/package/bff_spec.rb b/spec/unit/provider/package/bff_spec.rb index abe1d4155c..df407914d3 100644 --- a/spec/unit/provider/package/bff_spec.rb +++ b/spec/unit/provider/package/bff_spec.rb @@ -43,22 +43,22 @@ describe Chef::Provider::Package::Bff do it "should create a current resource with the name of new_resource" do status = double("Status", :stdout => @bffinfo, :exitstatus => 0) - expect(@provider).to receive(:shell_out).with("installp", "-L", "-d", "/tmp/samba.base", timeout: 900).and_return(status) - expect(@provider).to receive(:shell_out).with("lslpp", "-lcq", "samba.base", timeout: 900).and_return(@empty_status) + expect(@provider).to receive(:shell_out_compacted).with("installp", "-L", "-d", "/tmp/samba.base", timeout: 900).and_return(status) + expect(@provider).to receive(:shell_out_compacted).with("lslpp", "-lcq", "samba.base", timeout: 900).and_return(@empty_status) @provider.load_current_resource expect(@provider.current_resource.name).to eq("samba.base") end it "should set the current resource bff package name to the new resource bff package name" do status = double("Status", :stdout => @bffinfo, :exitstatus => 0) - expect(@provider).to receive(:shell_out).with("installp", "-L", "-d", "/tmp/samba.base", timeout: 900).and_return(status) - expect(@provider).to receive(:shell_out).with("lslpp", "-lcq", "samba.base", timeout: 900).and_return(@empty_status) + expect(@provider).to receive(:shell_out_compacted).with("installp", "-L", "-d", "/tmp/samba.base", timeout: 900).and_return(status) + expect(@provider).to receive(:shell_out_compacted).with("lslpp", "-lcq", "samba.base", timeout: 900).and_return(@empty_status) @provider.load_current_resource expect(@provider.current_resource.package_name).to eq("samba.base") end it "should raise an exception if a source is supplied but not found" do - allow(@provider).to receive(:shell_out).and_return(@empty_status) + allow(@provider).to receive(:shell_out_compacted).and_return(@empty_status) allow(::File).to receive(:exist?).with(@new_resource.source).and_return(false) @provider.load_current_resource @provider.define_resource_requirements @@ -67,8 +67,8 @@ describe Chef::Provider::Package::Bff do it "should get the source package version from lslpp if provided" do status = double("Status", :stdout => @bffinfo, :exitstatus => 0) - expect(@provider).to receive(:shell_out).with("installp", "-L", "-d", "/tmp/samba.base", timeout: 900).and_return(status) - expect(@provider).to receive(:shell_out).with("lslpp", "-lcq", "samba.base", timeout: 900).and_return(@empty_status) + expect(@provider).to receive(:shell_out_compacted).with("installp", "-L", "-d", "/tmp/samba.base", timeout: 900).and_return(status) + expect(@provider).to receive(:shell_out_compacted).with("lslpp", "-lcq", "samba.base", timeout: 900).and_return(@empty_status) @provider.load_current_resource expect(@provider.current_resource.package_name).to eq("samba.base") @@ -79,8 +79,8 @@ describe Chef::Provider::Package::Bff do info = "samba.base:samba.base.samples:3.3.12.0::COMMITTED:I:Samba for AIX: /etc/objrepos:samba.base:3.3.12.0::COMMITTED:I:Samba for AIX:" status = double("Status", :stdout => info, :exitstatus => 0) - expect(@provider).to receive(:shell_out).with("installp", "-L", "-d", "/tmp/samba.base", timeout: 900).and_return(status) - expect(@provider).to receive(:shell_out).with("lslpp", "-lcq", "samba.base", timeout: 900).and_return(@empty_status) + expect(@provider).to receive(:shell_out_compacted).with("installp", "-L", "-d", "/tmp/samba.base", timeout: 900).and_return(status) + expect(@provider).to receive(:shell_out_compacted).with("lslpp", "-lcq", "samba.base", timeout: 900).and_return(@empty_status) expect(logger).to receive(:warn).once.with(%r{bff package by product name}) @provider.load_current_resource @@ -92,8 +92,8 @@ describe Chef::Provider::Package::Bff do status = double("Status", :stdout => @bffinfo, :exitstatus => 0) @stdout = StringIO.new(@bffinfo) @stdin, @stderr = StringIO.new, StringIO.new - expect(@provider).to receive(:shell_out).with("installp", "-L", "-d", "/tmp/samba.base", timeout: 900).and_return(status) - expect(@provider).to receive(:shell_out).with("lslpp", "-lcq", "samba.base", timeout: 900).and_return(status) + expect(@provider).to receive(:shell_out_compacted).with("installp", "-L", "-d", "/tmp/samba.base", timeout: 900).and_return(status) + expect(@provider).to receive(:shell_out_compacted).with("lslpp", "-lcq", "samba.base", timeout: 900).and_return(status) @provider.load_current_resource expect(@provider.current_resource.version).to eq("3.3.12.0") end @@ -102,20 +102,20 @@ describe Chef::Provider::Package::Bff do status = double("Status", :stdout => "", :exitstatus => 1, :format_for_exception => "") @new_resource = Chef::Resource::Package.new("samba.base") @provider = Chef::Provider::Package::Bff.new(@new_resource, @run_context) - allow(@provider).to receive(:shell_out).and_return(status) + allow(@provider).to receive(:shell_out_compacted).and_return(status) expect { @provider.run_action(:install) }.to raise_error(Chef::Exceptions::Package) end it "should raise an exception if installp/lslpp fails to run" do status = double(:stdout => "", :exitstatus => -1, :format_for_exception => "") - allow(@provider).to receive(:shell_out).and_return(status) + allow(@provider).to receive(:shell_out_compacted).and_return(status) expect { @provider.load_current_resource }.to raise_error(Chef::Exceptions::Package) end it "should return a current resource with a nil version if the package is not found" do status = double("Status", :stdout => @bffinfo, :exitstatus => 0) - expect(@provider).to receive(:shell_out).with("installp", "-L", "-d", "/tmp/samba.base", timeout: 900).and_return(status) - expect(@provider).to receive(:shell_out).with("lslpp", "-lcq", "samba.base", timeout: 900).and_return(@empty_status) + expect(@provider).to receive(:shell_out_compacted).with("installp", "-L", "-d", "/tmp/samba.base", timeout: 900).and_return(status) + expect(@provider).to receive(:shell_out_compacted).with("lslpp", "-lcq", "samba.base", timeout: 900).and_return(@empty_status) @provider.load_current_resource expect(@provider.current_resource.version).to be_nil end @@ -124,7 +124,7 @@ describe Chef::Provider::Package::Bff do wrongbffinfo = "/usr/lib/objrepos:openssl.base:0.9.8.2400::COMMITTED:I:Open Secure Socket Layer: /etc/objrepos:openssl.base:0.9.8.2400::COMMITTED:I:Open Secure Socket Layer:" status = double("Status", :stdout => wrongbffinfo, :exitstatus => 0) - expect(@provider).to receive(:shell_out).with("installp", "-L", "-d", "/tmp/samba.base", timeout: 900).and_return(status) + expect(@provider).to receive(:shell_out_compacted).with("installp", "-L", "-d", "/tmp/samba.base", timeout: 900).and_return(status) expect { @provider.load_current_resource }.to raise_error(Chef::Exceptions::Package) end end @@ -132,19 +132,19 @@ describe Chef::Provider::Package::Bff do describe "candidate_version" do it "should return the candidate_version variable if already setup" do @provider.candidate_version = "3.3.12.0" - expect(@provider).not_to receive(:shell_out) + expect(@provider).not_to receive(:shell_out_compacted) @provider.candidate_version end it "should lookup the candidate_version if the variable is not already set" do status = double(:stdout => "", :exitstatus => 0) - expect(@provider).to receive(:shell_out).and_return(status) + expect(@provider).to receive(:shell_out_compacted).and_return(status) @provider.candidate_version end it "should throw and exception if the exitstatus is not 0" do @status = double(:stdout => "", :exitstatus => 1, :format_for_exception => "") - allow(@provider).to receive(:shell_out).and_return(@status) + allow(@provider).to receive(:shell_out_compacted).and_return(@status) expect { @provider.candidate_version }.to raise_error(Chef::Exceptions::Package) end @@ -152,7 +152,7 @@ describe Chef::Provider::Package::Bff do describe "install and upgrade" do it "should run installp -aYF -d with the package source to install" do - expect(@provider).to receive(:shell_out!).with("installp", "-aYF", "-d", "/tmp/samba.base", "samba.base", timeout: 900) + expect(@provider).to receive(:shell_out_compacted!).with("installp", "-aYF", "-d", "/tmp/samba.base", "samba.base", timeout: 900) @provider.install_package("samba.base", "3.3.12.0") end @@ -160,26 +160,26 @@ describe Chef::Provider::Package::Bff do @new_resource = Chef::Resource::Package.new("/tmp/samba.base") @provider = Chef::Provider::Package::Bff.new(@new_resource, @run_context) expect(@new_resource.source).to eq("/tmp/samba.base") - expect(@provider).to receive(:shell_out!).with("installp", "-aYF", "-d", "/tmp/samba.base", "/tmp/samba.base", timeout: 900) + expect(@provider).to receive(:shell_out_compacted!).with("installp", "-aYF", "-d", "/tmp/samba.base", "/tmp/samba.base", timeout: 900) @provider.install_package("/tmp/samba.base", "3.3.12.0") end it "should run installp with -eLogfile option." do @new_resource.options("-e/tmp/installp.log") - expect(@provider).to receive(:shell_out!).with("installp", "-aYF", "-e/tmp/installp.log", "-d", "/tmp/samba.base", "samba.base", timeout: 900) + expect(@provider).to receive(:shell_out_compacted!).with("installp", "-aYF", "-e/tmp/installp.log", "-d", "/tmp/samba.base", "samba.base", timeout: 900) @provider.install_package("samba.base", "3.3.12.0") end end describe "remove" do it "should run installp -u samba.base to remove the package" do - expect(@provider).to receive(:shell_out!).with("installp", "-u", "samba.base", timeout: 900) + expect(@provider).to receive(:shell_out_compacted!).with("installp", "-u", "samba.base", timeout: 900) @provider.remove_package("samba.base", "3.3.12.0") end it "should run installp -u -e/tmp/installp.log with options -e/tmp/installp.log" do @new_resource.options("-e/tmp/installp.log") - expect(@provider).to receive(:shell_out!).with("installp", "-u", "-e/tmp/installp.log", "samba.base", timeout: 900) + expect(@provider).to receive(:shell_out_compacted!).with("installp", "-u", "-e/tmp/installp.log", "samba.base", timeout: 900) @provider.remove_package("samba.base", "3.3.12.0") end diff --git a/spec/unit/provider/package/chocolatey_spec.rb b/spec/unit/provider/package/chocolatey_spec.rb index ff9dc3ca6b..a0a73c445a 100644 --- a/spec/unit/provider/package/chocolatey_spec.rb +++ b/spec/unit/provider/package/chocolatey_spec.rb @@ -46,7 +46,7 @@ ConEmu|15.10.25.0 allow(provider).to receive(:choco_install_path).and_return(choco_install_path) allow(provider).to receive(:choco_exe).and_return(choco_exe) local_list_obj = double(:stdout => local_list_stdout) - allow(provider).to receive(:shell_out!).with("#{choco_exe} list -l -r", { :returns => [0], :timeout => timeout }).and_return(local_list_obj) + allow(provider).to receive(:shell_out_compacted!).with("#{choco_exe} list -l -r", { :returns => [0], :timeout => timeout }).and_return(local_list_obj) end def allow_remote_list(package_names, args = nil) @@ -60,7 +60,7 @@ munin-node|1.6.1.20130823 EOF remote_list_obj = double(stdout: remote_list_stdout) package_names.each do |pkg| - allow(provider).to receive(:shell_out!).with("#{choco_exe} list -r #{pkg}#{args}", { :returns => [0], timeout: timeout }).and_return(remote_list_obj) + allow(provider).to receive(:shell_out_compacted!).with("#{choco_exe} list -r #{pkg}#{args}", { :returns => [0], timeout: timeout }).and_return(remote_list_obj) end end @@ -182,7 +182,7 @@ munin-node|1.6.1.20130823 it "should install a single package" do allow_remote_list(["git"]) provider.load_current_resource - expect(provider).to receive(:shell_out!).with("#{choco_exe} install -y git", { :returns => [0], :timeout => timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} install -y git", { :returns => [0], :timeout => timeout }).and_return(double) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end @@ -193,7 +193,7 @@ munin-node|1.6.1.20130823 allow_remote_list(["git"]) new_resource.timeout(timeout) provider.load_current_resource - expect(provider).to receive(:shell_out!).with("#{choco_exe} install -y git", { :returns => [0], :timeout => timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} install -y git", { :returns => [0], :timeout => timeout }).and_return(double) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end @@ -222,7 +222,7 @@ munin-node|1.6.1.20130823 new_resource.package_name("ConEmu") new_resource.version("15.10.25.1") provider.load_current_resource - expect(provider).to receive(:shell_out!).with("#{choco_exe} install -y --version 15.10.25.1 conemu", { :returns => [0], :timeout => timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} install -y --version 15.10.25.1 conemu", { :returns => [0], :timeout => timeout }).and_return(double) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end @@ -235,7 +235,7 @@ munin-node|1.6.1.20130823 new_resource.package_name(%w{chocolatey ConEmu}) new_resource.version([nil, "15.10.25.1"]) provider.load_current_resource - expect(provider).to receive(:shell_out!).with("#{choco_exe} install -y --version 15.10.25.1 conemu", { :returns => [0], :timeout => timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} install -y --version 15.10.25.1 conemu", { :returns => [0], :timeout => timeout }).and_return(double) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end @@ -245,7 +245,7 @@ munin-node|1.6.1.20130823 new_resource.package_name("conemu") new_resource.version("15.10.25.1") provider.load_current_resource - expect(provider).to receive(:shell_out!).with("#{choco_exe} install -y --version 15.10.25.1 conemu", { :returns => [0], :timeout => timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} install -y --version 15.10.25.1 conemu", { :returns => [0], :timeout => timeout }).and_return(double) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end @@ -255,8 +255,8 @@ munin-node|1.6.1.20130823 new_resource.package_name(%w{ConEmu git}) new_resource.version(["15.10.25.1", nil]) provider.load_current_resource - expect(provider).to receive(:shell_out!).with("#{choco_exe} install -y --version 15.10.25.1 conemu", { :returns => [0], :timeout => timeout }).and_return(double) - expect(provider).to receive(:shell_out!).with("#{choco_exe} install -y git", { :returns => [0], :timeout => timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} install -y --version 15.10.25.1 conemu", { :returns => [0], :timeout => timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} install -y git", { :returns => [0], :timeout => timeout }).and_return(double) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end @@ -265,7 +265,7 @@ munin-node|1.6.1.20130823 allow_remote_list(["git", "munin-node"]) new_resource.package_name(["git", "munin-node"]) provider.load_current_resource - expect(provider).to receive(:shell_out!).with("#{choco_exe} install -y git munin-node", { :returns => [0], :timeout => timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} install -y git munin-node", { :returns => [0], :timeout => timeout }).and_return(double) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end @@ -275,7 +275,7 @@ munin-node|1.6.1.20130823 allow_remote_list(["git"], " -source localpackages") new_resource.source("localpackages") provider.load_current_resource - expect(provider).to receive(:shell_out!).with("#{choco_exe} install -y -source localpackages git", { :returns => [0], :timeout => timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} install -y -source localpackages git", { :returns => [0], :timeout => timeout }).and_return(double) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end @@ -285,7 +285,7 @@ munin-node|1.6.1.20130823 allow_remote_list(["git"]) new_resource.options("-force") provider.load_current_resource - expect(provider).to receive(:shell_out!).with("#{choco_exe} install -y -force git", { :returns => [0], :timeout => timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} install -y -force git", { :returns => [0], :timeout => timeout }).and_return(double) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end @@ -319,7 +319,7 @@ munin-node|1.6.1.20130823 it "should install a package that is not installed" do allow_remote_list(["git"]) provider.load_current_resource - expect(provider).to receive(:shell_out!).with("#{choco_exe} upgrade -y git", { :returns => [0], :timeout => timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} upgrade -y git", { :returns => [0], :timeout => timeout }).and_return(double) provider.run_action(:upgrade) expect(new_resource).to be_updated_by_last_action end @@ -328,7 +328,7 @@ munin-node|1.6.1.20130823 allow_remote_list(["ConEmu"]) new_resource.package_name("ConEmu") provider.load_current_resource - expect(provider).to receive(:shell_out!).with("#{choco_exe} upgrade -y conemu", { :returns => [0], :timeout => timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} upgrade -y conemu", { :returns => [0], :timeout => timeout }).and_return(double) provider.run_action(:upgrade) expect(new_resource).to be_updated_by_last_action end @@ -337,7 +337,7 @@ munin-node|1.6.1.20130823 allow_remote_list(["conemu"]) new_resource.package_name("conemu") provider.load_current_resource - expect(provider).to receive(:shell_out!).with("#{choco_exe} upgrade -y conemu", { :returns => [0], :timeout => timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} upgrade -y conemu", { :returns => [0], :timeout => timeout }).and_return(double) provider.run_action(:upgrade) expect(new_resource).to be_updated_by_last_action end @@ -346,7 +346,7 @@ munin-node|1.6.1.20130823 allow_remote_list(["chocolatey"]) new_resource.package_name("chocolatey") provider.load_current_resource - expect(provider).not_to receive(:shell_out!).with("#{choco_exe} upgrade -y chocolatey", { :returns => [0], :timeout => timeout }) + expect(provider).not_to receive(:shell_out_compacted!).with("#{choco_exe} upgrade -y chocolatey", { :returns => [0], :timeout => timeout }) provider.run_action(:upgrade) expect(new_resource).not_to be_updated_by_last_action end @@ -355,7 +355,7 @@ munin-node|1.6.1.20130823 allow_remote_list(["git"]) new_resource.version("2.6.2") provider.load_current_resource - expect(provider).to receive(:shell_out!).with("#{choco_exe} upgrade -y --version 2.6.2 git", { :returns => [0], :timeout => timeout }) + expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} upgrade -y --version 2.6.2 git", { :returns => [0], :timeout => timeout }) provider.run_action(:upgrade) expect(new_resource).to be_updated_by_last_action end @@ -363,7 +363,7 @@ munin-node|1.6.1.20130823 it "upgrading multiple packages uses a single command" do allow_remote_list(%w{conemu git}) new_resource.package_name(%w{conemu git}) - expect(provider).to receive(:shell_out!).with("#{choco_exe} upgrade -y conemu git", { :returns => [0], :timeout => timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} upgrade -y conemu git", { :returns => [0], :timeout => timeout }).and_return(double) provider.run_action(:upgrade) expect(new_resource).to be_updated_by_last_action end @@ -415,7 +415,7 @@ munin-node|1.6.1.20130823 allow_remote_list(["ConEmu"]) new_resource.package_name("ConEmu") provider.load_current_resource - expect(provider).to receive(:shell_out!).with("#{choco_exe} uninstall -y ConEmu", { :returns => [0], :timeout => timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} uninstall -y ConEmu", { :returns => [0], :timeout => timeout }).and_return(double) provider.run_action(:remove) expect(new_resource).to be_updated_by_last_action end @@ -424,7 +424,7 @@ munin-node|1.6.1.20130823 allow_remote_list(["conemu"]) new_resource.package_name("conemu") provider.load_current_resource - expect(provider).to receive(:shell_out!).with("#{choco_exe} uninstall -y conemu", { :returns => [0], :timeout => timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} uninstall -y conemu", { :returns => [0], :timeout => timeout }).and_return(double) provider.run_action(:remove) expect(new_resource).to be_updated_by_last_action end @@ -434,7 +434,7 @@ munin-node|1.6.1.20130823 allow_remote_list(%w{git conemu}) new_resource.package_name(%w{git conemu}) provider.load_current_resource - expect(provider).to receive(:shell_out!).with("#{choco_exe} uninstall -y conemu", { :returns => [0], :timeout => timeout }).and_return(double) + expect(provider).to receive(:shell_out_compacted!).with("#{choco_exe} uninstall -y conemu", { :returns => [0], :timeout => timeout }).and_return(double) provider.run_action(:remove) expect(new_resource).to be_updated_by_last_action end @@ -457,7 +457,7 @@ describe "behavior when Chocolatey is not installed" do provider.instance_variable_set("@choco_install_path", nil) # we don't care what this returns, but we have to let it be called. - allow(provider).to receive(:shell_out!).and_return(double(:stdout => "")) + allow(provider).to receive(:shell_out_compacted!).and_return(double(:stdout => "")) end let(:error_regex) do diff --git a/spec/unit/provider/package/dpkg_spec.rb b/spec/unit/provider/package/dpkg_spec.rb index e01e1d9cce..c99e91dd46 100644 --- a/spec/unit/provider/package/dpkg_spec.rb +++ b/spec/unit/provider/package/dpkg_spec.rb @@ -51,8 +51,8 @@ Conflicts: wget-ssl end before(:each) do - allow(provider).to receive(:shell_out!).with("dpkg-deb", "-W", source, timeout: 900).and_return(dpkg_deb_status) - allow(provider).to receive(:shell_out!).with("dpkg", "-s", package, timeout: 900, returns: [0, 1]).and_return(double(stdout: "", exitstatus: 1)) + allow(provider).to receive(:shell_out_compacted!).with("dpkg-deb", "-W", source, timeout: 900).and_return(dpkg_deb_status) + allow(provider).to receive(:shell_out_compacted!).with("dpkg", "-s", package, timeout: 900, returns: [0, 1]).and_return(double(stdout: "", exitstatus: 1)) allow(::File).to receive(:exist?).with(source).and_return(true) end @@ -113,7 +113,7 @@ Conflicts: wget-ssl describe "gets the source package version from dpkg-deb" do def check_version(version) status = double(:stdout => "wget\t#{version}", :exitstatus => 0) - expect(provider).to receive(:shell_out!).with("dpkg-deb", "-W", source, timeout: 900).and_return(status) + expect(provider).to receive(:shell_out_compacted!).with("dpkg-deb", "-W", source, timeout: 900).and_return(status) provider.load_current_resource expect(provider.current_resource.package_name).to eq(["wget"]) expect(provider.candidate_version).to eq([version]) @@ -165,7 +165,7 @@ Conflicts: wget-ssl end it "should return the current version installed if found by dpkg" do - allow(provider).to receive(:shell_out!).with("dpkg", "-s", package, timeout: 900, returns: [0, 1]).and_return(dpkg_s_status) + allow(provider).to receive(:shell_out_compacted!).with("dpkg", "-s", package, timeout: 900, returns: [0, 1]).and_return(dpkg_s_status) provider.load_current_resource expect(provider.current_resource.version).to eq(["1.11.4-1ubuntu1"]) end @@ -178,7 +178,7 @@ Use dpkg --info (= dpkg-deb --info) to examine archive files, and dpkg --contents (= dpkg-deb --contents) to list their contents. EOF ) - expect(provider).to receive(:shell_out!).with("dpkg", "-s", package, returns: [0, 1], timeout: 900).and_return(dpkg_s_status) + expect(provider).to receive(:shell_out_compacted!).with("dpkg", "-s", package, returns: [0, 1], timeout: 900).and_return(dpkg_s_status) provider.load_current_resource expect(provider.current_resource.version).to eq([nil]) end @@ -192,7 +192,7 @@ Priority: extra Section: ruby EOF ) - expect(provider).to receive(:shell_out!).with("dpkg", "-s", package, returns: [0, 1], timeout: 900).and_return(dpkg_s_status) + expect(provider).to receive(:shell_out_compacted!).with("dpkg", "-s", package, returns: [0, 1], timeout: 900).and_return(dpkg_s_status) provider.load_current_resource expect(provider.current_resource.version).to eq([nil]) end @@ -201,13 +201,13 @@ Section: ruby dpkg_s_status = double( exitstatus: 3, stderr: "i am very, very angry with you. i'm very, very cross. go to your room.", stdout: "" ) - expect(provider).to receive(:shell_out!).with("dpkg", "-s", package, returns: [0, 1], timeout: 900).and_raise(Mixlib::ShellOut::ShellCommandFailed) + expect(provider).to receive(:shell_out_compacted!).with("dpkg", "-s", package, returns: [0, 1], timeout: 900).and_raise(Mixlib::ShellOut::ShellCommandFailed) expect { provider.load_current_resource }.to raise_error(Mixlib::ShellOut::ShellCommandFailed) end it "should raise an exception if dpkg-deb -W fails to run" do status = double(:stdout => "", :exitstatus => -1) - expect(provider).to receive(:shell_out_compact_timeout!).with("dpkg-deb", "-W", "/tmp/wget_1.11.4-1ubuntu1_amd64.deb").and_raise(Mixlib::ShellOut::ShellCommandFailed) + expect(provider).to receive(:shell_out_compacted!).with("dpkg-deb", "-W", "/tmp/wget_1.11.4-1ubuntu1_amd64.deb", timeout: 900).and_raise(Mixlib::ShellOut::ShellCommandFailed) expect { provider.load_current_resource }.to raise_error(Mixlib::ShellOut::ShellCommandFailed) end end diff --git a/spec/unit/provider/package/freebsd/pkg_spec.rb b/spec/unit/provider/package/freebsd/pkg_spec.rb index 4b3a94aa33..259bd7a4c4 100644 --- a/spec/unit/provider/package/freebsd/pkg_spec.rb +++ b/spec/unit/provider/package/freebsd/pkg_spec.rb @@ -79,21 +79,21 @@ describe Chef::Provider::Package::Freebsd::Pkg, "load_current_resource" do it "should return the version number when it is installed" do pkg_info = OpenStruct.new(:stdout => "zsh-4.3.6_7") - expect(@provider).to receive(:shell_out!).with("pkg_info", "-E", "zsh*", env: nil, returns: [0, 1], timeout: 900).and_return(pkg_info) + expect(@provider).to receive(:shell_out_compacted!).with("pkg_info", "-E", "zsh*", env: nil, returns: [0, 1], timeout: 900).and_return(pkg_info) allow(@provider).to receive(:package_name).and_return("zsh") expect(@provider.current_installed_version).to eq("4.3.6_7") end it "does not set the current version number when the package is not installed" do pkg_info = OpenStruct.new(:stdout => "") - expect(@provider).to receive(:shell_out!).with("pkg_info", "-E", "zsh*", env: nil, returns: [0, 1], timeout: 900).and_return(pkg_info) + expect(@provider).to receive(:shell_out_compacted!).with("pkg_info", "-E", "zsh*", env: nil, returns: [0, 1], timeout: 900).and_return(pkg_info) allow(@provider).to receive(:package_name).and_return("zsh") expect(@provider.current_installed_version).to be_nil end it "should return the port path for a valid port name" do whereis = OpenStruct.new(:stdout => "zsh: /usr/ports/shells/zsh") - expect(@provider).to receive(:shell_out!).with("whereis", "-s", "zsh", env: nil, timeout: 900).and_return(whereis) + expect(@provider).to receive(:shell_out_compacted!).with("whereis", "-s", "zsh", env: nil, timeout: 900).and_return(whereis) allow(@provider).to receive(:port_name).and_return("zsh") expect(@provider.port_path).to eq("/usr/ports/shells/zsh") end @@ -102,7 +102,7 @@ describe Chef::Provider::Package::Freebsd::Pkg, "load_current_resource" do it "should return the ports candidate version when given a valid port path" do allow(@provider).to receive(:port_path).and_return("/usr/ports/shells/zsh") make_v = OpenStruct.new(:stdout => "4.3.6\n", :exitstatus => 0) - expect(@provider).to receive(:shell_out!).with("make", "-V", "PORTVERSION", { cwd: "/usr/ports/shells/zsh", returns: [0, 1], env: nil, timeout: 900 }).and_return(make_v) + expect(@provider).to receive(:shell_out_compacted!).with("make", "-V", "PORTVERSION", { cwd: "/usr/ports/shells/zsh", returns: [0, 1], env: nil, timeout: 900 }).and_return(make_v) expect(@provider.ports_candidate_version).to eq("4.3.6") end @@ -110,7 +110,7 @@ describe Chef::Provider::Package::Freebsd::Pkg, "load_current_resource" do allow(::File).to receive(:exist?).with("/usr/ports/Makefile").and_return(true) allow(@provider).to receive(:port_path).and_return("/usr/ports/shells/zsh") make_v = OpenStruct.new(:stdout => "zsh-4.3.6_7\n", :exitstatus => 0) - expect(@provider).to receive(:shell_out!).with("make", "-V", "PKGNAME", { cwd: "/usr/ports/shells/zsh", env: nil, returns: [0, 1], timeout: 900 }).and_return(make_v) + expect(@provider).to receive(:shell_out_compacted!).with("make", "-V", "PKGNAME", { cwd: "/usr/ports/shells/zsh", env: nil, returns: [0, 1], timeout: 900 }).and_return(make_v) #@provider.should_receive(:ports_makefile_variable_value).with("PKGNAME").and_return("zsh-4.3.6_7") expect(@provider.package_name).to eq("zsh") end @@ -127,7 +127,7 @@ describe Chef::Provider::Package::Freebsd::Pkg, "load_current_resource" do end it "should run pkg_add -r with the package name" do - expect(@provider).to receive(:shell_out!).with("pkg_add", "-r", "zsh", env: nil, timeout: 900).and_return(@cmd_result) + expect(@provider).to receive(:shell_out_compacted!).with("pkg_add", "-r", "zsh", env: nil, timeout: 900).and_return(@cmd_result) @provider.install_package("zsh", "4.3.6_7") end end @@ -142,7 +142,7 @@ describe Chef::Provider::Package::Freebsd::Pkg, "load_current_resource" do it "should figure out the port path from the package_name using whereis" do whereis = OpenStruct.new(:stdout => "zsh: /usr/ports/shells/zsh") - expect(@provider).to receive(:shell_out!).with("whereis", "-s", "zsh", env: nil, timeout: 900).and_return(whereis) + expect(@provider).to receive(:shell_out_compacted!).with("whereis", "-s", "zsh", env: nil, timeout: 900).and_return(whereis) expect(@provider.port_path).to eq("/usr/ports/shells/zsh") end @@ -178,7 +178,7 @@ describe Chef::Provider::Package::Freebsd::Pkg, "load_current_resource" do end it "should run pkg_add -r with the package name" do - expect(@provider).to receive(:shell_out!).with("pkg_add", "-r", "ruby18-iconv", env: nil, timeout: 900).and_return(@install_result) + expect(@provider).to receive(:shell_out_compacted!).with("pkg_add", "-r", "ruby18-iconv", env: nil, timeout: 900).and_return(@install_result) @provider.install_package("ruby-iconv", "1.0") end end @@ -193,7 +193,7 @@ describe Chef::Provider::Package::Freebsd::Pkg, "load_current_resource" do end it "should run pkg_delete with the package name and version" do - expect(@provider).to receive(:shell_out!).with("pkg_delete", "zsh-4.3.6_7", env: nil, timeout: 900).and_return(@pkg_delete) + expect(@provider).to receive(:shell_out_compacted!).with("pkg_delete", "zsh-4.3.6_7", env: nil, timeout: 900).and_return(@pkg_delete) @provider.remove_package("zsh", "4.3.6_7") end end @@ -213,14 +213,14 @@ describe Chef::Provider::Package::Freebsd::Pkg, "load_current_resource" do it "should return the port path for a valid port name" do whereis = OpenStruct.new(:stdout => "bonnie++: /usr/ports/benchmarks/bonnie++") - expect(@provider).to receive(:shell_out!).with("whereis", "-s", "bonnie++", env: nil, timeout: 900).and_return(whereis) + expect(@provider).to receive(:shell_out_compacted!).with("whereis", "-s", "bonnie++", env: nil, timeout: 900).and_return(whereis) allow(@provider).to receive(:port_name).and_return("bonnie++") expect(@provider.port_path).to eq("/usr/ports/benchmarks/bonnie++") end it "should return the version number when it is installed" do pkg_info = OpenStruct.new(:stdout => "bonnie++-1.96") - expect(@provider).to receive(:shell_out!).with("pkg_info", "-E", "bonnie++*", env: nil, returns: [0, 1], timeout: 900).and_return(pkg_info) + expect(@provider).to receive(:shell_out_compacted!).with("pkg_info", "-E", "bonnie++*", env: nil, returns: [0, 1], timeout: 900).and_return(pkg_info) allow(@provider).to receive(:package_name).and_return("bonnie++") expect(@provider.current_installed_version).to eq("1.96") end @@ -253,7 +253,7 @@ describe Chef::Provider::Package::Freebsd::Pkg, "load_current_resource" do allow(@provider).to receive(:latest_link_name).and_return("perl") cmd = OpenStruct.new(:status => true) - expect(@provider).to receive(:shell_out!).with("pkg_add", "-r", "perl", env: nil, timeout: 900).and_return(cmd) + expect(@provider).to receive(:shell_out_compacted!).with("pkg_add", "-r", "perl", env: nil, timeout: 900).and_return(cmd) @provider.install_package("perl5.8", "5.8.8_1") end @@ -267,7 +267,7 @@ describe Chef::Provider::Package::Freebsd::Pkg, "load_current_resource" do allow(@provider).to receive(:latest_link_name).and_return("mysql50-server") cmd = OpenStruct.new(:status => true) - expect(@provider).to receive(:shell_out!).with("pkg_add", "-r", "mysql50-server", env: nil, timeout: 900).and_return(cmd) + expect(@provider).to receive(:shell_out_compacted!).with("pkg_add", "-r", "mysql50-server", env: nil, timeout: 900).and_return(cmd) @provider.install_package("mysql50-server", "5.0.45_1") end end diff --git a/spec/unit/provider/package/freebsd/pkgng_spec.rb b/spec/unit/provider/package/freebsd/pkgng_spec.rb index 098052a057..2fdcb87758 100644 --- a/spec/unit/provider/package/freebsd/pkgng_spec.rb +++ b/spec/unit/provider/package/freebsd/pkgng_spec.rb @@ -67,7 +67,7 @@ describe Chef::Provider::Package::Freebsd::Port do end it "should query pkg database" do - expect(@provider).to receive(:shell_out!).with("pkg", "info", "zsh", env: nil, returns: [0, 70], timeout: 900).and_return(@pkg_info) + expect(@provider).to receive(:shell_out_compacted!).with("pkg", "info", "zsh", env: nil, returns: [0, 70], timeout: 900).and_return(@pkg_info) expect(@provider.current_installed_version).to eq("3.1.7") end end @@ -75,14 +75,14 @@ describe Chef::Provider::Package::Freebsd::Port do describe "determining candidate version" do it "should query repository" do pkg_query = OpenStruct.new(:stdout => "5.0.5\n", :exitstatus => 0) - expect(@provider).to receive(:shell_out!).with("pkg", "rquery", "%v", "zsh", env: nil, timeout: 900).and_return(pkg_query) + expect(@provider).to receive(:shell_out_compacted!).with("pkg", "rquery", "%v", "zsh", env: nil, timeout: 900).and_return(pkg_query) expect(@provider.candidate_version).to eq("5.0.5") end it "should query specified repository when given option" do @provider.new_resource.options("-r LocalMirror") # This requires LocalMirror repo configuration. pkg_query = OpenStruct.new(:stdout => "5.0.3\n", :exitstatus => 0) - expect(@provider).to receive(:shell_out!).with("pkg", "rquery", "-r", "LocalMirror", "%v", "zsh", env: nil, timeout: 900).and_return(pkg_query) + expect(@provider).to receive(:shell_out_compacted!).with("pkg", "rquery", "-r", "LocalMirror", "%v", "zsh", env: nil, timeout: 900).and_return(pkg_query) expect(@provider.candidate_version).to eq("5.0.3") end @@ -99,7 +99,7 @@ describe Chef::Provider::Package::Freebsd::Port do it "should handle package source from file" do @provider.new_resource.source("/nas/pkg/repo/zsh-5.0.1.txz") - expect(@provider).to receive(:shell_out!). + expect(@provider).to receive(:shell_out_compacted!). with("pkg", "add", "/nas/pkg/repo/zsh-5.0.1.txz", env: { "LC_ALL" => nil }, timeout: 900). and_return(@install_result) @provider.install_package("zsh", "5.0.1") @@ -107,21 +107,21 @@ describe Chef::Provider::Package::Freebsd::Port do it "should handle package source over ftp or http" do @provider.new_resource.source("http://repo.example.com/zsh-5.0.1.txz") - expect(@provider).to receive(:shell_out!). + expect(@provider).to receive(:shell_out_compacted!). with("pkg", "add", "http://repo.example.com/zsh-5.0.1.txz", env: { "LC_ALL" => nil }, timeout: 900). and_return(@install_result) @provider.install_package("zsh", "5.0.1") end it "should handle a package name" do - expect(@provider).to receive(:shell_out!). + expect(@provider).to receive(:shell_out_compacted!). with("pkg", "install", "-y", "zsh", env: { "LC_ALL" => nil }, timeout: 900).and_return(@install_result) @provider.install_package("zsh", "5.0.1") end it "should handle a package name with a specified repo" do @provider.new_resource.options("-r LocalMirror") # This requires LocalMirror repo configuration. - expect(@provider).to receive(:shell_out!). + expect(@provider).to receive(:shell_out_compacted!). with("pkg", "install", "-y", "-r", "LocalMirror", "zsh", env: { "LC_ALL" => nil }, timeout: 900).and_return(@install_result) @provider.install_package("zsh", "5.0.1") end @@ -133,14 +133,14 @@ describe Chef::Provider::Package::Freebsd::Port do end it "should call pkg delete" do - expect(@provider).to receive(:shell_out!). + expect(@provider).to receive(:shell_out_compacted!). with("pkg", "delete", "-y", "zsh-5.0.1", env: nil, timeout: 900).and_return(@install_result) @provider.remove_package("zsh", "5.0.1") end it "should not include repo option in pkg delete" do @provider.new_resource.options("-r LocalMirror") # This requires LocalMirror repo configuration. - expect(@provider).to receive(:shell_out!). + expect(@provider).to receive(:shell_out_compacted!). with("pkg", "delete", "-y", "zsh-5.0.1", env: nil, timeout: 900).and_return(@install_result) @provider.remove_package("zsh", "5.0.1") end diff --git a/spec/unit/provider/package/freebsd/port_spec.rb b/spec/unit/provider/package/freebsd/port_spec.rb index 5c87483fa6..26a960dedc 100644 --- a/spec/unit/provider/package/freebsd/port_spec.rb +++ b/spec/unit/provider/package/freebsd/port_spec.rb @@ -68,7 +68,7 @@ describe Chef::Provider::Package::Freebsd::Port do it "should check 'pkg_info' if system uses pkg_* tools" do allow(@new_resource).to receive(:supports_pkgng?) expect(@new_resource).to receive(:supports_pkgng?).and_return(false) - expect(@provider).to receive(:shell_out!).with("pkg_info", "-E", "zsh*", env: nil, returns: [0, 1], timeout: 900).and_return(@pkg_info) + expect(@provider).to receive(:shell_out_compacted!).with("pkg_info", "-E", "zsh*", env: nil, returns: [0, 1], timeout: 900).and_return(@pkg_info) expect(@provider.current_installed_version).to eq("3.1.7") end @@ -76,8 +76,8 @@ describe Chef::Provider::Package::Freebsd::Port do pkg_enabled = OpenStruct.new(:stdout => "yes\n") [1000016, 1000000, 901503, 902506, 802511].each do |freebsd_version| @node.automatic_attrs[:os_version] = freebsd_version - expect(@new_resource).to receive(:shell_out!).with("make", "-V", "WITH_PKGNG", env: nil).and_return(pkg_enabled) - expect(@provider).to receive(:shell_out!).with("pkg", "info", "zsh", env: nil, returns: [0, 70], timeout: 900).and_return(@pkg_info) + expect(@new_resource).to receive(:shell_out_compacted!).with("make", "-V", "WITH_PKGNG", env: nil).and_return(pkg_enabled) + expect(@provider).to receive(:shell_out_compacted!).with("pkg", "info", "zsh", env: nil, returns: [0, 70], timeout: 900).and_return(@pkg_info) expect(@provider.current_installed_version).to eq("3.1.7") end end @@ -85,7 +85,7 @@ describe Chef::Provider::Package::Freebsd::Port do it "should check 'pkg info' if the freebsd version is greater than or equal to 1000017" do freebsd_version = 1000017 @node.automatic_attrs[:os_version] = freebsd_version - expect(@provider).to receive(:shell_out!).with("pkg", "info", "zsh", env: nil, returns: [0, 70], timeout: 900).and_return(@pkg_info) + expect(@provider).to receive(:shell_out_compacted!).with("pkg", "info", "zsh", env: nil, returns: [0, 70], timeout: 900).and_return(@pkg_info) expect(@provider.current_installed_version).to eq("3.1.7") end end @@ -98,7 +98,7 @@ describe Chef::Provider::Package::Freebsd::Port do it "should return candidate version if port exists" do allow(::File).to receive(:exist?).with("/usr/ports/Makefile").and_return(true) allow(@provider).to receive(:port_dir).and_return("/usr/ports/shells/zsh") - expect(@provider).to receive(:shell_out!).with("make", "-V", "PORTVERSION", cwd: "/usr/ports/shells/zsh", env: nil, returns: [0, 1], timeout: 900). + expect(@provider).to receive(:shell_out_compacted!).with("make", "-V", "PORTVERSION", cwd: "/usr/ports/shells/zsh", env: nil, returns: [0, 1], timeout: 900). and_return(@port_version) expect(@provider.candidate_version).to eq("5.0.5") end @@ -122,13 +122,13 @@ describe Chef::Provider::Package::Freebsd::Port do it "should query system for path given just a name" do whereis = OpenStruct.new(:stdout => "zsh: /usr/ports/shells/zsh\n") - expect(@provider).to receive(:shell_out!).with("whereis", "-s", "zsh", env: nil, timeout: 900).and_return(whereis) + expect(@provider).to receive(:shell_out_compacted!).with("whereis", "-s", "zsh", env: nil, timeout: 900).and_return(whereis) expect(@provider.port_dir).to eq("/usr/ports/shells/zsh") end it "should raise exception if not found" do whereis = OpenStruct.new(:stdout => "zsh:\n") - expect(@provider).to receive(:shell_out!).with("whereis", "-s", "zsh", env: nil, timeout: 900).and_return(whereis) + expect(@provider).to receive(:shell_out_compacted!).with("whereis", "-s", "zsh", env: nil, timeout: 900).and_return(whereis) expect { @provider.port_dir }.to raise_error(Chef::Exceptions::Package, "Could not find port with the name zsh") end end @@ -140,7 +140,7 @@ describe Chef::Provider::Package::Freebsd::Port do it "should run make install in port directory" do allow(@provider).to receive(:port_dir).and_return("/usr/ports/shells/zsh") - expect(@provider).to receive(:shell_out!). + expect(@provider).to receive(:shell_out_compacted!). with("make", "-DBATCH", "install", "clean", :timeout => 1800, :cwd => "/usr/ports/shells/zsh", :env => nil). and_return(@install_result) @provider.install_package("zsh", "5.0.5") @@ -154,7 +154,7 @@ describe Chef::Provider::Package::Freebsd::Port do it "should run make deinstall in port directory" do allow(@provider).to receive(:port_dir).and_return("/usr/ports/shells/zsh") - expect(@provider).to receive(:shell_out!). + expect(@provider).to receive(:shell_out_compacted!). with("make", "deinstall", :timeout => 300, :cwd => "/usr/ports/shells/zsh", :env => nil). and_return(@install_result) @provider.remove_package("zsh", "5.0.5") diff --git a/spec/unit/provider/package/ips_spec.rb b/spec/unit/provider/package/ips_spec.rb index 45111601fa..eac0fd90f3 100644 --- a/spec/unit/provider/package/ips_spec.rb +++ b/spec/unit/provider/package/ips_spec.rb @@ -1,6 +1,6 @@ # # Author:: Bryan McLellan <btm@chef.io> -# Copyright:: Copyright 2012-2017, Chef Software Inc. +# Copyright:: Copyright 2012-2018, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -64,28 +64,28 @@ PKG_STATUS context "when loading current resource" do it "should create a current resource with the name of the new_resource" do - expect(@provider).to receive(:shell_out).with("pkg", "info", @new_resource.package_name, timeout: 900).and_return(local_output) - expect(@provider).to receive(:shell_out!).with("pkg", "info", "-r", @new_resource.package_name, timeout: 900).and_return(remote_output) + expect(@provider).to receive(:shell_out_compacted).with("pkg", "info", @new_resource.package_name, timeout: 900).and_return(local_output) + expect(@provider).to receive(:shell_out_compacted!).with("pkg", "info", "-r", @new_resource.package_name, timeout: 900).and_return(remote_output) expect(Chef::Resource::IpsPackage).to receive(:new).and_return(@current_resource) @provider.load_current_resource end it "should set the current resources package name to the new resources package name" do - expect(@provider).to receive(:shell_out).with("pkg", "info", @new_resource.package_name, timeout: 900).and_return(local_output) - expect(@provider).to receive(:shell_out!).with("pkg", "info", "-r", @new_resource.package_name, timeout: 900).and_return(remote_output) + expect(@provider).to receive(:shell_out_compacted).with("pkg", "info", @new_resource.package_name, timeout: 900).and_return(local_output) + expect(@provider).to receive(:shell_out_compacted!).with("pkg", "info", "-r", @new_resource.package_name, timeout: 900).and_return(remote_output) @provider.load_current_resource expect(@current_resource.package_name).to eq(@new_resource.package_name) end it "should run pkg info with the package name" do - expect(@provider).to receive(:shell_out).with("pkg", "info", @new_resource.package_name, timeout: 900).and_return(local_output) - expect(@provider).to receive(:shell_out!).with("pkg", "info", "-r", @new_resource.package_name, timeout: 900).and_return(remote_output) + expect(@provider).to receive(:shell_out_compacted).with("pkg", "info", @new_resource.package_name, timeout: 900).and_return(local_output) + expect(@provider).to receive(:shell_out_compacted!).with("pkg", "info", "-r", @new_resource.package_name, timeout: 900).and_return(remote_output) @provider.load_current_resource end it "should set the installed version to nil on the current resource if package state is not installed" do - expect(@provider).to receive(:shell_out).with("pkg", "info", @new_resource.package_name, timeout: 900).and_return(local_output) - expect(@provider).to receive(:shell_out!).with("pkg", "info", "-r", @new_resource.package_name, timeout: 900).and_return(remote_output) + expect(@provider).to receive(:shell_out_compacted).with("pkg", "info", @new_resource.package_name, timeout: 900).and_return(local_output) + expect(@provider).to receive(:shell_out_compacted!).with("pkg", "info", "-r", @new_resource.package_name, timeout: 900).and_return(remote_output) @provider.load_current_resource expect(@current_resource.version).to be_nil end @@ -107,33 +107,33 @@ Packaging Date: October 19, 2011 09:14:50 AM Size: 8.07 MB FMRI: pkg://solaris/crypto/gnupg@2.0.17,5.11-0.175.0.0.0.2.537:20111019T091450Z INSTALLED - expect(@provider).to receive(:shell_out).with("pkg", "info", @new_resource.package_name, timeout: 900).and_return(local) - expect(@provider).to receive(:shell_out!).with("pkg", "info", "-r", @new_resource.package_name, timeout: 900).and_return(remote_output) + expect(@provider).to receive(:shell_out_compacted).with("pkg", "info", @new_resource.package_name, timeout: 900).and_return(local) + expect(@provider).to receive(:shell_out_compacted!).with("pkg", "info", "-r", @new_resource.package_name, timeout: 900).and_return(remote_output) @provider.load_current_resource expect(@current_resource.version).to eq("2.0.17") end it "should return the current resource" do - expect(@provider).to receive(:shell_out).with("pkg", "info", @new_resource.package_name, timeout: 900).and_return(local_output) - expect(@provider).to receive(:shell_out!).with("pkg", "info", "-r", @new_resource.package_name, timeout: 900).and_return(remote_output) + expect(@provider).to receive(:shell_out_compacted).with("pkg", "info", @new_resource.package_name, timeout: 900).and_return(local_output) + expect(@provider).to receive(:shell_out_compacted!).with("pkg", "info", "-r", @new_resource.package_name, timeout: 900).and_return(remote_output) expect(@provider.load_current_resource).to eql(@current_resource) end end context "when installing a package" do it "should run pkg install with the package name and version" do - expect(@provider).to receive(:shell_out!).with("pkg", "install", "-q", "crypto/gnupg@2.0.17", timeout: 900) + expect(@provider).to receive(:shell_out_compacted!).with("pkg", "install", "-q", "crypto/gnupg@2.0.17", timeout: 900) @provider.install_package("crypto/gnupg", "2.0.17") end it "should run pkg install with the package name and version and options if specified" do - expect(@provider).to receive(:shell_out!).with("pkg", "--no-refresh", "install", "-q", "crypto/gnupg@2.0.17", timeout: 900) + expect(@provider).to receive(:shell_out_compacted!).with("pkg", "--no-refresh", "install", "-q", "crypto/gnupg@2.0.17", timeout: 900) @new_resource.options "--no-refresh" @provider.install_package("crypto/gnupg", "2.0.17") end it "raises an error if package fails to install" do - expect(@provider).to receive(:shell_out!).with("pkg", "--no-refresh", "install", "-q", "crypto/gnupg@2.0.17", timeout: 900).and_raise(Mixlib::ShellOut::ShellCommandFailed) + expect(@provider).to receive(:shell_out_compacted!).with("pkg", "--no-refresh", "install", "-q", "crypto/gnupg@2.0.17", timeout: 900).and_raise(Mixlib::ShellOut::ShellCommandFailed) @new_resource.options("--no-refresh") expect { @provider.install_package("crypto/gnupg", "2.0.17") }.to raise_error(Mixlib::ShellOut::ShellCommandFailed) end @@ -152,8 +152,8 @@ Packaging Date: April 1, 2012 05:55:52 PM Size: 2.57 MB FMRI: pkg://omnios/security/sudo@1.8.4.1,5.11-0.151002:20120401T175552Z PKG_STATUS - expect(@provider).to receive(:shell_out).with("pkg", "info", @new_resource.package_name, timeout: 900).and_return(local_output) - expect(@provider).to receive(:shell_out!).with("pkg", "info", "-r", @new_resource.package_name, timeout: 900).and_return(remote) + expect(@provider).to receive(:shell_out_compacted).with("pkg", "info", @new_resource.package_name, timeout: 900).and_return(local_output) + expect(@provider).to receive(:shell_out_compacted!).with("pkg", "info", "-r", @new_resource.package_name, timeout: 900).and_return(remote) @provider.load_current_resource expect(@current_resource.version).to be_nil expect(@provider.candidate_version).to eql("1.8.4.1") @@ -193,8 +193,8 @@ Packaging Date: October 19, 2011 09:14:50 AM FMRI: pkg://solaris/crypto/gnupg@2.0.18,5.11-0.175.0.0.0.2.537:20111019T091450Z REMOTE - expect(@provider).to receive(:shell_out).with("pkg", "info", @new_resource.package_name, timeout: 900).and_return(local) - expect(@provider).to receive(:shell_out!).with("pkg", "info", "-r", @new_resource.package_name, timeout: 900).and_return(remote) + expect(@provider).to receive(:shell_out_compacted).with("pkg", "info", @new_resource.package_name, timeout: 900).and_return(local) + expect(@provider).to receive(:shell_out_compacted!).with("pkg", "info", "-r", @new_resource.package_name, timeout: 900).and_return(remote) expect(@provider).to receive(:install_package).exactly(0).times @provider.run_action(:install) end @@ -205,7 +205,7 @@ REMOTE end it "should run pkg install with the --accept flag" do - expect(@provider).to receive(:shell_out).with("pkg", "install", "-q", "--accept", "crypto/gnupg@2.0.17", timeout: 900).and_return(local_output) + expect(@provider).to receive(:shell_out_compacted!).with("pkg", "install", "-q", "--accept", "crypto/gnupg@2.0.17", timeout: 900).and_return(local_output) @provider.install_package("crypto/gnupg", "2.0.17") end end @@ -213,19 +213,19 @@ REMOTE context "when upgrading a package" do it "should run pkg install with the package name and version" do - expect(@provider).to receive(:shell_out).with("pkg", "install", "-q", "crypto/gnupg@2.0.17", timeout: 900).and_return(local_output) + expect(@provider).to receive(:shell_out_compacted!).with("pkg", "install", "-q", "crypto/gnupg@2.0.17", timeout: 900).and_return(local_output) @provider.upgrade_package("crypto/gnupg", "2.0.17") end end context "when uninstalling a package" do it "should run pkg uninstall with the package name and version" do - expect(@provider).to receive(:shell_out!).with("pkg", "uninstall", "-q", "crypto/gnupg@2.0.17", timeout: 900) + expect(@provider).to receive(:shell_out_compacted!).with("pkg", "uninstall", "-q", "crypto/gnupg@2.0.17", timeout: 900) @provider.remove_package("crypto/gnupg", "2.0.17") end it "should run pkg uninstall with the package name and version and options if specified" do - expect(@provider).to receive(:shell_out!).with("pkg", "--no-refresh", "uninstall", "-q", "crypto/gnupg@2.0.17", timeout: 900) + expect(@provider).to receive(:shell_out_compacted!).with("pkg", "--no-refresh", "uninstall", "-q", "crypto/gnupg@2.0.17", timeout: 900) @new_resource.options "--no-refresh" @provider.remove_package("crypto/gnupg", "2.0.17") end diff --git a/spec/unit/provider/package/macports_spec.rb b/spec/unit/provider/package/macports_spec.rb index 4961f4c467..04e0a9177e 100644 --- a/spec/unit/provider/package/macports_spec.rb +++ b/spec/unit/provider/package/macports_spec.rb @@ -76,13 +76,13 @@ The following ports are currently installed: EOF status = double(:stdout => stdout, :exitstatus => 0) - expect(@provider).to receive(:shell_out).and_return(status) + expect(@provider).to receive(:shell_out_compacted).and_return(status) expect(@provider.current_installed_version).to eq("0.9.8k_0") end it "should return nil if a package is not currently installed" do status = double(:stdout => " \n", :exitstatus => 0) - expect(@provider).to receive(:shell_out).and_return(status) + expect(@provider).to receive(:shell_out_compacted).and_return(status) expect(@provider.current_installed_version).to be_nil end end @@ -90,13 +90,13 @@ EOF describe "macports_candidate_version" do it "should return the latest available version of a given package" do status = double(:stdout => "version: 4.2.7\n", :exitstatus => 0) - expect(@provider).to receive(:shell_out).and_return(status) + expect(@provider).to receive(:shell_out_compacted).and_return(status) expect(@provider.macports_candidate_version).to eq("4.2.7") end it "should return nil if there is no version for a given package" do status = double(:stdout => "Error: port fadsfadsfads not found\n", :exitstatus => 0) - expect(@provider).to receive(:shell_out).and_return(status) + expect(@provider).to receive(:shell_out_compacted).and_return(status) expect(@provider.macports_candidate_version).to be_nil end end @@ -105,7 +105,7 @@ EOF it "should run the port install command with the correct version" do expect(@current_resource).to receive(:version).and_return("4.1.6") @provider.current_resource = @current_resource - expect(@provider).to receive(:shell_out!).with("port", "install", "zsh", "@4.2.7", timeout: 900) + expect(@provider).to receive(:shell_out_compacted!).with("port", "install", "zsh", "@4.2.7", timeout: 900) @provider.install_package("zsh", "4.2.7") end @@ -113,7 +113,7 @@ EOF it "should not do anything if a package already exists with the same version" do expect(@current_resource).to receive(:version).and_return("4.2.7") @provider.current_resource = @current_resource - expect(@provider).not_to receive(:shell_out!) + expect(@provider).not_to receive(:shell_out_compacted!) @provider.install_package("zsh", "4.2.7") end @@ -122,7 +122,7 @@ EOF expect(@current_resource).to receive(:version).and_return("4.1.6") @provider.current_resource = @current_resource @new_resource.options("-f") - expect(@provider).to receive(:shell_out!).with("port", "-f", "install", "zsh", "@4.2.7", timeout: 900) + expect(@provider).to receive(:shell_out_compacted!).with("port", "-f", "install", "zsh", "@4.2.7", timeout: 900) @provider.install_package("zsh", "4.2.7") end @@ -130,36 +130,36 @@ EOF describe "purge_package" do it "should run the port uninstall command with the correct version" do - expect(@provider).to receive(:shell_out!).with("port", "uninstall", "zsh", "@4.2.7", timeout: 900) + expect(@provider).to receive(:shell_out_compacted!).with("port", "uninstall", "zsh", "@4.2.7", timeout: 900) @provider.purge_package("zsh", "4.2.7") end it "should purge the currently active version if no explicit version is passed in" do - expect(@provider).to receive(:shell_out!).with("port", "uninstall", "zsh", timeout: 900) + expect(@provider).to receive(:shell_out_compacted!).with("port", "uninstall", "zsh", timeout: 900) @provider.purge_package("zsh", nil) end it "should add options to the port command when specified" do @new_resource.options("-f") - expect(@provider).to receive(:shell_out!).with("port", "-f", "uninstall", "zsh", "@4.2.7", timeout: 900) + expect(@provider).to receive(:shell_out_compacted!).with("port", "-f", "uninstall", "zsh", "@4.2.7", timeout: 900) @provider.purge_package("zsh", "4.2.7") end end describe "remove_package" do it "should run the port deactivate command with the correct version" do - expect(@provider).to receive(:shell_out!).with("port", "deactivate", "zsh", "@4.2.7", timeout: 900) + expect(@provider).to receive(:shell_out_compacted!).with("port", "deactivate", "zsh", "@4.2.7", timeout: 900) @provider.remove_package("zsh", "4.2.7") end it "should remove the currently active version if no explicit version is passed in" do - expect(@provider).to receive(:shell_out!).with("port", "deactivate", "zsh", timeout: 900) + expect(@provider).to receive(:shell_out_compacted!).with("port", "deactivate", "zsh", timeout: 900) @provider.remove_package("zsh", nil) end it "should add options to the port command when specified" do @new_resource.options("-f") - expect(@provider).to receive(:shell_out!).with("port", "-f", "deactivate", "zsh", "@4.2.7", timeout: 900) + expect(@provider).to receive(:shell_out_compacted!).with("port", "-f", "deactivate", "zsh", "@4.2.7", timeout: 900) @provider.remove_package("zsh", "4.2.7") end end @@ -169,7 +169,7 @@ EOF expect(@current_resource).to receive(:version).at_least(:once).and_return("4.1.6") @provider.current_resource = @current_resource - expect(@provider).to receive(:shell_out!).with("port", "upgrade", "zsh", "@4.2.7", timeout: 900) + expect(@provider).to receive(:shell_out_compacted!).with("port", "upgrade", "zsh", "@4.2.7", timeout: 900) @provider.upgrade_package("zsh", "4.2.7") end @@ -177,7 +177,7 @@ EOF it "should not run the port upgrade command if the version is already installed" do expect(@current_resource).to receive(:version).at_least(:once).and_return("4.2.7") @provider.current_resource = @current_resource - expect(@provider).not_to receive(:shell_out!) + expect(@provider).not_to receive(:shell_out_compacted!) @provider.upgrade_package("zsh", "4.2.7") end @@ -195,7 +195,7 @@ EOF expect(@current_resource).to receive(:version).at_least(:once).and_return("4.1.6") @provider.current_resource = @current_resource - expect(@provider).to receive(:shell_out!).with("port", "-f", "upgrade", "zsh", "@4.2.7", timeout: 900) + expect(@provider).to receive(:shell_out_compacted!).with("port", "-f", "upgrade", "zsh", "@4.2.7", timeout: 900) @provider.upgrade_package("zsh", "4.2.7") end diff --git a/spec/unit/provider/package/msu_spec.rb b/spec/unit/provider/package/msu_spec.rb index b9091d757a..de805fcb39 100644 --- a/spec/unit/provider/package/msu_spec.rb +++ b/spec/unit/provider/package/msu_spec.rb @@ -1,6 +1,6 @@ # # Author:: Nimisha Sharad (<nimisha.sharad@msystechnologies.com>) -# Copyright:: Copyright 2008-2016, Chef Software, Inc. +# Copyright:: Copyright 2008-2018, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -243,7 +243,7 @@ The operation completed successfully. describe "#extract_msu_contents" do it "extracts the msu contents by using mixlib shellout" do - expect(provider).to receive(:shell_out_with_timeout!).with("#{ENV['SYSTEMROOT']}\\system32\\expand.exe -f:* msu_file destination") + expect(provider).to receive(:shell_out!).with("#{ENV['SYSTEMROOT']}\\system32\\expand.exe -f:* msu_file destination") provider.extract_msu_contents("msu_file", "destination") end end diff --git a/spec/unit/provider/package/openbsd_spec.rb b/spec/unit/provider/package/openbsd_spec.rb index 20eb85dfcf..07950acf6e 100644 --- a/spec/unit/provider/package/openbsd_spec.rb +++ b/spec/unit/provider/package/openbsd_spec.rb @@ -45,16 +45,16 @@ describe Chef::Provider::Package::Openbsd do context "when not already installed" do before do - allow(provider).to receive(:shell_out!).with("pkg_info", "-e", "#{name}->0", anything()).and_return(instance_double("shellout", :stdout => "")) + allow(provider).to receive(:shell_out_compacted!).with("pkg_info", "-e", "#{name}->0", anything()).and_return(instance_double("shellout", :stdout => "")) end context "when there is a single candidate" do context "when source is not provided" do it "should run the installation command" do - expect(provider).to receive(:shell_out!).with("pkg_info", "-I", name, anything()).and_return( + expect(provider).to receive(:shell_out_compacted!).with("pkg_info", "-I", name, anything()).and_return( instance_double("shellout", :stdout => "#{name}-#{version}\n")) - expect(provider).to receive(:shell_out!).with( + expect(provider).to receive(:shell_out_compacted!).with( "pkg_add", "-r", "#{name}-#{version}", { :env => { "PKG_PATH" => "http://ftp.OpenBSD.org/pub/OpenBSD/5.5/packages/amd64/" }, timeout: 900 } ) { OpenStruct.new :status => true } @@ -69,7 +69,7 @@ describe Chef::Provider::Package::Openbsd do context "if no version is specified" do it "should raise an exception" do - expect(provider).to receive(:shell_out!).with("pkg_info", "-I", name, anything()).and_return( + expect(provider).to receive(:shell_out_compacted!).with("pkg_info", "-I", name, anything()).and_return( instance_double("shellout", :stdout => "#{name}-#{version}-#{flavor_a}\n#{name}-#{version}-#{flavor_b}\n")) expect { provider.run_action(:install) }.to raise_error(Chef::Exceptions::Package, /multiple matching candidates/) end @@ -83,10 +83,10 @@ describe Chef::Provider::Package::Openbsd do context "if no version is specified" do it "should run the installation command" do - expect(provider).to receive(:shell_out!).with("pkg_info", "-e", "#{package_name}->0", anything()).and_return(instance_double("shellout", :stdout => "")) - expect(provider).to receive(:shell_out!).with("pkg_info", "-I", name, anything()).and_return( + expect(provider).to receive(:shell_out_compacted!).with("pkg_info", "-e", "#{package_name}->0", anything()).and_return(instance_double("shellout", :stdout => "")) + expect(provider).to receive(:shell_out_compacted!).with("pkg_info", "-I", name, anything()).and_return( instance_double("shellout", :stdout => "#{name}-#{version}-#{flavor}\n")) - expect(provider).to receive(:shell_out!).with( + expect(provider).to receive(:shell_out_compacted!).with( "pkg_add", "-r", "#{name}-#{version}-#{flavor}", { env: { "PKG_PATH" => "http://ftp.OpenBSD.org/pub/OpenBSD/5.5/packages/amd64/" }, timeout: 900 } ) { OpenStruct.new :status => true } @@ -98,11 +98,11 @@ describe Chef::Provider::Package::Openbsd do context "if a version is specified" do it "should use the flavor from the version" do - expect(provider).to receive(:shell_out!).with("pkg_info", "-I", "#{name}-#{version}-#{flavor_b}", anything()).and_return( + expect(provider).to receive(:shell_out_compacted!).with("pkg_info", "-I", "#{name}-#{version}-#{flavor_b}", anything()).and_return( instance_double("shellout", :stdout => "#{name}-#{version}-#{flavor_a}\n")) new_resource.version("#{version}-#{flavor_b}") - expect(provider).to receive(:shell_out!).with( + expect(provider).to receive(:shell_out_compacted!).with( "pkg_add", "-r", "#{name}-#{version}-#{flavor_b}", { env: { "PKG_PATH" => "http://ftp.OpenBSD.org/pub/OpenBSD/5.5/packages/amd64/" }, timeout: 900 } ) { OpenStruct.new :status => true } @@ -122,7 +122,7 @@ describe Chef::Provider::Package::Openbsd do @provider.current_resource = @current_resource end it "should run the command to delete the installed package" do - expect(@provider).to receive(:shell_out!).with( + expect(@provider).to receive(:shell_out_compacted!).with( "pkg_delete", @name, env: nil, timeout: 900 ) { OpenStruct.new :status => true } @provider.remove_package(@name, nil) diff --git a/spec/unit/provider/package/pacman_spec.rb b/spec/unit/provider/package/pacman_spec.rb index ceae73dbd1..d41df8c24b 100644 --- a/spec/unit/provider/package/pacman_spec.rb +++ b/spec/unit/provider/package/pacman_spec.rb @@ -30,7 +30,7 @@ describe Chef::Provider::Package::Pacman do @provider = Chef::Provider::Package::Pacman.new(@new_resource, @run_context) allow(Chef::Resource::Package).to receive(:new).and_return(@current_resource) - allow(@provider).to receive(:shell_out).and_return(@status) + allow(@provider).to receive(:shell_out_compacted).and_return(@status) @stdin = StringIO.new @stdout = StringIO.new(<<-ERR) error: package "nano" not found @@ -51,17 +51,17 @@ ERR end it "should run pacman query with the package name" do - expect(@provider).to receive(:shell_out).with("pacman", "-Qi", @new_resource.package_name, { timeout: 900 }).and_return(@status) + expect(@provider).to receive(:shell_out_compacted).with("pacman", "-Qi", @new_resource.package_name, { timeout: 900 }).and_return(@status) @provider.load_current_resource end it "should read stdout on pacman" do - allow(@provider).to receive(:shell_out).and_return(@status) + allow(@provider).to receive(:shell_out_compacted).and_return(@status) @provider.load_current_resource end it "should set the installed version to nil on the current resource if pacman installed version not exists" do - allow(@provider).to receive(:shell_out).and_return(@status) + allow(@provider).to receive(:shell_out_compacted).and_return(@status) @provider.load_current_resource end @@ -89,14 +89,14 @@ Description : Pico editor clone with enhancements PACMAN status = double(:stdout => stdout, :exitstatus => 0) - allow(@provider).to receive(:shell_out).and_return(status) + allow(@provider).to receive(:shell_out_compacted).and_return(status) @provider.load_current_resource expect(@current_resource.version).to eq("2.2.2-1") end it "should set the candidate version if pacman has one" do status = double(:stdout => "core nano 2.2.3-1", :exitstatus => 0) - allow(@provider).to receive(:shell_out).and_return(status) + allow(@provider).to receive(:shell_out_compacted).and_return(status) @provider.load_current_resource expect(@provider.candidate_version).to eql("2.2.3-1") end @@ -123,7 +123,7 @@ PACMAN_CONF status = double(:stdout => "customrepo nano 1.2.3-4", :exitstatus => 0) allow(::File).to receive(:exist?).with("/etc/pacman.conf").and_return(true) allow(::File).to receive(:read).with("/etc/pacman.conf").and_return(@pacman_conf) - allow(@provider).to receive(:shell_out).and_return(status) + allow(@provider).to receive(:shell_out_compacted).and_return(status) @provider.load_current_resource expect(@provider.candidate_version).to eql("1.2.3-4") @@ -140,7 +140,7 @@ PACMAN_CONF end it "should raise an exception if pacman does not return a candidate version" do - allow(@provider).to receive(:shell_out).and_return(@status) + allow(@provider).to receive(:shell_out_compacted).and_return(@status) expect { @provider.candidate_version }.to raise_error(Chef::Exceptions::Package) end @@ -151,12 +151,12 @@ PACMAN_CONF describe Chef::Provider::Package::Pacman, "install_package" do it "should run pacman install with the package name and version" do - expect(@provider).to receive(:shell_out!).with("pacman", "--sync", "--noconfirm", "--noprogressbar", "nano", { timeout: 900 }) + expect(@provider).to receive(:shell_out_compacted!).with("pacman", "--sync", "--noconfirm", "--noprogressbar", "nano", { timeout: 900 }) @provider.install_package("nano", "1.0") end it "should run pacman install with the package name and version and options if specified" do - expect(@provider).to receive(:shell_out!).with("pacman", "--sync", "--noconfirm", "--noprogressbar", "--debug", "nano", { timeout: 900 }) + expect(@provider).to receive(:shell_out_compacted!).with("pacman", "--sync", "--noconfirm", "--noprogressbar", "--debug", "nano", { timeout: 900 }) @new_resource.options("--debug") @provider.install_package("nano", "1.0") @@ -172,12 +172,12 @@ PACMAN_CONF describe Chef::Provider::Package::Pacman, "remove_package" do it "should run pacman remove with the package name" do - expect(@provider).to receive(:shell_out!).with("pacman", "--remove", "--noconfirm", "--noprogressbar", "nano", { timeout: 900 }) + expect(@provider).to receive(:shell_out_compacted!).with("pacman", "--remove", "--noconfirm", "--noprogressbar", "nano", { timeout: 900 }) @provider.remove_package("nano", "1.0") end it "should run pacman remove with the package name and options if specified" do - expect(@provider).to receive(:shell_out!).with("pacman", "--remove", "--noconfirm", "--noprogressbar", "--debug", "nano", { timeout: 900 }) + expect(@provider).to receive(:shell_out_compacted!).with("pacman", "--remove", "--noconfirm", "--noprogressbar", "--debug", "nano", { timeout: 900 }) @new_resource.options("--debug") @provider.remove_package("nano", "1.0") diff --git a/spec/unit/provider/package/paludis_spec.rb b/spec/unit/provider/package/paludis_spec.rb index df0150c8c0..5481a33c0d 100644 --- a/spec/unit/provider/package/paludis_spec.rb +++ b/spec/unit/provider/package/paludis_spec.rb @@ -1,6 +1,6 @@ # # Author:: Vasiliy Tolstov <v.tolstov@selfip.ru> -# Copyright:: Copyright 2014-2016, Chef Software Inc. +# Copyright:: Copyright 2014-2018, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -47,19 +47,19 @@ PKG_STATUS context "when loading current resource" do it "should create a current resource with the name of the new_resource" do - expect(@provider).to receive(:shell_out!).and_return(@shell_out) + expect(@provider).to receive(:shell_out_compacted!).and_return(@shell_out) expect(Chef::Resource::Package).to receive(:new).and_return(@current_resource) @provider.load_current_resource end it "should set the current resources package name to the new resources package name" do - expect(@provider).to receive(:shell_out!).and_return(@shell_out) + expect(@provider).to receive(:shell_out_compacted!).and_return(@shell_out) expect(@current_resource).to receive(:package_name).with(@new_resource.package_name) @provider.load_current_resource end it "should run pkg info with the package name" do - expect(@provider).to receive(:shell_out!).with("cave", "-L", "warning", "print-ids", "-M", "none", "-m", @new_resource.package_name, "-f", "%c/%p %v %r\n").and_return(@shell_out) + expect(@provider).to receive(:shell_out_compacted!).with("cave", "-L", "warning", "print-ids", "-M", "none", "-m", @new_resource.package_name, "-f", "%c/%p %v %r\n", timeout: 900).and_return(@shell_out) @provider.load_current_resource end @@ -72,26 +72,26 @@ user/ntp 0 accounts user/ntp 0 installed-accounts net/ntp 4.2.6_p5-r1 installed INSTALLED - expect(@provider).to receive(:shell_out!).and_return(@shell_out) + expect(@provider).to receive(:shell_out_compacted!).and_return(@shell_out) @provider.load_current_resource expect(@current_resource.version).to eq("4.2.6_p5-r1") expect(@provider.candidate_version).to eql("4.2.6_p5-r2") end it "should return the current resource" do - expect(@provider).to receive(:shell_out!).and_return(@shell_out) + expect(@provider).to receive(:shell_out_compacted!).and_return(@shell_out) expect(@provider.load_current_resource).to eql(@current_resource) end end context "when installing a package" do it "should run pkg install with the package name and version" do - expect(@provider).to receive(:shell_out!).with("cave", "-L", "warning", "resolve", "-x", "=net/ntp-4.2.6_p5-r2", { :timeout => @new_resource.timeout || 900 }) + expect(@provider).to receive(:shell_out_compacted!).with("cave", "-L", "warning", "resolve", "-x", "=net/ntp-4.2.6_p5-r2", { :timeout => @new_resource.timeout || 900 }) @provider.install_package("net/ntp", "4.2.6_p5-r2") end it "should run pkg install with the package name and version and options if specified" do - expect(@provider).to receive(:shell_out!).with("cave", "-L", "warning", "resolve", "-x", "--preserve-world", "=net/ntp-4.2.6_p5-r2", { :timeout => @new_resource.timeout || 900 }) + expect(@provider).to receive(:shell_out_compacted!).with("cave", "-L", "warning", "resolve", "-x", "--preserve-world", "=net/ntp-4.2.6_p5-r2", { :timeout => @new_resource.timeout || 900 }) @new_resource.options "--preserve-world" @provider.install_package("net/ntp", "4.2.6_p5-r2") end @@ -101,7 +101,7 @@ INSTALLED sys-process/lsof 4.87 arbor sys-process/lsof 4.87 x86_64 PKG_STATUS - expect(@provider).to receive(:shell_out!).with("cave", "-L", "warning", "resolve", "-x", "=sys-process/lsof-4.87", { :timeout => @new_resource.timeout || 900 }) + expect(@provider).to receive(:shell_out_compacted!).with("cave", "-L", "warning", "resolve", "-x", "=sys-process/lsof-4.87", { :timeout => @new_resource.timeout || 900 }) @provider.install_package("sys-process/lsof", "4.87") end @@ -110,7 +110,7 @@ PKG_STATUS sys-process/lsof 4.87 arbor sys-process/lsof 4.87 x86_64 PKG_STATUS - expect(@provider).to receive(:shell_out!).and_return(@shell_out) + expect(@provider).to receive(:shell_out_compacted!).and_return(@shell_out) @provider.load_current_resource expect(@current_resource.version).to be_nil expect(@provider.candidate_version).to eql("4.87") @@ -119,14 +119,14 @@ PKG_STATUS context "when upgrading a package" do it "should run pkg install with the package name and version" do - expect(@provider).to receive(:shell_out!).with("cave", "-L", "warning", "resolve", "-x", "=net/ntp-4.2.6_p5-r2", { :timeout => @new_resource.timeout || 900 }) + expect(@provider).to receive(:shell_out_compacted!).with("cave", "-L", "warning", "resolve", "-x", "=net/ntp-4.2.6_p5-r2", { :timeout => @new_resource.timeout || 900 }) @provider.upgrade_package("net/ntp", "4.2.6_p5-r2") end end context "when uninstalling a package" do it "should run pkg uninstall with the package name and version" do - expect(@provider).to receive(:shell_out!).with("cave", "-L", "warning", "uninstall", "-x", "=net/ntp-4.2.6_p5-r2") + expect(@provider).to receive(:shell_out_compacted!).with("cave", "-L", "warning", "uninstall", "-x", "=net/ntp-4.2.6_p5-r2", timeout: 900) @provider.remove_package("net/ntp", "4.2.6_p5-r2") end diff --git a/spec/unit/provider/package/portage_spec.rb b/spec/unit/provider/package/portage_spec.rb index 40dc44b113..7bf8e7f2e8 100644 --- a/spec/unit/provider/package/portage_spec.rb +++ b/spec/unit/provider/package/portage_spec.rb @@ -1,6 +1,6 @@ # # Author:: Caleb Tennis (<caleb.tennis@gmail.com>) -# Copyright:: Copyright 2008-2016, Chef Software Inc. +# Copyright:: Copyright 2008-2018, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,19 +22,19 @@ describe Chef::Provider::Package::Portage, "load_current_resource" do @node = Chef::Node.new @events = Chef::EventDispatch::Dispatcher.new @run_context = Chef::RunContext.new(@node, {}, @events) - @new_resource = Chef::Resource::Package.new("dev-util/git") - @new_resource_without_category = Chef::Resource::Package.new("git") - @current_resource = Chef::Resource::Package.new("dev-util/git") + @new_resource = Chef::Resource::PortagePackage.new("dev-util/git") + @new_resource_without_category = Chef::Resource::PortagePackage.new("git") + @current_resource = Chef::Resource::PortagePackage.new("dev-util/git") @provider = Chef::Provider::Package::Portage.new(@new_resource, @run_context) - allow(Chef::Resource::Package).to receive(:new).and_return(@current_resource) + allow(Chef::Resource::PortagePackage).to receive(:new).and_return(@current_resource) end describe "when determining the current state of the package" do it "should create a current resource with the name of new_resource" do allow(::Dir).to receive(:[]).with("/var/db/pkg/dev-util/git-*").and_return(["/var/db/pkg/dev-util/git-1.0.0"]) - expect(Chef::Resource::Package).to receive(:new).and_return(@current_resource) + expect(Chef::Resource::PortagePackage).to receive(:new).and_return(@current_resource) @provider.load_current_resource end @@ -108,26 +108,26 @@ describe Chef::Provider::Package::Portage, "load_current_resource" do describe Chef::Provider::Package::Portage, "candidate_version" do it "should return the candidate_version variable if already set" do @provider.candidate_version = "1.0.0" - expect(@provider).not_to receive(:shell_out) + expect(@provider).not_to receive(:shell_out_compacted) @provider.candidate_version end it "should throw an exception if the exitstatus is not 0" do status = double(:stdout => "", :stderr => "", :exitstatus => 1) - allow(@provider).to receive(:shell_out).and_return(status) + allow(@provider).to receive(:shell_out_compacted).and_return(status) expect { @provider.candidate_version }.to raise_error(Chef::Exceptions::Package) end it "should find the candidate_version if a category is specifed and there are no duplicates" do status = double(:stdout => "dev-vcs/git-2.16.2", :exitstatus => 0) - expect(@provider).to receive(:shell_out).and_return(status) + expect(@provider).to receive(:shell_out_compacted).and_return(status) expect(@provider.candidate_version).to eq("2.16.2") end it "should find the candidate_version if a category is not specifed and there are no duplicates" do status = double(:stdout => "dev-vcs/git-2.16.2", :exitstatus => 0) @provider = Chef::Provider::Package::Portage.new(@new_resource_without_category, @run_context) - expect(@provider).to receive(:shell_out).and_return(status) + expect(@provider).to receive(:shell_out_compacted).and_return(status) expect(@provider.candidate_version).to eq("2.16.2") end @@ -141,24 +141,24 @@ Please use a more specific atom. EOF status = double(:stdout => "", :stderr => stderr_output, :exitstatus => 1) @provider = Chef::Provider::Package::Portage.new(@new_resource_without_category, @run_context) - expect(@provider).to receive(:shell_out).and_return(status) + expect(@provider).to receive(:shell_out_compacted).and_return(status) expect { @provider.candidate_version }.to raise_error(Chef::Exceptions::Package) end end describe Chef::Provider::Package::Portage, "install_package" do it "should install a normally versioned package using portage" do - expect(@provider).to receive(:shell_out!).with("emerge", "-g", "--color", "n", "--nospinner", "--quiet", "=dev-util/git-1.0.0") + expect(@provider).to receive(:shell_out_compacted!).with("emerge", "-g", "--color", "n", "--nospinner", "--quiet", "=dev-util/git-1.0.0", timeout: 3600) @provider.install_package("dev-util/git", "1.0.0") end it "should install a tilde versioned package using portage" do - expect(@provider).to receive(:shell_out!).with("emerge", "-g", "--color", "n", "--nospinner", "--quiet", "~dev-util/git-1.0.0") + expect(@provider).to receive(:shell_out_compacted!).with("emerge", "-g", "--color", "n", "--nospinner", "--quiet", "~dev-util/git-1.0.0", timeout: 3600) @provider.install_package("dev-util/git", "~1.0.0") end it "should add options to the emerge command when specified" do - expect(@provider).to receive(:shell_out!).with("emerge", "-g", "--color", "n", "--nospinner", "--quiet", "--oneshot", "=dev-util/git-1.0.0") + expect(@provider).to receive(:shell_out_compacted!).with("emerge", "-g", "--color", "n", "--nospinner", "--quiet", "--oneshot", "=dev-util/git-1.0.0", timeout: 3600) @new_resource.options "--oneshot" @provider.install_package("dev-util/git", "1.0.0") end @@ -166,12 +166,12 @@ EOF describe Chef::Provider::Package::Portage, "remove_package" do it "should un-emerge the package with no version specified" do - expect(@provider).to receive(:shell_out!).with("emerge", "--unmerge", "--color", "n", "--nospinner", "--quiet", "dev-util/git") + expect(@provider).to receive(:shell_out_compacted!).with("emerge", "--unmerge", "--color", "n", "--nospinner", "--quiet", "dev-util/git", timeout: 3600) @provider.remove_package("dev-util/git", nil) end it "should un-emerge the package with a version specified" do - expect(@provider).to receive(:shell_out!).with("emerge", "--unmerge", "--color", "n", "--nospinner", "--quiet", "=dev-util/git-1.0.0") + expect(@provider).to receive(:shell_out_compacted!).with("emerge", "--unmerge", "--color", "n", "--nospinner", "--quiet", "=dev-util/git-1.0.0", timeout: 3600) @provider.remove_package("dev-util/git", "1.0.0") end end diff --git a/spec/unit/provider/package/rpm_spec.rb b/spec/unit/provider/package/rpm_spec.rb index 3730878026..91d4ca69b4 100644 --- a/spec/unit/provider/package/rpm_spec.rb +++ b/spec/unit/provider/package/rpm_spec.rb @@ -44,8 +44,8 @@ describe Chef::Provider::Package::Rpm do allow(::File).to receive(:exist?).with("PLEASE STUB File.exists? EXACTLY").and_return(true) # Ensure all shell out usage is stubbed with exact arguments - allow(provider).to receive(:shell_out!).with("PLEASE STUB YOUR SHELLOUT CALLS").and_return(nil) - allow(provider).to receive(:shell_out).with("PLEASE STUB YOUR SHELLOUT CALLS").and_return(nil) + allow(provider).to receive(:shell_out_compacted!).with("PLEASE STUB YOUR SHELLOUT CALLS").and_return(nil) + allow(provider).to receive(:shell_out_compacted).with("PLEASE STUB YOUR SHELLOUT CALLS").and_return(nil) end describe "when the package source is not valid" do @@ -85,11 +85,11 @@ describe Chef::Provider::Package::Rpm do describe "when the package source is valid" do before do - expect(provider).to receive(:shell_out!). + expect(provider).to receive(:shell_out_compacted!). with("rpm", "-qp", "--queryformat", "%{NAME} %{VERSION}-%{RELEASE}\n", package_source, timeout: 900). and_return(rpm_qp_status) - expect(provider).to receive(:shell_out). + expect(provider).to receive(:shell_out_compacted). with("rpm", "-q", "--queryformat", "%{NAME} %{VERSION}-%{RELEASE}\n", package_name, timeout: 900). and_return(rpm_q_status) end @@ -151,7 +151,7 @@ describe Chef::Provider::Package::Rpm do context "when at the desired version already" do it "does nothing when the correct version is installed" do - expect(provider).to_not receive(:shell_out!).with("rpm", "-i", "/tmp/imagemagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900) + expect(provider).to_not receive(:shell_out_compacted!).with("rpm", "-i", "/tmp/imagemagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900) provider.action_install end @@ -162,7 +162,7 @@ describe Chef::Provider::Package::Rpm do let(:rpm_q_stdout) { "imagemagick-c++ 0.5.4.7-7.el6_5" } it "runs rpm -u with the package source to upgrade" do - expect(provider).to receive(:shell_out!).with("rpm", "-U", "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900) + expect(provider).to receive(:shell_out_compacted!).with("rpm", "-U", "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900) provider.action_install end end @@ -178,7 +178,7 @@ describe Chef::Provider::Package::Rpm do let(:rpm_q_stdout) { "imagemagick-c++ 21.4-19.el6_5" } it "should run rpm -u --oldpackage with the package source to downgrade" do - expect(provider).to receive(:shell_out!).with("rpm", "-U", "--oldpackage", "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900) + expect(provider).to receive(:shell_out_compacted!).with("rpm", "-U", "--oldpackage", "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900) provider.action_install end @@ -192,7 +192,7 @@ describe Chef::Provider::Package::Rpm do context "when at the desired version already" do it "does nothing when the correct version is installed" do - expect(provider).to_not receive(:shell_out!).with("rpm", "-i", "/tmp/imagemagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900) + expect(provider).to_not receive(:shell_out_compacted!).with("rpm", "-i", "/tmp/imagemagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900) provider.action_upgrade end @@ -203,7 +203,7 @@ describe Chef::Provider::Package::Rpm do let(:rpm_q_stdout) { "imagemagick-c++ 0.5.4.7-7.el6_5" } it "runs rpm -u with the package source to upgrade" do - expect(provider).to receive(:shell_out!).with("rpm", "-U", "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900) + expect(provider).to receive(:shell_out_compacted!).with("rpm", "-U", "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900) provider.action_upgrade end end @@ -219,7 +219,7 @@ describe Chef::Provider::Package::Rpm do let(:rpm_q_stdout) { "imagemagick-c++ 21.4-19.el6_5" } it "should run rpm -u --oldpackage with the package source to downgrade" do - expect(provider).to receive(:shell_out!).with("rpm", "-U", "--oldpackage", "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900) + expect(provider).to receive(:shell_out_compacted!).with("rpm", "-U", "--oldpackage", "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900) provider.action_upgrade end @@ -231,7 +231,7 @@ describe Chef::Provider::Package::Rpm do let(:action) { :remove } it "should remove the package" do - expect(provider).to receive(:shell_out!).with("rpm", "-e", "ImageMagick-c++-6.5.4.7-7.el6_5", timeout: 900) + expect(provider).to receive(:shell_out_compacted!).with("rpm", "-e", "ImageMagick-c++-6.5.4.7-7.el6_5", timeout: 900) provider.action_remove end end @@ -357,7 +357,7 @@ describe Chef::Provider::Package::Rpm do describe "action install" do it "installs the package" do - expect(provider).to receive(:shell_out!).with("rpm", "-i", package_source, timeout: 900) + expect(provider).to receive(:shell_out_compacted!).with("rpm", "-i", package_source, timeout: 900) provider.action_install end @@ -365,7 +365,7 @@ describe Chef::Provider::Package::Rpm do context "when custom resource options are given" do it "installs with custom options specified in the resource" do new_resource.options("--dbpath /var/lib/rpm") - expect(provider).to receive(:shell_out!).with("rpm", "--dbpath", "/var/lib/rpm", "-i", package_source, timeout: 900) + expect(provider).to receive(:shell_out_compacted!).with("rpm", "--dbpath", "/var/lib/rpm", "-i", package_source, timeout: 900) provider.action_install end end @@ -376,7 +376,7 @@ describe Chef::Provider::Package::Rpm do let(:action) { :upgrade } it "installs the package" do - expect(provider).to receive(:shell_out!).with("rpm", "-i", package_source, timeout: 900) + expect(provider).to receive(:shell_out_compacted!).with("rpm", "-i", package_source, timeout: 900) provider.action_upgrade end @@ -387,7 +387,7 @@ describe Chef::Provider::Package::Rpm do let(:action) { :remove } it "should do nothing" do - expect(provider).to_not receive(:shell_out!).with("rpm", "-e", "ImageMagick-c++-6.5.4.7-7.el6_5", timeout: 900) + expect(provider).to_not receive(:shell_out_compacted!).with("rpm", "-e", "ImageMagick-c++-6.5.4.7-7.el6_5", timeout: 900) provider.action_remove end end @@ -413,7 +413,7 @@ describe Chef::Provider::Package::Rpm do it "should install from a path when the package is a path and the source is nil" do expect(new_resource.source).to eq("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm") provider.current_resource = current_resource - expect(provider).to receive(:shell_out!).with("rpm", "-i", "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900) + expect(provider).to receive(:shell_out_compacted!).with("rpm", "-i", "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900) provider.install_package("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", "6.5.4.7-7.el6_5") end @@ -421,7 +421,7 @@ describe Chef::Provider::Package::Rpm do expect(new_resource.source).to eq("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm") current_resource.version("21.4-19.el5") provider.current_resource = current_resource - expect(provider).to receive(:shell_out!).with("rpm", "-U", "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900) + expect(provider).to receive(:shell_out_compacted!).with("rpm", "-U", "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900) provider.upgrade_package("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", "6.5.4.7-7.el6_5") end end diff --git a/spec/unit/provider/package/rubygems_spec.rb b/spec/unit/provider/package/rubygems_spec.rb index 28bd371539..3b1a13e49c 100644 --- a/spec/unit/provider/package/rubygems_spec.rb +++ b/spec/unit/provider/package/rubygems_spec.rb @@ -190,21 +190,21 @@ describe Chef::Provider::Package::Rubygems::AlternateGemEnvironment do it "determines the gem paths from shelling out to gem env" do gem_env_output = ["/path/to/gems", "/another/path/to/gems"].join(File::PATH_SEPARATOR) shell_out_result = OpenStruct.new(stdout: gem_env_output) - expect(@gem_env).to receive(:shell_out!).with("/usr/weird/bin/gem env gempath").and_return(shell_out_result) + expect(@gem_env).to receive(:shell_out_compacted!).with("/usr/weird/bin/gem env gempath").and_return(shell_out_result) expect(@gem_env.gem_paths).to eq(["/path/to/gems", "/another/path/to/gems"]) end it "caches the gempaths by gem_binary" do gem_env_output = ["/path/to/gems", "/another/path/to/gems"].join(File::PATH_SEPARATOR) shell_out_result = OpenStruct.new(stdout: gem_env_output) - expect(@gem_env).to receive(:shell_out!).with("/usr/weird/bin/gem env gempath").and_return(shell_out_result) + expect(@gem_env).to receive(:shell_out_compacted!).with("/usr/weird/bin/gem env gempath").and_return(shell_out_result) expected = ["/path/to/gems", "/another/path/to/gems"] expect(@gem_env.gem_paths).to eq(["/path/to/gems", "/another/path/to/gems"]) expect(Chef::Provider::Package::Rubygems::AlternateGemEnvironment.gempath_cache["/usr/weird/bin/gem"]).to eq(expected) end it "uses the cached result for gem paths when available" do - expect(@gem_env).not_to receive(:shell_out!) + expect(@gem_env).not_to receive(:shell_out_compacted!) expected = ["/path/to/gems", "/another/path/to/gems"] Chef::Provider::Package::Rubygems::AlternateGemEnvironment.gempath_cache["/usr/weird/bin/gem"] = expected expect(@gem_env.gem_paths).to eq(["/path/to/gems", "/another/path/to/gems"]) @@ -280,7 +280,7 @@ RubyGems Environment: - https://rubygems.org/ - http://gems.github.com/ JRUBY_GEM_ENV - expect(@gem_env).to receive(:shell_out!).with("/usr/weird/bin/gem env").and_return(double("jruby_gem_env", stdout: gem_env_out)) + expect(@gem_env).to receive(:shell_out_compacted!).with("/usr/weird/bin/gem env").and_return(double("jruby_gem_env", stdout: gem_env_out)) expected = ["ruby", Gem::Platform.new("universal-java-1.6")] expect(@gem_env.gem_platforms).to eq(expected) # it should also cache the result @@ -288,7 +288,7 @@ RubyGems Environment: end it "uses the cached result for gem platforms if available" do - expect(@gem_env).not_to receive(:shell_out!) + expect(@gem_env).not_to receive(:shell_out_compacted!) expected = ["ruby", Gem::Platform.new("universal-java-1.6")] Chef::Provider::Package::Rubygems::AlternateGemEnvironment.platform_cache["/usr/weird/bin/gem"] = expected expect(@gem_env.gem_platforms).to eq(expected) @@ -322,7 +322,7 @@ RubyGems Environment: - https://rubygems.org/ - http://gems.github.com/ RBX_GEM_ENV - expect(@gem_env).to receive(:shell_out!).with("/usr/weird/bin/gem env").and_return(double("rbx_gem_env", stdout: gem_env_out)) + expect(@gem_env).to receive(:shell_out_compacted!).with("/usr/weird/bin/gem env").and_return(double("rbx_gem_env", stdout: gem_env_out)) expect(@gem_env.gem_platforms).to eq(Gem.platforms) expect(Chef::Provider::Package::Rubygems::AlternateGemEnvironment.platform_cache["/usr/weird/bin/gem"]).to eq(Gem.platforms) end @@ -684,7 +684,7 @@ describe Chef::Provider::Package::Rubygems do it "installs the gem by shelling out when options are provided as a String" do expected = "gem install rspec-core -q --no-rdoc --no-ri -v \"#{target_version}\" --source=https://www.rubygems.org #{options}" - expect(provider).to receive(:shell_out!).with(expected, env: nil, timeout: 900) + expect(provider).to receive(:shell_out_compacted!).with(expected, env: nil, timeout: 900) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end @@ -697,7 +697,7 @@ describe Chef::Provider::Package::Rubygems do Chef::Config[:rubygems_url] = "https://mirror1" expect(provider.gem_env).to receive(:candidate_version_from_remote).with(gem_dep, Chef::Config[:rubygems_url]).and_return(version) expected = "#{gem_binary} install rspec-core -q --no-rdoc --no-ri -v \"#{target_version}\" --source=https://mirror1" - expect(provider).to receive(:shell_out!).with(expected, env: nil, timeout: 900) + expect(provider).to receive(:shell_out_compacted!).with(expected, env: nil, timeout: 900) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end @@ -709,7 +709,7 @@ describe Chef::Provider::Package::Rubygems do it "installs the gem with rubygems.org as an added source" do expected = "#{gem_binary} install rspec-core -q --no-rdoc --no-ri -v \"#{target_version}\" --source=#{source} --source=https://www.rubygems.org" - expect(provider).to receive(:shell_out!).with(expected, env: nil, timeout: 900) + expect(provider).to receive(:shell_out_compacted!).with(expected, env: nil, timeout: 900) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end @@ -720,7 +720,7 @@ describe Chef::Provider::Package::Rubygems do it "ignores the Chef::Config setting" do Chef::Config[:rubygems_url] = "https://ignored" expected = "#{gem_binary} install rspec-core -q --no-rdoc --no-ri -v \"#{target_version}\" --source=#{source}" - expect(provider).to receive(:shell_out!).with(expected, env: nil, timeout: 900) + expect(provider).to receive(:shell_out_compacted!).with(expected, env: nil, timeout: 900) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end @@ -733,7 +733,7 @@ describe Chef::Provider::Package::Rubygems do it "installs the gem with an array as an added source" do expected = "#{gem_binary} install rspec-core -q --no-rdoc --no-ri -v \"#{target_version}\" --source=https://mirror1 --source=https://mirror2 --source=https://www.rubygems.org" - expect(provider).to receive(:shell_out!).with(expected, env: nil, timeout: 900) + expect(provider).to receive(:shell_out_compacted!).with(expected, env: nil, timeout: 900) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end @@ -744,7 +744,7 @@ describe Chef::Provider::Package::Rubygems do it "ignores the Chef::Config setting" do Chef::Config[:rubygems_url] = "https://ignored" expected = "#{gem_binary} install rspec-core -q --no-rdoc --no-ri -v \"#{target_version}\" --source=https://mirror1 --source=https://mirror2" - expect(provider).to receive(:shell_out!).with(expected, env: nil, timeout: 900) + expect(provider).to receive(:shell_out_compacted!).with(expected, env: nil, timeout: 900) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end @@ -758,7 +758,7 @@ describe Chef::Provider::Package::Rubygems do it "installs the gem" do new_resource.clear_sources(true) expected = "#{gem_binary} install rspec-core -q --no-rdoc --no-ri -v \"#{target_version}\" --clear-sources --source=#{source} --source=https://www.rubygems.org" - expect(provider).to receive(:shell_out!).with(expected, env: nil, timeout: 900) + expect(provider).to receive(:shell_out_compacted!).with(expected, env: nil, timeout: 900) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end @@ -770,7 +770,7 @@ describe Chef::Provider::Package::Rubygems do it "installs the gem by shelling out when options are provided but no version is given" do expected = "gem install rspec-core -q --no-rdoc --no-ri -v \"#{candidate_version}\" --source=https://www.rubygems.org #{options}" - expect(provider).to receive(:shell_out!).with(expected, env: nil, timeout: 900) + expect(provider).to receive(:shell_out_compacted!).with(expected, env: nil, timeout: 900) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end @@ -833,7 +833,7 @@ describe Chef::Provider::Package::Rubygems do let(:gem_binary) { "/usr/weird/bin/gem" } it "installs the gem by shelling out to gem install" do - expect(provider).to receive(:shell_out!).with("#{gem_binary} install rspec-core -q --no-rdoc --no-ri -v \"#{target_version}\" --source=https://www.rubygems.org", env: nil, timeout: 900) + expect(provider).to receive(:shell_out_compacted!).with("#{gem_binary} install rspec-core -q --no-rdoc --no-ri -v \"#{target_version}\" --source=https://www.rubygems.org", env: nil, timeout: 900) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end @@ -843,7 +843,7 @@ describe Chef::Provider::Package::Rubygems do let(:target_version) { ">= 0" } it "installs the gem by shelling out to gem install" do - expect(provider).to receive(:shell_out!).with("#{gem_binary} install #{source} -q --no-rdoc --no-ri -v \"#{target_version}\"", env: nil, timeout: 900) + expect(provider).to receive(:shell_out_compacted!).with("#{gem_binary} install #{source} -q --no-rdoc --no-ri -v \"#{target_version}\"", env: nil, timeout: 900) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end @@ -855,7 +855,7 @@ describe Chef::Provider::Package::Rubygems do it "installs the gem from file by shelling out to gem install when the package is a path and the source is nil" do expect(new_resource.source).to eq(gem_name) - expect(provider).to receive(:shell_out!).with("#{gem_binary} install #{gem_name} -q --no-rdoc --no-ri -v \"#{target_version}\"", env: nil, timeout: 900) + expect(provider).to receive(:shell_out_compacted!).with("#{gem_binary} install #{gem_name} -q --no-rdoc --no-ri -v \"#{target_version}\"", env: nil, timeout: 900) provider.run_action(:install) expect(new_resource).to be_updated_by_last_action end @@ -902,7 +902,7 @@ describe Chef::Provider::Package::Rubygems do let(:options) { "-i /alt/install/location" } it "uninstalls via the gem command" do - expect(provider).to receive(:shell_out!).with("gem uninstall rspec -q -x -I -a #{options}", env: nil, timeout: 900) + expect(provider).to receive(:shell_out_compacted!).with("gem uninstall rspec -q -x -I -a #{options}", env: nil, timeout: 900) provider.action_remove end end @@ -921,7 +921,7 @@ describe Chef::Provider::Package::Rubygems do let(:gem_binary) { "/usr/weird/bin/gem" } it "uninstalls via the gem command" do - expect(provider).to receive(:shell_out!).with("#{gem_binary} uninstall rspec -q -x -I -a", env: nil, timeout: 900) + expect(provider).to receive(:shell_out_compacted!).with("#{gem_binary} uninstall rspec -q -x -I -a", env: nil, timeout: 900) provider.action_remove end end diff --git a/spec/unit/provider/package/smartos_spec.rb b/spec/unit/provider/package/smartos_spec.rb index 51bffa17b6..cb5e987a85 100644 --- a/spec/unit/provider/package/smartos_spec.rb +++ b/spec/unit/provider/package/smartos_spec.rb @@ -41,26 +41,26 @@ describe Chef::Provider::Package::SmartOS, "load_current_resource" do describe "when loading current resource" do it "should create a current resource with the name of the new_resource" do - expect(@provider).to receive(:shell_out!).and_return(@shell_out) + expect(@provider).to receive(:shell_out_compacted!).and_return(@shell_out) expect(Chef::Resource::Package).to receive(:new).and_return(@current_resource) @provider.load_current_resource end it "should set the current resource package name" do - expect(@provider).to receive(:shell_out!).and_return(@shell_out) + expect(@provider).to receive(:shell_out_compacted!).and_return(@shell_out) expect(@current_resource).to receive(:package_name).with(@new_resource.package_name) @provider.load_current_resource end it "should set the installed version if it is installed" do - expect(@provider).to receive(:shell_out!).and_return(@shell_out) + expect(@provider).to receive(:shell_out_compacted!).and_return(@shell_out) @provider.load_current_resource expect(@current_resource.version).to eq("2.1.5nb2") end it "should set the installed version to nil if it's not installed" do out = OpenStruct.new(:stdout => nil) - expect(@provider).to receive(:shell_out!).and_return(out) + expect(@provider).to receive(:shell_out_compacted!).and_return(out) @provider.load_current_resource expect(@current_resource.version).to eq(nil) end @@ -70,7 +70,7 @@ describe Chef::Provider::Package::SmartOS, "load_current_resource" do describe "candidate_version" do it "should return the candidate_version variable if already setup" do @provider.candidate_version = "2.1.1" - expect(@provider).not_to receive(:shell_out!) + expect(@provider).not_to receive(:shell_out_compacted!) @provider.candidate_version end @@ -80,7 +80,7 @@ describe Chef::Provider::Package::SmartOS, "load_current_resource" do and_yield("something-varnish-1.1.1 something varnish like\n"). and_yield("varnish-2.3.4 actual varnish\n") @shell_out = double("shell_out!", :stdout => search) - expect(@provider).to receive(:shell_out!).with("/opt/local/bin/pkgin", "se", "varnish", :env => nil, :returns => [0, 1], :timeout => 900).and_return(@shell_out) + expect(@provider).to receive(:shell_out_compacted!).with("/opt/local/bin/pkgin", "se", "varnish", :env => nil, :returns => [0, 1], :timeout => 900).and_return(@shell_out) expect(@provider.candidate_version).to eq("2.3.4") end @@ -90,7 +90,7 @@ describe Chef::Provider::Package::SmartOS, "load_current_resource" do and_yield("something-varnish-1.1.1;;something varnish like\n"). and_yield("varnish-2.3.4;;actual varnish\n") @shell_out = double("shell_out!", :stdout => search) - expect(@provider).to receive(:shell_out!).with("/opt/local/bin/pkgin", "se", "varnish", :env => nil, :returns => [0, 1], :timeout => 900).and_return(@shell_out) + expect(@provider).to receive(:shell_out_compacted!).with("/opt/local/bin/pkgin", "se", "varnish", :env => nil, :returns => [0, 1], :timeout => 900).and_return(@shell_out) expect(@provider.candidate_version).to eq("2.3.4") end end @@ -99,8 +99,8 @@ describe Chef::Provider::Package::SmartOS, "load_current_resource" do it "run pkgin and install the package" do out = OpenStruct.new(:stdout => nil) - expect(@provider).to receive(:shell_out!).with("/opt/local/sbin/pkg_info", "-E", "varnish*", { :env => nil, :returns => [0, 1], :timeout => 900 }).and_return(@shell_out) - expect(@provider).to receive(:shell_out!).with("/opt/local/bin/pkgin", "-y", "install", "varnish-2.1.5nb2", { :env => nil, :timeout => 900 }).and_return(out) + expect(@provider).to receive(:shell_out_compacted!).with("/opt/local/sbin/pkg_info", "-E", "varnish*", { :env => nil, :returns => [0, 1], :timeout => 900 }).and_return(@shell_out) + expect(@provider).to receive(:shell_out_compacted!).with("/opt/local/bin/pkgin", "-y", "install", "varnish-2.1.5nb2", { :env => nil, :timeout => 900 }).and_return(out) @provider.load_current_resource @provider.install_package("varnish", "2.1.5nb2") end diff --git a/spec/unit/provider/package/solaris_spec.rb b/spec/unit/provider/package/solaris_spec.rb index 2fba2e3a08..57a0288f58 100644 --- a/spec/unit/provider/package/solaris_spec.rb +++ b/spec/unit/provider/package/solaris_spec.rb @@ -50,19 +50,19 @@ PKGINFO end it "should create a current resource with the name of new_resource" do - allow(@provider).to receive(:shell_out).and_return(@status) + allow(@provider).to receive(:shell_out_compacted).and_return(@status) @provider.load_current_resource expect(@provider.current_resource.name).to eq("SUNWbash") end it "should set the current reource package name to the new resource package name" do - allow(@provider).to receive(:shell_out).and_return(@status) + allow(@provider).to receive(:shell_out_compacted).and_return(@status) @provider.load_current_resource expect(@provider.current_resource.package_name).to eq("SUNWbash") end it "should raise an exception if a source is supplied but not found" do - allow(@provider).to receive(:shell_out).and_return(@status) + allow(@provider).to receive(:shell_out_compacted).and_return(@status) allow(::File).to receive(:exist?).and_return(false) @provider.load_current_resource @provider.define_resource_requirements @@ -71,8 +71,8 @@ PKGINFO it "should get the source package version from pkginfo if provided" do status = double(:stdout => @pkginfo, :exitstatus => 0) - expect(@provider).to receive(:shell_out).with("pkginfo", "-l", "-d", "/tmp/bash.pkg", "SUNWbash", { timeout: 900 }).and_return(status) - expect(@provider).to receive(:shell_out).with("pkginfo", "-l", "SUNWbash", { timeout: 900 }).and_return(@status) + expect(@provider).to receive(:shell_out_compacted).with("pkginfo", "-l", "-d", "/tmp/bash.pkg", "SUNWbash", { timeout: 900 }).and_return(status) + expect(@provider).to receive(:shell_out_compacted).with("pkginfo", "-l", "SUNWbash", { timeout: 900 }).and_return(@status) @provider.load_current_resource expect(@provider.current_resource.package_name).to eq("SUNWbash") @@ -81,8 +81,8 @@ PKGINFO it "should return the current version installed if found by pkginfo" do status = double(:stdout => @pkginfo, :exitstatus => 0) - expect(@provider).to receive(:shell_out).with("pkginfo", "-l", "-d", "/tmp/bash.pkg", "SUNWbash", { timeout: 900 }).and_return(@status) - expect(@provider).to receive(:shell_out).with("pkginfo", "-l", "SUNWbash", { timeout: 900 }).and_return(status) + expect(@provider).to receive(:shell_out_compacted).with("pkginfo", "-l", "-d", "/tmp/bash.pkg", "SUNWbash", { timeout: 900 }).and_return(@status) + expect(@provider).to receive(:shell_out_compacted).with("pkginfo", "-l", "SUNWbash", { timeout: 900 }).and_return(status) @provider.load_current_resource expect(@provider.current_resource.version).to eq("11.10.0,REV=2005.01.08.05.16") end @@ -90,19 +90,19 @@ PKGINFO it "should raise an exception if the source is not set but we are installing" do @new_resource = Chef::Resource::Package.new("SUNWbash") @provider = Chef::Provider::Package::Solaris.new(@new_resource, @run_context) - allow(@provider).to receive(:shell_out).and_return(@status) + allow(@provider).to receive(:shell_out_compacted).and_return(@status) expect { @provider.run_action(:install) }.to raise_error(Chef::Exceptions::Package) end it "should raise an exception if pkginfo fails to run" do status = double(:stdout => "", :exitstatus => -1) - allow(@provider).to receive(:shell_out).and_return(status) + allow(@provider).to receive(:shell_out_compacted).and_return(status) expect { @provider.load_current_resource }.to raise_error(Chef::Exceptions::Package) end it "should return a current resource with a nil version if the package is not found" do - expect(@provider).to receive(:shell_out).with("pkginfo", "-l", "-d", "/tmp/bash.pkg", "SUNWbash", { timeout: 900 }).and_return(@status) - expect(@provider).to receive(:shell_out).with("pkginfo", "-l", "SUNWbash", { timeout: 900 }).and_return(@status) + expect(@provider).to receive(:shell_out_compacted).with("pkginfo", "-l", "-d", "/tmp/bash.pkg", "SUNWbash", { timeout: 900 }).and_return(@status) + expect(@provider).to receive(:shell_out_compacted).with("pkginfo", "-l", "SUNWbash", { timeout: 900 }).and_return(@status) @provider.load_current_resource expect(@provider.current_resource.version).to be_nil end @@ -111,20 +111,20 @@ PKGINFO describe "candidate_version" do it "should return the candidate_version variable if already setup" do @provider.candidate_version = "11.10.0,REV=2005.01.08.05.16" - expect(@provider).not_to receive(:shell_out) + expect(@provider).not_to receive(:shell_out_compacted) @provider.candidate_version end it "should lookup the candidate_version if the variable is not already set" do status = double(:stdout => "", :exitstatus => 0) - allow(@provider).to receive(:shell_out).and_return(status) - expect(@provider).to receive(:shell_out) + allow(@provider).to receive(:shell_out_compacted).and_return(status) + expect(@provider).to receive(:shell_out_compacted) @provider.candidate_version end it "should throw and exception if the exitstatus is not 0" do status = double(:stdout => "", :exitstatus => 1) - allow(@provider).to receive(:shell_out).and_return(status) + allow(@provider).to receive(:shell_out_compacted).and_return(status) expect { @provider.candidate_version }.to raise_error(Chef::Exceptions::Package) end @@ -132,7 +132,7 @@ PKGINFO describe "install and upgrade" do it "should run pkgadd -n -d with the package source to install" do - expect(@provider).to receive(:shell_out!).with("pkgadd", "-n", "-d", "/tmp/bash.pkg", "all", { timeout: 900 }) + expect(@provider).to receive(:shell_out_compacted!).with("pkgadd", "-n", "-d", "/tmp/bash.pkg", "all", { timeout: 900 }) @provider.install_package("SUNWbash", "11.10.0,REV=2005.01.08.05.16") end @@ -140,26 +140,26 @@ PKGINFO @new_resource = Chef::Resource::Package.new("/tmp/bash.pkg") @provider = Chef::Provider::Package::Solaris.new(@new_resource, @run_context) expect(@new_resource.source).to eq("/tmp/bash.pkg") - expect(@provider).to receive(:shell_out!).with("pkgadd", "-n", "-d", "/tmp/bash.pkg", "all", { timeout: 900 }) + expect(@provider).to receive(:shell_out_compacted!).with("pkgadd", "-n", "-d", "/tmp/bash.pkg", "all", { timeout: 900 }) @provider.install_package("/tmp/bash.pkg", "11.10.0,REV=2005.01.08.05.16") end it "should run pkgadd -n -a /tmp/myadmin -d with the package options -a /tmp/myadmin" do @new_resource.options "-a /tmp/myadmin" - expect(@provider).to receive(:shell_out!).with("pkgadd", "-n", "-a", "/tmp/myadmin", "-d", "/tmp/bash.pkg", "all", { timeout: 900 }) + expect(@provider).to receive(:shell_out_compacted!).with("pkgadd", "-n", "-a", "/tmp/myadmin", "-d", "/tmp/bash.pkg", "all", { timeout: 900 }) @provider.install_package("SUNWbash", "11.10.0,REV=2005.01.08.05.16") end end describe "remove" do it "should run pkgrm -n to remove the package" do - expect(@provider).to receive(:shell_out!).with("pkgrm", "-n", "SUNWbash", { timeout: 900 }) + expect(@provider).to receive(:shell_out_compacted!).with("pkgrm", "-n", "SUNWbash", { timeout: 900 }) @provider.remove_package("SUNWbash", "11.10.0,REV=2005.01.08.05.16") end it "should run pkgrm -n -a /tmp/myadmin with options -a /tmp/myadmin" do @new_resource.options "-a /tmp/myadmin" - expect(@provider).to receive(:shell_out!).with("pkgrm", "-n", "-a", "/tmp/myadmin", "SUNWbash", { timeout: 900 }) + expect(@provider).to receive(:shell_out_compacted!).with("pkgrm", "-n", "-a", "/tmp/myadmin", "SUNWbash", { timeout: 900 }) @provider.remove_package("SUNWbash", "11.10.0,REV=2005.01.08.05.16") end diff --git a/spec/unit/provider/package/windows_spec.rb b/spec/unit/provider/package/windows_spec.rb index 0f4fd465c8..aed0ca88be 100644 --- a/spec/unit/provider/package/windows_spec.rb +++ b/spec/unit/provider/package/windows_spec.rb @@ -398,13 +398,20 @@ describe Chef::Provider::Package::Windows, :windows_only do context "a missing local file is given" do let(:resource_source) { "C:/a_missing_file.exe" } let(:installer_type) { nil } - - it "raises a Package error" do + before do allow(::File).to receive(:exist?).with(provider.new_resource.source).and_return(false) - provider.load_current_resource + end + + it "raises a Package error" do expect { provider.run_action(:install) }.to raise_error(Chef::Exceptions::Package) end + + it "why_run mode doesn't raise an error" do + Chef::Config[:why_run] = true + expect { provider.run_action(:install) }.not_to raise_error + Chef::Config[:why_run] = false + end end end diff --git a/spec/unit/provider/package/zypper_spec.rb b/spec/unit/provider/package/zypper_spec.rb index 819278a795..4ba8ac36ac 100644 --- a/spec/unit/provider/package/zypper_spec.rb +++ b/spec/unit/provider/package/zypper_spec.rb @@ -1,6 +1,6 @@ # # Author:: Adam Jacob (<adam@chef.io>) -# Copyright:: Copyright 2008-2017, Chef Software Inc. +# Copyright:: Copyright 2008-2018, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -34,18 +34,18 @@ describe Chef::Provider::Package::Zypper do before(:each) do allow(Chef::Resource::Package).to receive(:new).and_return(current_resource) - allow(provider).to receive(:shell_out!).and_return(status) + allow(provider).to receive(:shell_out_compacted!).and_return(status) allow(provider).to receive(:`).and_return("2.0") end def shell_out_expectation(*command, **options) options[:timeout] ||= 900 - expect(provider).to receive(:shell_out).with(*command, **options) + expect(provider).to receive(:shell_out_compacted).with(*command, **options) end def shell_out_expectation!(*command, **options) options[:timeout] ||= 900 - expect(provider).to receive(:shell_out!).with(*command, **options) + expect(provider).to receive(:shell_out_compacted!).with(*command, **options) end describe "when loading the current package state" do @@ -67,7 +67,7 @@ describe Chef::Provider::Package::Zypper do end it "should set the installed version to nil on the current resource if zypper info installed version is (none)" do - allow(provider).to receive(:shell_out).and_return(status) + allow(provider).to receive(:shell_out_compacted).and_return(status) expect(current_resource).to receive(:version).with([nil]).and_return(true) provider.load_current_resource end @@ -75,7 +75,7 @@ describe Chef::Provider::Package::Zypper do it "should set the installed version if zypper info has one (zypper version < 1.13.0)" do status = double(:stdout => "Version: 1.0\nInstalled: Yes\n", :exitstatus => 0) - allow(provider).to receive(:shell_out!).and_return(status) + allow(provider).to receive(:shell_out_compacted!).and_return(status) expect(current_resource).to receive(:version).with(["1.0"]).and_return(true) provider.load_current_resource end @@ -83,7 +83,7 @@ describe Chef::Provider::Package::Zypper do it "should set the installed version if zypper info has one (zypper version >= 1.13.0)" do status = double(:stdout => "Version : 1.0 \nInstalled : Yes \n", :exitstatus => 0) - allow(provider).to receive(:shell_out!).and_return(status) + allow(provider).to receive(:shell_out_compacted!).and_return(status) expect(current_resource).to receive(:version).with(["1.0"]).and_return(true) provider.load_current_resource end @@ -91,7 +91,7 @@ describe Chef::Provider::Package::Zypper do it "should set the installed version if zypper info has one (zypper version >= 1.13.17)" do status = double(:stdout => "Version : 1.0\nInstalled : Yes (automatically)\n", :exitstatus => 0) - allow(provider).to receive(:shell_out!).and_return(status) + allow(provider).to receive(:shell_out_compacted!).and_return(status) expect(current_resource).to receive(:version).with(["1.0"]).and_return(true) provider.load_current_resource end @@ -99,7 +99,7 @@ describe Chef::Provider::Package::Zypper do it "should set the candidate version if zypper info has one (zypper version < 1.13.0)" do status = double(:stdout => "Version: 1.0\nInstalled: No\nStatus: out-of-date (version 0.9 installed)", :exitstatus => 0) - allow(provider).to receive(:shell_out!).and_return(status) + allow(provider).to receive(:shell_out_compacted!).and_return(status) provider.load_current_resource expect(provider.candidate_version).to eql(["1.0"]) end @@ -107,7 +107,7 @@ describe Chef::Provider::Package::Zypper do it "should set the candidate version if zypper info has one (zypper version >= 1.13.0)" do status = double(:stdout => "Version : 1.0 \nInstalled : No \nStatus : out-of-date (version 0.9 installed)", :exitstatus => 0) - allow(provider).to receive(:shell_out!).and_return(status) + allow(provider).to receive(:shell_out_compacted!).and_return(status) provider.load_current_resource expect(provider.candidate_version).to eql(["1.0"]) end @@ -269,35 +269,33 @@ describe Chef::Provider::Package::Zypper do describe "action_lock" do it "should lock if the package is not already locked" do - prov = provider - allow(prov).to receive(:shell_out_compact_timeout!).with( - "zypper", "--non-interactive", "info", new_resource.package_name + expect(provider).to receive(:shell_out_compacted!).with( + "zypper", "--non-interactive", "info", new_resource.package_name, timeout: 900 ).and_return(status) - allow(prov).to receive(:shell_out_compact_timeout!).with( - "zypper", "locks" + expect(provider).to receive(:shell_out_compacted!).with( + "zypper", "locks", timeout: 900 ).and_return(instance_double( Mixlib::ShellOut, stdout: "1 | somethingelse | package | (any)" )) - expect(prov).to receive(:lock_package).with(["cups"], [nil]) + expect(provider).to receive(:lock_package).with(["cups"], [nil]) - prov.load_current_resource - prov.action_lock + provider.load_current_resource + provider.action_lock end it "should not lock if the package is already locked" do - prov = provider - allow(prov).to receive(:shell_out_compact_timeout!).with( - "zypper", "--non-interactive", "info", new_resource.package_name + expect(provider).to receive(:shell_out_compacted!).with( + "zypper", "--non-interactive", "info", new_resource.package_name, timeout: 900 ).and_return(status) - allow(prov).to receive(:shell_out_compact_timeout!).with( - "zypper", "locks" + expect(provider).to receive(:shell_out_compacted!).with( + "zypper", "locks", timeout: 900 ).and_return(instance_double( Mixlib::ShellOut, stdout: "1 | cups | package | (any)" )) - expect(prov).to_not receive(:lock_package) + expect(provider).to_not receive(:lock_package) - prov.load_current_resource - prov.action_lock + provider.load_current_resource + provider.action_lock end end @@ -326,33 +324,31 @@ describe Chef::Provider::Package::Zypper do describe "action_unlock" do it "should unlock if the package is not already unlocked" do - prov = provider - allow(prov).to receive(:shell_out_compact_timeout!).with( - "zypper", "--non-interactive", "info", new_resource.package_name + allow(provider).to receive(:shell_out_compacted!).with( + "zypper", "--non-interactive", "info", new_resource.package_name, timeout: 900 ).and_return(status) - allow(prov).to receive(:shell_out_compact_timeout!).with( - "zypper", "locks" + allow(provider).to receive(:shell_out_compacted!).with( + "zypper", "locks", timeout: 900 ).and_return(instance_double( Mixlib::ShellOut, stdout: "1 | cups | package | (any)" )) - expect(prov).to receive(:unlock_package).with(["cups"], [nil]) + expect(provider).to receive(:unlock_package).with(["cups"], [nil]) - prov.load_current_resource + provider.load_current_resource provider.action_unlock end it "should not unlock if the package is already unlocked" do - prov = provider - allow(prov).to receive(:shell_out_compact_timeout!).with( - "zypper", "--non-interactive", "info", new_resource.package_name + allow(provider).to receive(:shell_out_compacted!).with( + "zypper", "--non-interactive", "info", new_resource.package_name, timeout: 900 ).and_return(status) - allow(prov).to receive(:shell_out_compact_timeout!).with( - "zypper", "locks" + allow(provider).to receive(:shell_out_compacted!).with( + "zypper", "locks", timeout: 900 ).and_return(instance_double( Mixlib::ShellOut, stdout: "1 | somethingelse | package | (any)" )) - expect(prov).to_not receive(:unlock_package) + expect(provider).to_not receive(:unlock_package) - prov.load_current_resource + provider.load_current_resource provider.action_unlock end end diff --git a/spec/unit/provider/package_spec.rb b/spec/unit/provider/package_spec.rb index da74c932a8..2eb7cf63e1 100644 --- a/spec/unit/provider/package_spec.rb +++ b/spec/unit/provider/package_spec.rb @@ -1,6 +1,6 @@ # # Author:: Adam Jacob (<adam@chef.io>) -# Copyright:: Copyright 2008-2016, Chef Software, Inc. +# Copyright:: Copyright 2008-2018, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/spec/unit/provider/user/aix_spec.rb b/spec/unit/provider/user/aix_spec.rb index c70fdd9a57..aa62edd878 100644 --- a/spec/unit/provider/user/aix_spec.rb +++ b/spec/unit/provider/user/aix_spec.rb @@ -52,7 +52,7 @@ describe Chef::Provider::User::Aix do end it "should call chpasswd correctly" do - expect(provider).to receive(:shell_out!).with("echo 'adam:Ostagazuzulum' | chpasswd -e").and_return true + expect(provider).to receive(:shell_out_compacted!).with("echo 'adam:Ostagazuzulum' | chpasswd -e").and_return true provider.manage_user end end @@ -61,7 +61,7 @@ describe Chef::Provider::User::Aix do context "with a system user" do before { new_resource.system(true) } it "should add the user to the system group" do - expect(provider).to receive(:shell_out!).with("useradd", "-g", "system", "adam") + expect(provider).to receive(:shell_out_compacted!).with("useradd", "-g", "system", "adam") provider.create_user end end @@ -74,13 +74,13 @@ describe Chef::Provider::User::Aix do end it "should create the home directory" do - allow(provider).to receive(:shell_out!).with("usermod", "-d", "/home/adam", "adam") + allow(provider).to receive(:shell_out_compacted!).with("usermod", "-d", "/home/adam", "adam") expect(FileUtils).to receive(:mkdir_p).and_return(true) provider.manage_user end it "should move an existing home dir" do - allow(provider).to receive(:shell_out!).with("usermod", "-d", "/mnt/home/adam", "adam") + allow(provider).to receive(:shell_out_compacted!).with("usermod", "-d", "/mnt/home/adam", "adam") new_resource.home("/mnt/home/adam") allow(File).to receive(:directory?).with("/home/adam").and_return(true) expect(FileUtils).to receive(:mv).with("/home/adam", "/mnt/home/adam") @@ -89,7 +89,7 @@ describe Chef::Provider::User::Aix do it "should not pass -m" do allow(FileUtils).to receive(:mkdir_p).and_return(true) - expect(provider).to receive(:shell_out!).with("usermod", "-d", "/home/adam", "adam") + expect(provider).to receive(:shell_out_compacted!).with("usermod", "-d", "/home/adam", "adam") provider.manage_user end end diff --git a/spec/unit/provider/user/dscl_spec.rb b/spec/unit/provider/user/dscl_spec.rb index 1019a9ae0f..928cf020e8 100644 --- a/spec/unit/provider/user/dscl_spec.rb +++ b/spec/unit/provider/user/dscl_spec.rb @@ -116,31 +116,31 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30" describe "when shelling out to dscl" do it "should run dscl with the supplied cmd /Path args" do shell_return = shellcmdresult.new("stdout", "err", 0) - expect(provider).to receive(:shell_out).with("dscl", ".", "-cmd", "/Path", "args").and_return(shell_return) + expect(provider).to receive(:shell_out_compacted).with("dscl", ".", "-cmd", "/Path", "args").and_return(shell_return) expect(provider.run_dscl("cmd", "/Path", "args")).to eq("stdout") end it "returns an empty string from delete commands" do shell_return = shellcmdresult.new("out", "err", 23) - expect(provider).to receive(:shell_out).with("dscl", ".", "-delete", "/Path", "args").and_return(shell_return) + expect(provider).to receive(:shell_out_compacted).with("dscl", ".", "-delete", "/Path", "args").and_return(shell_return) expect(provider.run_dscl("delete", "/Path", "args")).to eq("") end it "should raise an exception for any other command" do shell_return = shellcmdresult.new("out", "err", 23) - expect(provider).to receive(:shell_out).with("dscl", ".", "-cmd", "/Path", "arguments").and_return(shell_return) + expect(provider).to receive(:shell_out_compacted).with("dscl", ".", "-cmd", "/Path", "arguments").and_return(shell_return) expect { provider.run_dscl("cmd", "/Path", "arguments") }.to raise_error(Chef::Exceptions::DsclCommandFailed) end it "raises an exception when dscl reports 'no such key'" do shell_return = shellcmdresult.new("No such key: ", "err", 23) - expect(provider).to receive(:shell_out).with("dscl", ".", "-cmd", "/Path", "args").and_return(shell_return) + expect(provider).to receive(:shell_out_compacted).with("dscl", ".", "-cmd", "/Path", "args").and_return(shell_return) expect { provider.run_dscl("cmd", "/Path", "args") }.to raise_error(Chef::Exceptions::DsclCommandFailed) end it "raises an exception when dscl reports 'eDSRecordNotFound'" do shell_return = shellcmdresult.new("<dscl_cmd> DS Error: -14136 (eDSRecordNotFound)", "err", -14136) - expect(provider).to receive(:shell_out).with("dscl", ".", "-cmd", "/Path", "args").and_return(shell_return) + expect(provider).to receive(:shell_out_compacted).with("dscl", ".", "-cmd", "/Path", "args").and_return(shell_return) expect { provider.run_dscl("cmd", "/Path", "args") }.to raise_error(Chef::Exceptions::DsclCommandFailed) end end @@ -284,7 +284,7 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30" end it "should run createhomedir to create the user's new home folder" do - expect(provider).to receive(:shell_out!).with("/usr/sbin/createhomedir", "-c", "-u", "toor") + expect(provider).to receive(:shell_out_compacted!).with("/usr/sbin/createhomedir", "-c", "-u", "toor") provider.ditto_home end @@ -399,8 +399,8 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30" let(:user_plist_file) { nil } before do - expect(provider).to receive(:shell_out).with("dscacheutil", "-flushcache") - expect(provider).to receive(:shell_out).with("plutil", "-convert", "xml1", "-o", "-", "/var/db/dslocal/nodes/Default/users/toor.plist") do + expect(provider).to receive(:shell_out_compacted).with("dscacheutil", "-flushcache") + expect(provider).to receive(:shell_out_compacted).with("plutil", "-convert", "xml1", "-o", "-", "/var/db/dslocal/nodes/Default/users/toor.plist") do if user_plist_file.nil? shellcmdresult.new("Can not find the file", "Sorry!!", 1) else @@ -743,7 +743,7 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30") expect(provider).to receive(:prepare_password_shadow_info).and_return({}) mock_shellout = double("Mock::Shellout") allow(mock_shellout).to receive(:run_command) - expect(provider).to receive(:shell_out).and_return(mock_shellout) + expect(provider).to receive(:shell_out_compacted).and_return(mock_shellout) expect(provider).to receive(:read_user_info) expect(provider).to receive(:dscl_set) expect(provider).to receive(:sleep).with(3) @@ -812,7 +812,7 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30") it "should raise an exception when the group does not exist" do shell_return = shellcmdresult.new("<dscl_cmd> DS Error: -14136 (eDSRecordNotFound)", "err", -14136) - expect(provider).to receive(:shell_out).with("dscl", ".", "-read", "/Groups/newgroup", "PrimaryGroupID").and_return(shell_return) + expect(provider).to receive(:shell_out_compacted).with("dscl", ".", "-read", "/Groups/newgroup", "PrimaryGroupID").and_return(shell_return) expect { provider.dscl_set_gid }.to raise_error(Chef::Exceptions::GroupIDNotFound) end end @@ -867,8 +867,8 @@ ea18e18b720e358e7fbe3cfbeaa561456f6ba008937a30") describe "when the user exists" do before do - expect(provider).to receive(:shell_out).with("dscacheutil", "-flushcache") - expect(provider).to receive(:shell_out).with("plutil", "-convert", "xml1", "-o", "-", "/var/db/dslocal/nodes/Default/users/toor.plist") do + expect(provider).to receive(:shell_out_compacted).with("dscacheutil", "-flushcache") + expect(provider).to receive(:shell_out_compacted).with("plutil", "-convert", "xml1", "-o", "-", "/var/db/dslocal/nodes/Default/users/toor.plist") do shellcmdresult.new(File.read(File.join(CHEF_SPEC_DATA, "mac_users/10.9.plist.xml")), "", 0) end provider.load_current_resource diff --git a/spec/unit/provider/user/pw_spec.rb b/spec/unit/provider/user/pw_spec.rb index 079fd44ef5..8cc69f88af 100644 --- a/spec/unit/provider/user/pw_spec.rb +++ b/spec/unit/provider/user/pw_spec.rb @@ -1,6 +1,6 @@ # # Author:: Stephen Haynes (<sh@nomitor.com>) -# Copyright:: Copyright 2008-2017, Chef Software Inc. +# Copyright:: Copyright 2008-2018, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -81,12 +81,12 @@ describe Chef::Provider::User::Pw do describe "create_user" do before(:each) do - allow(@provider).to receive(:shell_out!).and_return(true) + allow(@provider).to receive(:shell_out_compacted!).and_return(true) allow(@provider).to receive(:modify_password).and_return(true) end it "should run pw useradd with the return of set_options" do - expect(@provider).to receive(:shell_out!).with("pw", "useradd", "adam", "-m").and_return(true) + expect(@provider).to receive(:shell_out_compacted!).with( "pw", "useradd", "adam", "-m").and_return(true) @provider.create_user end @@ -98,12 +98,12 @@ describe Chef::Provider::User::Pw do describe "manage_user" do before(:each) do - allow(@provider).to receive(:shell_out!).and_return(true) + allow(@provider).to receive(:shell_out_compacted!).and_return(true) allow(@provider).to receive(:modify_password).and_return(true) end it "should run pw usermod with the return of set_options" do - expect(@provider).to receive(:shell_out!).with("pw", "usermod", "adam", "-m").and_return(true) + expect(@provider).to receive(:shell_out_compacted!).with( "pw", "usermod", "adam", "-m").and_return(true) @provider.manage_user end @@ -116,12 +116,12 @@ describe Chef::Provider::User::Pw do describe "remove_user" do it "should run pw userdel with the new resources user name" do @new_resource.manage_home false - expect(@provider).to receive(:shell_out!).with("pw", "userdel", @new_resource.username).and_return(true) + expect(@provider).to receive(:shell_out_compacted!).with( "pw", "userdel", @new_resource.username).and_return(true) @provider.remove_user end it "should run pw userdel with the new resources user name and -r if manage_home is true" do - expect(@provider).to receive(:shell_out!).with("pw", "userdel", @new_resource.username, "-r").and_return(true) + expect(@provider).to receive(:shell_out_compacted!).with( "pw", "userdel", @new_resource.username, "-r").and_return(true) @provider.remove_user end end @@ -140,14 +140,14 @@ describe Chef::Provider::User::Pw do describe "when locking the user" do it "should run pw lock with the new resources username" do - expect(@provider).to receive(:shell_out!).with("pw", "lock", @new_resource.username) + expect(@provider).to receive(:shell_out_compacted!).with( "pw", "lock", @new_resource.username) @provider.lock_user end end describe "when unlocking the user" do it "should run pw unlock with the new resources username" do - expect(@provider).to receive(:shell_out!).with("pw", "unlock", @new_resource.username) + expect(@provider).to receive(:shell_out_compacted!).with( "pw", "unlock", @new_resource.username) @provider.unlock_user end end @@ -155,7 +155,7 @@ describe Chef::Provider::User::Pw do describe "when modifying the password" do before(:each) do @status = double("Status", exitstatus: 0) - allow(@provider).to receive(:shell_out!).and_return(@status) + allow(@provider).to receive(:shell_out_compacted!).and_return(@status) end describe "and the new password has not been specified" do @@ -202,12 +202,12 @@ describe Chef::Provider::User::Pw do end it "should run pw usermod with the username and the option -H 0" do - expect(@provider).to receive(:shell_out!).with("pw usermod adam -H 0", { :input => "abracadabra" }).and_return(@status) + expect(@provider).to receive(:shell_out_compacted!).with( "pw usermod adam -H 0", { :input => "abracadabra" }).and_return(@status) @provider.modify_password end it "should raise an exception if pw usermod fails" do - expect(@provider).to receive(:shell_out!).and_raise(Mixlib::ShellOut::ShellCommandFailed) + expect(@provider).to receive(:shell_out_compacted!).and_raise(Mixlib::ShellOut::ShellCommandFailed) expect { @provider.modify_password }.to raise_error(Mixlib::ShellOut::ShellCommandFailed) end diff --git a/spec/unit/provider/user/solaris_spec.rb b/spec/unit/provider/user/solaris_spec.rb index ecc85677e7..b39e065f48 100644 --- a/spec/unit/provider/user/solaris_spec.rb +++ b/spec/unit/provider/user/solaris_spec.rb @@ -58,7 +58,7 @@ describe Chef::Provider::User::Solaris do it "should use its own shadow file writer to set the password" do expect(provider).to receive(:write_shadow_file) - allow(provider).to receive(:shell_out!).and_return(true) + allow(provider).to receive(:shell_out_compacted!).and_return(true) provider.manage_user end @@ -69,7 +69,7 @@ describe Chef::Provider::User::Solaris do password_file.puts "adam:existingpassword:15441::::::" password_file.close stub_const("Chef::Provider::User::Solaris::PASSWORD_FILE", password_file.path) - allow(provider).to receive(:shell_out!).and_return(true) + allow(provider).to receive(:shell_out_compacted!).and_return(true) # may not be able to write to /etc for tests... temp_file = Tempfile.new("shadow") allow(Tempfile).to receive(:new).with("shadow", "/etc").and_return(temp_file) @@ -84,7 +84,7 @@ describe Chef::Provider::User::Solaris do context "with a system user" do before { new_resource.system(true) } it "should not pass -r" do - expect(provider).to receive(:shell_out!).with("useradd", "adam") + expect(provider).to receive(:shell_out_compacted!).with( "useradd", "adam") provider.create_user end end @@ -92,7 +92,7 @@ describe Chef::Provider::User::Solaris do context "with manage_home" do before { new_resource.manage_home(true) } it "should not pass -r" do - expect(provider).to receive(:shell_out!).with("useradd", "-m", "adam") + expect(provider).to receive(:shell_out_compacted!).with( "useradd", "-m", "adam") provider.create_user end end @@ -162,7 +162,7 @@ describe Chef::Provider::User::Solaris do describe "when locking the user" do it "should run passwd -l with the new resources username" do shell_return = shellcmdresult.new("", "", 0) - expect(provider).to receive(:shell_out!).with("passwd", "-l", "adam").and_return(shell_return) + expect(provider).to receive(:shell_out_compacted!).with("passwd", "-l", "adam").and_return(shell_return) provider.lock_user end end @@ -170,7 +170,7 @@ describe Chef::Provider::User::Solaris do describe "when unlocking the user" do it "should run passwd -u with the new resources username" do shell_return = shellcmdresult.new("", "", 0) - expect(provider).to receive(:shell_out!).with("passwd", "-u", "adam").and_return(shell_return) + expect(provider).to receive(:shell_out_compacted!).with("passwd", "-u", "adam").and_return(shell_return) provider.unlock_user end end diff --git a/spec/unit/resource/freebsd_package_spec.rb b/spec/unit/resource/freebsd_package_spec.rb index b609284895..9747c41a88 100644 --- a/spec/unit/resource/freebsd_package_spec.rb +++ b/spec/unit/resource/freebsd_package_spec.rb @@ -93,6 +93,7 @@ describe Chef::Resource::FreebsdPackage do [1000016, 1000000, 901503, 902506, 802511].each do |freebsd_version| node.automatic_attrs[:os_version] = freebsd_version + expect(Chef).to receive(:deprecated).with(:freebsd_package_provider, kind_of(String)) resource.after_created expect(resource.provider).to eq(Chef::Provider::Package::Freebsd::Pkg) end diff --git a/spec/unit/resource/kernel_module_spec.rb b/spec/unit/resource/kernel_module_spec.rb new file mode 100644 index 0000000000..03cda28471 --- /dev/null +++ b/spec/unit/resource/kernel_module_spec.rb @@ -0,0 +1,48 @@ +# +# 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" + +describe Chef::Resource::KernelModule do + let(:resource) { Chef::Resource::KernelModule.new("foo") } + + it "sets resource name as :kernel_module" do + expect(resource.resource_name).to eql(:kernel_module) + end + + it "is not a preview resource in Chef 15" do + pending("Chef 15") unless Chef::VERSION.start_with?("15") + expect(resource.class.preview_resource).to be_falsey + end + + it "sets the default action as :install" do + expect(resource.action).to eql([:install]) + end + + it "sets the modname property as its name property" do + expect(resource.modname).to eql("foo") + end + + it "supports :create and :flush actions" do + expect { resource.action :install }.not_to raise_error + expect { resource.action :uninstall }.not_to raise_error + expect { resource.action :blacklist }.not_to raise_error + expect { resource.action :load }.not_to raise_error + expect { resource.action :unload }.not_to raise_error + expect { resource.action :delete }.to raise_error(ArgumentError) + end +end diff --git a/spec/unit/resource/mount_spec.rb b/spec/unit/resource/mount_spec.rb index fd81901f45..721f30cf09 100644 --- a/spec/unit/resource/mount_spec.rb +++ b/spec/unit/resource/mount_spec.rb @@ -44,6 +44,16 @@ describe Chef::Resource::Mount do expect(resource.device).to eql("/dev/sdb3") end + it "allows you to set mount_point property" do + resource.mount_point "U:" + expect(resource.mount_point).to eql("U:") + end + + it "raises error when mount_point property is not set" do + resource.mount_point nil + expect { resource.mounted("poop") }.to raise_error(ArgumentError) + end + it "sets fsck_device to '-' by default" do expect(resource.fsck_device).to eql("-") end diff --git a/spec/unit/resource/ssh_known_hosts_entry_spec.rb b/spec/unit/resource/ssh_known_hosts_entry_spec.rb new file mode 100644 index 0000000000..3bae37dfe7 --- /dev/null +++ b/spec/unit/resource/ssh_known_hosts_entry_spec.rb @@ -0,0 +1,55 @@ +# +# 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" + +describe Chef::Resource::SshKnownHostsEntry do + let(:node) { Chef::Node.new } + let(:run_context) do + node.automatic[:root_group] = "superduper" + empty_events = Chef::EventDispatch::Dispatcher.new + Chef::RunContext.new(node, {}, empty_events) + end + let(:resource) { Chef::Resource::SshKnownHostsEntry.new("example.com", run_context) } + + it "is not a preview resource in Chef 15" do + pending("Chef 15") unless Chef::VERSION.start_with?("15") + expect(resource.class.preview_resource).to be_falsey + end + + it "sets resource name as :ssh_known_hosts_entry" do + expect(resource.resource_name).to eql(:ssh_known_hosts_entry) + end + + it "sets group property to node['root_group'] by default" do + expect(resource.group).to eql("superduper") + end + + it "sets the default action as :create" do + expect(resource.action).to eql([:create]) + end + + it "sets the host property as its name property" do + expect(resource.host).to eql("example.com") + end + + it "supports :create and :flush actions" do + expect { resource.action :create }.not_to raise_error + expect { resource.action :flush }.not_to raise_error + expect { resource.action :delete }.to raise_error(ArgumentError) + end +end diff --git a/spec/unit/resource/windows_feature_dism.rb b/spec/unit/resource/windows_feature_dism.rb index 4627387ddb..87d99ecbaf 100644 --- a/spec/unit/resource/windows_feature_dism.rb +++ b/spec/unit/resource/windows_feature_dism.rb @@ -32,7 +32,7 @@ describe Chef::Resource::WindowsFeatureDism do end it "the feature_name property is the name_property" do - node.automatic[:platform_version] = "6.2" + node.automatic[:platform_version] = "6.2.9200" expect(resource.feature_name).to eql(%w{snmp dhcp}) end @@ -47,25 +47,25 @@ describe Chef::Resource::WindowsFeatureDism do end it "coerces comma separated lists of features to a lowercase array on 2012+" do - node.automatic[:platform_version] = "6.2" + node.automatic[:platform_version] = "6.2.9200" resource.feature_name "SNMP, DHCP" expect(resource.feature_name).to eql(%w{snmp dhcp}) end it "coerces a single feature as a String to a lowercase array on 2012+" do - node.automatic[:platform_version] = "6.2" + node.automatic[:platform_version] = "6.2.9200" resource.feature_name "SNMP" expect(resource.feature_name).to eql(["snmp"]) end it "coerces comma separated lists of features to an array, but preserves case on < 2012" do - node.automatic[:platform_version] = "6.1" + node.automatic[:platform_version] = "6.1.7601" resource.feature_name "SNMP, DHCP" expect(resource.feature_name).to eql(%w{SNMP DHCP}) end it "coerces a single feature as a String to an array, but preserves case on < 2012" do - node.automatic[:platform_version] = "6.1" + node.automatic[:platform_version] = "6.1.7601" resource.feature_name "SNMP" expect(resource.feature_name).to eql(["SNMP"]) end diff --git a/spec/unit/resource/windows_feature_powershell.rb b/spec/unit/resource/windows_feature_powershell.rb index a9b6f5f88f..3dc1604361 100644 --- a/spec/unit/resource/windows_feature_powershell.rb +++ b/spec/unit/resource/windows_feature_powershell.rb @@ -18,7 +18,10 @@ require "spec_helper" describe Chef::Resource::WindowsFeaturePowershell do - let(:resource) { Chef::Resource::WindowsFeaturePowershell.new(%w{SNMP DHCP}) } + let(:node) { Chef::Node.new } + let(:events) { Chef::EventDispatch::Dispatcher.new } + let(:run_context) { Chef::RunContext.new(node, {}, events) } + let(:resource) { Chef::Resource::WindowsFeaturePowershell.new(%w{SNMP DHCP}, run_context) } it "sets resource name as :windows_feature_powershell" do expect(resource.resource_name).to eql(:windows_feature_powershell) @@ -28,24 +31,42 @@ describe Chef::Resource::WindowsFeaturePowershell do expect(resource.action).to eql([:install]) end + it "the feature_name property is the name_property" do + node.automatic[:platform_version] = "6.2.9200" + expect(resource.feature_name).to eql(%w{snmp dhcp}) + end + + it "sets the default action as :install" do + expect(resource.action).to eql([:install]) + end + it "supports :delete, :install, :remove actions" do expect { resource.action :delete }.not_to raise_error expect { resource.action :install }.not_to raise_error expect { resource.action :remove }.not_to raise_error end - it "sets the feature_name property as its name_property" do - expect(resource.feature_name).to eql(%w{SNMP DHCP}) + it "coerces comma separated lists of features to a lowercase array on 2012+" do + node.automatic[:platform_version] = "6.2.9200" + resource.feature_name "SNMP, DHCP" + expect(resource.feature_name).to eql(%w{snmp dhcp}) + end + + it "coerces a single feature as a String to a lowercase array on 2012+" do + node.automatic[:platform_version] = "6.2.9200" + resource.feature_name "SNMP" + expect(resource.feature_name).to eql(["snmp"]) end - it "coerces comma separated lists of features to arrays" do + it "coerces comma separated lists of features to an array, but preserves case on < 2012" do + node.automatic[:platform_version] = "6.1.7601" resource.feature_name "SNMP, DHCP" expect(resource.feature_name).to eql(%w{SNMP DHCP}) end - it "coerces a single feature as a String into an array" do + it "coerces a single feature as a String to an array, but preserves case on < 2012" do + node.automatic[:platform_version] = "6.1.7601" resource.feature_name "SNMP" expect(resource.feature_name).to eql(["SNMP"]) end - end diff --git a/spec/unit/resource_spec.rb b/spec/unit/resource_spec.rb index 2866d5439f..26660c9415 100644 --- a/spec/unit/resource_spec.rb +++ b/spec/unit/resource_spec.rb @@ -867,7 +867,7 @@ end snitch_var1 = snitch_var2 = 0 runner = Chef::Runner.new(run_context) - Chef::Provider::SnakeOil.provides :cat + Chef::Provider::SnakeOil.provides :cat, __core_override__: true resource1.only_if { snitch_var1 = 1 } resource1.not_if { snitch_var2 = 2 } @@ -1144,4 +1144,38 @@ end it { is_expected.to eq [:two, :one] } end end + + describe ".preview_resource" do + let(:klass) { Class.new(Chef::Resource) } + + before do + allow(Chef::DSL::Resources).to receive(:add_resource_dsl).with(:test_resource) + end + + it "defaults to false" do + expect(klass.preview_resource).to eq false + end + + it "can be set to true" do + klass.preview_resource(true) + expect(klass.preview_resource).to eq true + end + + it "does not affect provides by default" do + expect(Chef.resource_handler_map).to receive(:set).with(:test_resource, klass, { canonical: true }) + klass.resource_name(:test_resource) + end + + it "adds allow_cookbook_override when true" do + expect(Chef.resource_handler_map).to receive(:set).with(:test_resource, klass, { canonical: true, allow_cookbook_override: true }) + klass.preview_resource(true) + klass.resource_name(:test_resource) + end + + it "allows manually overriding back to false" do + expect(Chef.resource_handler_map).to receive(:set).with(:test_resource, klass, { allow_cookbook_override: false }) + klass.preview_resource(true) + klass.provides(:test_resource, allow_cookbook_override: false) + end + end end diff --git a/spec/unit/util/selinux_spec.rb b/spec/unit/util/selinux_spec.rb index 5081281cf4..8da6492fae 100644 --- a/spec/unit/util/selinux_spec.rb +++ b/spec/unit/util/selinux_spec.rb @@ -1,6 +1,6 @@ # # Author:: Serdar Sutay (<serdar@chef.io>) -# Copyright:: Copyright 2013-2017, Chef Software Inc. +# Copyright:: Copyright 2013-2018, Chef Software Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -124,21 +124,21 @@ describe Chef::Util::Selinux do end it "should call restorecon non-recursive by default" do - expect(@test_instance).to receive(:shell_out_compact!).twice.with(@restorecon_enabled_path, [ "-R", path ]) + expect(@test_instance).to receive(:shell_out_compacted!).with(@restorecon_enabled_path, "-R", path).twice @test_instance.restore_security_context(path) expect(File).not_to receive(:executable?) @test_instance.restore_security_context(path) end it "should call restorecon recursive when recursive is set" do - expect(@test_instance).to receive(:shell_out_compact!).twice.with(@restorecon_enabled_path, [ "-R", "-r", path ]) + expect(@test_instance).to receive(:shell_out_compacted!).with(@restorecon_enabled_path, "-R", "-r", path).twice @test_instance.restore_security_context(path, true) expect(File).not_to receive(:executable?) @test_instance.restore_security_context(path, true) end it "should call restorecon non-recursive when recursive is not set" do - expect(@test_instance).to receive(:shell_out_compact!).twice.with(@restorecon_enabled_path, [ "-R", path ]) + expect(@test_instance).to receive(:shell_out_compacted!).with(@restorecon_enabled_path, "-R", path).twice @test_instance.restore_security_context(path) expect(File).not_to receive(:executable?) @test_instance.restore_security_context(path) |