diff --git a/Batali b/Batali index f94661b..2e532a8 100644 --- a/Batali +++ b/Batali @@ -19,7 +19,6 @@ Batali.define do ref: 'master' cookbook 'application', '4.1.6' cookbook 'users' - cookbook 'chef-solo-search' cookbook 'sudo' cookbook 'hostname' cookbook 'redis', @@ -27,16 +26,15 @@ Batali.define do ref: 'v0.5.6' cookbook 'ufw' cookbook 'firewall' - cookbook 'ssh_known_hosts' cookbook 'nginx' - cookbook 'build-essential', '~> 2.2.4' + cookbook 'build-essential' cookbook 'mysql' cookbook 'database' cookbook 'mysql2_chef_gem' - cookbook 'omnibus_updater', '~> 1.0.4' + cookbook 'omnibus_updater' cookbook 'timezone-ii' cookbook 'nodejs', '~> 3.0.0' - cookbook 'ark', '~> 2.2.1' + cookbook 'ark' cookbook 'logrotate' end diff --git a/batali.manifest b/batali.manifest index 386456c..47b4f56 100644 --- a/batali.manifest +++ b/batali.manifest @@ -91,13 +91,77 @@ { "name": "build-essential", "dependencies": [ - + [ + "seven_zip", + ">= 0.0.0" + ], + [ + "mingw", + ">= 1.1" + ] ], - "version": "2.2.4", + "version": "8.0.0", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/build-essential/versions/2.2.4/download", - "version": "2.2.4" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/build-essential/versions/8.0.0/download", + "version": "8.0.0" + } + }, + { + "name": "seven_zip", + "dependencies": [ + [ + "windows", + ">= 1.2.2" + ] + ], + "version": "1.0.4", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/seven_zip/versions/1.0.4/download", + "version": "1.0.4" + } + }, + { + "name": "windows", + "dependencies": [ + [ + "chef_handler", + ">= 0.0.0" + ] + ], + "version": "1.38.4", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/windows/versions/1.38.4/download", + "version": "1.38.4" + } + }, + { + "name": "chef_handler", + "dependencies": [ + + ], + "version": "1.3.0", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/chef_handler/versions/1.3.0/download", + "version": "1.3.0" + } + }, + { + "name": "mingw", + "dependencies": [ + [ + "seven_zip", + ">= 0.0.0" + ] + ], + "version": "2.0.0", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/mingw/versions/2.0.0/download", + "version": "2.0.0" } }, { @@ -170,11 +234,11 @@ "dependencies": [ ], - "version": "3.10.0", + "version": "5.0.0", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/yum/versions/3.10.0/download", - "version": "3.10.0" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/yum/versions/5.0.0/download", + "version": "5.0.0" } }, { @@ -208,42 +272,27 @@ "name": "yum-epel", "dependencies": [ [ - "yum", - "~> 3.2" + "compat_resource", + ">= 12.16.3" ] ], - "version": "0.6.5", + "version": "2.1.1", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/yum-epel/versions/0.6.5/download", - "version": "0.6.5" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/yum-epel/versions/2.1.1/download", + "version": "2.1.1" } }, { - "name": "windows", - "dependencies": [ - [ - "chef_handler", - ">= 0.0.0" - ] - ], - "version": "1.38.4", - "source": { - "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/windows/versions/1.38.4/download", - "version": "1.38.4" - } - }, - { - "name": "chef_handler", + "name": "compat_resource", "dependencies": [ ], - "version": "1.3.0", + "version": "12.16.3", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/chef_handler/versions/1.3.0/download", - "version": "1.3.0" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/compat_resource/versions/12.16.3/download", + "version": "12.16.3" } }, { @@ -254,11 +303,11 @@ ">= 1.34.6" ] ], - "version": "4.1.6", + "version": "5.0.8", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/iis/versions/4.1.6/download", - "version": "4.1.6" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/iis/versions/5.0.8/download", + "version": "5.0.8" } }, { @@ -366,14 +415,14 @@ "dependencies": [ [ "rsyslog", - "~> 2.0" + ">= 2.0" ] ], - "version": "2.4.1", + "version": "2.4.3", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/bluepill/versions/2.4.1/download", - "version": "2.4.1" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/bluepill/versions/2.4.3/download", + "version": "2.4.3" } }, { @@ -388,6 +437,36 @@ "version": "2.2.0" } }, + { + "name": "build-essential", + "dependencies": [ + [ + "7-zip", + ">= 0.0.0" + ] + ], + "version": "2.4.0", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/build-essential/versions/2.4.0/download", + "version": "2.4.0" + } + }, + { + "name": "7-zip", + "dependencies": [ + [ + "windows", + ">= 1.2.2" + ] + ], + "version": "1.0.2", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/7-zip/versions/1.0.2/download", + "version": "1.0.2" + } + }, { "name": "ohai", "dependencies": [ @@ -427,6 +506,21 @@ "version": "0.2.0" } }, + { + "name": "yum-epel", + "dependencies": [ + [ + "yum", + ">= 3.6.3" + ] + ], + "version": "0.7.1", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/yum-epel/versions/0.7.1/download", + "version": "0.7.1" + } + }, { "name": "mysql2_chef_gem", "dependencies": [ @@ -558,11 +652,11 @@ "dependencies": [ ], - "version": "0.7.0", + "version": "2.0.0", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/tar/versions/0.7.0/download", - "version": "0.7.0" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/tar/versions/2.0.0/download", + "version": "2.0.0" } }, { @@ -582,11 +676,11 @@ "dependencies": [ ], - "version": "3.7.0", + "version": "5.0.1", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/postfix/versions/3.7.0/download", - "version": "3.7.0" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/postfix/versions/5.0.1/download", + "version": "5.0.1" } }, { @@ -656,18 +750,26 @@ } }, { - "name": "seven_zip", + "name": "ark", "dependencies": [ + [ + "build-essential", + ">= 0.0.0" + ], [ "windows", - ">= 1.2.2" + ">= 0.0.0" + ], + [ + "seven_zip", + ">= 0.0.0" ] ], - "version": "1.0.4", + "version": "2.2.1", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/seven_zip/versions/1.0.4/download", - "version": "1.0.4" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/ark/versions/2.2.1/download", + "version": "2.2.1" } }, { @@ -702,23 +804,11 @@ "dependencies": [ ], - "version": "2.0.3", + "version": "4.0.3", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/users/versions/2.0.3/download", - "version": "2.0.3" - } - }, - { - "name": "chef-solo-search", - "dependencies": [ - - ], - "version": "0.5.1", - "source": { - "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/chef-solo-search/versions/0.5.1/download", - "version": "0.5.1" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/users/versions/4.0.3/download", + "version": "4.0.3" } }, { @@ -726,11 +816,11 @@ "dependencies": [ ], - "version": "2.9.0", + "version": "3.3.1", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/sudo/versions/2.9.0/download", - "version": "2.9.0" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/sudo/versions/3.3.1/download", + "version": "3.3.1" } }, { @@ -741,11 +831,11 @@ ">= 0.0.0" ] ], - "version": "0.3.0", + "version": "0.4.0", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/hostname/versions/0.3.0/download", - "version": "0.3.0" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/hostname/versions/0.4.0/download", + "version": "0.4.0" } }, { @@ -784,11 +874,11 @@ ">= 2.0" ] ], - "version": "1.0.0", + "version": "3.1.0", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/ufw/versions/1.0.0/download", - "version": "1.0.0" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/ufw/versions/3.1.0/download", + "version": "3.1.0" } }, { @@ -799,38 +889,11 @@ ">= 0.0.0" ] ], - "version": "2.5.0", + "version": "2.5.4", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/firewall/versions/2.5.0/download", - "version": "2.5.0" - } - }, - { - "name": "ssh_known_hosts", - "dependencies": [ - [ - "partial_search", - ">= 0.0.0" - ] - ], - "version": "2.0.0", - "source": { - "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/ssh_known_hosts/versions/2.0.0/download", - "version": "2.0.0" - } - }, - { - "name": "partial_search", - "dependencies": [ - - ], - "version": "1.0.9", - "source": { - "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/partial_search/versions/1.0.9/download", - "version": "1.0.9" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/firewall/versions/2.5.4/download", + "version": "2.5.4" } }, { @@ -838,11 +901,11 @@ "dependencies": [ ], - "version": "1.0.6", + "version": "3.0.2", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/omnibus_updater/versions/1.0.6/download", - "version": "1.0.6" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/omnibus_updater/versions/3.0.2/download", + "version": "3.0.2" } }, { @@ -857,29 +920,6 @@ "version": "0.2.0" } }, - { - "name": "ark", - "dependencies": [ - [ - "build-essential", - ">= 0.0.0" - ], - [ - "windows", - ">= 0.0.0" - ], - [ - "seven_zip", - ">= 0.0.0" - ] - ], - "version": "2.2.1", - "source": { - "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/ark/versions/2.2.1/download", - "version": "2.2.1" - } - }, { "name": "logrotate", "dependencies": [ diff --git a/cookbooks/7-zip/CHANGELOG.md b/cookbooks/7-zip/CHANGELOG.md new file mode 100644 index 0000000..183bcf7 --- /dev/null +++ b/cookbooks/7-zip/CHANGELOG.md @@ -0,0 +1,13 @@ +7-zip Cookbook CHANGELOG +======================== +This file is used to list changes made in each version of the 7-zip cookbook. + + +v1.0.2 +------ +### Improvement +- **[COOK-3476](https://tickets.opscode.com/browse/COOK-3476)** - Upgrade to 7-zip 9.22 + +1.0.0 +----- +- initial release diff --git a/cookbooks/7-zip/README.md b/cookbooks/7-zip/README.md new file mode 100644 index 0000000..4bfd6be --- /dev/null +++ b/cookbooks/7-zip/README.md @@ -0,0 +1,50 @@ +7-zip Cookbook +============== +[7-Zip](http://www.7-zip.org/) is a file archiver with a high compression ratio. This cookbook installs the full 7-zip suite of tools (GUI and CLI). + + +Requirements +------------ +### Platform +- Windows XP +- Windows Vista +- Windows Server 2003 R2 +- Windows 7 +- Windows Server 2008 (R1, R2) +- Windows 8 +- Windows Server 2012 + +### Cookbooks +- windows + + +Attributes +---------- +- `node['7-zip']['home']` - location to install 7-zip files to. default is `%SYSTEMDRIVE%\7-zip` + + +Usage +----- +### default +Downloads and installs 7-zip to the location specified by `node['7-zip']['home']`. Also ensures `node['7-zip']['home']` is in the system path. + + +License & Authors +----------------- +- Author:: Seth Chisamore () + +```text +Copyright:: 2011, Opscode, Inc. + +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. +``` diff --git a/cookbooks/7-zip/attributes/default.rb b/cookbooks/7-zip/attributes/default.rb new file mode 100644 index 0000000..adc1903 --- /dev/null +++ b/cookbooks/7-zip/attributes/default.rb @@ -0,0 +1,31 @@ +# +# Author:: Seth Chisamore () +# Cookbook Name:: 7-zip +# Attribute:: default +# +# Copyright:: Copyright (c) 2011 Opscode, Inc. +# +# 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. +# + +if kernel['machine'] =~ /x86_64/ + default['7-zip']['url'] = "http://downloads.sourceforge.net/sevenzip/7z922-x64.msi" + default['7-zip']['checksum'] = "f09bf515289eea45185a4cc673e3bbc18ce608c55b4cf96e77833435c9cdf3dc" + default['7-zip']['package_name'] = "7-Zip 9.22 (x64 edition)" +else + default['7-zip']['url'] = "http://downloads.sourceforge.net/sevenzip/7z922.msi" + default['7-zip']['checksum'] = "86df264d22c3dd3ab80cb55a118da2d41bdd95c2db2cd09a6bbdf48f069e3d7a" + default['7-zip']['package_name'] = "7-Zip 9.22" +end + +default['7-zip']['home'] = "#{ENV['SYSTEMDRIVE']}\\7-zip" diff --git a/cookbooks/7-zip/metadata.json b/cookbooks/7-zip/metadata.json new file mode 100644 index 0000000..98ab32d --- /dev/null +++ b/cookbooks/7-zip/metadata.json @@ -0,0 +1,31 @@ +{ + "name": "7-zip", + "version": "1.0.2", + "description": "Installs/Configures the 7-zip file archiver", + "long_description": "7-zip Cookbook\n==============\n[7-Zip](http://www.7-zip.org/) is a file archiver with a high compression ratio. This cookbook installs the full 7-zip suite of tools (GUI and CLI).\n\n\nRequirements\n------------\n### Platform\n- Windows XP\n- Windows Vista\n- Windows Server 2003 R2\n- Windows 7\n- Windows Server 2008 (R1, R2)\n- Windows 8\n- Windows Server 2012\n\n### Cookbooks\n- windows\n\n\nAttributes\n----------\n- `node['7-zip']['home']` - location to install 7-zip files to. default is `%SYSTEMDRIVE%\\7-zip`\n\n\nUsage\n-----\n### default\nDownloads and installs 7-zip to the location specified by `node['7-zip']['home']`. Also ensures `node['7-zip']['home']` is in the system path.\n\n\nLicense & Authors\n-----------------\n- Author:: Seth Chisamore ()\n\n```text\nCopyright:: 2011, Opscode, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n", + "maintainer": "Opscode, Inc.", + "maintainer_email": "cookbooks@opscode.com", + "license": "Apache 2.0", + "platforms": { + "windows": ">= 0.0.0" + }, + "dependencies": { + "windows": ">= 1.2.2" + }, + "recommendations": { + }, + "suggestions": { + }, + "conflicting": { + }, + "providing": { + }, + "replacing": { + }, + "attributes": { + }, + "groupings": { + }, + "recipes": { + } +} \ No newline at end of file diff --git a/cookbooks/7-zip/metadata.rb b/cookbooks/7-zip/metadata.rb new file mode 100644 index 0000000..fa83e9f --- /dev/null +++ b/cookbooks/7-zip/metadata.rb @@ -0,0 +1,10 @@ +name "7-zip" +maintainer "Opscode, Inc." +maintainer_email "cookbooks@opscode.com" +license "Apache 2.0" +description "Installs/Configures the 7-zip file archiver" +long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) +version "1.0.2" +supports "windows" + +depends "windows", ">= 1.2.2" diff --git a/cookbooks/ssh_known_hosts/attributes/default.rb b/cookbooks/7-zip/recipes/default.rb similarity index 58% rename from cookbooks/ssh_known_hosts/attributes/default.rb rename to cookbooks/7-zip/recipes/default.rb index 76d69a1..155cbb6 100644 --- a/cookbooks/ssh_known_hosts/attributes/default.rb +++ b/cookbooks/7-zip/recipes/default.rb @@ -1,8 +1,9 @@ # -# Author:: Seth Vargo () -# Attributes:: default +# Author:: Seth Chisamore () +# Cookbook Name:: 7-zip +# Recipe:: default # -# Copyright 2013, Seth Vargo +# Copyright 2011, Opscode, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,7 +18,14 @@ # limitations under the License. # -default['ssh_known_hosts']['file'] = '/etc/ssh/ssh_known_hosts' -default['ssh_known_hosts']['key_type'] = 'rsa,dsa' -default['ssh_known_hosts']['cacher']['data_bag'] = 'server_data' -default['ssh_known_hosts']['cacher']['data_bag_item'] = 'known_hosts' +windows_package node['7-zip']['package_name'] do + source node['7-zip']['url'] + checksum node['7-zip']['checksum'] + options "INSTALLDIR=\"#{node['7-zip']['home']}\"" + action :install +end + +# update path +windows_path node['7-zip']['home'] do + action :add +end diff --git a/cookbooks/bluepill/.foodcritic b/cookbooks/bluepill/.foodcritic new file mode 100644 index 0000000..6c2ff5a --- /dev/null +++ b/cookbooks/bluepill/.foodcritic @@ -0,0 +1 @@ +~FC059 diff --git a/cookbooks/bluepill/CHANGELOG.md b/cookbooks/bluepill/CHANGELOG.md index e2da6b1..655cf05 100644 --- a/cookbooks/bluepill/CHANGELOG.md +++ b/cookbooks/bluepill/CHANGELOG.md @@ -1,15 +1,21 @@ -bluepill Cookbook CHANGELOG -=========================== +# bluepill Cookbook CHANGELOG This file is used to list changes made in each version of the bluepill cookbook. -2.4.1 (11-10-2015) ------- +## 2.4.3 (04-18-2016) +- Added ChefSpec custom matchers and examples + +## 2.4.2 (02-19-2016) +- Loosened the dependecy on rsyslog so the latest cookbook can be used +- Updated testing dependencies and configurations + +WARNING: It was noted after the release of 2.4.2 that the loosened dependency on rsyslog increased the minimum required Chef release to 12.0 for this cookbook. Chef 11 users will need to use 2.4.1. + +## 2.4.1 (11-10-2015) - Require rsyslog ~> 2.0.0 to preserve Chef 11 compatibility - Fix rsyslog restarting on RHEL - Use platform_family when setting platform specific node attributes and fix bad syntax. This should improve RHEL support -v2.4.0 (09-17-2015) ------- +## v2.4.0 (09-17-2015) - Updated the LSB Required-Start and Required-Stop comments of the LSB init script template to be valid - Added name to the bluepill_test cookbook metadata for Chef 12 - If a defaults file on RHEL or Debian based systems exist for the service source that within the init scripts. Example if /etc/default/bar exists on debian for the bar service then source that @@ -27,72 +33,55 @@ v2.4.0 (09-17-2015) - Added a chefignore file and added additional files to the gitignore - Added source_url and issues_url metadata for Supermarket -v2.3.2 ------- +## v2.3.2 - Never actually released -v2.3.1 ------- +## v2.3.1 ### New Feature - **[COOK-3705](https://tickets.chef.io/browse/COOK-3705)** - Add init.d script with LSB style - -v2.3.0 ------- +## v2.3.0 ### Improvement - **[COOK-3503](https://tickets.chef.io/browse/COOK-3503)** - Add why-run support -v2.2.2 ------- +## v2.2.2 - [COOK-2507] - stringify language attributes -v2.2.0 ------- +## v2.2.0 - [COOK-547] - Add `load` action to provider to reload services when template changes. -v2.1.0 ------- +## v2.1.0 - [COOK-1295] - The bluepill cookbook does not create the default log file - [COOK-1840] - Enable bluepill to log to rsyslog -v2.0.0 ------- +## v2.0.0 This version uses platform_family attribute (in the provider), making the cookbook incompatible with older versions of Chef/Ohai, hence the major version bump. - - [COOK-1644] - Bluepill cookbook fails on Redhat due to missing default or redhat template directory. - [COOK-1920] - init script should have a template file named after platform_family instead of using file specificity -v1.1.2 ------- +## v1.1.2 - [COOK-1730] - Add ability to specify which version of bluepill to install -v1.1.0 ------- +## v1.1.0 - [COOK-1592] - use mixlib-shellout instead of execute, add test-kitchen -v1.0.6 ------- +## v1.0.6 - [COOK-1304] - support amazon linux - [COOK-1427] - resolve foodcritic warnings -v1.0.4 ------- +## v1.0.4 - [COOK-1106] - fix chkconfig loader for CentOS 5 - [COOK-1107] - use integer for GID instead of string -v1.0.2 ------- +## v1.0.2 - [COOK-1043] - Bluepill cookbook fails on OS X because it tries to use root group -v1.0.0 ------- +## v1.0.0 - [COOK-943] - add init script for freebsd -v0.3.0 ------- +## v0.3.0 - [COOK-867] - enable bluepill service on RHEL family - [COOK-550] - add freebsd support -v0.2.2 ------- +## v0.2.2 - Fixes COOK-524, COOK-632 diff --git a/cookbooks/bluepill/CONTRIBUTING.md b/cookbooks/bluepill/CONTRIBUTING.md new file mode 100644 index 0000000..ef2f2b8 --- /dev/null +++ b/cookbooks/bluepill/CONTRIBUTING.md @@ -0,0 +1,2 @@ +Please refer to +https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD diff --git a/cookbooks/bluepill/MAINTAINERS.md b/cookbooks/bluepill/MAINTAINERS.md new file mode 100644 index 0000000..00eed8d --- /dev/null +++ b/cookbooks/bluepill/MAINTAINERS.md @@ -0,0 +1,18 @@ + + +# Maintainers +This file lists how this cookbook project is maintained. When making changes to the system, this +file tells you who needs to review your patch - you need a simple majority of maintainers +for the relevant subsystems to provide a :+1: on your pull request. Additionally, you need +to not receive a veto from a Lieutenant or the Project Lead. + +Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) +for details on the process and how to become a maintainer or the project lead. + +# Project Maintainer +* [Tim Smith](https://github.com/tas50) + +# Maintainers +* [Jennifer Davis](https://github.com/sigje) +* [Tim Smith](https://github.com/tas50) +* [Thom May](https://github.com/thommay) diff --git a/cookbooks/bluepill/README.md b/cookbooks/bluepill/README.md index 7efe25d..68bfebc 100644 --- a/cookbooks/bluepill/README.md +++ b/cookbooks/bluepill/README.md @@ -1,40 +1,30 @@ -bluepill Cookbook -================= - -[![Build Status](https://travis-ci.org/chef-cookbooks/bluepill.svg?branch=master)](https://travis-ci.org/chef-cookbooks/bluepill) -[![Cookbook Version](https://img.shields.io/cookbook/v/bluepill.svg)](https://supermarket.chef.io/cookbooks/bluepill) +# bluepill Cookbook +[![Build Status](https://travis-ci.org/chef-cookbooks/bluepill.svg?branch=master)](https://travis-ci.org/chef-cookbooks/bluepill) [![Cookbook Version](https://img.shields.io/cookbook/v/bluepill.svg)](https://supermarket.chef.io/cookbooks/bluepill) Installs bluepill Ruby Gem and configures it to manage services. Also includes a LWRP. - -Requirements ------------- -#### Platforms +## Requirements +### Platforms Bluepill is a pure Ruby service management tool/library, so this cookbook should work on any system. The attributes do set up paths based on FHS locations, see below. -#### Chef -- Chef 11+ +### Chef +- Chef 12+ -#### Cookbooks +### Cookbooks - none - -Attributes ----------- +## Attributes Default locations for bluepill are in "FHS compliant" locations. +- `node["bluepill"]["bin"]` - Path to bluepill program, default is 'bluepill' in the RubyGems binary directory. +- `node["bluepill"]["logfile"]` - Location of the bluepill log file, default "/var/log/bluepill.log". +- `node["bluepill"]["conf_dir"]` - Location of service config files (pills), default "/etc/bluepill". +- `node["bluepill"]["pid_dir"]` - Location of pidfiles, default "/var/run/bluepill" +- `node["bluepill"]["state_dir"]` - Location of state directory, default "/var/lib/bluepill" +- `node["bluepill"]["init_dir"]` - Location of init script directory, default selected by platform. +- `node["bluepill"]["version"]` - Version of bluepill to install, default is latest. +- `node["bluepill"]["use_rsyslog"]` - Enable configuration and use of rsyslog for bluepill. -* `node["bluepill"]["bin"]` - Path to bluepill program, default is 'bluepill' in the RubyGems binary directory. -* `node["bluepill"]["logfile"]` - Location of the bluepill log file, default "/var/log/bluepill.log". -* `node["bluepill"]["conf_dir"]` - Location of service config files (pills), default "/etc/bluepill". -* `node["bluepill"]["pid_dir"]` - Location of pidfiles, default "/var/run/bluepill" -* `node["bluepill"]["state_dir"]` - Location of state directory, default "/var/lib/bluepill" -* `node["bluepill"]["init_dir"]` - Location of init script directory, default selected by platform. -* `node["bluepill"]["version"]` - Version of bluepill to install, default is latest. -* `node["bluepill"]["use_rsyslog"]` - Enable configuration and use of rsyslog for bluepill. - - -Resources/Providers -------------------- +# Custom Resources This cookbook contains an LWRP, `bluepill_service`. This can be used with the normal Chef service resource, by using the `provider` parameter, or by specifying the `bluepill_service` shortcut. These two resources are equivalent. ```ruby @@ -52,9 +42,7 @@ The load action should probably always be specified, to ensure that if bluepill The recipe using the service must contain a template resource for the pill and it must be named `my_app.pill.erb`, where `my_app` is the service name passed to the bluepill service resource. - -Usage ------ +## Usage Be sure to include the bluepill recipe in the run list to ensure that the gem and bluepill-related directories are created. This will also make the cookbook available on the system and other cookbooks won't need to explicitly depend on it in the metadata. If the default directory locations in the attributes/default.rb aren't what you want, change them by setting them either in the attributes file itself, or create attributes in a role applied to any systems that will use bluepill. @@ -76,11 +64,35 @@ end See bluepill's documentation for more information on creating pill templates. +## Testing +This cookbook has the following [ChefSpec custom matchers](https://github.com/sethvargo/chefspec#packaging-custom-matchers) defined: -License & Authors ------------------ +- enable_bluepill_service +- load_bluepill_service +- reload_bluepill_service +- start_bluepill_service +- disable_bluepill_service +- stop_bluepill_service +- restart_bluepill_service -**Author:** Cookbook Engineering Team () +### ChefSpec Examples: + +``` +it 'enables my_app bluepill service' do + chef_run.converge('my_app::default', described_recipe) + expect(chef_run).to enable_bluepill_service('my_app') +end + +it 'reloads my_app bluepill service when pill file changes' do + chef_run.converge('my_app::default', described_recipe) + expect(chef_run).to create_template('/etc/bluepill/my_app.pill') + my_app_pill = chef_run.template('/etc/bluepill/my_app.pill') + expect(my_app_pill).to notify('bluepill_service[my_app]').to(:reload).delayed +end +``` + +## License & Authors +**Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io)) **Copyright:** 2010-2015, Chef Software, Inc. diff --git a/cookbooks/bluepill/libraries/matchers.rb b/cookbooks/bluepill/libraries/matchers.rb new file mode 100644 index 0000000..da9fe67 --- /dev/null +++ b/cookbooks/bluepill/libraries/matchers.rb @@ -0,0 +1,33 @@ +if defined?(ChefSpec) + + ChefSpec.define_matcher(:bluepill_service) + + def enable_bluepill_service(service) + ChefSpec::Matchers::ResourceMatcher.new(:bluepill_service, :enable, service) + end + + def load_bluepill_service(service) + ChefSpec::Matchers::ResourceMatcher.new(:bluepill_service, :load, service) + end + + def reload_bluepill_service(service) + ChefSpec::Matchers::ResourceMatcher.new(:bluepill_service, :reload, service) + end + + def start_bluepill_service(service) + ChefSpec::Matchers::ResourceMatcher.new(:bluepill_service, :start, service) + end + + def disable_bluepill_service(service) + ChefSpec::Matchers::ResourceMatcher.new(:bluepill_service, :disable, service) + end + + def stop_bluepill_service(service) + ChefSpec::Matchers::ResourceMatcher.new(:bluepill_service, :stop, service) + end + + def restart_bluepill_service(service) + ChefSpec::Matchers::ResourceMatcher.new(:bluepill_service, :restart, service) + end + +end diff --git a/cookbooks/bluepill/metadata.json b/cookbooks/bluepill/metadata.json index 6227366..9446821 100644 --- a/cookbooks/bluepill/metadata.json +++ b/cookbooks/bluepill/metadata.json @@ -1 +1 @@ -{"name":"bluepill","version":"2.4.1","description":"Installs bluepill gem and configures to manage services, includes bluepill_service LWRP","long_description":"bluepill Cookbook\n=================\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/bluepill.svg?branch=master)](https://travis-ci.org/chef-cookbooks/bluepill)\n[![Cookbook Version](https://img.shields.io/cookbook/v/bluepill.svg)](https://supermarket.chef.io/cookbooks/bluepill)\n\nInstalls bluepill Ruby Gem and configures it to manage services. Also includes a LWRP.\n\n\nRequirements\n------------\n#### Platforms\nBluepill is a pure Ruby service management tool/library, so this cookbook should work on any system. The attributes do set up paths based on FHS locations, see below.\n\n#### Chef\n- Chef 11+\n\n#### Cookbooks\n- none\n\n\nAttributes\n----------\nDefault locations for bluepill are in \"FHS compliant\" locations.\n\n* `node[\"bluepill\"][\"bin\"]` - Path to bluepill program, default is 'bluepill' in the RubyGems binary directory.\n* `node[\"bluepill\"][\"logfile\"]` - Location of the bluepill log file, default \"/var/log/bluepill.log\".\n* `node[\"bluepill\"][\"conf_dir\"]` - Location of service config files (pills), default \"/etc/bluepill\".\n* `node[\"bluepill\"][\"pid_dir\"]` - Location of pidfiles, default \"/var/run/bluepill\"\n* `node[\"bluepill\"][\"state_dir\"]` - Location of state directory, default \"/var/lib/bluepill\"\n* `node[\"bluepill\"][\"init_dir\"]` - Location of init script directory, default selected by platform.\n* `node[\"bluepill\"][\"version\"]` - Version of bluepill to install, default is latest.\n* `node[\"bluepill\"][\"use_rsyslog\"]` - Enable configuration and use of rsyslog for bluepill.\n\n\nResources/Providers\n-------------------\nThis cookbook contains an LWRP, `bluepill_service`. This can be used with the normal Chef service resource, by using the `provider` parameter, or by specifying the `bluepill_service` shortcut. These two resources are equivalent.\n\n```ruby\nservice 'my_app' do\n provider bluepill_service\n action [:enable, :load, :start]\nend\n\nbluepill_service 'my_app' do\n action [:enable, :load, :start]\nend\n```\n\nThe load action should probably always be specified, to ensure that if bluepill isn't running already it gets started. The\n\nThe recipe using the service must contain a template resource for the pill and it must be named `my_app.pill.erb`, where `my_app` is the service name passed to the bluepill service resource.\n\n\nUsage\n-----\nBe sure to include the bluepill recipe in the run list to ensure that the gem and bluepill-related directories are created. This will also make the cookbook available on the system and other cookbooks won't need to explicitly depend on it in the metadata.\n\nIf the default directory locations in the attributes/default.rb aren't what you want, change them by setting them either in the attributes file itself, or create attributes in a role applied to any systems that will use bluepill.\n\nExample pill template resource and .erb file:\n\n```ruby\ntemplate '/etc/bluepill/my_app.pill' do\n source 'my_app.pill.erb'\nend\n\nBluepill.application('my_app') do |app|\n app.process('my_app') do |process|\n process.pid_file = '/var/run/my_app.pid'\n process.start_command = '/usr/bin/my_app'\n end\nend\n```\n\nSee bluepill's documentation for more information on creating pill templates.\n\n\nLicense & Authors\n-----------------\n\n**Author:** Cookbook Engineering Team ()\n\n**Copyright:** 2010-2015, Chef Software, Inc.\n\n```\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{},"dependencies":{"rsyslog":"~> 2.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{"bluepill::default":"Installs bluepill rubygem and sets up management directories"}} \ No newline at end of file +{"name":"bluepill","version":"2.4.3","description":"Installs bluepill gem and configures to manage services, includes bluepill_service LWRP","long_description":"# bluepill Cookbook\n[![Build Status](https://travis-ci.org/chef-cookbooks/bluepill.svg?branch=master)](https://travis-ci.org/chef-cookbooks/bluepill) [![Cookbook Version](https://img.shields.io/cookbook/v/bluepill.svg)](https://supermarket.chef.io/cookbooks/bluepill)\n\nInstalls bluepill Ruby Gem and configures it to manage services. Also includes a LWRP.\n\n## Requirements\n### Platforms\nBluepill is a pure Ruby service management tool/library, so this cookbook should work on any system. The attributes do set up paths based on FHS locations, see below.\n\n### Chef\n- Chef 12+\n\n### Cookbooks\n- none\n\n## Attributes\nDefault locations for bluepill are in \"FHS compliant\" locations.\n- `node[\"bluepill\"][\"bin\"]` - Path to bluepill program, default is 'bluepill' in the RubyGems binary directory.\n- `node[\"bluepill\"][\"logfile\"]` - Location of the bluepill log file, default \"/var/log/bluepill.log\".\n- `node[\"bluepill\"][\"conf_dir\"]` - Location of service config files (pills), default \"/etc/bluepill\".\n- `node[\"bluepill\"][\"pid_dir\"]` - Location of pidfiles, default \"/var/run/bluepill\"\n- `node[\"bluepill\"][\"state_dir\"]` - Location of state directory, default \"/var/lib/bluepill\"\n- `node[\"bluepill\"][\"init_dir\"]` - Location of init script directory, default selected by platform.\n- `node[\"bluepill\"][\"version\"]` - Version of bluepill to install, default is latest.\n- `node[\"bluepill\"][\"use_rsyslog\"]` - Enable configuration and use of rsyslog for bluepill.\n\n# Custom Resources\nThis cookbook contains an LWRP, `bluepill_service`. This can be used with the normal Chef service resource, by using the `provider` parameter, or by specifying the `bluepill_service` shortcut. These two resources are equivalent.\n\n```ruby\nservice 'my_app' do\n provider bluepill_service\n action [:enable, :load, :start]\nend\n\nbluepill_service 'my_app' do\n action [:enable, :load, :start]\nend\n```\n\nThe load action should probably always be specified, to ensure that if bluepill isn't running already it gets started. The\n\nThe recipe using the service must contain a template resource for the pill and it must be named `my_app.pill.erb`, where `my_app` is the service name passed to the bluepill service resource.\n\n## Usage\nBe sure to include the bluepill recipe in the run list to ensure that the gem and bluepill-related directories are created. This will also make the cookbook available on the system and other cookbooks won't need to explicitly depend on it in the metadata.\n\nIf the default directory locations in the attributes/default.rb aren't what you want, change them by setting them either in the attributes file itself, or create attributes in a role applied to any systems that will use bluepill.\n\nExample pill template resource and .erb file:\n\n```ruby\ntemplate '/etc/bluepill/my_app.pill' do\n source 'my_app.pill.erb'\nend\n\nBluepill.application('my_app') do |app|\n app.process('my_app') do |process|\n process.pid_file = '/var/run/my_app.pid'\n process.start_command = '/usr/bin/my_app'\n end\nend\n```\n\nSee bluepill's documentation for more information on creating pill templates.\n\n## Testing\nThis cookbook has the following [ChefSpec custom matchers](https://github.com/sethvargo/chefspec#packaging-custom-matchers) defined:\n\n- enable_bluepill_service\n- load_bluepill_service\n- reload_bluepill_service\n- start_bluepill_service\n- disable_bluepill_service\n- stop_bluepill_service\n- restart_bluepill_service\n\n### ChefSpec Examples:\n\n```\nit 'enables my_app bluepill service' do\n chef_run.converge('my_app::default', described_recipe)\n expect(chef_run).to enable_bluepill_service('my_app')\nend\n\nit 'reloads my_app bluepill service when pill file changes' do\n chef_run.converge('my_app::default', described_recipe)\n expect(chef_run).to create_template('/etc/bluepill/my_app.pill')\n my_app_pill = chef_run.template('/etc/bluepill/my_app.pill')\n expect(my_app_pill).to notify('bluepill_service[my_app]').to(:reload).delayed\nend\n```\n\n## License & Authors\n**Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io))\n\n**Copyright:** 2010-2015, Chef Software, Inc.\n\n```\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{},"dependencies":{"rsyslog":">= 2.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{"bluepill::default":"Installs bluepill rubygem and sets up management directories"}} \ No newline at end of file diff --git a/cookbooks/build-essential/.foodcritic b/cookbooks/build-essential/.foodcritic new file mode 100644 index 0000000..be0967f --- /dev/null +++ b/cookbooks/build-essential/.foodcritic @@ -0,0 +1,2 @@ +~FC052 +~FC057 diff --git a/cookbooks/build-essential/CHANGELOG.md b/cookbooks/build-essential/CHANGELOG.md index 2c3423a..229366d 100644 --- a/cookbooks/build-essential/CHANGELOG.md +++ b/cookbooks/build-essential/CHANGELOG.md @@ -1,70 +1,82 @@ -build-essential Cookbook CHANGELOG -================================== +# build-essential Cookbook CHANGELOG + This file is used to list changes made in each version of the build-essential cookbook. -v2.2.4 (2015-10-06) -------------------- -* Add patch package on Fedora systems -* Add additional platforms to Kitchen CI -* Use Chef standard Rubocop file and resolve several issues -* Update contributing and testing docs -* Update Gemfile with the latest testing and development deps -* Add maintainers.md and maintainers.toml files -* Add chefignore file to limit the files uploaded to the Chef server -* Add source_url and issues_url metadata for Supermarket +## v2.4.0 (2016-03-21) -v2.2.3 (2015-04-15) -------------------- -* Don’t install omnibus-build-essential on Solaris 10 - We decided it’s easier to use the old GCC that ships with Solaris 10. -* Use ChefDK for all Travis testing. +- Add gettext package to RHEL / FreeBSD to match other platforms +- Fix OS X version detection logic to properly detect OS X 10.10 and 10.11 -v2.2.2 (2015-03-27) -------------------- -* Update Solar 10’s omnibus-build-essential to 0.0.5 +## v2.3.1 (2016-02-18) -v2.2.1 (2015-03-23) -------------------- -* Install GNU Patch on Solaris 11 +- Restore Chef 11 compatibility and add Travis / Test Kitchen testing for Chef 11 -v2.2.0 (2015-03-18) -------------------- -* [solaris] Differentiate between Solaris 10 and 11 -* [solaris] Add ucb compat package -* [solaris] Solaris 10 build essential setup -* Fix metadata to use a string instead of a bool (see #56, #57) +## v2.3.0 (2016-02-17) -v2.1.3 (2014-11-18) -------------------- -* Update metadata for supported versions of OS X (10.7+) as noted from - v2.0.0 previously (#38) -* Clarify requirement to have apt package cache updated in README. (#41) -* Fix Xcode CLI installation on OS X (#50) +- Add mingw/msys based build tools for Windows -v2.1.2 (2014-10-14) -------------------- -* Mac OS X 10.10 Yosemite support +## v2.2.4 (2015-10-06) -v2.1.0 (2014-10-14) -------------------- -* Use fully-qualified names when installing FreeBSD package +- Add patch package on Fedora systems +- Add additional platforms to Kitchen CI +- Use Chef standard Rubocop file and resolve several issues +- Update contributing and testing docs +- Update Gemfile with the latest testing and development deps +- Add maintainers.md and maintainers.toml files +- Add chefignore file to limit the files uploaded to the Chef server +- Add source_url and issues_url metadata for Supermarket -v2.0.6 (2014-08-11) -------------------- -* Use the resource form of `remote_file` to prevent context issues +## v2.2.3 (2015-04-15) -v2.0.4 (2014-06-06) -------------------- -* [COOK-4661] added patch package to _rhel recipe +- Don't install omnibus-build-essential on Solaris 10 - We decided it's easier to use the old GCC that ships with Solaris 10. +- Use ChefDK for all Travis testing. +## v2.2.2 (2015-03-27) + +- Update Solar 10's omnibus-build-essential to 0.0.5 + +## v2.2.1 (2015-03-23) + +- Install GNU Patch on Solaris 11 + +## v2.2.0 (2015-03-18) + +- [solaris] Differentiate between Solaris 10 and 11 +- [solaris] Add ucb compat package +- [solaris] Solaris 10 build essential setup +- Fix metadata to use a string instead of a bool (see #56, #57) + +## v2.1.3 (2014-11-18) + +- Update metadata for supported versions of OS X (10.7+) as noted from +- v2.0.0 previously (#38) +- Clarify requirement to have apt package cache updated in README. (#41) +- Fix Xcode CLI installation on OS X (#50) + +## v2.1.2 (2014-10-14) + +- Mac OS X 10.10 Yosemite support + +## v2.1.0 (2014-10-14) + +- Use fully-qualified names when installing FreeBSD package + +## v2.0.6 (2014-08-11) + +- Use the resource form of `remote_file` to prevent context issues + +## v2.0.4 (2014-06-06) + +- [COOK-4661] added patch package to _rhel recipe + +## v2.0.2 (2014-05-02) -v2.0.2 (2014-05-02) -------------------- - Updated documentation about older Chef versions - Added new SVG badges to the README - Fix a bug where `potentially_at_compile_time` fails on non-resources -v2.0.0 (2014-03-13) -------------------- +## v2.0.0 (2014-03-13) + - Updated tested harnesses to use latest ecosystem tools - Added support for FreeBSD - Added support for installing XCode Command Line Tools on OSX (10.7, 10.8, 10.9) @@ -80,57 +92,60 @@ v2.0.0 (2014-03-13) - `compiletime` -> `compile_time` in node attributes - Cookbook version 2.x no longer supports Chef 10.x -v1.4.4 (2014-02-27) -------------------- +## v1.4.4 (2014-02-27) + - [COOK-4245] Wrong package name used for developer tools on OS X 10.9 -v1.4.2 ------- +## v1.4.2 + ### Bug + - **[COOK-3318](https://tickets.chef.io/browse/COOK-3318)** - Use Mixlib::ShellOut instead of Chef::ShellOut ### New Feature + - **[COOK-3093](https://tickets.chef.io/browse/COOK-3093)** - Add OmniOS support ### Improvement + - **[COOK-3024](https://tickets.chef.io/browse/COOK-3024)** - Use newer package on SmartOS -v1.4.0 ------- +## v1.4.0 + This version splits up the default recipe into recipes included based on the node's platform_family. - [COOK-2505] - backport omnibus builder improvements -v1.3.4 ------- +## v1.3.4 + - [COOK-2272] - Complete `platform_family` conversion in build-essential -v1.3.2 ------- +## v1.3.2 + - [COOK-2069] - build-essential will install osx-gcc-installer when XCode is present -v1.3.0 ------- +## v1.3.0 + - [COOK-1895] - support smartos -v1.2.0 ------- +## v1.2.0 + - Add test-kitchen support (source repo only) - [COOK-1677] - build-essential cookbook support for OpenSuse and SLES - [COOK-1718] - build-essential cookbook metadata should include scientific - [COOK-1768] - The apt-get update in build-essentials needs to be renamed -v1.1.2 ------- +## v1.1.2 + - [COOK-1620] - support OS X 10.8 -v1.1.0 ------- +## v1.1.0 + - [COOK-1098] - support amazon linux - [COOK-1149] - support Mac OS X - [COOK-1296] - allow for compile-time installation of packages through an attribute (see README) -v1.0.2 ------- +## v1.0.2 + - [COOK-1098] - Add Amazon Linux platform support - [COOK-1149] - Add OS X platform support diff --git a/cookbooks/build-essential/CONTRIBUTING.md b/cookbooks/build-essential/CONTRIBUTING.md new file mode 100644 index 0000000..ef2f2b8 --- /dev/null +++ b/cookbooks/build-essential/CONTRIBUTING.md @@ -0,0 +1,2 @@ +Please refer to +https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD diff --git a/cookbooks/build-essential/MAINTAINERS.md b/cookbooks/build-essential/MAINTAINERS.md new file mode 100644 index 0000000..d7de891 --- /dev/null +++ b/cookbooks/build-essential/MAINTAINERS.md @@ -0,0 +1,18 @@ + + +# Maintainers +This file lists how this cookbook project is maintained. When making changes to the system, this +file tells you who needs to review your patch - you need a simple majority of maintainers +for the relevant subsystems to provide a :+1: on your pull request. Additionally, you need +to not receive a veto from a Lieutenant or the Project Lead. + +Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) +for details on the process and how to become a maintainer or the project lead. + +# Project Maintainer +* [Jennifer Davis](https://github.com/sigje) + +# Maintainers +* [Jennifer Davis](https://github.com/sigje) +* [Tim Smith](https://github.com/tas50) +* [Thom May](https://github.com/thommay) diff --git a/cookbooks/build-essential/README.md b/cookbooks/build-essential/README.md index dfb153a..cee8624 100644 --- a/cookbooks/build-essential/README.md +++ b/cookbooks/build-essential/README.md @@ -1,98 +1,93 @@ -Description -=========== -[![Cookbook Version](http://img.shields.io/cookbook/v/build-essential.svg)][cookbook] -[![Build Status](http://img.shields.io/travis/chef-cookbooks/build-essential.svg)][travis] +# build-essential Cookbook +[![Cookbook Version](http://img.shields.io/cookbook/v/build-essential.svg)][cookbook] [![Build Status](http://img.shields.io/travis/chef-cookbooks/build-essential.svg)][travis] -[cookbook]: https://community.chef.io/cookbooks/build-essential -[travis]: http://travis-ci.org/chef-cookbooks/build-essential +Installs packages required for compiling C software from source. Use this cookbook if you wish to compile C programs, or install RubyGems with native extensions. -Installs packages required for compiling C software from source. Use this -cookbook if you wish to compile C programs, or install RubyGems with native -extensions. +## Requirements +### Platforms +- Debian/Ubuntu +- RHEL/CentOS/Scientific/Amazon/Oracle +- openSUSE +- SmartOS +- Fedora +- Mac OS X +- FreeBSD + +### Chef +- Chef 11+ + +### Cookbooks +- Suggests pkgutil for Solaris based platforms -Requirements ------------- -Chef 11+ and Ohai 6.14+ are required. For the latest list of supported -platforms, please see the `metadata.rb`. **Note for Debian platform family:** On Debian platform-family systems, it is recommended that `apt-get update` be run, to ensure that the package cache is updated. It's not in the scope of this cookbook to do that, as it can [create a duplicate resource](https://tickets.chef.io/browse/CHEF-3694). We recommend using the [apt](https://supermarket.chef.io/cookbooks/apt) cookbook to do this. -**Note for OmniOS**: Currently, OmniOS's Ruby package is built with -GCC 4.6.3, and the path is hardcoded, as the gcc binaries are not -installed in the default $PATH. This means that in order to install -RubyGems into the "system" Ruby, one must install `developer/gcc46`. -[An issue](https://github.com/omniti-labs/omnios-build/issues/19) is -open upstream w/ OmniOS to rebuild the Ruby package with GCC 4.7.2. +**Note for OmniOS**: Currently, OmniOS's Ruby package is built with GCC 4.6.3, and the path is hardcoded, as the gcc binaries are not installed in the default $PATH. This means that in order to install RubyGems into the "system" Ruby, one must install `developer/gcc46`. [An issue](https://github.com/omniti-labs/omnios-build/issues/19) is open upstream w/ OmniOS to rebuild the Ruby package with GCC 4.7.2. -Attributes ----------- -| Attribute | Default | Description | -|----------------|:-------:|-----------------------------------| -| `compile_time` | `false` | Execute resources at compile time | +## Attributes +Attribute | Default | Description +----------------------------------------- | :--------------------------: | --------------------------------- +`node['build-essential']['compile_time']` | `false` | Execute resources at compile time +`node['build-essential']['msys']['path']` | `#{ENV['SYSTEMDRIVE']\\msys` | Destination for msys (Windows only) -Usage ------ +## Usage Include the build-essential recipe in your run list: ```sh knife node run_list add NODE "recipe[build-essential::default]" ``` -or add the build-essential recipe as a dependency and include it from inside -another cookbook: +or add the build-essential recipe as a dependency and include it from inside another cookbook: ```ruby include_recipe 'build-essential::default' ``` ### Gems with C extensions -For RubyGems that include native C extensions you wish to use with Chef, you -should do the following. +For RubyGems that include native C extensions you wish to use with Chef, you should do the following. +- Set the `compile_time` attribute to true in your wrapper cookbook or role: -1. Set the `compile_time` attribute to true in your wrapper cookbook or role: + ```ruby + # Wrapper attribute + default['build-essential']['compile_time'] = true + ``` - ```ruby - # Wrapper attribute - default['build-essential']['compile_time'] = true - ``` + ```ruby + # Role + default_attributes( + 'build-essential' => { + 'compile_time' => true + } + ) + ``` - ```ruby - # Role - default_attributes( - 'build-essential' => { - 'compile_time' => true - } - ) - ``` +- Ensure that the C libraries, which include files and other assorted "dev" -1. Ensure that the C libraries, which include files and other assorted "dev" -type packages, are installed in the compile phase after the build-essential -recipe is executed. For example: + type packages, are installed in the compile phase after the build-essential - ```ruby - include_recipe 'build-essential::default' + recipe is executed. For example: - package('mypackage-devel') { action :nothing }.run_action(:install) - ``` + ```ruby + include_recipe 'build-essential::default' -1. Use the `chef_gem` resource in your recipe to install the gem with the native -extension: + package('mypackage-devel') { action :nothing }.run_action(:install) + ``` - ```ruby - chef_gem 'gem-with-native-extension' - ``` +- Use the `chef_gem` resource in your recipe to install the gem with the native + extension: -License & Authors ------------------ -- Author: Seth Vargo () -- Author: Joshua Timberman () -- Author: Seth Chisamore () + ```ruby + chef_gem 'gem-with-native-extension' + ``` -```text -Copyright 2009-2015, Chef Software, Inc. () +## License & Authors +**Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io)) +**Copyright:** 2009-2015, 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. You may obtain a copy of the License at @@ -106,3 +101,5 @@ See the License for the specific language governing permissions and limitations under the License. ``` +[cookbook]: https://supermarket.chef.io/cookbooks/build-essential +[travis]: http://travis-ci.org/chef-cookbooks/build-essential diff --git a/cookbooks/build-essential/attributes/default.rb b/cookbooks/build-essential/attributes/default.rb index ca383ee..21189fd 100644 --- a/cookbooks/build-essential/attributes/default.rb +++ b/cookbooks/build-essential/attributes/default.rb @@ -2,7 +2,7 @@ # Cookbook Name:: build-essential # Attributes:: default # -# Copyright 2008-2012, Chef Software, Inc. +# Copyright 2008-2016, 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. @@ -18,3 +18,4 @@ # default['build-essential']['compile_time'] = false +default['build-essential']['msys']['path'] = "#{ENV['SYSTEMDRIVE']}\\msys" diff --git a/cookbooks/build-essential/libraries/_msys_helper.rb b/cookbooks/build-essential/libraries/_msys_helper.rb new file mode 100644 index 0000000..e7f60af --- /dev/null +++ b/cookbooks/build-essential/libraries/_msys_helper.rb @@ -0,0 +1,15 @@ +module BuildEssential + module MsysHelper + # + # This function returns a struct representing an + # msys package. It has two fields: url and checksum + # + # @return [OpenStruct] + # + def msys_p(url, checksum) + OpenStruct.new(url: url, checksum: checksum) + end + end +end + +Chef::Recipe.send(:include, BuildEssential::MsysHelper) diff --git a/cookbooks/build-essential/libraries/timing.rb b/cookbooks/build-essential/libraries/timing.rb index 8e136c7..654a8dd 100644 --- a/cookbooks/build-essential/libraries/timing.rb +++ b/cookbooks/build-essential/libraries/timing.rb @@ -2,7 +2,7 @@ # Cookbook Name:: build-essential # Library:: timing # -# Copyright 2014, Chef Software, Inc. +# Copyright 2014-2016, 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/cookbooks/build-essential/libraries/xcode_command_line_tools.rb b/cookbooks/build-essential/libraries/xcode_command_line_tools.rb index 826cb63..30d4511 100644 --- a/cookbooks/build-essential/libraries/xcode_command_line_tools.rb +++ b/cookbooks/build-essential/libraries/xcode_command_line_tools.rb @@ -2,7 +2,7 @@ # Cookbook Name:: build-essential # Library:: xcode_command_line_tools # -# Copyright 2014, Chef Software, Inc. +# Copyright 2014-2016, 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. @@ -29,10 +29,12 @@ class Chef def initialize(name, run_context = nil) super - @provider = case node['platform_version'].to_f - when 10.7, 10.8 + # => Break down SemVer + major, minor, _patch = node['platform_version'].split('.').map { |v| String(v) } + @provider = case [major, minor].join('.') + when '10.7', '10.8' Provider::XcodeCommandLineToolsFromDmg - when 10.9, 10.10 + when '10.9', '10.10', '10.11' Provider::XcodeCommandLineToolsFromSoftwareUpdate else Chef::Log.warn <<-EOH @@ -112,7 +114,7 @@ class Chef when 10.8 'http://devimages.apple.com/downloads/xcode/command_line_tools_for_xcode_os_x_mountain_lion_march_2014.dmg' else - fail "Unknown DMG download URL for OSX #{node['platform_version']}" + raise "Unknown DMG download URL for OSX #{node['platform_version']}" end end diff --git a/cookbooks/build-essential/metadata.json b/cookbooks/build-essential/metadata.json index d3420e3..9803c84 100644 --- a/cookbooks/build-essential/metadata.json +++ b/cookbooks/build-essential/metadata.json @@ -1 +1 @@ -{"name":"build-essential","version":"2.2.4","description":"Installs C compiler / build tools","long_description":"","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{"amazon":">= 0.0.0","centos":">= 0.0.0","debian":">= 0.0.0","fedora":">= 0.0.0","freebsd":">= 0.0.0","mac_os_x":">= 10.7.0","mac_os_x_server":">= 10.7.0","oracle":">= 0.0.0","redhat":">= 0.0.0","scientific":">= 0.0.0","smartos":">= 0.0.0","suse":">= 0.0.0","ubuntu":">= 0.0.0"},"dependencies":{},"recommendations":{},"suggestions":{"pkgutil":">= 0.0.0"},"conflicting":{},"providing":{},"replacing":{},"attributes":{"build-essential/compile_time":{"display_name":"Build Essential Compile Time Execution","description":"Execute resources at compile time.","default":"false","recipes":["build-essential::default"]}},"groupings":{},"recipes":{"build-essential":"Installs packages required for compiling C software from source."},"source_url":"https://github.com/chef-cookbooks/build-essential","issues_url":"https://github.com/chef-cookbooks/build-essential/issues"} \ No newline at end of file +{"name":"build-essential","version":"2.4.0","description":"Installs C compiler / build tools","long_description":"# build-essential Cookbook\n[![Cookbook Version](http://img.shields.io/cookbook/v/build-essential.svg)][cookbook] [![Build Status](http://img.shields.io/travis/chef-cookbooks/build-essential.svg)][travis]\n\nInstalls packages required for compiling C software from source. Use this cookbook if you wish to compile C programs, or install RubyGems with native extensions.\n\n## Requirements\n### Platforms\n- Debian/Ubuntu\n- RHEL/CentOS/Scientific/Amazon/Oracle\n- openSUSE\n- SmartOS\n- Fedora\n- Mac OS X\n- FreeBSD\n\n### Chef\n- Chef 11+\n\n### Cookbooks\n- Suggests pkgutil for Solaris based platforms\n\n\n**Note for Debian platform family:** On Debian platform-family systems, it is recommended that `apt-get update` be run, to ensure that the package cache is updated. It's not in the scope of this cookbook to do that, as it can [create a duplicate resource](https://tickets.chef.io/browse/CHEF-3694). We recommend using the [apt](https://supermarket.chef.io/cookbooks/apt) cookbook to do this.\n\n**Note for OmniOS**: Currently, OmniOS's Ruby package is built with GCC 4.6.3, and the path is hardcoded, as the gcc binaries are not installed in the default $PATH. This means that in order to install RubyGems into the \"system\" Ruby, one must install `developer/gcc46`. [An issue](https://github.com/omniti-labs/omnios-build/issues/19) is open upstream w/ OmniOS to rebuild the Ruby package with GCC 4.7.2.\n\n## Attributes\n\nAttribute | Default | Description\n----------------------------------------- | :--------------------------: | ---------------------------------\n`node['build-essential']['compile_time']` | `false` | Execute resources at compile time\n`node['build-essential']['msys']['path']` | `#{ENV['SYSTEMDRIVE']\\\\msys` | Destination for msys (Windows only)\n\n## Usage\nInclude the build-essential recipe in your run list:\n\n```sh\nknife node run_list add NODE \"recipe[build-essential::default]\"\n```\n\nor add the build-essential recipe as a dependency and include it from inside another cookbook:\n\n```ruby\ninclude_recipe 'build-essential::default'\n```\n\n### Gems with C extensions\nFor RubyGems that include native C extensions you wish to use with Chef, you should do the following.\n- Set the `compile_time` attribute to true in your wrapper cookbook or role:\n\n ```ruby\n # Wrapper attribute\n default['build-essential']['compile_time'] = true\n ```\n\n ```ruby\n # Role\n default_attributes(\n 'build-essential' => {\n 'compile_time' => true\n }\n )\n ```\n\n- Ensure that the C libraries, which include files and other assorted \"dev\"\n\n type packages, are installed in the compile phase after the build-essential\n\n recipe is executed. For example:\n\n ```ruby\n include_recipe 'build-essential::default'\n\n package('mypackage-devel') { action :nothing }.run_action(:install)\n ```\n\n- Use the `chef_gem` resource in your recipe to install the gem with the native\n\n extension:\n\n ```ruby\n chef_gem 'gem-with-native-extension'\n ```\n\n## License & Authors\n**Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io))\n\n**Copyright:** 2009-2015, Chef Software, Inc.\n\n```\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n\n[cookbook]: https://supermarket.chef.io/cookbooks/build-essential\n[travis]: http://travis-ci.org/chef-cookbooks/build-essential\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{"amazon":">= 0.0.0","centos":">= 0.0.0","debian":">= 0.0.0","fedora":">= 0.0.0","freebsd":">= 0.0.0","mac_os_x":">= 10.7.0","mac_os_x_server":">= 10.7.0","oracle":">= 0.0.0","redhat":">= 0.0.0","scientific":">= 0.0.0","smartos":">= 0.0.0","suse":">= 0.0.0","ubuntu":">= 0.0.0","windows":">= 0.0.0"},"dependencies":{"7-zip":">= 0.0.0"},"recommendations":{},"suggestions":{"pkgutil":">= 0.0.0"},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{"build-essential":"Installs packages required for compiling C software from source."}} \ No newline at end of file diff --git a/cookbooks/build-essential/providers/msys_archive.rb b/cookbooks/build-essential/providers/msys_archive.rb new file mode 100644 index 0000000..08f8be9 --- /dev/null +++ b/cookbooks/build-essential/providers/msys_archive.rb @@ -0,0 +1,102 @@ +# +# Cookbook Name:: build-essential +# Provider:: msys_archive +# +# Copyright 2016, 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. +# 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. +# + +use_inline_resources + +action :unpack do + directory msys_dir do + action :create + end + + directory "dir-#{mingw_dir}" do + action :create + path mingw_dir + only_if do + new_resource.mingw + end + end + + directory cache_dir do + action :create + end + + # Unpacking involves downloading the tar.whatever. + # Then we unpack the tar.whatever with 7z, which + # leaves us with a tar, which can finally be + # untarred with 7z. + + remote_file cache_path do + source new_resource.source + checksum new_resource.checksum + notifies :run, "execute[#{archive_name}]", :immediately + end + + execute archive_name do + command extract_cmd(cache_path, cache_dir) + action :nothing + notifies :run, "execute[#{tar_name}]", :immediately + end + + execute tar_name do + command extract_cmd(tar_path, unpack_root_dir) + action :nothing + end +end + +# msys packages will be extracted into the root dir +# mingw packages will get extracted into the root/mingw dir +def unpack_root_dir + if new_resource.mingw + mingw_dir + else + msys_dir + end +end + +def msys_dir + new_resource.root_dir +end + +def mingw_dir + ::File.join(new_resource.root_dir, 'mingw') +end + +def archive_name + ::File.basename(new_resource.source) +end + +def cache_dir + ::File.join(unpack_root_dir, '.cache') +end + +def cache_path + ::File.join(cache_dir, archive_name) +end + +def tar_name + ::File.basename(archive_name, ::File.extname(archive_name)) +end + +def tar_path + ::File.join(cache_dir, tar_name) +end + +def extract_cmd(source_file, dest_dir) + "7z x #{source_file} -o#{dest_dir} -r -y" +end diff --git a/cookbooks/build-essential/recipes/_debian.rb b/cookbooks/build-essential/recipes/_debian.rb index 217032b..ded2d85 100644 --- a/cookbooks/build-essential/recipes/_debian.rb +++ b/cookbooks/build-essential/recipes/_debian.rb @@ -2,7 +2,7 @@ # Cookbook Name:: build-essential # Recipe:: debian # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright 2008-2016, 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/cookbooks/build-essential/recipes/_fedora.rb b/cookbooks/build-essential/recipes/_fedora.rb index 8d52bbc..296df5c 100644 --- a/cookbooks/build-essential/recipes/_fedora.rb +++ b/cookbooks/build-essential/recipes/_fedora.rb @@ -2,7 +2,7 @@ # Cookbook Name:: build-essential # Recipe:: fedora # -# Copyright 2008-2015, Chef Software, Inc. +# Copyright 2008-2016, 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/cookbooks/build-essential/recipes/_freebsd.rb b/cookbooks/build-essential/recipes/_freebsd.rb index 48c12c9..350571e 100644 --- a/cookbooks/build-essential/recipes/_freebsd.rb +++ b/cookbooks/build-essential/recipes/_freebsd.rb @@ -2,7 +2,7 @@ # Cookbook Name:: build-essential # Recipe:: freebsd # -# Copyright 2014, Chef Software, Inc. +# Copyright 2014-2016, 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. @@ -21,4 +21,5 @@ potentially_at_compile_time do package 'devel/gmake' package 'devel/autoconf' package 'devel/m4' + package 'devel/gettext' end diff --git a/cookbooks/build-essential/recipes/_mac_os_x.rb b/cookbooks/build-essential/recipes/_mac_os_x.rb index f577613..1a235a4 100644 --- a/cookbooks/build-essential/recipes/_mac_os_x.rb +++ b/cookbooks/build-essential/recipes/_mac_os_x.rb @@ -2,7 +2,7 @@ # Cookbook Name:: build-essential # Recipe:: mac_os_x # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright 2008-2016, 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/cookbooks/build-essential/recipes/_omnios.rb b/cookbooks/build-essential/recipes/_omnios.rb index cba2bd7..13e0c16 100644 --- a/cookbooks/build-essential/recipes/_omnios.rb +++ b/cookbooks/build-essential/recipes/_omnios.rb @@ -2,7 +2,7 @@ # Cookbook Name:: build-essential # Recipe:: omnios # -# Copyright 2013, Chef Software, Inc. +# Copyright 2013-2016, 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/cookbooks/build-essential/recipes/_rhel.rb b/cookbooks/build-essential/recipes/_rhel.rb index e2b08a6..9719a33 100644 --- a/cookbooks/build-essential/recipes/_rhel.rb +++ b/cookbooks/build-essential/recipes/_rhel.rb @@ -2,7 +2,7 @@ # Cookbook Name:: build-essential # Recipe:: rhel # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright 2008-2016, 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. @@ -27,6 +27,7 @@ potentially_at_compile_time do package 'make' package 'm4' package 'patch' + package 'gettext-devel' # Ensure GCC 4 is available on older pre-6 EL if node['platform_version'].to_i < 6 diff --git a/cookbooks/build-essential/recipes/_smartos.rb b/cookbooks/build-essential/recipes/_smartos.rb index f969bb8..7005484 100644 --- a/cookbooks/build-essential/recipes/_smartos.rb +++ b/cookbooks/build-essential/recipes/_smartos.rb @@ -2,7 +2,7 @@ # Cookbook Name:: build-essential # Recipe:: smartos # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright 2008-2016, 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/cookbooks/build-essential/recipes/_solaris2.rb b/cookbooks/build-essential/recipes/_solaris2.rb index 2da9800..00c845d 100644 --- a/cookbooks/build-essential/recipes/_solaris2.rb +++ b/cookbooks/build-essential/recipes/_solaris2.rb @@ -2,7 +2,7 @@ # Cookbook Name:: build-essential # Recipe:: solaris2 # -# Copyright 2013, Chef Software, Inc. +# Copyright 2013-2016, 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. @@ -44,5 +44,5 @@ when 5.11 package 'ucb' end else - fail "Sorry, we don't support Solaris version #{node['platform_version']} at this juncture." + raise "Sorry, we don't support Solaris version #{node['platform_version']} at this juncture." end diff --git a/cookbooks/build-essential/recipes/_suse.rb b/cookbooks/build-essential/recipes/_suse.rb index 6618c0e..f66bf46 100644 --- a/cookbooks/build-essential/recipes/_suse.rb +++ b/cookbooks/build-essential/recipes/_suse.rb @@ -2,7 +2,7 @@ # Cookbook Name:: build-essential # Recipe:: suse # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright 2008-2016, 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/cookbooks/build-essential/recipes/_windows.rb b/cookbooks/build-essential/recipes/_windows.rb new file mode 100644 index 0000000..bd9c598 --- /dev/null +++ b/cookbooks/build-essential/recipes/_windows.rb @@ -0,0 +1,112 @@ +# +# Cookbook Name:: build-essential +# Recipe:: _mingw +# +# Copyright 2016, 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. +# 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 'ostruct' + +include_recipe '7-zip::default' + +[ + msys_p('http://downloads.sourceforge.net/mingw/msysCORE-1.0.17-1-msys-1.0.17-bin.tar.lzma', + '2d707ae394f5797a0718a1ffd886d4be1a83ed1f68a4ee4a5b19efd3208b037f'), + msys_p('http://downloads.sourceforge.net/mingw/msysCORE-1.0.17-1-msys-1.0.17-ext.tar.lzma', + '2c68f68cb2caa27aa014461133cf578433e62c823cdac3350be62b9c3e6460a0'), + msys_p('http://downloads.sourceforge.net/mingw/coreutils-5.97-3-msys-1.0.13-bin.tar.lzma', + 'f8c7990416ea16a74ac336dcfe0f596bc46b8724b2d58cf8a3509414220b2366'), + msys_p('http://downloads.sourceforge.net/mingw/coreutils-5.97-3-msys-1.0.13-ext.tar.lzma', + '3f525aa6c94ff79ffd656ddf0a56d3244f982ea4a0d274674d9875afc1e04579'), + msys_p('http://downloads.sourceforge.net/mingw/libiconv-1.14-1-msys-1.0.17-dll-2.tar.lzma', + '196921e8c232259c8e6a6852b9ee8d9ab2d29a91419f0c8dc27ba6f034231683'), + msys_p('http://downloads.sourceforge.net/mingw/libintl-0.18.1.1-1-msys-1.0.17-dll-8.tar.lzma', + '29db8c969661c511fbe2a341ab25c993c5f9c555842a75d6ddbcfa70dec16910'), + msys_p('http://downloads.sourceforge.net/mingw/libtermcap-0.20050421_1-2-msys-1.0.13-dll-0.tar.lzma', + '62b58fe0880f0972fcc84a819265989b02439c1c5185870227bd25f870f7adb6'), + msys_p('http://downloads.sourceforge.net/mingw/make-3.81-3-msys-1.0.13-bin.tar.lzma', + '847f0cbbf07135801c8e67bf692d29b1821e816ad828753c997fa869a9b89988'), + msys_p('http://downloads.sourceforge.net/mingw/perl-5.8.8-1-msys-1.0.17-bin.tar.lzma', + '987b939ce00172dd034105d2a908cee5704f67027de98f4dcc69a1006a327a99'), + msys_p('http://downloads.sourceforge.net/mingw/zlib-1.2.3-2-msys-1.0.13-dll.tar.lzma', + '4178940828b928b2d5a33042cc83fbb992b4bfb9ffeaef6dc3e555f2a6a8c0d1'), + msys_p('http://downloads.sourceforge.net/mingw/libgdbm-1.8.3-3-msys-1.0.13-dll-3.tar.lzma', + '7412f874487652e70022ab8601655ee359ed537b017b7dba360b69237c9093c6'), + msys_p('http://downloads.sourceforge.net/mingw/libcrypt-1.1_1-3-msys-1.0.13-dll-0.tar.lzma', + '31f157b6993509849407672503b8b89e09e9e37e8833b6678b9cbbcbf597f918'), + msys_p('http://downloads.sourceforge.net/mingw/bash-3.1.23-1-msys-1.0.18-bin.tar.xz', + '38da5419969ab883058a96322bb0f51434dd4e9f71de09cd4f75b96750944533'), + msys_p('http://downloads.sourceforge.net/mingw/mksh-40.0.0c-1-msys-1.0.17-bin.tar.lzma', + '8311342acf0b9f0264fd0d8384a826537973d798ca5904349fea1e0c9d909e54'), + msys_p('http://downloads.sourceforge.net/mingw/termcap-0.20050421_1-2-msys-1.0.13-bin.tar.lzma', + '906e756332b5fd6c10eeb4b6362f5957dd8cafa5679f89d9adbae59dff7f2ff2'), + msys_p('http://downloads.sourceforge.net/mingw/libregex-1.20090805-2-msys-1.0.13-dll-1.tar.lzma', + '85dd8c1e27a90675c5f867be57ba7ae2bb55dde8cd2d19f284c896be134bd3d1'), + msys_p('http://downloads.sourceforge.net/mingw/crypt-1.1_1-3-msys-1.0.13-bin.tar.lzma', + '58369b42c38144d3aa5a337ebf1e182a66e88db30ccc42796f2074f251ee1fed'), + msys_p('http://downloads.sourceforge.net/mingw/m4-1.4.14-1-msys-1.0.13-bin.tar.lzma', + '41058bc9a691ad01fdd979f1a4ac4ee071bd5ce93f660db5c0b3cfad4487e33e'), + msys_p('http://downloads.sourceforge.net/mingw/bison-2.4.2-1-msys-1.0.13-bin.tar.lzma', + '349f3e312bf71f8a2ac68a7bd2f86b03dacc565b0fd27eef5d604e8be402390e'), + msys_p('http://downloads.sourceforge.net/mingw/flex-2.5.35-2-msys-1.0.13-bin.tar.lzma', + '9715511a2eafb7e2402029059d4b9db96bd40d8b72908db2571c009745c47a63'), + msys_p('http://downloads.sourceforge.net/mingw/findutils-4.4.2-2-msys-1.0.13-bin.tar.lzma', + '779e819b7942dc070c45f4cba633e6a9ae4bfe8b506a3541f4ce86ad0595726d'), + msys_p('http://downloads.sourceforge.net/mingw/sed-4.2.1-2-msys-1.0.13-bin.tar.lzma', + 'f73059204cecb691e7840108b7c0cbbfcebf50c0e5c6e3a2326e0eedce5d1b94'), + msys_p('http://downloads.sourceforge.net/mingw/gawk-3.1.7-2-msys-1.0.13-bin.tar.lzma', + 'eb15478ea76e75b666ad7fc7049de21b9f487e0e1ea0e96d40953a477e91c3dd'), + msys_p('http://downloads.sourceforge.net/mingw/grep-2.5.4-2-msys-1.0.13-bin.tar.lzma', + '4842a1754df98db994622e8ffab3bea7fbce77e05778cd5d3831e76ac90440ba'), + msys_p('http://downloads.sourceforge.net/mingw/less-436-2-msys-1.0.13-bin.tar.lzma', + '1bbd114846026f9ca4fcc4e18ba20f060384f623f1ef22b326df8c55419c0b84'), + msys_p('http://downloads.sourceforge.net/mingw/diffutils-2.8.7.20071206cvs-3-msys-1.0.13-bin.tar.lzma', + '522889b044492dd2337c4752ba6262995a11f352ca5fb8a8660349413ea9b864'), + msys_p('http://downloads.sourceforge.net/mingw/texinfo-4.13a-2-msys-1.0.13-bin.tar.lzma', + '241eb8e376bf69588d0e02aede35771503c5dcb15c440f97e15e30da79fea864'), + msys_p('http://downloads.sourceforge.net/mingw/libmagic-5.04-1-msys-1.0.13-dll-1.tar.lzma', + '65117008598675823b3fb25296d0d6c332ce56b72950e0f90f9063ac098afac3'), + msys_p('http://downloads.sourceforge.net/mingw/file-5.04-1-msys-1.0.13-bin.tar.lzma', + 'e9ceffa49629524c84d07da77c1a5f37837f68a09e56cad30bea1df0a21e5fc2'), + msys_p('http://downloads.sourceforge.net/mingw/mintty-1.0.3-1-msys-1.0.17-bin.tar.lzma', + '0b3e7b57c81646eccaff3ca0310abe8367ace69992640be87199ecf5d9443085'), + msys_p('http://downloads.sourceforge.net/mingw/patch-2.6.1-1-msys-1.0.13-bin.tar.lzma', + 'c8b7771304fb5e9fc33d8fca9045402f2e1bca055bf0b28127f3c3e85a254f67') +].each do |package| + potentially_at_compile_time do + build_essential_msys_archive package.url do + checksum package.checksum + root_dir node['build-essential']['msys']['path'] + end + end +end + +[ + msys_p('http://iweb.dl.sourceforge.net/project/tdm-gcc/TDM-GCC%205%20series/5.1.0-tdm64-1/gcc-5.1.0-tdm64-1-core.tar.lzma', + '29393aac890847089ad1e93f81a28f6744b1609c00b25afca818f3903e42e4bd'), + msys_p('http://iweb.dl.sourceforge.net/project/tdm-gcc/MinGW-w64%20runtime/GCC%205%20series/mingw64runtime-v4-git20150618-gcc5-tdm64-1.tar.lzma', + '29186e0bb36824b10026d78bdcf238d631d8fc1d90718d2ebbd9ec239b6f94dd'), + msys_p('http://sourceforge.net/projects/tdm-gcc/files/GNU%20binutils/binutils-2.25-tdm64-1.tar.lzma', + '4722bb7b4d46cef714234109e25e5d1cfd29f4e53365b6d615c8a00735f60e40'), + msys_p('http://sourceforge.net/projects/tdm-gcc/files/TDM-GCC%205%20series/5.1.0-tdm64-1/gcc-5.1.0-tdm64-1-c++.tar.lzma', + '17fd497318d1ac187a113e8665330d746ad9607a0406ab2374db0d8e6f4094d1') +].each do |package| + potentially_at_compile_time do + build_essential_msys_archive package.url do + root_dir node['build-essential']['msys']['path'] + checksum package.checksum + mingw true + end + end +end diff --git a/cookbooks/build-essential/recipes/default.rb b/cookbooks/build-essential/recipes/default.rb index 46bcad7..199735f 100644 --- a/cookbooks/build-essential/recipes/default.rb +++ b/cookbooks/build-essential/recipes/default.rb @@ -2,7 +2,7 @@ # Cookbook Name:: build-essential # Recipe:: default # -# Copyright 2008-2009, Chef Software, Inc. +# Copyright 2008-2016, 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/cookbooks/build-essential/resources/build_essential.rb b/cookbooks/build-essential/resources/build_essential.rb new file mode 100644 index 0000000..5a0ea6a --- /dev/null +++ b/cookbooks/build-essential/resources/build_essential.rb @@ -0,0 +1,106 @@ +# +# Cookbook:: build-essential +# resource:: build_essential +# +# Copyright:: 2008-2016, 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. +# 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. +# + +provides :build_essential +resource_name :build_essential + +property :compile_time, [true, false], default: false + +action :install do + case node['platform_family'] + when 'debian' + package %w( autoconf binutils-doc bison build-essential flex gettext ncurses-dev ) + when 'fedora', 'rhel' + package %w( autoconf bison flex gcc gcc-c++ gettext kernel-devel make m4 ncurses-devel patch ) + + # Ensure GCC 4 is available on older pre-6 EL + package %w( gcc44 gcc44-c++ ) if node['platform_version'].to_i < 6 + when 'freebsd' + package 'devel/gmake' + package 'devel/autoconf' + package 'devel/m4' + package 'devel/gettext' + # Only install gcc on freebsd 9.x - 10 uses clang + package 'lang/gcc49' if node['platform_version'].to_i <= 9 + when 'mac_os_x' + xcode_command_line_tools 'install' + when 'omnios' + package 'developer/gcc48' + package 'developer/object-file' + package 'developer/linker' + package 'developer/library/lint' + package 'developer/build/gnu-make' + package 'system/header' + package 'system/library/math/header-math' + + # Per OmniOS documentation, the gcc bin dir isn't in the default + # $PATH, so add it to the running process environment + # http://omnios.omniti.com/wiki.php/DevEnv + ENV['PATH'] = "#{ENV['PATH']}:/opt/gcc-4.7.2/bin" + when 'solaris2' + if node['platform_version'].to_f == 5.10 + Chef::Log.warn('build-essential does not support Solaris 10. You will need to install SUNWbison, SUNWgcc, SUNWggrp, SUNWgmake, and SUNWgtar from the Solaris DVD') + elsif node['platform_version'].to_f == 5.11 + package 'autoconf' + package 'automake' + package 'bison' + package 'gnu-coreutils' + package 'flex' + package 'gcc' do + # lock because we don't use 5 yet + version '4.8.2' + end + package 'gcc-3' + package 'gnu-grep' + package 'gnu-make' + package 'gnu-patch' + package 'gnu-tar' + package 'make' + package 'pkg-config' + package 'ucb' + end + when 'smartos' + package 'autoconf' + package 'binutils' + package 'build-essential' + package 'gcc47' + package 'gmake' + package 'pkg-config' + when 'suse' + package %w( autoconf bison flex gcc gcc-c++ kernel-default-devel make m4 ) + package %w( gcc48 gcc48-c++ ) if node['platform_version'].to_i < 12 + when 'windows' + include_recipe 'build-essential::_windows' + else + Chef::Log.warn <<-EOH + A build-essential recipe does not exist for '#{node['platform_family']}'. This + means the build-essential cookbook does not have support for the + #{node['platform_family']} family. If you are not compiling gems with native + extensions or building packages from source, this will likely not affect you. + EOH + end +end + +# this resource forces itself to run at compile_time +def after_created + return unless compile_time + Array(action).each do |action| + run_action(action) + end +end diff --git a/cookbooks/build-essential/resources/msys_archive.rb b/cookbooks/build-essential/resources/msys_archive.rb new file mode 100644 index 0000000..fe95391 --- /dev/null +++ b/cookbooks/build-essential/resources/msys_archive.rb @@ -0,0 +1,7 @@ +actions :unpack +default_action :unpack + +attribute :source, kind_of: String, name_attribute: true +attribute :root_dir, kind_of: String, required: true +attribute :mingw, kind_of: [TrueClass, FalseClass], default: false +attribute :checksum, kind_of: String diff --git a/cookbooks/build-essential/resources/xcode_command_line_tools.rb b/cookbooks/build-essential/resources/xcode_command_line_tools.rb new file mode 100644 index 0000000..850612e --- /dev/null +++ b/cookbooks/build-essential/resources/xcode_command_line_tools.rb @@ -0,0 +1,61 @@ +# +# Cookbook:: build-essential +# Resource:: xcode_command_line_tools +# +# Copyright:: 2014-2016, 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. +# 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. +# + +resource_name :xcode_command_line_tools + +action :install do + if installed? + Chef::Log.debug("#{new_resource} already installed - skipping") + else + converge_by("Install #{new_resource}") do + # This script was graciously borrowed and modified from Tim Sutton's + # osx-vm-templates at https://github.com/timsutton/osx-vm-templates/blob/b001475df54a9808d3d56d06e71b8fa3001fff42/scripts/xcode-cli-tools.sh + execute 'install XCode Command Line tools' do + command <<-EOH.gsub(/^ {14}/, '') + # create the placeholder file that's checked by CLI updates' .dist code + # in Apple's SUS catalog + touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress + # find the CLI Tools update + PROD=$(softwareupdate -l | grep "\*.*Command Line" | head -n 1 | awk -F"*" '{print $2}' | sed -e 's/^ *//' | tr -d '\n') + # install it + softwareupdate -i "$PROD" --verbose + # Remove the placeholder to prevent perpetual appearance in the update utility + rm -f /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress + EOH + # rubocop:enable Metrics/LineLength + end + end + end +end + +action_class do + # + # Determine if the XCode Command Line Tools are installed + # + # @return [true, false] + # + def installed? + cmd = Mixlib::ShellOut.new('pkgutil --pkgs=com.apple.pkg.CLTools_Executables') + cmd.run_command + cmd.error! + true + rescue Mixlib::ShellOut::ShellCommandFailed + false + end +end diff --git a/cookbooks/chef-solo-search/.gitignore b/cookbooks/chef-solo-search/.gitignore deleted file mode 100644 index 0a0905a..0000000 --- a/cookbooks/chef-solo-search/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/Gemfile.lock -/tests/gemfiles/*.lock diff --git a/cookbooks/chef-solo-search/.travis.yml b/cookbooks/chef-solo-search/.travis.yml deleted file mode 100644 index 4e5cf34..0000000 --- a/cookbooks/chef-solo-search/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -before_install: gem update --system 1.8.25 -before_script: chef-solo -v -rvm: - - 1.9.3 - - 1.9.2 - - 1.8.7 -gemfile: - - tests/gemfiles/Gemfile.11 - - tests/gemfiles/Gemfile.10 diff --git a/cookbooks/chef-solo-search/CHANGELOG b/cookbooks/chef-solo-search/CHANGELOG deleted file mode 100644 index a33d492..0000000 --- a/cookbooks/chef-solo-search/CHANGELOG +++ /dev/null @@ -1,31 +0,0 @@ -========================== -chef-solo-search Changelog -========================== - -Version 0.5.1, September 19, 2013 ---------------------------------- -* Added missing metadata.json file - - -Version 0.5.0, September 19, 2013 ---------------------------------- -* Allow node data bag path to be configured -* updated install instructions with focus on Chef 11 -* Fixed Treetop dependency such that the omnibus installer is working -* Added proper ruby Gemfile -* use rake as runner for the tests -* Fixed Travis CI builds - - -Version 0.4.0, March 8, 2013 ----------------------------- -* Added support for 'chef_environment:_default' to queries. -* Special case for lucene "anything range" [* TO *] -* Added support for ruby bundler -* Added support for Berkshelf - -Version 0.3.0, July 27, 2011 ----------------------------- -First release of chef-solo-search as a self-contained project. -Search functionality has been added to the original concept and the search -extension as well as the data bags extension are shipped in libraries/ diff --git a/cookbooks/chef-solo-search/Gemfile b/cookbooks/chef-solo-search/Gemfile deleted file mode 100644 index b68f200..0000000 --- a/cookbooks/chef-solo-search/Gemfile +++ /dev/null @@ -1,8 +0,0 @@ -source 'https://rubygems.org' - -gem 'chef', '>= 10.4' -gem 'treetop' -gem 'rake' -gem 'ruby-wmi' -gem 'win32-service', :platforms => [:mswin, :mingw] - diff --git a/cookbooks/chef-solo-search/LICENSE b/cookbooks/chef-solo-search/LICENSE deleted file mode 100644 index c04563e..0000000 --- a/cookbooks/chef-solo-search/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -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. - diff --git a/cookbooks/chef-solo-search/NOTICE b/cookbooks/chef-solo-search/NOTICE deleted file mode 100644 index 26adc44..0000000 --- a/cookbooks/chef-solo-search/NOTICE +++ /dev/null @@ -1,23 +0,0 @@ -======================== -chef-solo-search Notices -======================== - -Developed at edelight GmbH (http://www.edelight-group.com/). - -Contributors: - - * Arjun Singh - * Brian p o'rourke - * Chris Roberts - * Greg Karékinian - * Jeff Wallace - * Michael Glass - * Miquel Torres - * Markus Korn - * Matt Gleeson - * Patrick Debois - * Patrick Wyatt - * Paweł Pacana - * Seth Chisamore - * Teemu Matilainen - * Tyler Rick diff --git a/cookbooks/chef-solo-search/README.md b/cookbooks/chef-solo-search/README.md deleted file mode 100644 index e9c97b1..0000000 --- a/cookbooks/chef-solo-search/README.md +++ /dev/null @@ -1,148 +0,0 @@ -# chef-solo-search - -[![Build Status](https://travis-ci.org/edelight/chef-solo-search.png?branch=master)](https://travis-ci.org/edelight/chef-solo-search) - -Chef-solo-search is a cookbook library that adds data bag search powers -to Chef Solo. Data bag support was added to Chef Solo by Chef 0.10.4. -Please see *Supported queries* for a list of query types which are supported. - -## Requirements - - * ruby >= 1.8 - * ruby-chef >= 0.10.4 - -## Installation - -Install this cookbook into your Chef repository using your favorite cookbook -management tool -([Librarian](https://github.com/applicationsonline/librarian-chef), -[Berkshelf](https://github.com/RiotGames/berkshelf), knife...). - -In Chef 11, you must either add this to the run list of the nodes where it's used or include it as a dependency in the recipes that use it. [See changes in Chef 11.](http://docs.opscode.com/breaking_changes_chef_11.html#non-recipe-file-evaluation-includes-dependencies) - -Now you have to make sure chef-solo knows about data bags, therefore add - - data_bag_path "/data_bags" - -to the config file of chef-solo (defaults to /etc/chef/solo.rb). - -The same for your roles, add - - role_path "/roles" - -## Supported queries - -The search methods supports a basic sub-set of the lucene query language. -Sample supported queries are: - -### General queries: - - search(:users, "*:*") - search(:users) - search(:users, nil) - getting all items in ':users' - search(:users, "username:*") - search(:users, "username:[* TO *]") - getting all items from ':users' which have a 'username' attribute - search(:users, "(NOT username:*)") - search(:users, "(NOT username:[* TO *])") - getting all items from ':users' which don't have a 'username' attribute - -### Queries on attributes with string values: - - search(:users, "username:speedy") - getting all items from ':users' with username equals 'speedy' - search(:users, "NOT username:speedy") - getting all items from ':users' with username is unequal to 'speedy' - search(:users, "username:spe*") - getting all items which 'username'-value begins with 'spe' - -### Queries on attributes with array values: - - search(:users, "children:tom") - getting all items which 'children' attribute contains 'tom' - search(:users, "children:t*") - getting all items which have at least one element in 'children' - which starts with 't' - -### Queries on attributes with boolean values: - - search(:users, "married:true") - -### Queries in attributes with integer values: - - search(:users, "age:35") - -### OR conditions in queries: - - search(:users, "age:42 OR age:22") - -### AND conditions in queries: - - search(:users, "married:true AND age:35") - -### NOT condition in queries: - - search(:users, "children:tom NOT gender:female") - -### More complex queries: - - search(:users, "children:tom NOT gender:female AND age:42") - - -## Supported Objects -The search methods have support for 'roles', 'nodes' and 'databags'. - -### Roles -You can use the standard role objects in json form and put them into your role path - - { - "name": "monitoring", - "default_attributes": { }, - "override_attributes": { }, - "json_class": "Chef::Role", - "description": "This is just a monitoring role, no big deal.", - "run_list": [ - ], - "chef_type": "role" - - -### Nodes -Nodes are injected through a databag called 'node'. Create a databag called 'node' and put your json files there -You can use the standard node objects in json form. - - { - "id": "vagrant", - "name": "vagrant-vm", - "chef_environment": "_default", - "json_class": "Chef::Node", - "automatic": { - "hostname": "vagrant.vm", - "os": "centos" - }, - "normal": { - }, - "chef_type": "node", - "default": { - }, - "override": { - }, - "run_list": [ - "role[monitoring]" - ] - } - -### Databags -You can use the standard databag objects in json form - - { - "id": "my-ssh", - "hostgroup_name": "all", - "command_line": "$USER1$/check_ssh $HOSTADDRESS$" - } - -## Running tests - -Running tests is as simple as: - - % rake test diff --git a/cookbooks/chef-solo-search/Rakefile b/cookbooks/chef-solo-search/Rakefile deleted file mode 100644 index 8bb4eab..0000000 --- a/cookbooks/chef-solo-search/Rakefile +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env rake -require "rake/testtask" - -Rake::TestTask.new do |t| - t.pattern = "tests/test_*.rb" - t.libs = %w(libraries) -end - -desc "Run tests" -task :default => :test diff --git a/cookbooks/chef-solo-search/libraries/search.rb b/cookbooks/chef-solo-search/libraries/search.rb deleted file mode 100644 index 5c1d155..0000000 --- a/cookbooks/chef-solo-search/libraries/search.rb +++ /dev/null @@ -1,74 +0,0 @@ -# -# Copyright 2011, edelight GmbH -# -# Authors: -# Markus Korn -# Seth Chisamore -# -# 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. -# - -if Chef::Config[:solo] - - # add currrent dir to load path - $: << File.dirname(__FILE__) - - # All chef/solr_query/* classes were removed in Chef 11; Load vendored copy - # that ships with this cookbook - $: << File.expand_path("vendor", File.dirname(__FILE__)) if Chef::VERSION.to_i >= 11 - - # Ensure the treetop gem is installed and available - begin - require 'treetop' - rescue LoadError - run_context = Chef::RunContext.new(Chef::Node.new, {}, Chef::EventDispatch::Dispatcher.new) - chef_gem = Chef::Resource::ChefGem.new("treetop", run_context) - chef_gem.version('>= 1.4') - chef_gem.run_action(:install) - end - - require 'search/overrides' - require 'search/parser' - - module Search; class Helper; end; end - - # The search and data_bag related methods moved form `Chef::Mixin::Language` - # to `Chef::DSL::DataQuery` in Chef 11. - if Chef::VERSION.to_i >= 11 - module Chef::DSL::DataQuery - def self.included(base) - base.send(:include, Search::Overrides) - end - end - Search::Helper.send(:include, Chef::DSL::DataQuery) - else - module Chef::Mixin::Language - def self.included(base) - base.send(:include, Search::Overrides) - end - end - Search::Helper.send(:include, Chef::Mixin::Language) - end - - class Chef - class Search - class Query - def initialize(*args) - end - def search(*args, &block) - ::Search::Helper.new.search(*args, &block) - end - end - end - end -end diff --git a/cookbooks/chef-solo-search/libraries/search/overrides.rb b/cookbooks/chef-solo-search/libraries/search/overrides.rb deleted file mode 100644 index 6189621..0000000 --- a/cookbooks/chef-solo-search/libraries/search/overrides.rb +++ /dev/null @@ -1,100 +0,0 @@ -# -# Copyright 2011, edelight GmbH -# -# Authors: -# Markus Korn -# Seth Chisamore -# -# 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. -# - -module Search - module Overrides - # Overwrite the search method of recipes to operate locally by using - # data found in data_bags. - # Only very basic lucene syntax is supported and also sorting the result - # is not implemented, if this search method does not support a given query - # an exception is raised. - # This search() method returns a block iterator or an Array, depending - # on how this method is called. - def search(obj, query=nil, sort=nil, start=0, rows=1000, &block) - if !sort.nil? - raise "Sorting search results is not supported" - end - _query = Query.parse(query) - if _query.nil? - raise "Query #{query} is not supported" - end - _result = [] - - case obj - when :node - nodes = search_nodes(_query, start, rows, &block) - _result += nodes - when :role - roles = search_roles(_query, start, rows, &block) - _result += roles - else - bags = search_data_bag(_query, obj, start, rows, &block) - _result += bags - end - - - if block_given? - pos = 0 - while (pos >= start and pos < (start + rows) and pos < _result.size) - yield _result[pos] - pos += 1 - end - else - return _result.slice(start, rows) - end - end - - def search_nodes(_query, start, rows, &block) - _result = [] - node_path = Chef::Config[:nodes_path] || File.join(Chef::Config[:data_bag_path], "node") - Dir.glob(File.join(node_path, "*.json")).map do |f| - # parse and hashify the node - node = Chef::JSONCompat.from_json(IO.read(f)) - if _query.match(node.to_hash) - _result << node - end - end - return _result - end - - def search_roles(_query, start, rows, &block) - _result = [] - Dir.glob(File.join(Chef::Config[:role_path], "*.json")).map do |f| - # parse and hashify the role - role = Chef::JSONCompat.from_json(IO.read(f)) - if _query.match(role.to_hash) - _result << role - end - end - return _result - end - - def search_data_bag(_query, bag_name, start, rows, &block) - _result = [] - data_bag(bag_name.to_s).each do |bag_item_id| - bag_item = data_bag_item(bag_name.to_s, bag_item_id) - if _query.match(bag_item) - _result << bag_item - end - end - return _result - end - end -end diff --git a/cookbooks/chef-solo-search/libraries/search/parser.rb b/cookbooks/chef-solo-search/libraries/search/parser.rb deleted file mode 100644 index 0955630..0000000 --- a/cookbooks/chef-solo-search/libraries/search/parser.rb +++ /dev/null @@ -1,222 +0,0 @@ -# -# Copyright 2011, edelight GmbH -# -# Authors: -# Markus Korn -# -# 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/solr_query/query_transform' - -# mock QueryTransform such that we can access the location of the lucene grammar -class Chef - class SolrQuery - class QueryTransform - def self.base_path - class_variable_get(:@@base_path) - end - end - end -end - -def build_flat_hash(hsh, prefix="") - result = {} - hsh.each_pair do |key, value| - if value.kind_of?(Hash) - result.merge!(build_flat_hash(value, "#{prefix}#{key}_")) - else - result[prefix+key] = value - end - end - result -end - -module Lucene - - class Term < Treetop::Runtime::SyntaxNode - # compares a query value and a value, tailing '*'-wildcards are handled correctly. - # Value can either be a string or an array, all other objects are converted - # to a string and than checked. - def match( value ) - if value.is_a?(Array) - value.any?{ |x| self.match(x) } - else - File.fnmatch(self.text_value, value.to_s) - end - end - end - - class Field < Treetop::Runtime::SyntaxNode - # simple field -> value matches, supporting tailing '*'-wildcards in keys - # as well as in values - def match( item ) - keys = self.elements[0].match(item) - if keys.nil? - false - else - keys.any?{ |key| self.elements[1].match(item[key]) } - end - end - end - - # we don't support range matches - # range of integers would be easy to implement - # but string ranges are hard - class FiledRange < Treetop::Runtime::SyntaxNode - end - - # we handle '[* TO *]' as a special case since it is common in - # cookbooks for matching the existence of keys - class InclFieldRange - def match(item) - field = self.elements[0].text_value - range_start = self.elements[1].transform - range_end = self.elements[2].transform - if range_start == "*" and range_end == "*" - !!item[field] - else - raise "Ranges not really supported yet" - end - end - end - - class ExclFieldRange < FieldRange - end - - class RangeValue < Treetop::Runtime::SyntaxNode - end - - class FieldName < Treetop::Runtime::SyntaxNode - def match( item ) - if self.text_value.count("_") > 0 - item.merge!(build_flat_hash(item)) - end - if self.text_value.end_with?("*") - part = self.text_value.chomp("*") - item.keys.collect{ |key| key.start_with?(part)? key: nil}.compact - else - if item.has_key?(self.text_value) - [self.text_value,] - else - nil - end - end - end - end - - class Body < Treetop::Runtime::SyntaxNode - def match( item ) - self.elements[0].match( item ) - end - end - - class Group < Treetop::Runtime::SyntaxNode - def match( item ) - self.elements[0].match(item) - end - end - - class BinaryOp < Treetop::Runtime::SyntaxNode - def match( item ) - self.elements[1].match( - self.elements[0].match(item), - self.elements[2].match(item) - ) - end - end - - class OrOperator < Treetop::Runtime::SyntaxNode - def match( cond1, cond2 ) - cond1 or cond2 - end - end - - class AndOperator < Treetop::Runtime::SyntaxNode - def match( cond1, cond2 ) - cond1 and cond2 - end - end - - # we don't support fuzzy string matching - class FuzzyOp < Treetop::Runtime::SyntaxNode - end - - class BoostOp < Treetop::Runtime::SyntaxNode - end - - class FuzzyParam < Treetop::Runtime::SyntaxNode - end - - class UnaryOp < Treetop::Runtime::SyntaxNode - def match( item ) - self.elements[0].match( - self.elements[1].match(item) - ) - end - end - - class NotOperator < Treetop::Runtime::SyntaxNode - def match( cond ) - not cond - end - end - - class RequiredOperator < Treetop::Runtime::SyntaxNode - end - - class ProhibitedOperator < Treetop::Runtime::SyntaxNode - end - - class Phrase < Treetop::Runtime::SyntaxNode - # a quoted ::Term - def match( value ) - self.elements[0].match(value) - end - end -end - -class Query - # initialize the parser by using the grammar shipped with chef - @@grammar = File.join(Chef::SolrQuery::QueryTransform.base_path, "lucene.treetop") - Treetop.load(@@grammar) - @@parser = LuceneParser.new - - def self.parse(data) - # parse the query into a query tree - if data.nil? - data = "*:*" - end - tree = @@parser.parse(data) - if tree.nil? - msg = "Parse error at offset: #{@@parser.index}\n" - msg += "Reason: #{@@parser.failure_reason}" - raise "Query #{data} is not supported: #{msg}" - end - self.clean_tree(tree) - tree - end - - private - - def self.clean_tree(root_node) - # remove all SyntaxNode elements from the tree, we don't need them as - # the related ruby class already knowns what to do. - return if root_node.elements.nil? - root_node.elements.delete_if do |node| - node.class.name == "Treetop::Runtime::SyntaxNode" - end - root_node.elements.each { |node| self.clean_tree(node) } - end -end - diff --git a/cookbooks/chef-solo-search/libraries/vendor/chef/solr_query/lucene.treetop b/cookbooks/chef-solo-search/libraries/vendor/chef/solr_query/lucene.treetop deleted file mode 100644 index df2d180..0000000 --- a/cookbooks/chef-solo-search/libraries/vendor/chef/solr_query/lucene.treetop +++ /dev/null @@ -1,150 +0,0 @@ -# -# Author:: Seth Falcon () -# Copyright:: Copyright (c) 2010-2011 Opscode, 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. -# - -grammar Lucene - - rule body - (expression / space)* - end - - rule expression - operation / group / field / field_range / term / string - end - - rule term - keyword valid_letter+ / !keyword !"?" valid_letter - end - - rule field - field_name ":" (term/string/group) - end - - rule field_range - field_name ":" "[" range_value " TO " range_value "]" - / - field_name ":" "{" range_value " TO " range_value "}" - end - - rule field_name - !keyword valid_letter+ - end - - rule range_value - valid_letter+ / "*" - end - - rule group - space? '(' body ')' space? - end - - rule operation - binary_op / unary_op / fuzzy_op / boost_op - end - - rule unary_op - not_op / required_op / prohibited_op - end - - rule binary_op - (group / field / field_range / term) space? boolean_operator space+ body - end - - rule boolean_operator - and_operator / or_operator - end - - rule and_operator - 'AND' / '&&' - end - - rule or_operator - 'OR' / '||' - end - - rule not_op - not_operator space (group / field / field_range / term / string) - / - bang_operator space? (group / field / field_range / term / string) - end - - rule not_operator - 'NOT' - end - - rule bang_operator - '!' - end - - rule required_op - !valid_letter required_operator (term/string) - / - required_operator (term/string) - end - - rule required_operator - '+' - end - - rule prohibited_op - !valid_letter prohibited_operator (field/field_range/term/string) - end - - rule prohibited_operator - '-' - end - - rule boost_op - (term/string) '^' fuzzy_param - end - - rule fuzzy_op - (term/string) '~' fuzzy_param? (space / !valid_letter) - end - - rule fuzzy_param - [0-9] '.'? [0-9] / [0-9]+ - end - - rule string - '"' term (space term)* '"' - end - - rule keyword - 'AND' / 'OR' / 'NOT' - end - - rule valid_letter - start_letter+ ([a-zA-Z0-9@*?_.-] / '\\' special_char)* - end - - rule start_letter - [a-zA-Z0-9@._*] / '\\' special_char - end - - rule end_letter - [a-zA-Z0-9*?_.] / '\\' special_char - end - - rule special_char - [-+&|!(){}\[\]^"~*?:\\] - end - - rule space - [\s]+ - end -end diff --git a/cookbooks/chef-solo-search/libraries/vendor/chef/solr_query/lucene_nodes.rb b/cookbooks/chef-solo-search/libraries/vendor/chef/solr_query/lucene_nodes.rb deleted file mode 100644 index b50304f..0000000 --- a/cookbooks/chef-solo-search/libraries/vendor/chef/solr_query/lucene_nodes.rb +++ /dev/null @@ -1,285 +0,0 @@ -# -# Author:: Seth Falcon () -# Copyright:: Copyright (c) 2010-2011 Opscode, 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 'treetop' - -module Lucene - SEP = "__=__" - - class Term < Treetop::Runtime::SyntaxNode - def to_array - "T:#{self.text_value}" - end - - def transform - self.text_value - end - end - - class Field < Treetop::Runtime::SyntaxNode - def to_array - field = self.elements[0].text_value - term = self.elements[1].to_array - "(F:#{field} #{term})" - end - - def transform - field = self.elements[0].text_value - term = self.elements[1] - if term.is_a? Phrase - str = term.transform - # remove quotes - str = str[1 ... (str.length - 1)] - "content:\"#{field}#{SEP}#{str}\"" - else - "content:#{field}#{SEP}#{term.transform}" - end - end - end - - class FieldRange < Treetop::Runtime::SyntaxNode - - def to_array - field = self.elements[0].text_value - range_start = self.elements[1].to_array - range_end = self.elements[2].to_array - "(FR:#{field} #{left}#{range_start}#{right} #{left}#{range_end}#{right})" - end - - def transform - field = self.elements[0].text_value - range_start = self.elements[1].transform - range_end = self.elements[2].transform - # FIXME: handle special cases for missing start/end - if ("*" == range_start && "*" == range_end) - "content:#{field}#{SEP}*" - elsif "*" == range_end - "content:#{left}#{field}#{SEP}#{range_start} TO #{field}#{SEP}\\ufff0#{right}" - elsif "*" == range_start - "content:#{left}#{field}#{SEP} TO #{field}#{SEP}#{range_end}#{right}" - else - "content:#{left}#{field}#{SEP}#{range_start} TO #{field}#{SEP}#{range_end}#{right}" - end - end - - end - - class InclFieldRange < FieldRange - def left - "[" - end - def right - "]" - end - end - - class ExclFieldRange < FieldRange - def left - "{" - end - def right - "}" - end - end - - class RangeValue < Treetop::Runtime::SyntaxNode - def to_array - self.text_value - end - - def transform - to_array - end - end - - class FieldName < Treetop::Runtime::SyntaxNode - def to_array - self.text_value - end - - def transform - to_array - end - end - - - class Body < Treetop::Runtime::SyntaxNode - def to_array - self.elements.map { |x| x.to_array }.join(" ") - end - - def transform - self.elements.map { |x| x.transform }.join(" ") - end - end - - class Group < Treetop::Runtime::SyntaxNode - def to_array - "(" + self.elements[0].to_array + ")" - end - - def transform - "(" + self.elements[0].transform + ")" - end - end - - class BinaryOp < Treetop::Runtime::SyntaxNode - def to_array - op = self.elements[1].to_array - a = self.elements[0].to_array - b = self.elements[2].to_array - "(#{op} #{a} #{b})" - end - - def transform - op = self.elements[1].transform - a = self.elements[0].transform - b = self.elements[2].transform - "#{a} #{op} #{b}" - end - end - - class AndOperator < Treetop::Runtime::SyntaxNode - def to_array - "OP:AND" - end - - def transform - "AND" - end - end - - class OrOperator < Treetop::Runtime::SyntaxNode - def to_array - "OP:OR" - end - - def transform - "OR" - end - end - - class FuzzyOp < Treetop::Runtime::SyntaxNode - def to_array - a = self.elements[0].to_array - param = self.elements[1] - if param - "(OP:~ #{a} #{param.to_array})" - else - "(OP:~ #{a})" - end - end - - def transform - a = self.elements[0].transform - param = self.elements[1] - if param - "#{a}~#{param.transform}" - else - "#{a}~" - end - end - end - - class BoostOp < Treetop::Runtime::SyntaxNode - def to_array - a = self.elements[0].to_array - param = self.elements[1] - "(OP:^ #{a} #{param.to_array})" - end - - def transform - a = self.elements[0].transform - param = self.elements[1] - "#{a}^#{param.transform}" - end - end - - class FuzzyParam < Treetop::Runtime::SyntaxNode - def to_array - self.text_value - end - - def transform - self.text_value - end - end - - class UnaryOp < Treetop::Runtime::SyntaxNode - def to_array - op = self.elements[0].to_array - a = self.elements[1].to_array - "(#{op} #{a})" - end - - def transform - op = self.elements[0].transform - a = self.elements[1].transform - spc = case op - when "+", "-" - "" - else - " " - end - "#{op}#{spc}#{a}" - end - - end - - class NotOperator < Treetop::Runtime::SyntaxNode - def to_array - "OP:NOT" - end - - def transform - "NOT" - end - - end - - class RequiredOperator < Treetop::Runtime::SyntaxNode - def to_array - "OP:+" - end - - def transform - "+" - end - - end - - class ProhibitedOperator < Treetop::Runtime::SyntaxNode - def to_array - "OP:-" - end - - def transform - "-" - end - end - - class Phrase < Treetop::Runtime::SyntaxNode - def to_array - "STR:#{self.text_value}" - end - - def transform - "#{self.text_value}" - end - end -end diff --git a/cookbooks/chef-solo-search/libraries/vendor/chef/solr_query/query_transform.rb b/cookbooks/chef-solo-search/libraries/vendor/chef/solr_query/query_transform.rb deleted file mode 100644 index 84bf5a1..0000000 --- a/cookbooks/chef-solo-search/libraries/vendor/chef/solr_query/query_transform.rb +++ /dev/null @@ -1,65 +0,0 @@ -# -# Author:: Seth Falcon () -# Copyright:: Copyright (c) 2010-2011 Opscode, 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 'treetop' -require 'chef/solr_query/lucene_nodes' - -class Chef - class Exceptions - class QueryParseError < StandardError - end - end -end - -class Chef - class SolrQuery - class QueryTransform - @@base_path = File.expand_path(File.dirname(__FILE__)) - Treetop.load(File.join(@@base_path, 'lucene.treetop')) - @@parser = LuceneParser.new - - def self.parse(data) - tree = @@parser.parse(data) - msg = "Parse error at offset: #{@@parser.index}\n" - msg += "Reason: #{@@parser.failure_reason}" - raise Chef::Exceptions::QueryParseError, msg if tree.nil? - self.clean_tree(tree) - tree.to_array - end - - def self.transform(data) - return "*:*" if data == "*:*" - tree = @@parser.parse(data) - msg = "Parse error at offset: #{@@parser.index}\n" - msg += "Reason: #{@@parser.failure_reason}" - raise Chef::Exceptions::QueryParseError, msg if tree.nil? - self.clean_tree(tree) - tree.transform - end - - private - - def self.clean_tree(root_node) - return if root_node.elements.nil? - root_node.elements.delete_if do |node| - node.class.name == "Treetop::Runtime::SyntaxNode" - end - root_node.elements.each { |node| self.clean_tree(node) } - end - end - end -end diff --git a/cookbooks/chef-solo-search/metadata.json b/cookbooks/chef-solo-search/metadata.json deleted file mode 100644 index 6d58afb..0000000 --- a/cookbooks/chef-solo-search/metadata.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "license": "Apache 2.0", - "replacing": { - }, - "suggestions": { - }, - "long_description": "# chef-solo-search\n\n[![Build Status](https://travis-ci.org/edelight/chef-solo-search.png?branch=master)](https://travis-ci.org/edelight/chef-solo-search)\n\nChef-solo-search is a cookbook library that adds data bag search powers\nto Chef Solo. Data bag support was added to Chef Solo by Chef 0.10.4.\nPlease see *Supported queries* for a list of query types which are supported.\n\n## Requirements\n\n * ruby >= 1.8\n * ruby-chef >= 0.10.4\n\n## Installation\n\nInstall this cookbook into your Chef repository using your favorite cookbook\nmanagement tool\n([Librarian](https://github.com/applicationsonline/librarian-chef),\n[Berkshelf](https://github.com/RiotGames/berkshelf), knife...).\n\nIn Chef 11, you must either add this to the run list of the nodes where it's used or include it as a dependency in the recipes that use it. [See changes in Chef 11.](http://docs.opscode.com/breaking_changes_chef_11.html#non-recipe-file-evaluation-includes-dependencies)\n\nNow you have to make sure chef-solo knows about data bags, therefore add\n\n data_bag_path \"/data_bags\"\n\nto the config file of chef-solo (defaults to /etc/chef/solo.rb).\n\nThe same for your roles, add\n\n role_path \"/roles\"\n\n## Supported queries\n\nThe search methods supports a basic sub-set of the lucene query language.\nSample supported queries are:\n\n### General queries:\n\n search(:users, \"*:*\")\n search(:users)\n search(:users, nil)\n getting all items in ':users'\n search(:users, \"username:*\")\n search(:users, \"username:[* TO *]\")\n getting all items from ':users' which have a 'username' attribute\n search(:users, \"(NOT username:*)\")\n search(:users, \"(NOT username:[* TO *])\")\n getting all items from ':users' which don't have a 'username' attribute\n\n### Queries on attributes with string values:\n\n search(:users, \"username:speedy\")\n getting all items from ':users' with username equals 'speedy'\n search(:users, \"NOT username:speedy\")\n getting all items from ':users' with username is unequal to 'speedy'\n search(:users, \"username:spe*\")\n getting all items which 'username'-value begins with 'spe'\n\n### Queries on attributes with array values:\n\n search(:users, \"children:tom\")\n getting all items which 'children' attribute contains 'tom'\n search(:users, \"children:t*\")\n getting all items which have at least one element in 'children'\n which starts with 't'\n\n### Queries on attributes with boolean values:\n\n search(:users, \"married:true\")\n\n### Queries in attributes with integer values:\n\n search(:users, \"age:35\")\n\n### OR conditions in queries:\n\n search(:users, \"age:42 OR age:22\")\n\n### AND conditions in queries:\n\n search(:users, \"married:true AND age:35\")\n\n### NOT condition in queries:\n\n search(:users, \"children:tom NOT gender:female\")\n\n### More complex queries:\n\n search(:users, \"children:tom NOT gender:female AND age:42\")\n\n\n## Supported Objects\nThe search methods have support for 'roles', 'nodes' and 'databags'.\n\n### Roles\nYou can use the standard role objects in json form and put them into your role path\n\n {\n \"name\": \"monitoring\",\n \"default_attributes\": { },\n \"override_attributes\": { },\n \"json_class\": \"Chef::Role\",\n \"description\": \"This is just a monitoring role, no big deal.\",\n \"run_list\": [\n ],\n \"chef_type\": \"role\"\n\n\n### Nodes\nNodes are injected through a databag called 'node'. Create a databag called 'node' and put your json files there\nYou can use the standard node objects in json form.\n\n {\n \"id\": \"vagrant\",\n \"name\": \"vagrant-vm\",\n \"chef_environment\": \"_default\",\n \"json_class\": \"Chef::Node\",\n \"automatic\": {\n \"hostname\": \"vagrant.vm\",\n \"os\": \"centos\"\n },\n \"normal\": {\n },\n \"chef_type\": \"node\",\n \"default\": {\n },\n \"override\": {\n },\n \"run_list\": [\n \"role[monitoring]\"\n ]\n }\n\n### Databags\nYou can use the standard databag objects in json form\n\n {\n \"id\": \"my-ssh\",\n \"hostgroup_name\": \"all\",\n \"command_line\": \"$USER1$/check_ssh $HOSTADDRESS$\"\n }\n\n## Running tests\n\nRunning tests is as simple as:\n\n % rake test\n", - "attributes": { - }, - "providing": { - }, - "maintainer_email": "markus.korn@edelight.de", - "groupings": { - }, - "conflicting": { - }, - "description": "Data bag search for Chef Solo", - "name": "chef-solo-search", - "version": "0.5.1", - "dependencies": { - }, - "platforms": { - "freebsd": ">= 0.0.0", - "fedora": ">= 0.0.0", - "debian": ">= 0.0.0", - "ubuntu": ">= 0.0.0", - "centos": ">= 0.0.0", - "redhat": ">= 0.0.0" - }, - "maintainer": "edelight GmbH", - "recipes": { - }, - "recommendations": { - } -} \ No newline at end of file diff --git a/cookbooks/chef-solo-search/metadata.rb b/cookbooks/chef-solo-search/metadata.rb deleted file mode 100644 index 8cdecc2..0000000 --- a/cookbooks/chef-solo-search/metadata.rb +++ /dev/null @@ -1,11 +0,0 @@ -name "chef-solo-search" -maintainer "edelight GmbH" -maintainer_email "markus.korn@edelight.de" -license "Apache 2.0" -description "Data bag search for Chef Solo" -long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -version "0.5.1" - -%w{ ubuntu debian redhat centos fedora freebsd}.each do |os| - supports os -end diff --git a/cookbooks/chef-solo-search/recipes/default.rb b/cookbooks/chef-solo-search/recipes/default.rb deleted file mode 100644 index 8ffa4a1..0000000 --- a/cookbooks/chef-solo-search/recipes/default.rb +++ /dev/null @@ -1,2 +0,0 @@ -# This file is intentionally blank, which allows this -# entire repository to be used as a cookbook diff --git a/cookbooks/chef-solo-search/tests/data/data_bags/node/alpha.json b/cookbooks/chef-solo-search/tests/data/data_bags/node/alpha.json deleted file mode 100644 index d06ac6d..0000000 --- a/cookbooks/chef-solo-search/tests/data/data_bags/node/alpha.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "id": "alpha", - "name": "alpha.example.com", - "json_class": "Chef::Node", - "run_list": ["role[test_server]"], - "chef_environment": "default", - "automatic": { - "hostname": "alpha.example.com" - } -} diff --git a/cookbooks/chef-solo-search/tests/data/data_bags/node/beta.json b/cookbooks/chef-solo-search/tests/data/data_bags/node/beta.json deleted file mode 100644 index 9e4f267..0000000 --- a/cookbooks/chef-solo-search/tests/data/data_bags/node/beta.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "id": "beta", - "name": "beta.example.com", - "json_class": "Chef::Node", - "run_list": ["role[test_server]","role[beta_server]"], - "chef_environment": "default", - "automatic": { - "hostname": "beta.example.com" - } -} diff --git a/cookbooks/chef-solo-search/tests/data/data_bags/node/without_json_class.json b/cookbooks/chef-solo-search/tests/data/data_bags/node/without_json_class.json deleted file mode 100644 index e64c88c..0000000 --- a/cookbooks/chef-solo-search/tests/data/data_bags/node/without_json_class.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "id": "without_json_class", - "name": "wjc.example.com", - "chef_environment": "default", - "hostname": "wjc.example.com", - "run_list": ["role[test_server]"] -} diff --git a/cookbooks/chef-solo-search/tests/data/data_bags/users/jerry.json b/cookbooks/chef-solo-search/tests/data/data_bags/users/jerry.json deleted file mode 100644 index bdfe6e5..0000000 --- a/cookbooks/chef-solo-search/tests/data/data_bags/users/jerry.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "id": "jerry", - "username": "speedy", - "age": 22, - "gender": "male", - "married": true, - "color": "green" -} diff --git a/cookbooks/chef-solo-search/tests/data/data_bags/users/lea.json b/cookbooks/chef-solo-search/tests/data/data_bags/users/lea.json deleted file mode 100644 index 4b58de4..0000000 --- a/cookbooks/chef-solo-search/tests/data/data_bags/users/lea.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "id": "lea", - "username": "lea", - "age": 35, - "gender": "female", - "married": true, - "children": ["tom"], - "tag": "tag::test", - "tags": ["tag::first", "tag::second"] -} diff --git a/cookbooks/chef-solo-search/tests/data/data_bags/users/mike.json b/cookbooks/chef-solo-search/tests/data/data_bags/users/mike.json deleted file mode 100644 index 215b30d..0000000 --- a/cookbooks/chef-solo-search/tests/data/data_bags/users/mike.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "id": "mike", - "username": "mike the hammer", - "age": 42, - "gender": "male", - "married": true, - "children": ["tom", "jerry"], - "address": { - "street": { - "floor": 1 - } - } -} diff --git a/cookbooks/chef-solo-search/tests/data/data_bags/users/tom.json b/cookbooks/chef-solo-search/tests/data/data_bags/users/tom.json deleted file mode 100644 index b1622a4..0000000 --- a/cookbooks/chef-solo-search/tests/data/data_bags/users/tom.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "id": "tom", - "username": "tom von homme", - "age": 13, - "gender": "male", - "married": false, - "address": { - "street": "wilhelmsstrasse" - } -} diff --git a/cookbooks/chef-solo-search/tests/gemfiles/Gemfile.10 b/cookbooks/chef-solo-search/tests/gemfiles/Gemfile.10 deleted file mode 100644 index e4860d6..0000000 --- a/cookbooks/chef-solo-search/tests/gemfiles/Gemfile.10 +++ /dev/null @@ -1,4 +0,0 @@ -source "https://rubygems.org" - -gem "chef", "~> 10.0" -gem "rake" diff --git a/cookbooks/chef-solo-search/tests/gemfiles/Gemfile.11 b/cookbooks/chef-solo-search/tests/gemfiles/Gemfile.11 deleted file mode 100644 index 6753b4d..0000000 --- a/cookbooks/chef-solo-search/tests/gemfiles/Gemfile.11 +++ /dev/null @@ -1,5 +0,0 @@ -source "https://rubygems.org" - -gem "chef", "~> 11.0" -gem "rake" -gem "treetop" diff --git a/cookbooks/chef-solo-search/tests/test_data_bags.rb b/cookbooks/chef-solo-search/tests/test_data_bags.rb deleted file mode 100644 index 05fd9bb..0000000 --- a/cookbooks/chef-solo-search/tests/test_data_bags.rb +++ /dev/null @@ -1,45 +0,0 @@ -# -# Copyright 2011, edelight GmbH -# -# Authors: -# Markus Korn -# -# 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 "test/unit" -require "chef" - -# mocking chef such that it thinks it's running as chef-solo and knows about -# the location of the data_bag -Chef::Config[:solo] = true -Chef::Config[:data_bag_path] = "tests/data/data_bags" - -def data_bag_item(bag, item) - # wrapper around creating a new Recipe instance and calling data_bag on it - node = Chef::Node.new() - events = Chef::EventDispatch::Dispatcher.new - cookbooks = Chef::CookbookCollection.new() - run_context = Chef::RunContext.new(node, cookbooks, events) - return Chef::Recipe.new("test_cookbook", "test_recipe", run_context).data_bag_item(bag, item) -end - -class TestDataBags < Test::Unit::TestCase - - def test_data_bag - item = data_bag_item("users", "mike") - assert_equal item["age"], 42 - assert_equal item[:age], nil #upstream code for chef-solo does not use mashes - end - -end diff --git a/cookbooks/chef-solo-search/tests/test_search.rb b/cookbooks/chef-solo-search/tests/test_search.rb deleted file mode 100644 index 8d4c20b..0000000 --- a/cookbooks/chef-solo-search/tests/test_search.rb +++ /dev/null @@ -1,244 +0,0 @@ -# -# Copyright 2011, edelight GmbH -# -# Authors: -# Markus Korn -# -# 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 "rubygems" -require "test/unit" -require "chef" - -# mocking chef such that it thinks it's running as chef-solo and knows about -# the location of the data_bag -Chef::Config[:solo] = true -Chef::Config[:data_bag_path] = "#{File.dirname(__FILE__)}/data/data_bags" - -# load the extension -require File.expand_path('../../libraries/search', __FILE__) - -module SearchDbTests - - def test_search_all - # try to get data of all users - nodes = search(:users, "*:*") - assert_equal nodes.length, 4 - nodes = search(:users) - assert_equal nodes.length, 4 - nodes = search(:users, nil) - assert_equal nodes.length, 4 - end - - def test_search_exact_match - nodes = search(:users, "username:speedy") - assert_equal nodes.length, 1 - assert_equal nodes[0]["username"], "speedy" - end - - def test_get_all_with_field - nodes = search(:users, "username:*") - assert nodes.length > 0 - assert nodes.all?{|x| !x["username"].nil?} - end - - def test_get_all_without_field - nodes = search(:users, "(NOT username:*)") - assert nodes.length == 0 - nodes = search(:users, "(NOT color:*)") - assert nodes.length == 3 - assert nodes.all?{|x| x["color"].nil?} - end - - def test_get_all_but_speedy - nodes = search(:users, "NOT username:speedy") - assert nodes.length > 0 - assert nodes.all?{|x| x["username"] != "speedy"} - end - - def test_array_includes - nodes = search(:users, "children:tom") - assert nodes.length == 2 - assert nodes.all?{ |x| x["children"].include?("tom") } - nodes = search(:users, "children:jerry") - assert nodes.length == 1 - assert nodes.all?{ |x| x["children"].include?("jerry") } - end - - def test_boolean - nodes = search(:users, "married:true") - assert nodes.length == 3 - assert nodes.all?{ |x| x["married"] == true } - nodes = search(:users, "married:false") - assert nodes.length == 1 - assert nodes[0]["married"] == false - end - - def test_integer - nodes = search(:users, "age:35") - assert nodes.length == 1 - assert nodes[0]["age"] == 35 - end - - def test_AND_condition - nodes = search(:users, "married:true AND age:35") - assert nodes.length == 1 - assert nodes[0]["username"] == "lea" - end - - def test_OR_condition - nodes = search(:users, "age:42 OR age:22") - assert nodes.length == 2 - end - - def test_NOT_condition - nodes = search(:users, "children:tom AND (NOT gender:female)") - assert nodes.length == 1 - nodes = search(:users, "children:tom AND (NOT gender:female) AND age:42") - assert nodes.length == 1 - nodes = search(:users, "children:tom AND (NOT gender:female) AND (NOT age:42)") - assert nodes.length == 0 - end - - def test_any_value - nodes = search(:users, "children:*") - assert nodes.length == 2 - end - - def test_any_value_lucene_range - nodes = search(:users, "address:[* TO *]") - assert nodes.length == 2 - end - - def test_general_lucene_range_fails - assert_raises RuntimeError do - nodes = search(:users, "children:[aaa TO zzz]") - end - end - - def test_block_usage - # bracket syntax - result = [] - search(:users, "*:*") {|x| result << x["id"]} - assert result.length == 4 - - # do...end syntax - result = [] - search(:users) do |x| - result << x["id"] - end - assert result.length == 4 - end - - def test_check_escaped_chars - nodes = search(:users, 'tag:tag\:\:test') - assert nodes.length == 1 - nodes = search(:users, "tag:tag\\:\\:test") - assert nodes.length == 1 - nodes = search(:users, 'tags:tag\:\:first') - assert nodes.length == 1 - nodes = search(:users, "tags:tag\\:\\:first") - assert nodes.length == 1 - nodes = search(:users, 'tags:tag\:\:*') - assert nodes.length == 1 - nodes = search(:users, "tags:tag\\:\\:*") - assert nodes.length == 1 - end - - def test_wildcards - nodes = search(:users, "gender:f??ale") - assert nodes.length == 1 - nodes = search(:users, "username:spee?y") - assert nodes.length == 1 - nodes = search(:users, "username:spee*") - assert nodes.length == 1 - end - - def test_empty_field_value - assert_raise(RuntimeError) { - search(:users, "gender:#{nil} AND age:35") - } - assert_raise(RuntimeError) { - search(:users, "gender: AND age:35") - } - assert_raise(RuntimeError) { - search(:users, "gender:\"\" AND age:35") - } - end - - def test_OR_group - nodes = search(:users, "id:(mike OR tom)") - assert nodes.length == 2 - end - - def test_nested_fieldnames - nodes = search(:users, "address_street:wilhelmsstrasse") - assert nodes.length == 1 - nodes = search(:users, "address_street_floor:1") - assert nodes.length == 1 - end -end - -module SearchNodeTests - def test_list_nodes - nodes = search(:node) - assert_equal Chef::Node, nodes.find{ |n| n["hostname"] == "alpha.example.com" }.class - assert_equal Chef::Node, nodes.find{ |n| n["hostname"] == "beta.example.com" }.class - assert_equal Hash, nodes.find{ |n| n["hostname"] == "wjc.example.com" }.class - assert_equal 3, nodes.length - end - - def test_search_node_with_wide_filter - nodes = search(:node, "role:test_server AND chef_environment:default") - assert_equal 2, nodes.length - end - - def test_search_node_with_narrow_filter - nodes = search(:node, "role:beta_server") - assert_equal 1, nodes.length - end - - def test_search_node_with_attr_filter - nodes = search(:node, "hostname:beta.example.com") - assert_equal 1, nodes.length - end - - def test_search_node_without_json_class - nodes = search(:node, "chef_environment:default") - assert_equal 3, nodes.length - end -end - -class TestImplicitSearchDB < Test::Unit::TestCase - include SearchDbTests - include SearchNodeTests - - def search(*args, &block) - # wrapper around creating a new Recipe instance and calling search on it - node = Chef::Node.new() - cookbooks = Chef::CookbookCollection.new() - run_context = Chef::RunContext.new(node, cookbooks, nil) - return Chef::Recipe.new("test_cookbook", "test_recipe", run_context).search(*args, &block) - end -end - -class TestExplicitSearchDB < Test::Unit::TestCase - include SearchDbTests - include SearchNodeTests - - def search(*args, &block) - Chef::Search::Query.new.search(*args, &block) - end -end - diff --git a/cookbooks/compat_resource/CHANGELOG.md b/cookbooks/compat_resource/CHANGELOG.md new file mode 100644 index 0000000..592b3b8 --- /dev/null +++ b/cookbooks/compat_resource/CHANGELOG.md @@ -0,0 +1,48 @@ +# compat_resource Cookbook CHANGELOG + +This file is used to list changes made in each version of the compat_resource cookbook. + +## 12.16.2 (2016-11-09) + +- Sync chef-client changes from Chef 12.16.42 + +## 12.16.1 (2016-10-20) + +- add delayed_action helper + +## 12.16.0 (2016-10-19) + +- Sync chef-client changes from Chef 12.16.14 + +## 12.14.7 (2016-09-26) + +- Update to 12.14.89 Chef +- Fix autoload by applying fix from #106 + +## 12.14.6 (2016-09-20) + +- Update backported codebase to Chef 12.14.77 which brings in yum_repository updates and why-run enabled by default in custom resources + +## 12.14.5 (2016-09-19) + +- Prevent spamming messages in Chefspec runs for cookbooks that depend on compat_resource + +## 12.14.4 (2016-09-19) + +- Fix delayed notifications cloning + +## 12.14.3 (2016-09-12) + +- Fix subscribes notifications + +## 12.14.2 (2016-09-09) + +- Improve documentation +- keep ChefCompat::Resource defined even if we don't load + +## 12.14.1 (2016-09-07) + +- add yum_repository resource from Chef 12.14 +- Update the minimum chef version in the metadata to 12.1 +- Added maintainers files +- suppress constant redef warnings when running chefspec diff --git a/cookbooks/compat_resource/CONTRIBUTING.md b/cookbooks/compat_resource/CONTRIBUTING.md new file mode 100644 index 0000000..ef2f2b8 --- /dev/null +++ b/cookbooks/compat_resource/CONTRIBUTING.md @@ -0,0 +1,2 @@ +Please refer to +https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD diff --git a/cookbooks/compat_resource/MAINTAINERS.md b/cookbooks/compat_resource/MAINTAINERS.md new file mode 100644 index 0000000..5ae0806 --- /dev/null +++ b/cookbooks/compat_resource/MAINTAINERS.md @@ -0,0 +1,16 @@ + + +# Maintainers + +This file lists how this cookbook project is maintained. When making changes to the system, this file tells you who needs to review your patch - you need a review from an existing maintainer for the cookbook to provide a :+1: on your pull request. Additionally, you need to not receive a veto from a Lieutenant or the Project Lead. + +Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) for details on the process and how to become a maintainer or the project lead. + +# Project Maintainer +* [Lamont Granquist](https://github.com/lamont-granquist) + +# Maintainers +* [Jennifer Davis](https://github.com/sigje) +* [Tim Smith](https://github.com/tas50) +* [Thom May](https://github.com/thommay) +* [Lamont Granquist](https://github.com/lamont-granquist) diff --git a/cookbooks/compat_resource/README.md b/cookbooks/compat_resource/README.md new file mode 100644 index 0000000..f5c17e5 --- /dev/null +++ b/cookbooks/compat_resource/README.md @@ -0,0 +1,60 @@ +# compat_resource cookbook + +[![Build Status](https://travis-ci.org/chef-cookbooks/compat_resource.svg?branch=master)](https://travis-ci.org/chef-cookbooks/compat_resource) [![Cookbook Version](https://img.shields.io/cookbook/v/compat_resource.svg)](https://supermarket.chef.io/cookbooks/compat_resource) + +This cookbook backports functionality introduced in the latest chef-client releases to any chef-client from 12.1 onwards. This includes [Custom Resource](https://docs.chef.io/custom_resources.html) functionality, notification improvements, as well as new resources added to core chef. It allows for the usage of these new resources in cookbooks without requiring the very latest Chef client release. + +## Backported functionality + +- [Custom Resources](https://docs.chef.io/custom_resources.html) +- [apt_repository](https://docs.chef.io/resource_apt_repository.html) +- [apt_update](https://docs.chef.io/resource_apt_update.html) +- [systemd_unit](https://docs.chef.io/resource_systemd_unit.html) +- [yum_repository](https://docs.chef.io/resource_yum_repository.html) +- [:before notifications](https://docs.chef.io/resources.html#timers) + +## Requirements + +### Platforms + +- All platforms supported by Chef + +### Chef + +- Chef 12.1+ + +### Cookbooks + +- none + +## Usage + +To use this cookbook, put `depends 'compat_resource'` in the metadata.rb of your cookbook. Once this is done, you can use all the new custom resource features to define resources. It Just Works. + +## Custom Resources? + +Curious about how to use custom resources? + +- Docs: +- Slides: + +## License & Authors + +- Author:: Lamont Granquist ([lamont@chef.io](mailto:lamont@chef.io)) +- Author:: John Keiser ([jkeiser@chef.io](mailto:jkeiser@chef.io)) + +```text +Copyright:: 2015-2016 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. +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. +``` diff --git a/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef.rb b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef.rb new file mode 100644 index 0000000..219b05b --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef.rb @@ -0,0 +1,29 @@ +module ChefCompat + module CopiedFromChef + def self.extend_chef_module(chef_module, target) + target.instance_eval do + include chef_module + @chef_module = chef_module + def self.method_missing(name, *args, &block) + @chef_module.send(name, *args, &block) + end + def self.const_missing(name) + @chef_module.const_get(name) + end + end + end + + # This patch to CopiedFromChef's ActionClass is necessary for the include to work + require 'chef/resource' + class Chef < ::Chef + class Resource < ::Chef::Resource + module ActionClass + def self.use_inline_resources + end + def self.include_resource_dsl(include_resource_dsl) + end + end + end + end + end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/constants.rb b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/constants.rb new file mode 100644 index 0000000..4acd742 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/constants.rb @@ -0,0 +1,47 @@ +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# +# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!! +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + +begin + require 'chef/constants' +rescue LoadError; end + +require 'chef_compat/copied_from_chef' +class Chef +module ::ChefCompat +module CopiedFromChef +# +# Author:: John Keiser +# Copyright:: Copyright 2015-2016, 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. + +class Chef < (defined?(::Chef) ? ::Chef : Object) + NOT_PASSED = Object.new + def NOT_PASSED.to_s + "NOT_PASSED" + end + + def NOT_PASSED.inspect + to_s + end + NOT_PASSED.freeze +end +end +end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/delayed_evaluator.rb b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/delayed_evaluator.rb new file mode 100644 index 0000000..4fb687e --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/delayed_evaluator.rb @@ -0,0 +1,40 @@ +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# +# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!! +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + +begin + require 'chef/delayed_evaluator' +rescue LoadError; end + +require 'chef_compat/copied_from_chef' +class Chef +module ::ChefCompat +module CopiedFromChef +# +# Author:: John Keiser +# Copyright:: Copyright 2015-2016, 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. + +class Chef < (defined?(::Chef) ? ::Chef : Object) + class DelayedEvaluator < (defined?(::Chef::DelayedEvaluator) ? ::Chef::DelayedEvaluator : Proc) + end +end +end +end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/dsl/core.rb b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/dsl/core.rb new file mode 100644 index 0000000..8e30d30 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/dsl/core.rb @@ -0,0 +1,73 @@ +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# +# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!! +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + +begin + require 'chef/dsl/core' +rescue LoadError; end + +require 'chef_compat/copied_from_chef' +class Chef +module ::ChefCompat +module CopiedFromChef +#-- +# Author:: Adam Jacob () +# Author:: Christopher Walters () +# Copyright:: Copyright 2008-2016 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_compat/copied_from_chef/chef/dsl/declare_resource" +require "chef_compat/copied_from_chef/chef/dsl/universal" +require "chef_compat/copied_from_chef/chef/mixin/notifying_block" +require "chef_compat/copied_from_chef/chef/mixin/lazy_module_include" + +class Chef < (defined?(::Chef) ? ::Chef : Object) + module DSL + CopiedFromChef.extend_chef_module(::Chef::DSL, self) if defined?(::Chef::DSL) + # Part of a family of DSL mixins. + # + # Chef::DSL::Recipe mixes into Recipes and LWRP Providers. + # - this does not target core chef resources and providers. + # - this is restricted to recipe/resource/provider context where a resource collection exists. + # - cookbook authors should typically include modules into here. + # + # Chef::DSL::Core mixes into Recipes, LWRP Providers and Core Providers + # - this adds cores providers on top of the Recipe DSL. + # - this is restricted to recipe/resource/provider context where a resource collection exists. + # - core chef authors should typically include modules into here. + # + # Chef::DSL::Universal mixes into Recipes, LWRP Resources+Providers, Core Resources+Providers, and Attributes files. + # - this adds resources and attributes files. + # - do not add helpers which manipulate the resource collection. + # - this is for general-purpose stuff that is useful nearly everywhere. + # - it also pollutes the namespace of nearly every context, watch out. + # + module Core + CopiedFromChef.extend_chef_module(::Chef::DSL::Core, self) if defined?(::Chef::DSL::Core) + include Chef::DSL::Universal + include Chef::DSL::DeclareResource + include Chef::Mixin::NotifyingBlock + extend Chef::Mixin::LazyModuleInclude + end + end +end +end +end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/dsl/declare_resource.rb b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/dsl/declare_resource.rb new file mode 100644 index 0000000..45e69dc --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/dsl/declare_resource.rb @@ -0,0 +1,315 @@ +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# +# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!! +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + +begin + require 'chef/dsl/declare_resource' +rescue LoadError; end + +require 'chef_compat/copied_from_chef' +class Chef +module ::ChefCompat +module CopiedFromChef +#-- +# Author:: Adam Jacob () +# Author:: Christopher Walters +# Copyright:: Copyright 2008-2016 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. +# + + +class Chef < (defined?(::Chef) ? ::Chef : Object) + module DSL + CopiedFromChef.extend_chef_module(::Chef::DSL, self) if defined?(::Chef::DSL) + module DeclareResource + CopiedFromChef.extend_chef_module(::Chef::DSL::DeclareResource, self) if defined?(::Chef::DSL::DeclareResource) + + # Helper for switching run_contexts. Allows for using :parent or :root in place of + # passing the run_context. Executes the block in the run_context. Returns the return + # value of the passed block. + # + # @param rc [Chef::RunContext,Symbol] Either :root, :parent or a Chef::RunContext + # + # @return return value of the block + # + # @example + # # creates/returns a 'service[foo]' resource in the root run_context + # resource = with_run_context(:root) + # edit_resource(:service, "foo") do + # action :nothing + # end + # end + # + def with_run_context(rc) + raise ArgumentError, "with_run_context is useless without a block" unless block_given? + old_run_context = @run_context + @run_context = + case rc + when Chef::RunContext + rc + when :root + run_context.root_run_context + when :parent + run_context.parent_run_context + else + raise ArgumentError, "bad argument to run_context helper, must be :root, :parent, or a Chef::RunContext" + end + yield + ensure + @run_context = old_run_context + end + + # Lookup a resource in the resource collection by name and delete it. This + # will raise Chef::Exceptions::ResourceNotFound if the resource is not found. + # + # @param type [Symbol] The type of resource (e.g. `:file` or `:package`) + # @param name [String] The name of the resource (e.g. '/x/y.txt' or 'apache2') + # @param run_context [Chef::RunContext] the run_context of the resource collection to operate on + # + # @return [Chef::Resource] The resource + # + # @example + # delete_resource!(:template, '/x/y.txy') + # + def delete_resource!(type, name, run_context: self.run_context) + run_context.resource_collection.delete("#{type}[#{name}]").tap do |resource| + # Purge any pending notifications too. This will not raise an exception + # if there are no notifications. + if resource + run_context.before_notification_collection.delete(resource.declared_key) + run_context.immediate_notification_collection.delete(resource.declared_key) + run_context.delayed_notification_collection.delete(resource.declared_key) + end + end + end + + # Lookup a resource in the resource collection by name and delete it. Returns + # nil if the resource is not found and should not fail. + # + # @param type [Symbol] The type of resource (e.g. `:file` or `:package`) + # @param name [String] The name of the resource (e.g. '/x/y.txt' or 'apache2') + # @param run_context [Chef::RunContext] the run_context of the resource collection to operate on + # + # @return [Chef::Resource] The resource + # + # @example + # delete_resource(:template, '/x/y.txy') + # + def delete_resource(type, name, run_context: self.run_context) + delete_resource!(type, name, run_context: run_context) + rescue Chef::Exceptions::ResourceNotFound + nil + end + + # Lookup a resource in the resource collection by name and edit the resource. If the resource is not + # found this will raise Chef::Exceptions::ResourceNotFound. This is the correct API to use for + # "chef_rewind" functionality. + # + # @param type [Symbol] The type of resource (e.g. `:file` or `:package`) + # @param name [String] The name of the resource (e.g. '/x/y.txt' or 'apache2') + # @param run_context [Chef::RunContext] the run_context of the resource collection to operate on + # @param resource_attrs_block A block that lets you set attributes of the + # resource (it is instance_eval'd on the resource instance). + # + # @return [Chef::Resource] The updated resource + # + # @example + # edit_resource!(:template, '/x/y.txy') do + # cookbook_name: cookbook_name + # end + # + def edit_resource!(type, name, created_at = nil, run_context: self.run_context, &resource_attrs_block) + resource = find_resource!(type, name, run_context: run_context) + if resource_attrs_block + if defined?(new_resource) + resource.instance_exec(new_resource, &resource_attrs_block) + else + resource.instance_exec(&resource_attrs_block) + end + end + resource + end + + # Lookup a resource in the resource collection by name. If it exists, + # return it. If it does not exist, create it. This is a useful function + # for accumulator patterns. In CRUD terminology this is an "upsert" operation and is + # used to assert that the resource must exist with the specified properties. + # + # @param type [Symbol] The type of resource (e.g. `:file` or `:package`) + # @param name [String] The name of the resource (e.g. '/x/y.txt' or 'apache2') + # @param created_at [String] The caller of the resource. Use `caller[0]` + # to get the caller of your function. Defaults to the caller of this + # function. + # @param run_context [Chef::RunContext] the run_context of the resource collection to operate on + # @param resource_attrs_block A block that lets you set attributes of the + # resource (it is instance_eval'd on the resource instance). + # + # @return [Chef::Resource] The updated or created resource + # + # @example + # resource = edit_resource(:template, '/x/y.txy') do + # source "y.txy.erb" + # variables {} + # end + # resource.variables.merge!({ home: "/home/klowns" }) + # + def edit_resource(type, name, created_at = nil, run_context: self.run_context, &resource_attrs_block) + edit_resource!(type, name, created_at, run_context: run_context, &resource_attrs_block) + rescue Chef::Exceptions::ResourceNotFound + declare_resource(type, name, created_at, run_context: run_context, &resource_attrs_block) + end + + # Lookup a resource in the resource collection by name. If the resource is not + # found this will raise Chef::Exceptions::ResourceNotFound. This API is identical to the + # resources() call and while it is a synonym it is not intended to deprecate that call. + # + # @param type [Symbol] The type of resource (e.g. `:file` or `:package`) + # @param name [String] The name of the resource (e.g. '/x/y.txt' or 'apache2') + # @param run_context [Chef::RunContext] the run_context of the resource collection to operate on + # + # @return [Chef::Resource] The updated resource + # + # @example + # resource = find_resource!(:template, '/x/y.txy') + # + def find_resource!(type, name, run_context: self.run_context) + raise ArgumentError, "find_resource! does not take a block" if block_given? + run_context.resource_collection.find(type => name) + end + + # Lookup a resource in the resource collection by name. If the resource is not found + # the will be no exception raised and the call will return nil. If a block is given and + # no resource is found it will create the resource using the block, if the resource is + # found then the block will not be applied. The block version is similar to create_if_missing + # + # @param type [Symbol] The type of resource (e.g. `:file` or `:package`) + # @param name [String] The name of the resource (e.g. '/x/y.txt' or 'apache2') + # @param run_context [Chef::RunContext] the run_context of the resource collection to operate on + # + # @return [Chef::Resource] The updated resource + # + # @example + # if ( find_resource(:template, '/x/y.txy') ) + # # do something + # else + # # don't worry about the error + # end + # + # @example + # # this API can be used to return a resource from an outer run context, and will only create + # # an action :nothing service if one does not already exist. + # resource = with_run_context(:root) do + # find_resource(:service, 'whatever') do + # action :nothing + # end + # end + # + def find_resource(type, name, created_at: nil, run_context: self.run_context, &resource_attrs_block) + find_resource!(type, name, run_context: run_context) + rescue Chef::Exceptions::ResourceNotFound + if resource_attrs_block + declare_resource(type, name, created_at, run_context: run_context, &resource_attrs_block) + end # returns nil otherwise + end + + # Instantiates a resource (via #build_resource), then adds it to the + # resource collection. Note that resource classes are looked up directly, + # so this will create the resource you intended even if the method name + # corresponding to that resource has been overridden. + # + # @param type [Symbol] The type of resource (e.g. `:file` or `:package`) + # @param name [String] The name of the resource (e.g. '/x/y.txt' or 'apache2') + # @param created_at [String] The caller of the resource. Use `caller[0]` + # to get the caller of your function. Defaults to the caller of this + # function. + # @param run_context [Chef::RunContext] the run_context of the resource collection to operate on + # @param resource_attrs_block A block that lets you set attributes of the + # resource (it is instance_eval'd on the resource instance). + # + # @return [Chef::Resource] The new resource. + # + # @example + # declare_resource(:file, '/x/y.txy', caller[0]) do + # action :delete + # end + # # Equivalent to + # file '/x/y.txt' do + # action :delete + # end + # + def declare_resource(type, name, created_at = nil, run_context: self.run_context, create_if_missing: false, &resource_attrs_block) + created_at ||= caller[0] + + if create_if_missing + Chef::Log.deprecation "build_resource with a create_if_missing flag is deprecated, use edit_resource instead" + # midly goofy since we call edit_resource only to re-call ourselves, but that's why its deprecated... + return edit_resource(type, name, created_at, run_context: run_context, &resource_attrs_block) + end + + resource = build_resource(type, name, created_at, &resource_attrs_block) + + run_context.resource_collection.insert(resource, resource_type: type, instance_name: name) + resource + end + + # Instantiate a resource of the given +type+ with the given +name+ and + # attributes as given in the +resource_attrs_block+. + # + # The resource is NOT added to the resource collection. + # + # @param type [Symbol] The type of resource (e.g. `:file` or `:package`) + # @param name [String] The name of the resource (e.g. '/x/y.txt' or 'apache2') + # @param created_at [String] The caller of the resource. Use `caller[0]` + # to get the caller of your function. Defaults to the caller of this + # function. + # @param run_context [Chef::RunContext] the run_context of the resource collection to operate on + # @param resource_attrs_block A block that lets you set attributes of the + # resource (it is instance_eval'd on the resource instance). + # + # @return [Chef::Resource] The new resource. + # + # @example + # build_resource(:file, '/x/y.txy', caller[0]) do + # action :delete + # end + # + def build_resource(type, name, created_at = nil, run_context: self.run_context, &resource_attrs_block) + created_at ||= caller[0] + + # this needs to be lazy in order to avoid circular dependencies since ResourceBuilder + # will requires the entire provider+resolver universe + require "chef_compat/copied_from_chef/chef/resource_builder" unless defined?(Chef::ResourceBuilder) + + Chef::ResourceBuilder.new( + type: type, + name: name, + created_at: created_at, + params: @params, + run_context: run_context, + cookbook_name: cookbook_name, + recipe_name: recipe_name, + enclosing_provider: self.is_a?(Chef::Provider) ? self : nil + ).build(&resource_attrs_block) + end + end + end +end +end +end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/dsl/platform_introspection.rb b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/dsl/platform_introspection.rb new file mode 100644 index 0000000..7886000 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/dsl/platform_introspection.rb @@ -0,0 +1,292 @@ +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# +# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!! +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + +begin + require 'chef/dsl/platform_introspection' +rescue LoadError; end + +require 'chef_compat/copied_from_chef' +class Chef +module ::ChefCompat +module CopiedFromChef +# +# Author:: Adam Jacob () +# Copyright:: Copyright 2008-2016, 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. +# + +class Chef < (defined?(::Chef) ? ::Chef : Object) + module DSL + CopiedFromChef.extend_chef_module(::Chef::DSL, self) if defined?(::Chef::DSL) + + # == Chef::DSL::PlatformIntrospection + # Provides the DSL for platform-dependent switch logic, such as + # #value_for_platform. + module PlatformIntrospection + CopiedFromChef.extend_chef_module(::Chef::DSL::PlatformIntrospection, self) if defined?(::Chef::DSL::PlatformIntrospection) + + # Implementation class for determining platform dependent values + class PlatformDependentValue < (defined?(::Chef::DSL::PlatformIntrospection::PlatformDependentValue) ? ::Chef::DSL::PlatformIntrospection::PlatformDependentValue : Object) + + # Create a platform dependent value object. + # === Arguments + # platform_hash (Hash) a hash of the same structure as Chef::Platform, + # like this: + # { + # :debian => {:default => 'the value for all debian'} + # [:centos, :redhat, :fedora] => {:default => "value for all EL variants"} + # :ubuntu => { :default => "default for ubuntu", '10.04' => "value for 10.04 only"}, + # :default => "the default when nothing else matches" + # } + # * platforms can be specified as Symbols or Strings + # * multiple platforms can be grouped by using an Array as the key + # * values for platforms need to be Hashes of the form: + # {platform_version => value_for_that_version} + # * the exception to the above is the default value, which is given as + # :default => default_value + def initialize(platform_hash) +super if defined?(::Chef::DSL::PlatformIntrospection::PlatformDependentValue) + @values = {} + platform_hash.each { |platforms, value| set(platforms, value) } + end + + def value_for_node(node) + platform, version = node[:platform].to_s, node[:platform_version].to_s + # Check if we match a version constraint via Chef::VersionConstraint::Platform and Chef::Version::Platform + matched_value = match_versions(node) + if @values.key?(platform) && @values[platform].key?(version) + @values[platform][version] + elsif matched_value + matched_value + elsif @values.key?(platform) && @values[platform].key?("default") + @values[platform]["default"] + elsif @values.key?("default") + @values["default"] + else + nil + end + end + + private + + def match_versions(node) + begin + platform, version = node[:platform].to_s, node[:platform_version].to_s + return nil unless @values.key?(platform) + node_version = Chef::Version::Platform.new(version) + key_matches = [] + keys = @values[platform].keys + keys.each do |k| + begin + if Chef::VersionConstraint::Platform.new(k).include?(node_version) + key_matches << k + end + rescue Chef::Exceptions::InvalidVersionConstraint => e + Chef::Log.debug "Caught InvalidVersionConstraint. This means that a key in value_for_platform cannot be interpreted as a Chef::VersionConstraint::Platform." + Chef::Log.debug(e) + end + end + return @values[platform][version] if key_matches.include?(version) + case key_matches.length + when 0 + return nil + when 1 + return @values[platform][key_matches.first] + else + raise "Multiple matches detected for #{platform} with values #{@values}. The matches are: #{key_matches}" + end + rescue Chef::Exceptions::InvalidCookbookVersion => e + # Lets not break because someone passes a weird string like 'default' :) + Chef::Log.debug(e) + Chef::Log.debug "InvalidCookbookVersion exceptions are common and expected here: the generic constraint matcher attempted to match something which is not a constraint. Moving on to next version or constraint" + return nil + rescue Chef::Exceptions::InvalidPlatformVersion => e + Chef::Log.debug "Caught InvalidPlatformVersion, this means that Chef::Version::Platform does not know how to turn #{node_version} into an x.y.z format" + Chef::Log.debug(e) + return nil + end + end + + def set(platforms, value) + if platforms.to_s == "default" + @values["default"] = value + else + assert_valid_platform_values!(platforms, value) + Array(platforms).each { |platform| @values[platform.to_s] = normalize_keys(value) } + value + end + end + + def normalize_keys(hash) + hash.inject({}) do |h, key_value| + keys, value = *key_value + Array(keys).each do |key| + h[key.to_s] = value + end + h + end + end + + def assert_valid_platform_values!(platforms, value) + unless value.kind_of?(Hash) + msg = "platform dependent values must be specified in the format :platform => {:version => value} " + msg << "you gave a value #{value.inspect} for platform(s) #{platforms}" + raise ArgumentError, msg + end + end + end + + # Given a hash similar to the one we use for Platforms, select a value from the hash. Supports + # per platform defaults, along with a single base default. Arrays may be passed as hash keys and + # will be expanded. + # + # === Parameters + # platform_hash:: A platform-style hash. + # + # === Returns + # value:: Whatever the most specific value of the hash is. + def value_for_platform(platform_hash) + PlatformDependentValue.new(platform_hash).value_for_node(node) + end + + # Given a list of platforms, returns true if the current recipe is being run on a node with + # that platform, false otherwise. + # + # === Parameters + # args:: A list of platforms. Each platform can be in string or symbol format. + # + # === Returns + # true:: If the current platform is in the list + # false:: If the current platform is not in the list + def platform?(*args) + has_platform = false + + args.flatten.each do |platform| + has_platform = true if platform.to_s == node[:platform] + end + + has_platform + end + + # Implementation class for determining platform family dependent values + class PlatformFamilyDependentValue < (defined?(::Chef::DSL::PlatformIntrospection::PlatformFamilyDependentValue) ? ::Chef::DSL::PlatformIntrospection::PlatformFamilyDependentValue : Object) + + # Create a platform family dependent value object. + # === Arguments + # platform_family_hash (Hash) a map of platform families to values. + # like this: + # { + # :rhel => "value for all EL variants" + # :fedora => "value for fedora variants fedora and amazon" , + # [:fedora, :rhel] => "value for all known redhat variants" + # :debian => "value for debian variants including debian, ubuntu, mint" , + # :default => "the default when nothing else matches" + # } + # * platform families can be specified as Symbols or Strings + # * multiple platform families can be grouped by using an Array as the key + # * values for platform families can be any object, with no restrictions. Some examples: + # - [:stop, :start] + # - "mysql-devel" + # - { :key => "value" } + def initialize(platform_family_hash) +super if defined?(::Chef::DSL::PlatformIntrospection::PlatformFamilyDependentValue) + @values = {} + @values["default"] = nil + platform_family_hash.each { |platform_families, value| set(platform_families, value) } + end + + def value_for_node(node) + if node.key?(:platform_family) + platform_family = node[:platform_family].to_s + if @values.key?(platform_family) + @values[platform_family] + else + @values["default"] + end + else + @values["default"] + end + end + + private + + def set(platform_family, value) + if platform_family.to_s == "default" + @values["default"] = value + else + Array(platform_family).each { |family| @values[family.to_s] = value } + value + end + end + end + + # Given a hash mapping platform families to values, select a value from the hash. Supports a single + # base default if platform family is not in the map. Arrays may be passed as hash keys and will be + # expanded + # + # === Parameters + # platform_family_hash:: A hash in the form { platform_family_name => value } + # + # === Returns + # value:: Whatever the most specific value of the hash is. + def value_for_platform_family(platform_family_hash) + PlatformFamilyDependentValue.new(platform_family_hash).value_for_node(node) + end + + # Given a list of platform families, returns true if the current recipe is being run on a + # node within that platform family, false otherwise. + # + # === Parameters + # args:: A list of platform families. Each platform family can be in string or symbol format. + # + # === Returns + # true:: if the current node platform family is in the list. + # false:: if the current node platform family is not in the list. + def platform_family?(*args) + args.flatten.any? do |platform_family| + platform_family.to_s == node[:platform_family] + end + end + + # Shamelessly stolen from https://github.com/sethvargo/chef-sugar/blob/master/lib/chef/sugar/docker.rb + # Given a node object, returns whether the node is a docker container. + # + # === Parameters + # node:: [Chef::Node] The node to check. + # + # === Returns + # true:: if the current node is a docker container + # false:: if the current node is not a docker container + def docker?(node = run_context.nil? ? nil : run_context.node) + # Using "File.exist?('/.dockerinit') || File.exist?('/.dockerenv')" makes Travis sad, + # and that makes us sad too. + node && node[:virtualization] && node[:virtualization][:systems] && + node[:virtualization][:systems][:docker] && node[:virtualization][:systems][:docker] == "guest" + end + + end + end +end + +# **DEPRECATED** +# This used to be part of chef/mixin/language. Load the file to activate the deprecation code. +end +end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/dsl/recipe.rb b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/dsl/recipe.rb new file mode 100644 index 0000000..f896ec7 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/dsl/recipe.rb @@ -0,0 +1,37 @@ +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# +# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!! +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + +begin + require 'chef/dsl/recipe' +rescue LoadError; end + +require 'chef_compat/copied_from_chef' +class Chef +module ::ChefCompat +module CopiedFromChef +require "chef_compat/copied_from_chef/chef/dsl/core" +require "chef_compat/copied_from_chef/chef/mixin/lazy_module_include" +class Chef < (defined?(::Chef) ? ::Chef : Object) + module DSL + CopiedFromChef.extend_chef_module(::Chef::DSL, self) if defined?(::Chef::DSL) + module Recipe + CopiedFromChef.extend_chef_module(::Chef::DSL::Recipe, self) if defined?(::Chef::DSL::Recipe) + include Chef::DSL::Core + extend Chef::Mixin::LazyModuleInclude + module FullDSL + CopiedFromChef.extend_chef_module(::Chef::DSL::Recipe::FullDSL, self) if defined?(::Chef::DSL::Recipe::FullDSL) + include Chef::DSL::Recipe + extend Chef::Mixin::LazyModuleInclude + end + end + end +end +require "chef_compat/copied_from_chef/chef/resource" +end +end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/dsl/universal.rb b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/dsl/universal.rb new file mode 100644 index 0000000..7f529f1 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/dsl/universal.rb @@ -0,0 +1,70 @@ +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# +# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!! +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + +begin + require 'chef/dsl/universal' +rescue LoadError; end + +require 'chef_compat/copied_from_chef' +class Chef +module ::ChefCompat +module CopiedFromChef +#-- +# Author:: Adam Jacob () +# Author:: Christopher Walters () +# Copyright:: Copyright 2008-2016 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_compat/copied_from_chef/chef/dsl/platform_introspection" +require "chef_compat/copied_from_chef/chef/mixin/powershell_out" + +class Chef < (defined?(::Chef) ? ::Chef : Object) + module DSL + CopiedFromChef.extend_chef_module(::Chef::DSL, self) if defined?(::Chef::DSL) + # Part of a family of DSL mixins. + # + # Chef::DSL::Recipe mixes into Recipes and LWRP Providers. + # - this does not target core chef resources and providers. + # - this is restricted to recipe/resource/provider context where a resource collection exists. + # - cookbook authors should typically include modules into here. + # + # Chef::DSL::Core mixes into Recipes, LWRP Providers and Core Providers + # - this adds cores providers on top of the Recipe DSL. + # - this is restricted to recipe/resource/provider context where a resource collection exists. + # - core chef authors should typically include modules into here. + # + # Chef::DSL::Universal mixes into Recipes, LWRP Resources+Providers, Core Resources+Providers, and Attributes files. + # - this adds resources and attributes files. + # - do not add helpers which manipulate the resource collection. + # - this is for general-purpose stuff that is useful nearly everywhere. + # - it also pollutes the namespace of nearly every context, watch out. + # + module Universal + CopiedFromChef.extend_chef_module(::Chef::DSL::Universal, self) if defined?(::Chef::DSL::Universal) + include Chef::DSL::PlatformIntrospection + include Chef::Mixin::PowershellOut + include Chef::Mixin::ShellOut + end + end +end +end +end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/mixin/lazy_module_include.rb b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/mixin/lazy_module_include.rb new file mode 100644 index 0000000..a6b5244 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/mixin/lazy_module_include.rb @@ -0,0 +1,98 @@ +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# +# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!! +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + +begin + require 'chef/mixin/lazy_module_include' +rescue LoadError; end + +require 'chef_compat/copied_from_chef' +class Chef +module ::ChefCompat +module CopiedFromChef +# +# Copyright:: Copyright 2011-2016, 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. +# + +class Chef < (defined?(::Chef) ? ::Chef : Object) + module Mixin + CopiedFromChef.extend_chef_module(::Chef::Mixin, self) if defined?(::Chef::Mixin) + # If you have: + # + # module A + # extend LazyModuleInclude + # end + # + # module B + # include A + # end + # + # module C + # include B + # end + # + # module Monkeypatches + # def monkey + # puts "monkey!" + # end + # end + # + # A.send(:include, Monkeypatches) + # + # Then B and C and any classes that they're included in will also get the #monkey method patched into them. + # + module LazyModuleInclude + CopiedFromChef.extend_chef_module(::Chef::Mixin::LazyModuleInclude, self) if defined?(::Chef::Mixin::LazyModuleInclude) + + # Most of the magick is in this hook which creates a closure over the parent class and then builds an + # "infector" module which infects all descendants and which is responsible for updating the list of + # descendants in the parent class. + def included(klass) + super + parent_klass = self + infector = Module.new do + define_method(:included) do |subklass| + super(subklass) + subklass.extend(infector) + parent_klass.descendants.push(subklass) + end + end + klass.extend(infector) + parent_klass.descendants.push(klass) + end + + def descendants + @descendants ||= [] + end + + def include(*classes) + super + classes.each do |klass| + descendants.each do |descendant| + descendant.send(:include, klass) + end + end + end + end + end +end +end +end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/mixin/notifying_block.rb b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/mixin/notifying_block.rb new file mode 100644 index 0000000..0b90e27 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/mixin/notifying_block.rb @@ -0,0 +1,74 @@ +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# +# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!! +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + +begin + require 'chef/mixin/notifying_block' +rescue LoadError; end + +require 'chef_compat/copied_from_chef' +class Chef +module ::ChefCompat +module CopiedFromChef +#-- +# Author:: Lamont Granquist +# Copyright:: Copyright 2010-2016, 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. + +class Chef < (defined?(::Chef) ? ::Chef : Object) + module Mixin + CopiedFromChef.extend_chef_module(::Chef::Mixin, self) if defined?(::Chef::Mixin) + module NotifyingBlock + CopiedFromChef.extend_chef_module(::Chef::Mixin::NotifyingBlock, self) if defined?(::Chef::Mixin::NotifyingBlock) + + def notifying_block(&block) + begin + subcontext = subcontext_block(&block) + Chef::Runner.new(subcontext).converge + ensure + # recipes don't have a new_resource + if respond_to?(:new_resource) + if subcontext && subcontext.resource_collection.any?(&:updated?) + new_resource.updated_by_last_action(true) + end + end + end + end + + def subcontext_block(parent_context = nil, &block) + parent_context ||= @run_context + sub_run_context = parent_context.create_child + + begin + outer_run_context = @run_context + @run_context = sub_run_context + instance_eval(&block) + ensure + @run_context = outer_run_context + end + + sub_run_context + end + + end + end +end +end +end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/mixin/params_validate.rb b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/mixin/params_validate.rb new file mode 100644 index 0000000..0a16147 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/mixin/params_validate.rb @@ -0,0 +1,510 @@ +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# +# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!! +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + +begin + require 'chef/mixin/params_validate' +rescue LoadError; end + +require 'chef_compat/copied_from_chef' +class Chef +module ::ChefCompat +module CopiedFromChef +# +# Author:: Adam Jacob () +# Copyright:: Copyright 2008-2016, 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_compat/copied_from_chef/chef/constants" +require "chef_compat/copied_from_chef/chef/property" +require "chef_compat/copied_from_chef/chef/delayed_evaluator" + +class Chef < (defined?(::Chef) ? ::Chef : Object) + module Mixin + CopiedFromChef.extend_chef_module(::Chef::Mixin, self) if defined?(::Chef::Mixin) + module ParamsValidate + CopiedFromChef.extend_chef_module(::Chef::Mixin::ParamsValidate, self) if defined?(::Chef::Mixin::ParamsValidate) + # Takes a hash of options, along with a map to validate them. Returns the original + # options hash, plus any changes that might have been made (through things like setting + # default values in the validation map) + # + # For example: + # + # validate({ :one => "neat" }, { :one => { :kind_of => String }}) + # + # Would raise an exception if the value of :one above is not a kind_of? string. Valid + # map options are: + # + # @param opts [Hash] Validation opts. + # @option opts [Object,Array] :is An object, or list of + # objects, that must match the value using Ruby's `===` operator + # (`opts[:is].any? { |v| v === value }`). (See #_pv_is.) + # @option opts [Object,Array] :equal_to An object, or list + # of objects, that must be equal to the value using Ruby's `==` + # operator (`opts[:is].any? { |v| v == value }`) (See #_pv_equal_to.) + # @option opts [Regexp,Array] :regex An object, or + # list of objects, that must match the value with `regex.match(value)`. + # (See #_pv_regex) + # @option opts [Class,Array] :kind_of A class, or + # list of classes, that the value must be an instance of. (See + # #_pv_kind_of.) + # @option opts [Hash] :callbacks A hash of + # messages -> procs, all of which match the value. The proc must + # return a truthy or falsey value (true means it matches). (See + # #_pv_callbacks.) + # @option opts [Symbol,Array] :respond_to A method + # name, or list of method names, the value must respond to. (See + # #_pv_respond_to.) + # @option opts [Symbol,Array] :cannot_be A property, + # or a list of properties, that the value cannot have (such as `:nil` or + # `:empty`). The method with a questionmark at the end is called on the + # value (e.g. `value.empty?`). If the value does not have this method, + # it is considered valid (i.e. if you don't respond to `empty?` we + # assume you are not empty). (See #_pv_cannot_be.) + # @option opts [Proc] :coerce A proc which will be called to + # transform the user input to canonical form. The value is passed in, + # and the transformed value returned as output. Lazy values will *not* + # be passed to this method until after they are evaluated. Called in the + # context of the resource (meaning you can access other properties). + # (See #_pv_coerce.) (See #_pv_coerce.) + # @option opts [Boolean] :required `true` if this property + # must be present and not `nil`; `false` otherwise. This is checked + # after the resource is fully initialized. (See #_pv_required.) + # @option opts [Boolean] :name_property `true` if this + # property defaults to the same value as `name`. Equivalent to + # `default: lazy { name }`, except that #property_is_set? will + # return `true` if the property is set *or* if `name` is set. (See + # #_pv_name_property.) + # @option opts [Boolean] :name_attribute Same as `name_property`. + # @option opts [Object] :default The value this property + # will return if the user does not set one. If this is `lazy`, it will + # be run in the context of the instance (and able to access other + # properties). (See #_pv_default.) + # + def validate(opts, map) + map = map.validation_options if map.is_a?(Property) + + #-- + # validate works by taking the keys in the validation map, assuming it's a hash, and + # looking for _pv_:symbol as methods. Assuming it find them, it calls the right + # one. + #++ + raise ArgumentError, "Options must be a hash" unless opts.kind_of?(Hash) + raise ArgumentError, "Validation Map must be a hash" unless map.kind_of?(Hash) + + map.each do |key, validation| + unless key.kind_of?(Symbol) || key.kind_of?(String) + raise ArgumentError, "Validation map keys must be symbols or strings!" + end + case validation + when true + _pv_required(opts, key) + when false + true + when Hash + validation.each do |check, carg| + check_method = "_pv_#{check}" + if self.respond_to?(check_method, true) + self.send(check_method, opts, key, carg) + else + raise ArgumentError, "Validation map has unknown check: #{check}" + end + end + end + end + opts + end + + def lazy(&block) + DelayedEvaluator.new(&block) + end + + def set_or_return(symbol, value, validation) + property = SetOrReturnProperty.new(name: symbol, **validation) + property.call(self, value) + end + + private + + def explicitly_allows_nil?(key, validation) + validation.has_key?(:is) && _pv_is({ key => nil }, key, validation[:is], raise_error: false) + end + + # Return the value of a parameter, or nil if it doesn't exist. + def _pv_opts_lookup(opts, key) + if opts.has_key?(key.to_s) + opts[key.to_s] + elsif opts.has_key?(key.to_sym) + opts[key.to_sym] + else + nil + end + end + + # Raise an exception if the parameter is not found. + def _pv_required(opts, key, is_required = true, explicitly_allows_nil = false) + if is_required + return true if opts.has_key?(key.to_s) && (explicitly_allows_nil || !opts[key.to_s].nil?) + return true if opts.has_key?(key.to_sym) && (explicitly_allows_nil || !opts[key.to_sym].nil?) + raise Exceptions::ValidationFailed, "Required argument #{key.inspect} is missing!" + end + true + end + + # + # List of things values must be equal to. + # + # Uses Ruby's `==` to evaluate (equal_to == value). At least one must + # match for the value to be valid. + # + # `nil` passes this validation automatically. + # + # @return [Array,nil] List of things values must be equal to, or nil if + # equal_to is unspecified. + # + def _pv_equal_to(opts, key, to_be) + value = _pv_opts_lookup(opts, key) + unless value.nil? + to_be = Array(to_be) + to_be.each do |tb| + return true if value == tb + end + raise Exceptions::ValidationFailed, "Option #{key} must be equal to one of: #{to_be.join(", ")}! You passed #{value.inspect}." + end + end + + # + # List of things values must be instances of. + # + # Uses value.kind_of?(kind_of) to evaluate. At least one must match for + # the value to be valid. + # + # `nil` automatically passes this validation. + # + def _pv_kind_of(opts, key, to_be) + value = _pv_opts_lookup(opts, key) + unless value.nil? + to_be = Array(to_be) + to_be.each do |tb| + return true if value.kind_of?(tb) + end + raise Exceptions::ValidationFailed, "Option #{key} must be a kind of #{to_be}! You passed #{value.inspect}." + end + end + + # + # List of method names values must respond to. + # + # Uses value.respond_to?(respond_to) to evaluate. At least one must match + # for the value to be valid. + # + def _pv_respond_to(opts, key, method_name_list) + value = _pv_opts_lookup(opts, key) + unless value.nil? + Array(method_name_list).each do |method_name| + unless value.respond_to?(method_name) + raise Exceptions::ValidationFailed, "Option #{key} must have a #{method_name} method!" + end + end + end + end + + # + # List of things that must not be true about the value. + # + # Calls `value.?` All responses must be false for the value to be + # valid. + # Values which do not respond to ? are considered valid (because if + # a value doesn't respond to `:readable?`, then it probably isn't + # readable.) + # + # @example + # ```ruby + # property :x, cannot_be: [ :nil, :empty ] + # x [ 1, 2 ] #=> valid + # x 1 #=> valid + # x [] #=> invalid + # x nil #=> invalid + # ``` + # + def _pv_cannot_be(opts, key, predicate_method_base_name) + value = _pv_opts_lookup(opts, key) + if !value.nil? + Array(predicate_method_base_name).each do |method_name| + predicate_method = :"#{method_name}?" + + if value.respond_to?(predicate_method) + if value.send(predicate_method) + raise Exceptions::ValidationFailed, "Option #{key} cannot be #{predicate_method_base_name}" + end + end + end + end + end + + # + # The default value for a property. + # + # When the property is not assigned, this will be used. + # + # If this is a lazy value, it will either be passed the resource as a value, + # or if the lazy proc does not take parameters, it will be run in the + # context of the instance with instance_eval. + # + # @example + # ```ruby + # property :x, default: 10 + # ``` + # + # @example + # ```ruby + # property :x + # property :y, default: lazy { x+2 } + # ``` + # + # @example + # ```ruby + # property :x + # property :y, default: lazy { |r| r.x+2 } + # ``` + # + def _pv_default(opts, key, default_value) + value = _pv_opts_lookup(opts, key) + if value.nil? + default_value = default_value.freeze if !default_value.is_a?(DelayedEvaluator) + opts[key] = default_value + end + end + + # + # List of regexes values that must match. + # + # Uses regex.match() to evaluate. At least one must match for the value to + # be valid. + # + # `nil` passes regex validation automatically. + # + # @example + # ```ruby + # property :x, regex: [ /abc/, /xyz/ ] + # ``` + # + def _pv_regex(opts, key, regex) + value = _pv_opts_lookup(opts, key) + if !value.nil? + Array(regex).flatten.each do |r| + return true if r.match(value.to_s) + end + raise Exceptions::ValidationFailed, "Option #{key}'s value #{value} does not match regular expression #{regex.inspect}" + end + end + + # + # List of procs we pass the value to. + # + # All procs must return true for the value to be valid. If any procs do + # not return true, the key will be used for the message: `"Property x's + # value :y "`. + # + # @example + # ```ruby + # property :x, callbacks: { "is bigger than 10" => proc { |v| v <= 10 }, "is not awesome" => proc { |v| !v.awesome }} + # ``` + # + def _pv_callbacks(opts, key, callbacks) + raise ArgumentError, "Callback list must be a hash!" unless callbacks.kind_of?(Hash) + value = _pv_opts_lookup(opts, key) + if !value.nil? + callbacks.each do |message, zeproc| + unless zeproc.call(value) + raise Exceptions::ValidationFailed, "Option #{key}'s value #{value} #{message}!" + end + end + end + end + + # + # Allows a parameter to default to the value of the resource name. + # + # @example + # ```ruby + # property :x, name_property: true + # ``` + # + def _pv_name_property(opts, key, is_name_property = true) + if is_name_property + if opts[key].nil? + raise CannotValidateStaticallyError, "name_property cannot be evaluated without a resource." if self == Chef::Mixin::ParamsValidate + opts[key] = self.instance_variable_get(:"@name") + end + end + end + alias :_pv_name_attribute :_pv_name_property + + # + # List of valid things values can be. + # + # Uses Ruby's `===` to evaluate (is === value). At least one must match + # for the value to be valid. + # + # If a proc is passed, it is instance_eval'd in the resource, passed the + # value, and must return a truthy or falsey value. + # + # @example Class + # ```ruby + # property :x, String + # x 'valid' #=> valid + # x 1 #=> invalid + # x nil #=> invalid + # + # @example Value + # ```ruby + # property :x, [ :a, :b, :c, nil ] + # x :a #=> valid + # x nil #=> valid + # ``` + # + # @example Regex + # ```ruby + # property :x, /bar/ + # x 'foobar' #=> valid + # x 'foo' #=> invalid + # x nil #=> invalid + # ``` + # + # @example Proc + # ```ruby + # property :x, proc { |x| x > y } + # property :y, default: 2 + # x 3 #=> valid + # x 1 #=> invalid + # ``` + # + # @example Property + # ```ruby + # type = Property.new(is: String) + # property :x, type + # x 'foo' #=> valid + # x 1 #=> invalid + # x nil #=> invalid + # ``` + # + # @example RSpec Matcher + # ```ruby + # include RSpec::Matchers + # property :x, a_string_matching /bar/ + # x 'foobar' #=> valid + # x 'foo' #=> invalid + # x nil #=> invalid + # ``` + # + def _pv_is(opts, key, to_be, raise_error: true) + return true if !opts.has_key?(key.to_s) && !opts.has_key?(key.to_sym) + value = _pv_opts_lookup(opts, key) + to_be = [ to_be ].flatten(1) + errors = [] + passed = to_be.any? do |tb| + case tb + when Proc + raise CannotValidateStaticallyError, "is: proc { } must be evaluated once for each resource" if self == Chef::Mixin::ParamsValidate + instance_exec(value, &tb) + when Property + begin + validate(opts, { key => tb.validation_options }) + true + rescue Exceptions::ValidationFailed + # re-raise immediately if there is only one "is" so we get a better stack + raise if to_be.size == 1 + errors << $! + false + end + else + tb === value + end + end + if passed + true + else + message = "Property #{key} must be one of: #{to_be.map { |v| v.inspect }.join(", ")}! You passed #{value.inspect}." + unless errors.empty? + message << " Errors:\n#{errors.map { |m| "- #{m}" }.join("\n")}" + end + raise Exceptions::ValidationFailed, message + end + end + + # + # Method to mess with a value before it is validated and stored. + # + # Allows you to transform values into a canonical form that is easy to + # work with. + # + # This is passed the value to transform, and is run in the context of the + # instance (so it has access to other resource properties). It must return + # the value that will be stored in the instance. + # + # @example + # ```ruby + # property :x, Integer, coerce: { |v| v.to_i } + # ``` + # + def _pv_coerce(opts, key, coercer) + if opts.has_key?(key.to_s) + raise CannotValidateStaticallyError, "coerce must be evaluated for each resource." if self == Chef::Mixin::ParamsValidate + opts[key.to_s] = instance_exec(opts[key], &coercer) + elsif opts.has_key?(key.to_sym) + raise CannotValidateStaticallyError, "coerce must be evaluated for each resource." if self == Chef::Mixin::ParamsValidate + opts[key.to_sym] = instance_exec(opts[key], &coercer) + end + end + + # We allow Chef::Mixin::ParamsValidate.validate(), but we will raise an + # error if you try to do anything requiring there to be an actual resource. + # This way, you can statically validate things if you have constant validation + # (which is the norm). + extend self + + # Used by #set_or_return to avoid emitting a deprecation warning for + # "value nil" and to keep default stickiness working exactly the same + # @api private + class SetOrReturnProperty < (defined?(::Chef::Mixin::ParamsValidate::SetOrReturnProperty) ? ::Chef::Mixin::ParamsValidate::SetOrReturnProperty : Chef::Property) + def get(resource, nil_set: false) + value = super + # All values are sticky, frozen or not + if !is_set?(resource) + set_value(resource, value) + end + value + end + + def call(resource, value = NOT_PASSED) + # setting to nil does a get + if value.nil? && !explicitly_accepts_nil?(resource) + get(resource, nil_set: true) + else + super + end + end + end + end + end +end +end +end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/mixin/powershell_out.rb b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/mixin/powershell_out.rb new file mode 100644 index 0000000..b6b56f9 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/mixin/powershell_out.rb @@ -0,0 +1,117 @@ +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# +# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!! +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + +begin + require 'chef/mixin/powershell_out' +rescue LoadError; end + +require 'chef_compat/copied_from_chef' +class Chef +module ::ChefCompat +module CopiedFromChef +#-- +# Copyright:: Copyright 2015-2016, 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. + + +class Chef < (defined?(::Chef) ? ::Chef : Object) + module Mixin + CopiedFromChef.extend_chef_module(::Chef::Mixin, self) if defined?(::Chef::Mixin) + module PowershellOut + CopiedFromChef.extend_chef_module(::Chef::Mixin::PowershellOut, self) if defined?(::Chef::Mixin::PowershellOut) + include Chef::Mixin::ShellOut + include Chef::Mixin::WindowsArchitectureHelper + + # Run a command under powershell with the same API as shell_out. The + # options hash is extended to take an "architecture" flag which + # can be set to :i386 or :x86_64 to force the windows architecture. + # + # @param script [String] script to run + # @param options [Hash] options hash + # @return [Mixlib::Shellout] mixlib-shellout object + def powershell_out(*command_args) + script = command_args.first + options = command_args.last.is_a?(Hash) ? command_args.last : nil + + run_command_with_os_architecture(script, options) + end + + # Run a command under powershell with the same API as shell_out! + # (raises exceptions on errors) + # + # @param script [String] script to run + # @param options [Hash] options hash + # @return [Mixlib::Shellout] mixlib-shellout object + def powershell_out!(*command_args) + cmd = powershell_out(*command_args) + cmd.error! + cmd + end + + private + + # Helper function to run shell_out and wrap it with the correct + # flags to possibly disable WOW64 redirection (which we often need + # because chef-client runs as a 32-bit app on 64-bit windows). + # + # @param script [String] script to run + # @param options [Hash] options hash + # @return [Mixlib::Shellout] mixlib-shellout object + def run_command_with_os_architecture(script, options) + options ||= {} + options = options.dup + arch = options.delete(:architecture) + + with_os_architecture(nil, architecture: arch) do + shell_out( + build_powershell_command(script), + options + ) + end + end + + # Helper to build a powershell command around the script to run. + # + # @param script [String] script to run + # @retrurn [String] powershell command to execute + def build_powershell_command(script) + flags = [ + # Hides the copyright banner at startup. + "-NoLogo", + # Does not present an interactive prompt to the user. + "-NonInteractive", + # Does not load the Windows PowerShell profile. + "-NoProfile", + # always set the ExecutionPolicy flag + # see http://technet.microsoft.com/en-us/library/ee176961.aspx + "-ExecutionPolicy Unrestricted", + # Powershell will hang if STDIN is redirected + # http://connect.microsoft.com/PowerShell/feedback/details/572313/powershell-exe-can-hang-if-stdin-is-redirected + "-InputFormat None", + ] + + "powershell.exe #{flags.join(' ')} -Command \"#{script.gsub('"', '\"')}\"" + end + end + end +end +end +end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/mixin/properties.rb b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/mixin/properties.rb new file mode 100644 index 0000000..bdf9f7e --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/mixin/properties.rb @@ -0,0 +1,328 @@ +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# +# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!! +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + +begin + require 'chef/mixin/properties' +rescue LoadError; end + +require 'chef_compat/copied_from_chef' +class Chef +module ::ChefCompat +module CopiedFromChef +require "chef_compat/copied_from_chef/chef/delayed_evaluator" +require "chef_compat/copied_from_chef/chef/mixin/params_validate" +require "chef_compat/copied_from_chef/chef/property" + +class Chef < (defined?(::Chef) ? ::Chef : Object) + module Mixin + CopiedFromChef.extend_chef_module(::Chef::Mixin, self) if defined?(::Chef::Mixin) + module Properties + CopiedFromChef.extend_chef_module(::Chef::Mixin::Properties, self) if defined?(::Chef::Mixin::Properties) + module ClassMethods + CopiedFromChef.extend_chef_module(::Chef::Mixin::Properties::ClassMethods, self) if defined?(::Chef::Mixin::Properties::ClassMethods) + # + # The list of properties defined on this resource. + # + # Everything defined with `property` is in this list. + # + # @param include_superclass [Boolean] `true` to include properties defined + # on superclasses; `false` or `nil` to return the list of properties + # directly on this class. + # + # @return [Hash] The list of property names and types. + # + def properties(include_superclass = true) + if include_superclass + result = {} + ancestors.reverse_each { |c| result.merge!(c.properties(false)) if c.respond_to?(:properties) } + result + else + @properties ||= {} + end + end + + # + # Create a property on this resource class. + # + # If a superclass has this property, or if this property has already been + # defined by this resource, this will *override* the previous value. + # + # @param name [Symbol] The name of the property. + # @param type [Object,Array] The type(s) of this property. + # If present, this is prepended to the `is` validation option. + # @param options [Hash] Validation options. + # @option options [Object,Array] :is An object, or list of + # objects, that must match the value using Ruby's `===` operator + # (`options[:is].any? { |v| v === value }`). + # @option options [Object,Array] :equal_to An object, or list + # of objects, that must be equal to the value using Ruby's `==` + # operator (`options[:is].any? { |v| v == value }`) + # @option options [Regexp,Array] :regex An object, or + # list of objects, that must match the value with `regex.match(value)`. + # @option options [Class,Array] :kind_of A class, or + # list of classes, that the value must be an instance of. + # @option options [Hash] :callbacks A hash of + # messages -> procs, all of which match the value. The proc must + # return a truthy or falsey value (true means it matches). + # @option options [Symbol,Array] :respond_to A method + # name, or list of method names, the value must respond to. + # @option options [Symbol,Array] :cannot_be A property, + # or a list of properties, that the value cannot have (such as `:nil` or + # `:empty`). The method with a questionmark at the end is called on the + # value (e.g. `value.empty?`). If the value does not have this method, + # it is considered valid (i.e. if you don't respond to `empty?` we + # assume you are not empty). + # @option options [Proc] :coerce A proc which will be called to + # transform the user input to canonical form. The value is passed in, + # and the transformed value returned as output. Lazy values will *not* + # be passed to this method until after they are evaluated. Called in the + # context of the resource (meaning you can access other properties). + # @option options [Boolean] :required `true` if this property + # must be present; `false` otherwise. This is checked after the resource + # is fully initialized. + # @option options [Boolean] :name_property `true` if this + # property defaults to the same value as `name`. Equivalent to + # `default: lazy { name }`, except that #property_is_set? will + # return `true` if the property is set *or* if `name` is set. + # @option options [Boolean] :name_attribute Same as `name_property`. + # @option options [Object] :default The value this property + # will return if the user does not set one. If this is `lazy`, it will + # be run in the context of the instance (and able to access other + # properties). + # @option options [Boolean] :desired_state `true` if this property is + # part of desired state. Defaults to `true`. + # @option options [Boolean] :identity `true` if this property + # is part of object identity. Defaults to `false`. + # @option options [Boolean] :sensitive `true` if this property could + # contain sensitive information and whose value should be redacted + # in any resource reporting / auditing output. Defaults to `false`. + # + # @example Bare property + # property :x + # + # @example With just a type + # property :x, String + # + # @example With just options + # property :x, default: 'hi' + # + # @example With type and options + # property :x, String, default: 'hi' + # + def property(name, type = NOT_PASSED, **options) + name = name.to_sym + + options = options.inject({}) { |memo, (key, value)| memo[key.to_sym] = value; memo } + + options[:instance_variable_name] = :"@#{name}" if !options.has_key?(:instance_variable_name) + options[:name] = name + options[:declared_in] = self + + if type == NOT_PASSED + # If a type is not passed, the property derives from the + # superclass property (if any) + if properties.has_key?(name) + property = properties[name].derive(**options) + else + property = property_type(**options) + end + + # If a Property is specified, derive a new one from that. + elsif type.is_a?(Property) || (type.is_a?(Class) && type <= Property) + property = type.derive(**options) + + # If a primitive type was passed, combine it with "is" + else + if options[:is] + options[:is] = ([ type ] + [ options[:is] ]).flatten(1) + else + options[:is] = type + end + property = property_type(**options) + end + + local_properties = properties(false) + local_properties[name] = property + + property.emit_dsl + end + + # + # Create a reusable property type that can be used in multiple properties + # in different resources. + # + # @param options [Hash] Validation options. see #property for + # the list of options. + # + # @example + # property_type(default: 'hi') + # + def property_type(**options) + Property.derive(**options) + end + + # + # Create a lazy value for assignment to a default value. + # + # @param block The block to run when the value is retrieved. + # + # @return [Chef::DelayedEvaluator] The lazy value + # + def lazy(&block) + DelayedEvaluator.new(&block) + end + + # + # Get or set the list of desired state properties for this resource. + # + # State properties are properties that describe the desired state + # of the system, such as file permissions or ownership. + # In general, state properties are properties that could be populated by + # examining the state of the system (e.g., File.stat can tell you the + # permissions on an existing file). Contrarily, properties that are not + # "state properties" usually modify the way Chef itself behaves, for example + # by providing additional options for a package manager to use when + # installing a package. + # + # This list is used by the Chef client auditing system to extract + # information from resources to describe changes made to the system. + # + # This method is unnecessary when declaring properties with `property`; + # properties are added to state_properties by default, and can be turned off + # with `desired_state: false`. + # + # ```ruby + # property :x # part of desired state + # property :y, desired_state: false # not part of desired state + # ``` + # + # @param names [Array] A list of property names to set as desired + # state. + # + # @return [Array] All properties in desired state. + # + def state_properties(*names) + if !names.empty? + names = names.map { |name| name.to_sym }.uniq + + local_properties = properties(false) + # Add new properties to the list. + names.each do |name| + property = properties[name] + if !property + self.property name, instance_variable_name: false, desired_state: true + elsif !property.desired_state? + self.property name, desired_state: true + end + end + + # If state_attrs *excludes* something which is currently desired state, + # mark it as desired_state: false. + local_properties.each do |name, property| + if property.desired_state? && !names.include?(name) + self.property name, desired_state: false + end + end + end + + properties.values.select { |property| property.desired_state? } + end + + # + # Set the identity of this resource to a particular set of properties. + # + # This drives #identity, which returns data that uniquely refers to a given + # resource on the given node (in such a way that it can be correlated + # across Chef runs). + # + # This method is unnecessary when declaring properties with `property`; + # properties can be added to identity during declaration with + # `identity: true`. + # + # ```ruby + # property :x, identity: true # part of identity + # property :y # not part of identity + # ``` + # + # If no properties are marked as identity, "name" is considered the identity. + # + # @param names [Array] A list of property names to set as the identity. + # + # @return [Array] All identity properties. + # + def identity_properties(*names) + if !names.empty? + names = names.map { |name| name.to_sym } + + # Add or change properties that are not part of the identity. + names.each do |name| + property = properties[name] + if !property + self.property name, instance_variable_name: false, identity: true + elsif !property.identity? + self.property name, identity: true + end + end + + # If identity_properties *excludes* something which is currently part of + # the identity, mark it as identity: false. + properties.each do |name, property| + if property.identity? && !names.include?(name) + + self.property name, identity: false + end + end + end + + result = properties.values.select { |property| property.identity? } + result = [ properties[:name] ] if result.empty? + result + end + + def included(other) + other.extend ClassMethods + end + end + + def self.included(other) + other.extend ClassMethods + end + + include Chef::Mixin::ParamsValidate + + # + # Whether this property has been set (or whether it has a default that has + # been retrieved). + # + # @param name [Symbol] The name of the property. + # @return [Boolean] `true` if the property has been set. + # + def property_is_set?(name) + property = self.class.properties[name.to_sym] + raise ArgumentError, "Property #{name} is not defined in class #{self}" if !property + property.is_set?(self) + end + + # + # Clear this property as if it had never been set. It will thereafter return + # the default. + # been retrieved). + # + # @param name [Symbol] The name of the property. + # + def reset_property(name) + property = self.class.properties[name.to_sym] + raise ArgumentError, "Property #{name} is not defined in class #{self}" if !property + property.reset(self) + end + end + end +end +end +end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/property.rb b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/property.rb new file mode 100644 index 0000000..3399596 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/property.rb @@ -0,0 +1,713 @@ +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# +# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!! +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + +begin + require 'chef/property' +rescue LoadError; end + +require 'chef_compat/copied_from_chef' +class Chef +module ::ChefCompat +module CopiedFromChef +# +# Author:: John Keiser +# Copyright:: Copyright 2015-2016, John Keiser. +# 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_compat/copied_from_chef/chef/delayed_evaluator" + +class Chef < (defined?(::Chef) ? ::Chef : Object) + # + # Type and validation information for a property on a resource. + # + # A property named "x" manipulates the "@x" instance variable on a + # resource. The *presence* of the variable (`instance_variable_defined?(@x)`) + # tells whether the variable is defined; it may have any actual value, + # constrained only by validation. + # + # Properties may have validation, defaults, and coercion, and have full + # support for lazy values. + # + # @see Chef::Resource.property + # @see Chef::DelayedEvaluator + # + class Property < (defined?(::Chef::Property) ? ::Chef::Property : Object) + # + # Create a reusable property type that can be used in multiple properties + # in different resources. + # + # @param options [Hash] Validation options. See Chef::Resource.property for + # the list of options. + # + # @example + # Property.derive(default: 'hi') + # + def self.derive(**options) + new(**options) + end + + # + # Create a new property. + # + # @param options [Hash] Property options, including + # control options here, as well as validation options (see + # Chef::Mixin::ParamsValidate#validate for a description of validation + # options). + # @option options [Symbol] :name The name of this property. + # @option options [Class] :declared_in The class this property comes from. + # @option options [Symbol] :instance_variable_name The instance variable + # tied to this property. Must include a leading `@`. Defaults to `@`. + # `nil` means the property is opaque and not tied to a specific instance + # variable. + # @option options [Boolean] :desired_state `true` if this property is part of desired + # state. Defaults to `true`. + # @option options [Boolean] :identity `true` if this property is part of object + # identity. Defaults to `false`. + # @option options [Boolean] :name_property `true` if this + # property defaults to the same value as `name`. Equivalent to + # `default: lazy { name }`, except that #property_is_set? will + # return `true` if the property is set *or* if `name` is set. + # @option options [Boolean] :nillable `true` opt-in to Chef-13 style behavior where + # attempting to set a nil value will really set a nil value instead of issuing + # a warning and operating like a getter + # @option options [Object] :default The value this property + # will return if the user does not set one. If this is `lazy`, it will + # be run in the context of the instance (and able to access other + # properties) and cached. If not, the value will be frozen with Object#freeze + # to prevent users from modifying it in an instance. + # @option options [Proc] :coerce A proc which will be called to + # transform the user input to canonical form. The value is passed in, + # and the transformed value returned as output. Lazy values will *not* + # be passed to this method until after they are evaluated. Called in the + # context of the resource (meaning you can access other properties). + # @option options [Boolean] :required `true` if this property + # must be present; `false` otherwise. This is checked after the resource + # is fully initialized. + # + def initialize(**options) +super if defined?(::Chef::Property) + options = options.inject({}) { |memo, (key, value)| memo[key.to_sym] = value; memo } + @options = options + options[:name] = options[:name].to_sym if options[:name] + options[:instance_variable_name] = options[:instance_variable_name].to_sym if options[:instance_variable_name] + + # Replace name_attribute with name_property + if options.has_key?(:name_attribute) + # If we have both name_attribute and name_property and they differ, raise an error + if options.has_key?(:name_property) + raise ArgumentError, "Cannot specify both name_property and name_attribute together on property #{self}." + end + # replace name_property with name_attribute in place + options = Hash[options.map { |k, v| k == :name_attribute ? [ :name_property, v ] : [ k, v ] }] + @options = options + end + + # Only pick the first of :default, :name_property and :name_attribute if + # more than one is specified. + if options.has_key?(:default) && options[:name_property] + if options[:default].nil? || options.keys.index(:name_property) < options.keys.index(:default) + options.delete(:default) + preferred_default = :name_property + else + options.delete(:name_property) + preferred_default = :default + end + Chef.log_deprecation("Cannot specify both default and name_property together on property #{self}. Only one (#{preferred_default}) will be obeyed. In Chef 13, this will become an error. Please remove one or the other from the property.") + end + + # Validate the default early, so the user gets a good error message, and + # cache it so we don't do it again if so + begin + # If we can validate it all the way to output, do it. + @stored_default = input_to_stored_value(nil, default, is_default: true) + rescue Chef::Exceptions::CannotValidateStaticallyError + # If the validation is not static (i.e. has procs), we will have to + # coerce and validate the default each time we run + end + end + + def to_s + "#{name || ""}#{declared_in ? " of resource #{declared_in.resource_name}" : ""}" + end + + # + # The name of this property. + # + # @return [String] + # + def name + options[:name] + end + + # + # The class this property was defined in. + # + # @return [Class] + # + def declared_in + options[:declared_in] + end + + # + # The instance variable associated with this property. + # + # Defaults to `@` + # + # @return [Symbol] + # + def instance_variable_name + if options.has_key?(:instance_variable_name) + options[:instance_variable_name] + elsif name + :"@#{name}" + end + end + + # + # The raw default value for this resource. + # + # Does not coerce or validate the default. Does not evaluate lazy values. + # + # Defaults to `lazy { name }` if name_property is true; otherwise defaults to + # `nil` + # + def default + return options[:default] if options.has_key?(:default) + return Chef::DelayedEvaluator.new { name } if name_property? + nil + end + + # + # Whether this is part of the resource's natural identity or not. + # + # @return [Boolean] + # + def identity? + options[:identity] + end + + # + # Whether this is part of desired state or not. + # + # Defaults to true. + # + # @return [Boolean] + # + def desired_state? + return true if !options.has_key?(:desired_state) + options[:desired_state] + end + + # + # Whether this is name_property or not. + # + # @return [Boolean] + # + def name_property? + options[:name_property] + end + + # + # Whether this property has a default value. + # + # @return [Boolean] + # + def has_default? + options.has_key?(:default) || name_property? + end + + # + # Whether this property is required or not. + # + # @return [Boolean] + # + def required? + options[:required] + end + + # + # Whether this property is sensitive or not. + # + # Defaults to false. + # + # @return [Boolean] + # + def sensitive? + options.fetch(:sensitive, false) + end + + # + # Validation options. (See Chef::Mixin::ParamsValidate#validate.) + # + # @return [Hash] + # + def validation_options + @validation_options ||= options.reject do |k, v| + [:declared_in, :name, :instance_variable_name, :desired_state, :identity, :default, :name_property, :coerce, :required, :nillable, :sensitive].include?(k) + end + end + + # + # Handle the property being called. + # + # The base implementation does the property get-or-set: + # + # ```ruby + # resource.myprop # get + # resource.myprop value # set + # ``` + # + # Subclasses may implement this with any arguments they want, as long as + # the corresponding DSL calls it correctly. + # + # @param resource [Chef::Resource] The resource to get the property from. + # @param value The value to set (or NOT_PASSED if it is a get). + # + # @return The current value of the property. If it is a `set`, lazy values + # will be returned without running, validating or coercing. If it is a + # `get`, the non-lazy, coerced, validated value will always be returned. + # + def call(resource, value = NOT_PASSED) + if value == NOT_PASSED + return get(resource) + end + + if value.nil? && !nillable? + # In Chef 12, value(nil) does a *get* instead of a set, so we + # warn if the value would have been changed. In Chef 13, it will be + # equivalent to value = nil. + result = get(resource, nil_set: true) + + # Warn about this becoming a set in Chef 13. + begin + input_to_stored_value(resource, value) + # If nil is valid, and it would change the value, warn that this will change to a set. + if !result.nil? + Chef.log_deprecation("An attempt was made to change #{name} from #{result.inspect} to nil by calling #{name}(nil). In Chef 12, this does a get rather than a set. In Chef 13, this will change to set the value to nil.") + end + rescue Chef::Exceptions::DeprecatedFeatureError + raise + rescue + # If nil is invalid, warn that this will become an error. + Chef.log_deprecation("nil is an invalid value for #{self}. In Chef 13, this warning will change to an error. Error: #{$!}") + end + + result + else + # Anything else, such as myprop(value) is a set + set(resource, value) + end + end + + # + # Get the property value from the resource, handling lazy values, + # defaults, and validation. + # + # - If the property's value is lazy, it is evaluated, coerced and validated. + # - If the property has no value, and is required, raises ValidationFailed. + # - If the property has no value, but has a lazy default, it is evaluated, + # coerced and validated. If the evaluated value is frozen, the resulting + # - If the property has no value, but has a default, the default value + # will be returned and frozen. If the default value is lazy, it will be + # evaluated, coerced and validated, and the result stored in the property. + # - If the property has no value, but is name_property, `resource.name` + # is retrieved, coerced, validated and stored in the property. + # - Otherwise, `nil` is returned. + # + # @param resource [Chef::Resource] The resource to get the property from. + # + # @return The value of the property. + # + # @raise Chef::Exceptions::ValidationFailed If the value is invalid for + # this property, or if the value is required and not set. + # + def get(resource, nil_set: false) + # If it's set, return it (and evaluate any lazy values) + if is_set?(resource) + value = get_value(resource) + value = stored_value_to_output(resource, value) + + else + # We are getting the default value. + + # If the user does something like this: + # + # ``` + # class MyResource < Chef::Resource + # property :content + # action :create do + # file '/x.txt' do + # content content + # end + # end + # end + # ``` + # + # It won't do what they expect. This checks whether you try to *read* + # `content` while we are compiling the resource. + if !nil_set && + resource.respond_to?(:resource_initializing) && + resource.resource_initializing && + resource.respond_to?(:enclosing_provider) && + resource.enclosing_provider && + resource.enclosing_provider.new_resource && + resource.enclosing_provider.new_resource.respond_to?(name) + Chef::Log.warn("#{Chef::Log.caller_location}: property #{name} is declared in both #{resource} and #{resource.enclosing_provider}. Use new_resource.#{name} instead. At #{Chef::Log.caller_location}") + end + + if has_default? + # If we were able to cache the stored_default, grab it. + if defined?(@stored_default) + value = @stored_default + else + # Otherwise, we have to validate it now. + value = input_to_stored_value(resource, default, is_default: true) + end + value = stored_value_to_output(resource, value, is_default: true) + + # If the value is mutable (non-frozen), we set it on the instance + # so that people can mutate it. (All constant default values are + # frozen.) + if !value.frozen? && !value.nil? + set_value(resource, value) + end + + value + + elsif required? + raise Chef::Exceptions::ValidationFailed, "#{name} is required" + end + end + end + + # + # Set the value of this property in the given resource. + # + # Non-lazy values are coerced and validated before being set. Coercion + # and validation of lazy values is delayed until they are first retrieved. + # + # @param resource [Chef::Resource] The resource to set this property in. + # @param value The value to set. + # + # @return The value that was set, after coercion (if lazy, still returns + # the lazy value) + # + # @raise Chef::Exceptions::ValidationFailed If the value is invalid for + # this property. + # + def set(resource, value) + set_value(resource, input_to_stored_value(resource, value)) + end + + # + # Find out whether this property has been set. + # + # This will be true if: + # - The user explicitly set the value + # - The property has a default, and the value was retrieved. + # + # From this point of view, it is worth looking at this as "what does the + # user think this value should be." In order words, if the user grabbed + # the value, even if it was a default, they probably based calculations on + # it. If they based calculations on it and the value changes, the rest of + # the world gets inconsistent. + # + # @param resource [Chef::Resource] The resource to get the property from. + # + # @return [Boolean] + # + def is_set?(resource) + value_is_set?(resource) + end + + # + # Reset the value of this property so that is_set? will return false and the + # default will be returned in the future. + # + # @param resource [Chef::Resource] The resource to get the property from. + # + def reset(resource) + reset_value(resource) + end + + # + # Coerce an input value into canonical form for the property. + # + # After coercion, the value is suitable for storage in the resource. + # You must validate values after coercion, however. + # + # Does no special handling for lazy values. + # + # @param resource [Chef::Resource] The resource we're coercing against + # (to provide context for the coerce). + # @param value The value to coerce. + # + # @return The coerced value. + # + # @raise Chef::Exceptions::ValidationFailed If the value is invalid for + # this property. + # + def coerce(resource, value) + if options.has_key?(:coerce) + # If we have no default value, `nil` is never coerced or validated + unless !has_default? && value.nil? + value = exec_in_resource(resource, options[:coerce], value) + end + end + value + end + + # + # Validate a value. + # + # Calls Chef::Mixin::ParamsValidate#validate with #validation_options as + # options. + # + # @param resource [Chef::Resource] The resource we're validating against + # (to provide context for the validate). + # @param value The value to validate. + # + # @raise Chef::Exceptions::ValidationFailed If the value is invalid for + # this property. + # + def validate(resource, value) + # If we have no default value, `nil` is never coerced or validated + unless value.nil? && !has_default? + if resource + resource.validate({ name => value }, { name => validation_options }) + else + name = self.name || :property_type + Chef::Mixin::ParamsValidate.validate({ name => value }, { name => validation_options }) + end + end + end + + # + # Derive a new Property that is just like this one, except with some added or + # changed options. + # + # @param options [Hash] List of options that would be passed + # to #initialize. + # + # @return [Property] The new property type. + # + def derive(**modified_options) + # Since name_property, name_attribute and default override each other, + # if you specify one of them in modified_options it overrides anything in + # the original options. + options = self.options + if modified_options.has_key?(:name_property) || + modified_options.has_key?(:name_attribute) || + modified_options.has_key?(:default) + options = options.reject { |k, v| k == :name_attribute || k == :name_property || k == :default } + end + self.class.new(options.merge(modified_options)) + end + + # + # Emit the DSL for this property into the resource class (`declared_in`). + # + # Creates a getter and setter for the property. + # + def emit_dsl + # We don't create the getter/setter if it's a custom property; we will + # be using the existing getter/setter to manipulate it instead. + return if !instance_variable_name + + # We prefer this form because the property name won't show up in the + # stack trace if you use `define_method`. + declared_in.class_eval <<-EOM, __FILE__, __LINE__ + 1 + def #{name}(value=NOT_PASSED) + raise "Property `#{name}` of `\#{self}` was incorrectly passed a block. Possible property-resource collision. To call a resource named `#{name}` either rename the property or else use `declare_resource(:#{name}, ...)`" if block_given? + self.class.properties[#{name.inspect}].call(self, value) + end + def #{name}=(value) + raise "Property `#{name}` of `\#{self}` was incorrectly passed a block. Possible property-resource collision. To call a resource named `#{name}` either rename the property or else use `declare_resource(:#{name}, ...)`" if block_given? + self.class.properties[#{name.inspect}].set(self, value) + end + EOM + rescue SyntaxError + # If the name is not a valid ruby name, we use define_method. + declared_in.define_method(name) do |value = NOT_PASSED, &block| + raise "Property `#{name}` of `#{self}` was incorrectly passed a block! Possible property-resource collision. To call a resource named `#{name}` either rename the property or else use `declare_resource(:#{name}, ...)`" if block + self.class.properties[name].call(self, value) + end + declared_in.define_method("#{name}=") do |value, &block| + raise "Property `#{name}` of `#{self}` was incorrectly passed a block! Possible property-resource collision. To call a resource named `#{name}` either rename the property or else use `declare_resource(:#{name}, ...)`" if block + self.class.properties[name].set(self, value) + end + end + + # + # The options this Property will use for get/set behavior and validation. + # + # @see #initialize for a list of valid options. + # + attr_reader :options + + # + # Find out whether this type accepts nil explicitly. + # + # A type accepts nil explicitly if "is" allows nil, it validates as nil, *and* is not simply + # an empty type. + # + # A type is presumed to accept nil if it does coercion (which must handle nil). + # + # These examples accept nil explicitly: + # ```ruby + # property :a, [ String, nil ] + # property :a, [ String, NilClass ] + # property :a, [ String, proc { |v| v.nil? } ] + # ``` + # + # This does not (because the "is" doesn't exist or doesn't have nil): + # + # ```ruby + # property :x, String + # ``` + # + # These do not, even though nil would validate fine (because they do not + # have "is"): + # + # ```ruby + # property :a + # property :a, equal_to: [ 1, 2, 3, nil ] + # property :a, kind_of: [ String, NilClass ] + # property :a, respond_to: [ ] + # property :a, callbacks: { "a" => proc { |v| v.nil? } } + # ``` + # + # @param resource [Chef::Resource] The resource we're coercing against + # (to provide context for the coerce). + # + # @return [Boolean] Whether this value explicitly accepts nil. + # + # @api private + def explicitly_accepts_nil?(resource) + options.has_key?(:coerce) || + (options.has_key?(:is) && resource.send(:_pv_is, { name => nil }, name, options[:is], raise_error: false)) + end + + # @api private + def get_value(resource) + if instance_variable_name + resource.instance_variable_get(instance_variable_name) + else + resource.send(name) + end + end + + # @api private + def set_value(resource, value) + if instance_variable_name + resource.instance_variable_set(instance_variable_name, value) + else + resource.send(name, value) + end + end + + # @api private + def value_is_set?(resource) + if instance_variable_name + resource.instance_variable_defined?(instance_variable_name) + else + true + end + end + + # @api private + def reset_value(resource) + if instance_variable_name + if value_is_set?(resource) + resource.remove_instance_variable(instance_variable_name) + end + else + raise ArgumentError, "Property #{name} has no instance variable defined and cannot be reset" + end + end + + private + + def exec_in_resource(resource, proc, *args) + if resource + if proc.arity > args.size + value = proc.call(resource, *args) + else + value = resource.instance_exec(*args, &proc) + end + else + # If we don't have a resource yet, we can't exec in resource! + raise Chef::Exceptions::CannotValidateStaticallyError, "Cannot validate or coerce without a resource" + end + end + + def input_to_stored_value(resource, value, is_default: false) + unless value.is_a?(DelayedEvaluator) + value = coerce_and_validate(resource, value, is_default: is_default) + end + value + end + + def stored_value_to_output(resource, value, is_default: false) + # Crack open lazy values before giving the result to the user + if value.is_a?(DelayedEvaluator) + value = exec_in_resource(resource, value) + value = coerce_and_validate(resource, value, is_default: is_default) + end + value + end + + # Coerces and validates the value. If the value is a default, it will warn + # the user that invalid defaults are bad mmkay, and return it as if it were + # valid. + def coerce_and_validate(resource, value, is_default: false) + result = coerce(resource, value) + begin + # If the input is from a default, we need to emit an invalid default warning on validate. + validate(resource, result) + rescue Chef::Exceptions::CannotValidateStaticallyError + # This one gets re-raised + raise + rescue + # Anything else is just an invalid default: in those cases, we just + # warn and return the (possibly coerced) value to the user. + if is_default + if value.nil? + Chef.log_deprecation("Default value nil is invalid for property #{self}. Possible fixes: 1. Remove 'default: nil' if nil means 'undefined'. 2. Set a valid default value if there is a reasonable one. 3. Allow nil as a valid value of your property (for example, 'property #{name.inspect}, [ String, nil ], default: nil'). Error: #{$!}") + else + Chef.log_deprecation("Default value #{value.inspect} is invalid for property #{self}. In Chef 13 this will become an error: #{$!}.") + end + else + raise + end + end + + result + end + + def nillable? + !!options[:nillable] + end + end +end +end +end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/provider.rb b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/provider.rb new file mode 100644 index 0000000..7ccf87b --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/provider.rb @@ -0,0 +1,164 @@ +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# +# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!! +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + +begin + require 'chef/provider' +rescue LoadError; end + +require 'chef_compat/copied_from_chef' +class Chef +module ::ChefCompat +module CopiedFromChef +require "chef_compat/copied_from_chef/chef/dsl/core" +class Chef < (defined?(::Chef) ? ::Chef : Object) + class Provider < (defined?(::Chef::Provider) ? ::Chef::Provider : Object) + include Chef::DSL::Core + attr_accessor :action + def initialize(new_resource, run_context) +super if defined?(::Chef::Provider) + @new_resource = new_resource + @action = action + @current_resource = nil + @run_context = run_context + @converge_actions = nil + + @recipe_name = nil + @cookbook_name = nil + self.class.include_resource_dsl_module(new_resource) + end + def converge_if_changed(*properties, &converge_block) + if !converge_block + raise ArgumentError, "converge_if_changed must be passed a block!" + end + + properties = new_resource.class.state_properties.map { |p| p.name } if properties.empty? + properties = properties.map { |p| p.to_sym } + if current_resource + # Collect the list of modified properties + specified_properties = properties.select { |property| new_resource.property_is_set?(property) } + modified = specified_properties.select { |p| new_resource.send(p) != current_resource.send(p) } + if modified.empty? + properties_str = if sensitive + specified_properties.join(", ") + else + specified_properties.map { |p| "#{p}=#{new_resource.send(p).inspect}" }.join(", ") + end + Chef::Log.debug("Skipping update of #{new_resource}: has not changed any of the specified properties #{properties_str}.") + return false + end + + # Print the pretty green text and run the block + property_size = modified.map { |p| p.size }.max + modified.map! do |p| + properties_str = if sensitive + "(suppressed sensitive property)" + else + "#{new_resource.send(p).inspect} (was #{current_resource.send(p).inspect})" + end + " set #{p.to_s.ljust(property_size)} to #{properties_str}" + end + converge_by([ "update #{current_resource.identity}" ] + modified, &converge_block) + + else + # The resource doesn't exist. Mark that we are *creating* this, and + # write down any properties we are setting. + property_size = properties.map { |p| p.size }.max + created = properties.map do |property| + default = " (default value)" unless new_resource.property_is_set?(property) + properties_str = if sensitive + "(suppressed sensitive property)" + else + new_resource.send(property).inspect + end + " set #{property.to_s.ljust(property_size)} to #{properties_str}#{default}" + end + + converge_by([ "create #{new_resource.identity}" ] + created, &converge_block) + end + true + end + def self.include_resource_dsl(include_resource_dsl) + @include_resource_dsl = include_resource_dsl + end + def self.include_resource_dsl_module(resource) + if @include_resource_dsl && !defined?(@included_resource_dsl_module) + provider_class = self + @included_resource_dsl_module = Module.new do + extend Forwardable + define_singleton_method(:to_s) { "forwarder module for #{provider_class}" } + define_singleton_method(:inspect) { to_s } + # Add a delegator for each explicit property that will get the *current* value + # of the property by default instead of the *actual* value. + resource.class.properties.each do |name, property| + class_eval(<<-EOM, __FILE__, __LINE__) + def #{name}(*args, &block) + # If no arguments were passed, we process "get" by defaulting + # the value to current_resource, not new_resource. This helps + # avoid issues where resources accidentally overwrite perfectly + # valid stuff with default values. + if args.empty? && !block + if !new_resource.property_is_set?(__method__) && current_resource + return current_resource.public_send(__method__) + end + end + new_resource.public_send(__method__, *args, &block) + end + EOM + end + dsl_methods = + resource.class.public_instance_methods + + resource.class.protected_instance_methods - + provider_class.instance_methods - + resource.class.properties.keys + def_delegators(:new_resource, *dsl_methods) + end + include @included_resource_dsl_module + end + end + def self.use_inline_resources + extend InlineResources::ClassMethods + include InlineResources + end + module InlineResources + CopiedFromChef.extend_chef_module(::Chef::Provider::InlineResources, self) if defined?(::Chef::Provider::InlineResources) + def compile_and_converge_action(&block) + old_run_context = run_context + @run_context = run_context.create_child + return_value = instance_eval(&block) + Chef::Runner.new(run_context).converge + return_value + ensure + if run_context.resource_collection.any? { |r| r.updated? } + new_resource.updated_by_last_action(true) + end + @run_context = old_run_context + end + module ClassMethods + CopiedFromChef.extend_chef_module(::Chef::Provider::InlineResources::ClassMethods, self) if defined?(::Chef::Provider::InlineResources::ClassMethods) + def action(name, &block) + # We need the block directly in a method so that `super` works + define_method("compile_action_#{name}", &block) + # We try hard to use `def` because define_method doesn't show the method name in the stack. + begin + class_eval <<-EOM + def action_#{name} + compile_and_converge_action { compile_action_#{name} } + end + EOM + rescue SyntaxError + define_method("action_#{name}") { send("compile_action_#{name}") } + end + end + end + end + protected + end +end +end +end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/provider/apt_repository.rb b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/provider/apt_repository.rb new file mode 100644 index 0000000..ccc07c4 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/provider/apt_repository.rb @@ -0,0 +1,269 @@ +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# +# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!! +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + +begin + require 'chef/provider/apt_repository' +rescue LoadError; end + +require 'chef_compat/copied_from_chef' +class Chef +module ::ChefCompat +module CopiedFromChef +# +# Author:: Thom May () +# Copyright:: Copyright (c) 2016 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_compat/copied_from_chef/chef/resource" +require "chef_compat/copied_from_chef/chef/dsl/declare_resource" +require "chef_compat/copied_from_chef/chef/provider/noop" + +class Chef < (defined?(::Chef) ? ::Chef : Object) + class Provider < (defined?(::Chef::Provider) ? ::Chef::Provider : Object) + class AptRepository < (defined?(::Chef::Provider::AptRepository) ? ::Chef::Provider::AptRepository : Chef::Provider) + use_inline_resources + + include Chef::Mixin::ShellOut + extend Chef::Mixin::Which + + provides :apt_repository do + which("apt-get") + end + + def whyrun_supported? + true + end + + def load_current_resource + end + + action :add do + unless new_resource.key.nil? + if is_key_id?(new_resource.key) && !has_cookbook_file?(new_resource.key) + install_key_from_keyserver + else + install_key_from_uri + end + end + + declare_resource(:execute, "apt-cache gencaches") do + ignore_failure true + action :nothing + end + + declare_resource(:apt_update, new_resource.name) do + ignore_failure true + action :nothing + end + + components = if is_ppa_url?(new_resource.uri) && new_resource.components.empty? + "main" + else + new_resource.components + end + + repo = build_repo( + new_resource.uri, + new_resource.distribution, + components, + new_resource.trusted, + new_resource.arch, + new_resource.deb_src + ) + + declare_resource(:file, "/etc/apt/sources.list.d/#{new_resource.name}.list") do + owner "root" + group "root" + mode "0644" + content repo + sensitive new_resource.sensitive + action :create + notifies :run, "execute[apt-cache gencaches]", :immediately + notifies :update, "apt_update[#{new_resource.name}]", :immediately if new_resource.cache_rebuild + end + end + + action :remove do + if ::File.exist?("/etc/apt/sources.list.d/#{new_resource.name}.list") + converge_by "Removing #{new_resource.name} repository from /etc/apt/sources.list.d/" do + declare_resource(:file, "/etc/apt/sources.list.d/#{new_resource.name}.list") do + sensitive new_resource.sensitive + action :delete + notifies :update, "apt_update[#{new_resource.name}]", :immediately if new_resource.cache_rebuild + end + + declare_resource(:apt_update, new_resource.name) do + ignore_failure true + action :nothing + end + + end + end + end + + def is_key_id?(id) + id = id[2..-1] if id.start_with?("0x") + id =~ /^\h+$/ && [8, 16, 40].include?(id.length) + end + + def extract_fingerprints_from_cmd(cmd) + so = shell_out(cmd) + so.run_command + so.stdout.split(/\n/).map do |t| + if z = t.match(/^ +Key fingerprint = ([0-9A-F ]+)/) + z[1].split.join + end + end.compact + end + + def key_is_valid?(cmd, key) + valid = true + + so = shell_out(cmd) + so.run_command + so.stdout.split(/\n/).map do |t| + if t =~ %r{^\/#{key}.*\[expired: .*\]$} + Chef::Log.debug "Found expired key: #{t}" + valid = false + break + end + end + + Chef::Log.debug "key #{key} #{valid ? "is valid" : "is not valid"}" + valid + end + + def cookbook_name + new_resource.cookbook || new_resource.cookbook_name + end + + def has_cookbook_file?(fn) + run_context.has_cookbook_file_in_cookbook?(cookbook_name, fn) + end + + def no_new_keys?(file) + installed_keys = extract_fingerprints_from_cmd("apt-key finger") + proposed_keys = extract_fingerprints_from_cmd("gpg --with-fingerprint #{file}") + (installed_keys & proposed_keys).sort == proposed_keys.sort + end + + def install_key_from_uri + key_name = new_resource.key.gsub(/[^0-9A-Za-z\-]/, "_") + cached_keyfile = ::File.join(Chef::Config[:file_cache_path], key_name) + type = if new_resource.key.start_with?("http") + :remote_file + elsif has_cookbook_file?(new_resource.key) + :cookbook_file + else + raise Chef::Exceptions::FileNotFound, "Cannot locate key file" + end + + declare_resource(type, cached_keyfile) do + source new_resource.key + mode "0644" + sensitive new_resource.sensitive + action :create + end + + raise "The key #{cached_keyfile} is invalid and cannot be used to verify an apt repository." unless key_is_valid?("gpg #{cached_keyfile}", "") + + declare_resource(:execute, "apt-key add #{cached_keyfile}") do + sensitive new_resource.sensitive + action :run + not_if do + no_new_keys?(cached_keyfile) + end + notifies :run, "execute[apt-cache gencaches]", :immediately + end + end + + def install_key_from_keyserver(key = new_resource.key, keyserver = new_resource.keyserver) + cmd = "apt-key adv --recv" + cmd << " --keyserver-options http-proxy=#{new_resource.key_proxy}" if new_resource.key_proxy + cmd << " --keyserver " + cmd << if keyserver.start_with?("hkp://") + keyserver + else + "hkp://#{keyserver}:80" + end + + cmd << " #{key}" + + declare_resource(:execute, "install-key #{key}") do + command cmd + sensitive new_resource.sensitive + not_if do + present = extract_fingerprints_from_cmd("apt-key finger").any? do |fp| + fp.end_with? key.upcase + end + present && key_is_valid?("apt-key list", key.upcase) + end + notifies :run, "execute[apt-cache gencaches]", :immediately + end + + raise "The key #{key} is invalid and cannot be used to verify an apt repository." unless key_is_valid?("apt-key list", key.upcase) + end + + def install_ppa_key(owner, repo) + url = "https://launchpad.net/api/1.0/~#{owner}/+archive/#{repo}" + key_id = Chef::HTTP::Simple.new(url).get("signing_key_fingerprint").delete('"') + install_key_from_keyserver(key_id, "keyserver.ubuntu.com") + rescue Net::HTTPServerException => e + raise "Could not access Launchpad ppa API: #{e.message}" + end + + def is_ppa_url?(url) + url.start_with?("ppa:") + end + + def make_ppa_url(ppa) + return unless is_ppa_url?(ppa) + owner, repo = ppa[4..-1].split("/") + repo ||= "ppa" + + install_ppa_key(owner, repo) + "http://ppa.launchpad.net/#{owner}/#{repo}/ubuntu" + end + + def build_repo(uri, distribution, components, trusted, arch, add_src = false) + uri = make_ppa_url(uri) if is_ppa_url?(uri) + + uri = '"' + uri + '"' unless uri.start_with?("'", '"') + components = Array(components).join(" ") + options = [] + options << "arch=#{arch}" if arch + options << "trusted=yes" if trusted + optstr = unless options.empty? + "[" + options.join(" ") + "]" + end + info = [ optstr, uri, distribution, components ].compact.join(" ") + repo = "deb #{info}\n" + repo << "deb-src #{info}\n" if add_src + repo + end + end + end +end + +Chef::Provider::Noop.provides :apt_repository +end +end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/provider/apt_update.rb b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/provider/apt_update.rb new file mode 100644 index 0000000..677cb57 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/provider/apt_update.rb @@ -0,0 +1,105 @@ +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# +# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!! +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + +begin + require 'chef/provider/apt_update' +rescue LoadError; end + +require 'chef_compat/copied_from_chef' +class Chef +module ::ChefCompat +module CopiedFromChef +# +# Author:: Thom May () +# Copyright:: Copyright (c) 2016 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_compat/copied_from_chef/chef/provider" +require "chef_compat/copied_from_chef/chef/provider/noop" + +class Chef < (defined?(::Chef) ? ::Chef : Object) + class Provider < (defined?(::Chef::Provider) ? ::Chef::Provider : Object) + class AptUpdate < (defined?(::Chef::Provider::AptUpdate) ? ::Chef::Provider::AptUpdate : Chef::Provider) + use_inline_resources + + extend Chef::Mixin::Which + + provides :apt_update do + which("apt-get") + end + + APT_CONF_DIR = "/etc/apt/apt.conf.d" + STAMP_DIR = "/var/lib/apt/periodic" + + def whyrun_supported? + true + end + + def load_current_resource + end + + action :periodic do + if !apt_up_to_date? + converge_by "update new lists of packages" do + do_update + end + end + end + + action :update do + converge_by "force update new lists of packages" do + do_update + end + end + + private + + # Determines whether we need to run `apt-get update` + # + # @return [Boolean] + def apt_up_to_date? + ::File.exist?("#{STAMP_DIR}/update-success-stamp") && + ::File.mtime("#{STAMP_DIR}/update-success-stamp") > Time.now - new_resource.frequency + end + + def do_update + [STAMP_DIR, APT_CONF_DIR].each do |d| + declare_resource(:directory, d) do + recursive true + end + end + + declare_resource(:file, "#{APT_CONF_DIR}/15update-stamp") do + content "APT::Update::Post-Invoke-Success {\"touch #{STAMP_DIR}/update-success-stamp 2>/dev/null || true\";};\n" + action :create_if_missing + end + + declare_resource(:execute, "apt-get -q update") + end + + end + end +end + +Chef::Provider::Noop.provides :apt_update +end +end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/provider/noop.rb b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/provider/noop.rb new file mode 100644 index 0000000..87c34e6 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/provider/noop.rb @@ -0,0 +1,56 @@ +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# +# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!! +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + +begin + require 'chef/provider/noop' +rescue LoadError; end + +require 'chef_compat/copied_from_chef' +class Chef +module ::ChefCompat +module CopiedFromChef +# +# Author:: Thom May () +# Copyright:: Copyright (c) 2016 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. +# + +class Chef < (defined?(::Chef) ? ::Chef : Object) + class Provider < (defined?(::Chef::Provider) ? ::Chef::Provider : Object) + class Noop < (defined?(::Chef::Provider::Noop) ? ::Chef::Provider::Noop : Chef::Provider) + def load_current_resource; end + + def respond_to_missing?(method_sym, include_private = false) + method_sym.to_s.start_with?("action_") || super + end + + def method_missing(method_sym, *arguments, &block) + if method_sym.to_s =~ /^action_/ + Chef::Log.debug("NoOp-ing for #{method_sym}") + else + super + end + end + end + end +end +end +end +end diff --git a/cookbooks/yum/templates/default/repo.erb b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/provider/support/yum_repo.erb similarity index 100% rename from cookbooks/yum/templates/default/repo.erb rename to cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/provider/support/yum_repo.erb diff --git a/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/provider/systemd_unit.rb b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/provider/systemd_unit.rb new file mode 100644 index 0000000..1024cb8 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/provider/systemd_unit.rb @@ -0,0 +1,253 @@ +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# +# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!! +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + +begin + require 'chef/provider/systemd_unit' +rescue LoadError; end + +require 'chef_compat/copied_from_chef' +class Chef +module ::ChefCompat +module CopiedFromChef +# +# Author:: Nathan Williams () +# Copyright:: Copyright 2016, Nathan Williams +# 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_compat/copied_from_chef/chef/provider" + +class Chef < (defined?(::Chef) ? ::Chef : Object) + class Provider < (defined?(::Chef::Provider) ? ::Chef::Provider : Object) + class SystemdUnit < (defined?(::Chef::Provider::SystemdUnit) ? ::Chef::Provider::SystemdUnit : Chef::Provider) + include Chef::Mixin::Which + include Chef::Mixin::ShellOut + + provides :systemd_unit, os: "linux" + + def load_current_resource + @current_resource = Chef::Resource::SystemdUnit.new(new_resource.name) + + current_resource.content(::File.read(unit_path)) if ::File.exist?(unit_path) + current_resource.user(new_resource.user) + current_resource.enabled(enabled?) + current_resource.active(active?) + current_resource.masked(masked?) + current_resource.static(static?) + current_resource.triggers_reload(new_resource.triggers_reload) + + current_resource + end + + def define_resource_requirements + super + + requirements.assert(:create) do |a| + a.assertion { IniParse.parse(new_resource.to_ini) } + a.failure_message "Unit content is not valid INI text" + end + end + + def action_create + if current_resource.content != new_resource.to_ini + converge_by("creating unit: #{new_resource.name}") do + manage_unit_file(:create) + daemon_reload if new_resource.triggers_reload + end + end + end + + def action_delete + if ::File.exist?(unit_path) + converge_by("deleting unit: #{new_resource.name}") do + manage_unit_file(:delete) + daemon_reload if new_resource.triggers_reload + end + end + end + + def action_enable + if current_resource.static + Chef::Log.debug("#{new_resource.name} is a static unit, enabling is a NOP.") + end + + unless current_resource.enabled || current_resource.static + converge_by("enabling unit: #{new_resource.name}") do + systemctl_execute!(:enable, new_resource.name) + end + end + end + + def action_disable + if current_resource.static + Chef::Log.debug("#{new_resource.name} is a static unit, disabling is a NOP.") + end + + if current_resource.enabled && !current_resource.static + converge_by("disabling unit: #{new_resource.name}") do + systemctl_execute!(:disable, new_resource.name) + end + end + end + + def action_mask + unless current_resource.masked + converge_by("masking unit: #{new_resource.name}") do + systemctl_execute!(:mask, new_resource.name) + end + end + end + + def action_unmask + if current_resource.masked + converge_by("unmasking unit: #{new_resource.name}") do + systemctl_execute!(:unmask, new_resource.name) + end + end + end + + def action_start + unless current_resource.active + converge_by("starting unit: #{new_resource.name}") do + systemctl_execute!(:start, new_resource.name) + end + end + end + + def action_stop + if current_resource.active + converge_by("stopping unit: #{new_resource.name}") do + systemctl_execute!(:stop, new_resource.name) + end + end + end + + def action_restart + converge_by("restarting unit: #{new_resource.name}") do + systemctl_execute!(:restart, new_resource.name) + end + end + + def action_reload + if current_resource.active + converge_by("reloading unit: #{new_resource.name}") do + systemctl_execute!(:reload, new_resource.name) + end + else + Chef::Log.debug("#{new_resource.name} is not active, skipping reload.") + end + end + + def action_try_restart + converge_by("try-restarting unit: #{new_resource.name}") do + systemctl_execute!("try-restart", new_resource.name) + end + end + + def action_reload_or_restart + converge_by("reload-or-restarting unit: #{new_resource.name}") do + systemctl_execute!("reload-or-restart", new_resource.name) + end + end + + def action_reload_or_try_restart + converge_by("reload-or-try-restarting unit: #{new_resource.name}") do + systemctl_execute!("reload-or-try-restart", new_resource.name) + end + end + + def active? + systemctl_execute("is-active", new_resource.name).exitstatus == 0 + end + + def enabled? + systemctl_execute("is-enabled", new_resource.name).exitstatus == 0 + end + + def masked? + systemctl_execute(:status, new_resource.name).stdout.include?("masked") + end + + def static? + systemctl_execute("is-enabled", new_resource.name).stdout.include?("static") + end + + private + + def unit_path + if new_resource.user + "/etc/systemd/user/#{new_resource.name}" + else + "/etc/systemd/system/#{new_resource.name}" + end + end + + def manage_unit_file(action = :nothing) + Chef::Resource::File.new(unit_path, run_context).tap do |f| + f.owner "root" + f.group "root" + f.mode "0644" + f.content new_resource.to_ini + end.run_action(action) + end + + def daemon_reload + shell_out_with_systems_locale!("#{systemctl_path} daemon-reload") + end + + def systemctl_execute!(action, unit) + shell_out_with_systems_locale!("#{systemctl_cmd} #{action} #{unit}", systemctl_opts) + end + + def systemctl_execute(action, unit) + shell_out("#{systemctl_cmd} #{action} #{unit}", systemctl_opts) + end + + def systemctl_cmd + @systemctl_cmd ||= "#{systemctl_path} #{systemctl_args}" + end + + def systemctl_path + @systemctl_path ||= which("systemctl") + end + + def systemctl_args + @systemctl_args ||= new_resource.user ? "--user" : "--system" + end + + def systemctl_opts + @systemctl_opts ||= + if new_resource.user + { + :user => new_resource.user, + :environment => { + "DBUS_SESSION_BUS_ADDRESS" => "unix:path=/run/user/#{node['etc']['passwd'][new_resource.user]['uid']}/bus", + }, + } + else + {} + end + end + end + end +end +end +end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/provider/yum_repository.rb b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/provider/yum_repository.rb new file mode 100644 index 0000000..bfe415e --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/provider/yum_repository.rb @@ -0,0 +1,137 @@ +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# +# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!! +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + +begin + require 'chef/provider/yum_repository' +rescue LoadError; end + +require 'chef_compat/copied_from_chef' +class Chef +module ::ChefCompat +module CopiedFromChef +# +# Author:: Thom May () +# Copyright:: Copyright (c) 2016 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_compat/copied_from_chef/chef/resource" +require "chef_compat/copied_from_chef/chef/dsl/declare_resource" +require "chef_compat/copied_from_chef/chef/provider/noop" + +class Chef < (defined?(::Chef) ? ::Chef : Object) + class Provider < (defined?(::Chef::Provider) ? ::Chef::Provider : Object) + class YumRepository < (defined?(::Chef::Provider::YumRepository) ? ::Chef::Provider::YumRepository : Chef::Provider) + use_inline_resources + + extend Chef::Mixin::Which + + provides :yum_repository do + which "yum" + end + + def whyrun_supported?; true; end + + def load_current_resource; end + + action :create do + declare_resource(:template, "/etc/yum.repos.d/#{new_resource.repositoryid}.repo") do + if template_available?(new_resource.source) + source new_resource.source + else + source ::File.expand_path("../support/yum_repo.erb", __FILE__) + local true + end + sensitive new_resource.sensitive + variables(config: new_resource) + mode new_resource.mode + if new_resource.make_cache + notifies :run, "execute[yum clean metadata #{new_resource.repositoryid}]", :immediately if new_resource.clean_metadata || new_resource.clean_headers + notifies :run, "execute[yum-makecache-#{new_resource.repositoryid}]", :immediately + notifies :create, "ruby_block[yum-cache-reload-#{new_resource.repositoryid}]", :immediately + end + end + + declare_resource(:execute, "yum clean metadata #{new_resource.repositoryid}") do + command "yum clean metadata --disablerepo=* --enablerepo=#{new_resource.repositoryid}" + action :nothing + end + + # get the metadata for this repo only + declare_resource(:execute, "yum-makecache-#{new_resource.repositoryid}") do + command "yum -q -y makecache --disablerepo=* --enablerepo=#{new_resource.repositoryid}" + action :nothing + only_if { new_resource.enabled } + end + + # reload internal Chef yum cache + declare_resource(:ruby_block, "yum-cache-reload-#{new_resource.repositoryid}") do + block { Chef::Provider::Package::Yum::YumCache.instance.reload } + action :nothing + end + end + + action :delete do + declare_resource(:file, "/etc/yum.repos.d/#{new_resource.repositoryid}.repo") do + action :delete + notifies :run, "execute[yum clean all #{new_resource.repositoryid}]", :immediately + notifies :create, "ruby_block[yum-cache-reload-#{new_resource.repositoryid}]", :immediately + end + + declare_resource(:execute, "yum clean all #{new_resource.repositoryid}") do + command "yum clean all --disablerepo=* --enablerepo=#{new_resource.repositoryid}" + only_if "yum repolist | grep -P '^#{new_resource.repositoryid}([ \t]|$)'" + action :nothing + end + + declare_resource(:ruby_block, "yum-cache-reload-#{new_resource.repositoryid}") do + block { Chef::Provider::Package::Yum::YumCache.instance.reload } + action :nothing + end + end + + action :makecache do + declare_resource(:execute, "yum-makecache-#{new_resource.repositoryid}") do + command "yum -q -y makecache --disablerepo=* --enablerepo=#{new_resource.repositoryid}" + action :run + only_if { new_resource.enabled } + end + + declare_resource(:ruby_block, "yum-cache-reload-#{new_resource.repositoryid}") do + block { Chef::Provider::Package::Yum::YumCache.instance.reload } + action :run + end + end + + alias_method :action_add, :action_create + alias_method :action_remove, :action_delete + + def template_available?(path) + !path.nil? && run_context.has_template_in_cookbook?(new_resource.cookbook_name, path) + end + + end + end +end + +Chef::Provider::Noop.provides :yum_repository +end +end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/resource.rb b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/resource.rb new file mode 100644 index 0000000..e5c9a14 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/resource.rb @@ -0,0 +1,214 @@ +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# +# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!! +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + +begin + require 'chef/resource' +rescue LoadError; end + +require 'chef_compat/copied_from_chef' +class Chef +module ::ChefCompat +module CopiedFromChef +require "chef_compat/copied_from_chef/chef/resource/action_class" +require "chef_compat/copied_from_chef/chef/provider" +require "chef_compat/copied_from_chef/chef/mixin/properties" +require "chef_compat/copied_from_chef/chef/dsl/universal" +class Chef < (defined?(::Chef) ? ::Chef : Object) + class Resource < (defined?(::Chef::Resource) ? ::Chef::Resource : Object) + include Chef::Mixin::Properties + property :name, String, coerce: proc { |v| v.is_a?(Array) ? v.join(", ") : v.to_s }, desired_state: false + def initialize(name, run_context = nil) +super if defined?(::Chef::Resource) + name(name) unless name.nil? + @run_context = run_context + @noop = nil + @before = nil + @params = Hash.new + @provider = nil + @allowed_actions = self.class.allowed_actions.to_a + @action = self.class.default_action + @updated = false + @updated_by_last_action = false + @supports = {} + @ignore_failure = false + @retries = 0 + @retry_delay = 2 + @not_if = [] + @only_if = [] + @source_line = nil + # We would like to raise an error when the user gives us a guard + # interpreter and a ruby_block to the guard. In order to achieve this + # we need to understand when the user overrides the default guard + # interpreter. Therefore we store the default separately in a different + # attribute. + @guard_interpreter = nil + @default_guard_interpreter = :default + @elapsed_time = 0 + @sensitive = false + end + def action(arg = nil) + if arg + arg = Array(arg).map(&:to_sym) + arg.each do |action| + validate( + { action: action }, + { action: { kind_of: Symbol, equal_to: allowed_actions } } + ) + end + @action = arg + else + @action + end + end + alias_method :action=, :action + class UnresolvedSubscribes < (defined?(::Chef::Resource::UnresolvedSubscribes) ? ::Chef::Resource::UnresolvedSubscribes : self) + alias_method :to_s, :name + alias_method :declared_key, :name + end + def state_for_resource_reporter + state = {} + state_properties = self.class.state_properties + state_properties.each do |property| + if property.identity? || property.is_set?(self) + state[property.name] = property.sensitive? ? "*sensitive value suppressed*" : send(property.name) + end + end + state + end + alias_method :state, :state_for_resource_reporter + def identity + result = {} + identity_properties = self.class.identity_properties + identity_properties.each do |property| + result[property.name] = send(property.name) + end + return result.values.first if identity_properties.size == 1 + result + end + attr_reader :resource_initializing + def resource_initializing=(value) + if value + @resource_initializing = true + else + remove_instance_variable(:@resource_initializing) + end + end + def to_hash + # Grab all current state, then any other ivars (backcompat) + result = {} + self.class.state_properties.each do |p| + result[p.name] = p.get(self) + end + safe_ivars = instance_variables.map { |ivar| ivar.to_sym } - FORBIDDEN_IVARS + safe_ivars.each do |iv| + key = iv.to_s.sub(/^@/, "").to_sym + next if result.has_key?(key) + result[key] = instance_variable_get(iv) + end + result + end + def self.identity_property(name = nil) + result = identity_properties(*Array(name)) + if result.size > 1 + raise Chef::Exceptions::MultipleIdentityError, "identity_property cannot be called on an object with more than one identity property (#{result.map { |r| r.name }.join(", ")})." + end + result.first + end + attr_accessor :allowed_actions + def allowed_actions(value = NOT_PASSED) + if value != NOT_PASSED + self.allowed_actions = value + end + @allowed_actions + end + def resource_name + @resource_name || self.class.resource_name + end + def self.use_automatic_resource_name + automatic_name = convert_to_snake_case(self.name.split("::")[-1]) + resource_name automatic_name + end + def self.allowed_actions(*actions) + @allowed_actions ||= + if superclass.respond_to?(:allowed_actions) + superclass.allowed_actions.dup + else + [ :nothing ] + end + @allowed_actions |= actions.flatten + end + def self.allowed_actions=(value) + @allowed_actions = value.uniq + end + def self.default_action(action_name = NOT_PASSED) + unless action_name.equal?(NOT_PASSED) + @default_action = Array(action_name).map(&:to_sym) + self.allowed_actions |= @default_action + end + + if @default_action + @default_action + elsif superclass.respond_to?(:default_action) + superclass.default_action + else + [:nothing] + end + end + def self.default_action=(action_name) + default_action action_name + end + def self.action(action, &recipe_block) + action = action.to_sym + declare_action_class + action_class.action(action, &recipe_block) + self.allowed_actions += [ action ] + default_action action if Array(default_action) == [:nothing] + end + def self.load_current_value(&load_block) + define_method(:load_current_value!, &load_block) + end + def current_value_does_not_exist! + raise Chef::Exceptions::CurrentValueDoesNotExist + end + def self.action_class(&block) + return @action_class if @action_class && !block + # If the superclass needed one, then we need one as well. + if block || (superclass.respond_to?(:action_class) && superclass.action_class) + @action_class = declare_action_class(&block) + end + @action_class + end + def self.declare_action_class(&block) + @action_class ||= begin + if superclass.respond_to?(:action_class) + base_provider = superclass.action_class + end + base_provider ||= Chef::Provider + + resource_class = self + Class.new(base_provider) do + include ActionClass + self.resource_class = resource_class + end + end + @action_class.class_eval(&block) if block + @action_class + end + FORBIDDEN_IVARS = [:@run_context, :@not_if, :@only_if, :@enclosing_provider] + HIDDEN_IVARS = [:@allowed_actions, :@resource_name, :@source_line, :@run_context, :@name, :@not_if, :@only_if, :@elapsed_time, :@enclosing_provider] + class << self + end + @@sorted_descendants = nil + module DeprecatedLWRPClass + CopiedFromChef.extend_chef_module(::Chef::Resource::DeprecatedLWRPClass, self) if defined?(::Chef::Resource::DeprecatedLWRPClass) + end + end +end +end +end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/resource/action_class.rb b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/resource/action_class.rb new file mode 100644 index 0000000..20ff8e5 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/resource/action_class.rb @@ -0,0 +1,114 @@ +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# +# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!! +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + +begin + require 'chef/resource/action_class' +rescue LoadError; end + +require 'chef_compat/copied_from_chef' +class Chef +module ::ChefCompat +module CopiedFromChef +# +# Author:: John Keiser ("} action #{action ? action.inspect : ""}" + end + + def whyrun_supported? + true + end + + # + # If load_current_value! is defined on the resource, use that. + # + def load_current_resource + if new_resource.respond_to?(:load_current_value!) + # dup the resource and then reset desired-state properties. + current_resource = new_resource.dup + + # We clear desired state in the copy, because it is supposed to be actual state. + # We keep identity properties and non-desired-state, which are assumed to be + # "control" values like `recurse: true` + current_resource.class.properties.each do |name, property| + if property.desired_state? && !property.identity? && !property.name_property? + property.reset(current_resource) + end + end + + # Call the actual load_current_value! method. If it raises + # CurrentValueDoesNotExist, set current_resource to `nil`. + begin + # If the user specifies load_current_value do |desired_resource|, we + # pass in the desired resource as well as the current one. + if current_resource.method(:load_current_value!).arity > 0 + current_resource.load_current_value!(new_resource) + else + current_resource.load_current_value! + end + rescue Chef::Exceptions::CurrentValueDoesNotExist + current_resource = nil + end + end + + @current_resource = current_resource + end + + def self.included(other) + other.extend(ClassMethods) + other.use_inline_resources + other.include_resource_dsl true + end + + module ClassMethods + CopiedFromChef.extend_chef_module(::Chef::Resource::ActionClass::ClassMethods, self) if defined?(::Chef::Resource::ActionClass::ClassMethods) + # + # The Chef::Resource class this ActionClass was declared against. + # + # @return [Class] The Chef::Resource class this ActionClass was declared against. + # + attr_accessor :resource_class + + def to_s + "#{resource_class} action provider" + end + + def inspect + to_s + end + end + end + end +end +end +end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/resource/apt_repository.rb b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/resource/apt_repository.rb new file mode 100644 index 0000000..1580fad --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/resource/apt_repository.rb @@ -0,0 +1,66 @@ +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# +# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!! +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + +begin + require 'chef/resource/apt_repository' +rescue LoadError; end + +require 'chef_compat/copied_from_chef' +class Chef +module ::ChefCompat +module CopiedFromChef +# +# Author:: Thom May () +# Copyright:: Copyright (c) 2016 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_compat/copied_from_chef/chef/resource" + +class Chef < (defined?(::Chef) ? ::Chef : Object) + class Resource < (defined?(::Chef::Resource) ? ::Chef::Resource : Object) + class AptRepository < (defined?(::Chef::Resource::AptRepository) ? ::Chef::Resource::AptRepository : Chef::Resource) + resource_name :apt_repository + provides :apt_repository + + property :repo_name, String, name_property: true + property :uri, String + property :distribution, [ String, nil, false ], default: lazy { node["lsb"]["codename"] }, nillable: true, coerce: proc { |x| x ? x : nil } + property :components, Array, default: [] + property :arch, [String, nil, false], default: nil, nillable: true, coerce: proc { |x| x ? x : nil } + property :trusted, [TrueClass, FalseClass], default: false + # whether or not to add the repository as a source repo, too + property :deb_src, [TrueClass, FalseClass], default: false + property :keyserver, [String, nil, false], default: "keyserver.ubuntu.com", nillable: true, coerce: proc { |x| x ? x : nil } + property :key, [String, nil, false], default: nil, nillable: true, coerce: proc { |x| x ? x : nil } + property :key_proxy, [String, nil, false], default: nil, nillable: true, coerce: proc { |x| x ? x : nil } + + property :cookbook, [String, nil, false], default: nil, desired_state: false, nillable: true, coerce: proc { |x| x ? x : nil } + property :cache_rebuild, [TrueClass, FalseClass], default: true, desired_state: false + property :sensitive, [TrueClass, FalseClass], default: false, desired_state: false + + default_action :add + allowed_actions :add, :remove + end + end +end +end +end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/resource/apt_update.rb b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/resource/apt_update.rb new file mode 100644 index 0000000..31f5dc3 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/resource/apt_update.rb @@ -0,0 +1,52 @@ +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# +# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!! +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + +begin + require 'chef/resource/apt_update' +rescue LoadError; end + +require 'chef_compat/copied_from_chef' +class Chef +module ::ChefCompat +module CopiedFromChef +# +# Author:: Thom May () +# Copyright:: Copyright (c) 2016 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_compat/copied_from_chef/chef/resource" + +class Chef < (defined?(::Chef) ? ::Chef : Object) + class Resource < (defined?(::Chef::Resource) ? ::Chef::Resource : Object) + class AptUpdate < (defined?(::Chef::Resource::AptUpdate) ? ::Chef::Resource::AptUpdate : Chef::Resource) + resource_name :apt_update + provides :apt_update, os: "linux" + + property :frequency, Integer, default: 86_400 + + default_action :periodic + allowed_actions :update, :periodic + end + end +end +end +end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/resource/systemd_unit.rb b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/resource/systemd_unit.rb new file mode 100644 index 0000000..5f9f458 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/resource/systemd_unit.rb @@ -0,0 +1,81 @@ +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# +# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!! +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + +begin + require 'chef/resource/systemd_unit' +rescue LoadError; end + +require 'chef_compat/copied_from_chef' +class Chef +module ::ChefCompat +module CopiedFromChef +# +# Author:: Nathan Williams () +# Copyright:: Copyright 2016, Nathan Williams +# 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_compat/copied_from_chef/chef/resource" + +class Chef < (defined?(::Chef) ? ::Chef : Object) + class Resource < (defined?(::Chef::Resource) ? ::Chef::Resource : Object) + class SystemdUnit < (defined?(::Chef::Resource::SystemdUnit) ? ::Chef::Resource::SystemdUnit : Chef::Resource) + resource_name :systemd_unit + + default_action :nothing + allowed_actions :create, :delete, + :enable, :disable, + :mask, :unmask, + :start, :stop, + :restart, :reload, + :try_restart, :reload_or_restart, + :reload_or_try_restart + + property :enabled, [TrueClass, FalseClass] + property :active, [TrueClass, FalseClass] + property :masked, [TrueClass, FalseClass] + property :static, [TrueClass, FalseClass] + property :user, String, desired_state: false + property :content, [String, Hash] + property :triggers_reload, [TrueClass, FalseClass], + default: true, desired_state: false + + def to_ini + case content + when Hash + IniParse.gen do |doc| + content.each_pair do |sect, opts| + doc.section(sect) do |section| + opts.each_pair do |opt, val| + section.option(opt, val) + end + end + end + end.to_s + else + content.to_s + end + end + end + end +end +end +end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/resource/yum_repository.rb b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/resource/yum_repository.rb new file mode 100644 index 0000000..e733daa --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/resource/yum_repository.rb @@ -0,0 +1,98 @@ +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# +# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!! +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + +begin + require 'chef/resource/yum_repository' +rescue LoadError; end + +require 'chef_compat/copied_from_chef' +class Chef +module ::ChefCompat +module CopiedFromChef +# +# Author:: Thom May () +# Copyright:: Copyright (c) 2016 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_compat/copied_from_chef/chef/resource" + +class Chef < (defined?(::Chef) ? ::Chef : Object) + class Resource < (defined?(::Chef::Resource) ? ::Chef::Resource : Object) + class YumRepository < (defined?(::Chef::Resource::YumRepository) ? ::Chef::Resource::YumRepository : Chef::Resource) + resource_name :yum_repository + provides :yum_repository + + # http://linux.die.net/man/5/yum.conf + property :baseurl, String, regex: /.*/ + property :cost, String, regex: /^\d+$/ + property :clean_headers, [TrueClass, FalseClass], default: false # deprecated + property :clean_metadata, [TrueClass, FalseClass], default: true + property :description, String, regex: /.*/, default: "Yum Repository" + property :enabled, [TrueClass, FalseClass], default: true + property :enablegroups, [TrueClass, FalseClass] + property :exclude, String, regex: /.*/ + property :failovermethod, String, equal_to: %w{priority roundrobin} + property :fastestmirror_enabled, [TrueClass, FalseClass] + property :gpgcheck, [TrueClass, FalseClass], default: true + property :gpgkey, [String, Array], regex: /.*/ + property :http_caching, String, equal_to: %w{packages all none} + property :include_config, String, regex: /.*/ + property :includepkgs, String, regex: /.*/ + property :keepalive, [TrueClass, FalseClass] + property :make_cache, [TrueClass, FalseClass], default: true + property :max_retries, [String, Integer] + property :metadata_expire, String, regex: [/^\d+$/, /^\d+[mhd]$/, /never/] + property :mirrorexpire, String, regex: /.*/ + property :mirrorlist, String, regex: /.*/ + property :mirror_expire, String, regex: [/^\d+$/, /^\d+[mhd]$/] + property :mirrorlist_expire, String, regex: [/^\d+$/, /^\d+[mhd]$/] + property :mode, default: "0644" + property :priority, String, regex: /^(\d?[0-9]|[0-9][0-9])$/ + property :proxy, String, regex: /.*/ + property :proxy_username, String, regex: /.*/ + property :proxy_password, String, regex: /.*/ + property :username, String, regex: /.*/ + property :password, String, regex: /.*/ + property :repo_gpgcheck, [TrueClass, FalseClass] + property :report_instanceid, [TrueClass, FalseClass] + property :repositoryid, String, regex: /.*/, name_property: true + property :sensitive, [TrueClass, FalseClass], default: false + property :skip_if_unavailable, [TrueClass, FalseClass] + property :source, String, regex: /.*/ + property :sslcacert, String, regex: /.*/ + property :sslclientcert, String, regex: /.*/ + property :sslclientkey, String, regex: /.*/ + property :sslverify, [TrueClass, FalseClass] + property :timeout, String, regex: /^\d+$/ + property :options, Hash + + default_action :create + allowed_actions :create, :remove, :makecache, :add, :delete + + # provide compatibility with the yum cookbook < 3.0 properties + alias_method :url, :baseurl + alias_method :keyurl, :gpgkey + end + end +end +end +end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/resource_builder.rb b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/resource_builder.rb new file mode 100644 index 0000000..688e856 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/copied_from_chef/chef/resource_builder.rb @@ -0,0 +1,174 @@ +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# +# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!! +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + +begin + require 'chef/resource_builder' +rescue LoadError; end + +require 'chef_compat/copied_from_chef' +class Chef +module ::ChefCompat +module CopiedFromChef +# +# Author:: Lamont Granquist () +# Copyright:: Copyright 2015-2016, 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. +# + +# NOTE: this was extracted from the Recipe DSL mixin, relevant specs are in spec/unit/recipe_spec.rb + +class Chef < (defined?(::Chef) ? ::Chef : Object) + class ResourceBuilder < (defined?(::Chef::ResourceBuilder) ? ::Chef::ResourceBuilder : Object) + attr_reader :type + attr_reader :name + attr_reader :created_at + attr_reader :params + attr_reader :run_context + attr_reader :cookbook_name + attr_reader :recipe_name + attr_reader :enclosing_provider + attr_reader :resource + + # FIXME (ruby-2.1 syntax): most of these are mandatory + def initialize(type: nil, name: nil, created_at: nil, params: nil, run_context: nil, cookbook_name: nil, recipe_name: nil, enclosing_provider: nil) +super if defined?(::Chef::ResourceBuilder) + @type = type + @name = name + @created_at = created_at + @params = params + @run_context = run_context + @cookbook_name = cookbook_name + @recipe_name = recipe_name + @enclosing_provider = enclosing_provider + end + + def build(&block) + raise ArgumentError, "You must supply a name when declaring a #{type} resource" if name.nil? + + @resource = resource_class.new(name, run_context) + if resource.resource_name.nil? + raise Chef::Exceptions::InvalidResourceSpecification, "#{resource}.resource_name is `nil`! Did you forget to put `provides :blah` or `resource_name :blah` in your resource class?" + end + resource.source_line = created_at + resource.declared_type = type + + # If we have a resource like this one, we want to steal its state + # This behavior is very counter-intuitive and should be removed. + # See CHEF-3694, https://tickets.opscode.com/browse/CHEF-3694 + # Moved to this location to resolve CHEF-5052, https://tickets.opscode.com/browse/CHEF-5052 + if prior_resource + resource.load_from(prior_resource) + end + + resource.cookbook_name = cookbook_name + resource.recipe_name = recipe_name + # Determine whether this resource is being created in the context of an enclosing Provider + resource.enclosing_provider = enclosing_provider + + # XXX: this is required for definition params inside of the scope of a + # subresource to work correctly. + resource.params = params + + # Evaluate resource attribute DSL + if block_given? + resource.resource_initializing = true + begin + resource.instance_eval(&block) + ensure + resource.resource_initializing = false + end + end + + # emit a cloned resource warning if it is warranted + if prior_resource + if is_trivial_resource?(prior_resource) && identicalish_resources?(prior_resource, resource) + emit_harmless_cloning_debug + else + emit_cloned_resource_warning + end + end + + # Run optional resource hook + resource.after_created + + resource + end + + private + + def resource_class + # Checks the new platform => short_name => resource mapping initially + # then fall back to the older approach (Chef::Resource.const_get) for + # backward compatibility + @resource_class ||= Chef::Resource.resource_for_node(type, run_context.node) + end + + def is_trivial_resource?(resource) + trivial_resource = resource_class.new(name, run_context) + # force un-lazy the name property on the created trivial resource + name_property = resource_class.properties.find { |sym, p| p.name_property? } + trivial_resource.send(name_property[0]) unless name_property.nil? + identicalish_resources?(trivial_resource, resource) + end + + # this is an equality test specific to checking for 3694 cloning warnings + def identicalish_resources?(first, second) + skipped_ivars = [ :@source_line, :@cookbook_name, :@recipe_name, :@params, :@elapsed_time, :@declared_type ] + checked_ivars = ( first.instance_variables | second.instance_variables ) - skipped_ivars + non_matching_ivars = checked_ivars.reject do |iv| + if iv == :@action && ( [first.instance_variable_get(iv)].flatten == [:nothing] || [second.instance_variable_get(iv)].flatten == [:nothing] ) + # :nothing action on either side of the comparison always matches + true + else + first.instance_variable_get(iv) == second.instance_variable_get(iv) + end + end + Chef::Log.debug("ivars which did not match with the prior resource: #{non_matching_ivars}") + non_matching_ivars.empty? + end + + def emit_cloned_resource_warning + message = "Cloning resource attributes for #{resource} from prior resource (CHEF-3694)" + message << "\nPrevious #{prior_resource}: #{prior_resource.source_line}" if prior_resource.source_line + message << "\nCurrent #{resource}: #{resource.source_line}" if resource.source_line + Chef.log_deprecation(message) + end + + def emit_harmless_cloning_debug + Chef::Log.debug("Harmless resource cloning from #{prior_resource}:#{prior_resource.source_line} to #{resource}:#{resource.source_line}") + end + + def prior_resource + @prior_resource ||= + begin + key = "#{type}[#{name}]" + run_context.resource_collection.lookup_local(key) + rescue Chef::Exceptions::ResourceNotFound + nil + end + end + + end +end + +require "chef_compat/copied_from_chef/chef/resource" +end +end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/mixin/properties.rb b/cookbooks/compat_resource/files/lib/chef_compat/mixin/properties.rb new file mode 100644 index 0000000..a3920d1 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/mixin/properties.rb @@ -0,0 +1,8 @@ +require 'chef_compat/monkeypatches' +require 'chef_compat/copied_from_chef/chef/mixin/properties' + +module ChefCompat + module Mixin + Properties = ChefCompat::CopiedFromChef::Chef::Mixin::Properties + end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches.rb b/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches.rb new file mode 100644 index 0000000..9ac83e8 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches.rb @@ -0,0 +1,41 @@ +class Chef + class RunContext + class ChildRunContext < RunContext + # magic that lets us re-parse the ChildRunContext without erroring due to + # cheffish and chef-provisioning hooks having been loaded (on old versions of + # chef-client without the lazy hooks for those gems) + @__skip_method_checking = true + end + end +end + +# fix to quiet constant redefined warnings +if defined?(Chef::RunContext::ChildRunContext::CHILD_STATE) + Chef::RunContext::ChildRunContext.send(:remove_const, :CHILD_STATE) +end + +require 'chef_compat/monkeypatches/chef' +require 'chef_compat/monkeypatches/chef/exceptions' +require 'chef_compat/monkeypatches/chef/log' +require 'chef_compat/monkeypatches/chef/node' +require 'chef_compat/monkeypatches/chef/mixin/params_validate' +require 'chef_compat/monkeypatches/chef/property' +require 'chef_compat/monkeypatches/chef/provider' +require 'chef_compat/monkeypatches/chef/recipe' # copied from chef +require 'chef_compat/monkeypatches/chef/recipe_hook' +require 'chef_compat/monkeypatches/chef/resource' +require 'chef_compat/monkeypatches/chef/resource_builder' +require 'chef_compat/monkeypatches/chef/resource/lwrp_base' +require 'chef_compat/monkeypatches/chef/resource_collection' +require 'chef_compat/monkeypatches/chef/resource_collection/resource_list' +require 'chef_compat/monkeypatches/chef/resource_collection/resource_set' +require 'chef_compat/monkeypatches/chef/run_context' # copied from chef +require 'chef_compat/monkeypatches/chef/runner' # copied from chef + +# fix for Chef::RunContext instance that has already been created +ObjectSpace.each_object(Chef::RunContext) do |run_context| + run_context.node.run_context = run_context + run_context.instance_variable_set(:@loaded_recipes_hash, {}) + run_context.instance_variable_set(:@loaded_attributes_hash, {}) + run_context.initialize_child_state +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef.rb b/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef.rb new file mode 100644 index 0000000..9669f6a --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef.rb @@ -0,0 +1,33 @@ +class Chef + NOT_PASSED = Object.new if !defined?(NOT_PASSED) + # Earlier versions of Chef didn't have this message + module ChefCompatDeprecation + def log_deprecation(message, location=nil) + if !location + # Pick the first caller that is *not* part of the Chef or ChefCompat gem, + # that's the thing the user wrote. + chef_compat_gem_path = File.expand_path("../../..", __FILE__) + chef_gem_path = File.expand_path("../..",::Chef::Resource.instance_method(:initialize).source_location[0]) + caller(0..10).each do |c| + if !c.start_with?(chef_gem_path) && !c.start_with?(chef_compat_gem_path) + location = c + break + end + end + end + + begin + super + # Bleagh. `super_method` doesn't exist on older rubies and I haven't + # figured out a way to check for its existence otherwise. + rescue NoMethodError + Chef::Log.warn(message) + end + end + end + + class<= 12.5 && Chef::VERSION.to_f <= 12.8 + require 'chef/mixin/params_validate' + class Chef + module Mixin + module ParamsValidate + class SetOrReturnProperty < Chef::Property + # 12.9 introduced a new optional parameter to `get()` to avoid a nil-set warning. + # When their method gets called with 2 args, we need to ignore and call with 1. + alias_method :_original_get2, :get + def get(resource, *args) + _original_get2(resource) + end + end + end + end + end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/node.rb b/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/node.rb new file mode 100644 index 0000000..93379b0 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/node.rb @@ -0,0 +1,9 @@ +class Chef + class Node + unless method_defined?(:set_cookbook_attribute) + def set_cookbook_attribute + # this implementation deliberately left blank - we don't need to do anything we just need to not fail + end + end + end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/property.rb b/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/property.rb new file mode 100644 index 0000000..2308d32 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/property.rb @@ -0,0 +1,15 @@ +# 12.9 introduced a new optional parameter to `get()` to avoid a nil-set warning. +# We need to mimick it here. +if Chef::VERSION.to_f >= 12.5 && Chef::VERSION.to_f <= 12.8 + require 'chef/property' + class Chef + class Property + # 12.9 introduced a new optional parameter to `get()` to avoid a nil-set warning. + # When their method gets called with 2 args, we need to ignore and call with 1. + alias_method :_original_get, :get + def get(resource, *args) + _original_get(resource) + end + end + end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/provider.rb b/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/provider.rb new file mode 100644 index 0000000..591cedb --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/provider.rb @@ -0,0 +1,65 @@ +require 'chef/provider' +require 'chef/provider/lwrp_base' + +class Chef::Provider + if !defined?(InlineResources) + InlineResources = Chef::Provider::LWRPBase::InlineResources + end + module InlineResources + require 'chef/dsl/recipe' + require 'chef/dsl/platform_introspection' + require 'chef/dsl/data_query' + require 'chef/dsl/include_recipe' + include Chef::DSL::Recipe + include Chef::DSL::PlatformIntrospection + include Chef::DSL::DataQuery + include Chef::DSL::IncludeRecipe + + unless Chef::Provider::InlineResources::ClassMethods.instance_method(:action).source_location[0] =~ /chefspec/ + # Don't override action if chefspec is doing its thing + module ::ChefCompat + module Monkeypatches + module InlineResources + module ClassMethods + def action(name, &block) + super(name) { send("compile_action_#{name}") } + # We put the action in its own method so that super() works. + define_method("compile_action_#{name}", &block) + end + end + end + end + end + module ClassMethods + prepend ChefCompat::Monkeypatches::InlineResources::ClassMethods + end + end + end +end + + +class Chef + class Provider + class LWRPBase < Provider + if defined?(InlineResources) + module InlineResources + # since we upgrade the Chef::Runner and Chef::RunContext globally to >= 12.14 style classes, we need to also + # fix the use_inline_resources LWRPBase wrapper that creates a sub-resource collection with the ugpraded code + # from the Chef::Provider subclasses that do similar things in post-12.5 chef. + def recipe_eval_with_update_check(&block) + old_run_context = run_context + @run_context = run_context.create_child + return_value = instance_eval(&block) + Chef::Runner.new(run_context).converge + return_value + ensure + if run_context.resource_collection.any? { |r| r.updated? } + new_resource.updated_by_last_action(true) + end + @run_context = old_run_context + end + end + end + end + end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/recipe.rb b/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/recipe.rb new file mode 100644 index 0000000..7c4c8be --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/recipe.rb @@ -0,0 +1,118 @@ +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# +# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!! +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + +if Gem::Requirement.new('< 12.16.42').satisfied_by?(Gem::Version.new(Chef::VERSION)) +#-- +# Author:: Adam Jacob () +# Author:: Christopher Walters () +# Copyright:: Copyright 2008-2016, 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/dsl/recipe" +require "chef/mixin/from_file" +require "chef/mixin/deprecation" + +class Chef + # == Chef::Recipe + # A Recipe object is the context in which Chef recipes are evaluated. + class Recipe + attr_accessor :cookbook_name, :recipe_name, :recipe, :params, :run_context + + include Chef::DSL::Recipe + + include Chef::Mixin::FromFile + include Chef::Mixin::Deprecation + + # Parses a potentially fully-qualified recipe name into its + # cookbook name and recipe short name. + # + # For example: + # "aws::elastic_ip" returns [:aws, "elastic_ip"] + # "aws" returns [:aws, "default"] + # "::elastic_ip" returns [ current_cookbook, "elastic_ip" ] + #-- + # TODO: Duplicates functionality of RunListItem + def self.parse_recipe_name(recipe_name, current_cookbook: nil) + case recipe_name + when /(.+?)::(.+)/ + [ $1.to_sym, $2 ] + when /^::(.+)/ + raise "current_cookbook is nil, cannot resolve #{recipe_name}" if current_cookbook.nil? + [ current_cookbook.to_sym, $1 ] + else + [ recipe_name.to_sym, "default" ] + end + end + + def initialize(cookbook_name, recipe_name, run_context) + @cookbook_name = cookbook_name + @recipe_name = recipe_name + @run_context = run_context + # TODO: 5/19/2010 cw/tim: determine whether this can be removed + @params = Hash.new + end + + # Used in DSL mixins + def node + run_context.node + end + + # Used by the DSL to look up resources when executing in the context of a + # recipe. + def resources(*args) + run_context.resource_collection.find(*args) + end + + # This was moved to Chef::Node#tag, redirecting here for compatibility + def tag(*tags) + run_context.node.tag(*tags) + end + + # Returns true if the node is tagged with *all* of the supplied +tags+. + # + # === Parameters + # tags:: A list of tags + # + # === Returns + # true:: If all the parameters are present + # false:: If any of the parameters are missing + def tagged?(*tags) + tags.each do |tag| + return false unless run_context.node.tags.include?(tag) + end + true + end + + # Removes the list of tags from the node. + # + # === Parameters + # tags:: A list of tags + # + # === Returns + # tags:: The current list of run_context.node.tags + def untag(*tags) + tags.each do |tag| + run_context.node.tags.delete(tag) + end + end + end +end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/recipe_hook.rb b/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/recipe_hook.rb new file mode 100644 index 0000000..24aa20f --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/recipe_hook.rb @@ -0,0 +1,20 @@ +require 'chef/recipe' +require 'chef_compat/recipe' + +class Chef::Recipe + # If the cookbook depends on compat_resource, create a ChefCompat::Recipe object + # instead of Chef::Recipe, for the extra goodies. + def self.new(cookbook_name, recipe_name, run_context) + if run_context && + cookbook_name && + recipe_name && + run_context.cookbook_collection && + run_context.cookbook_collection[cookbook_name] && + run_context.cookbook_collection[cookbook_name].metadata.dependencies.has_key?('compat_resource') && + self != ::ChefCompat::Recipe + ::ChefCompat::Recipe.new(cookbook_name, recipe_name, run_context) + else + super + end + end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/resource.rb b/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/resource.rb new file mode 100644 index 0000000..d61b60b --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/resource.rb @@ -0,0 +1,156 @@ +# this is NOT an AUTOGENERATED file + +require 'chef/resource' + +class Chef + class Resource + + class UnresolvedSubscribes < self + # The full key ise given as the name in {Resource#subscribes} + alias_method :to_s, :name + alias_method :declared_key, :name + end + + # + # Force a delayed notification into this resource's run_context. + # + # This should most likely be paired with action :nothing + # + # @param arg [Array[Symbol], Symbol] A list of actions (e.g. `:create`) + # + def delayed_action(arg) + arg = Array(arg).map(&:to_sym) + arg.map do |action| + validate( + { action: action }, + { action: { kind_of: Symbol, equal_to: allowed_actions } } + ) + # the resource effectively sends a delayed notification to itself + run_context.add_delayed_action(Notification.new(self, action, self)) + end + end + + def subscribes(action, resources, timing = :delayed) + resources = [resources].flatten + resources.each do |resource| + if resource.is_a?(String) + resource = UnresolvedSubscribes.new(resource, run_context) + end + if resource.run_context.nil? + resource.run_context = run_context + end + resource.notifies(action, self, timing) + end + true + end + + def notifies(action, resource_spec, timing = :delayed) + # when using old-style resources(:template => "/foo.txt") style, you + # could end up with multiple resources. + validate_resource_spec!(resource_spec) + + resources = [ resource_spec ].flatten + resources.each do |resource| + + case timing.to_s + when "delayed" + notifies_delayed(action, resource) + when "immediate", "immediately" + notifies_immediately(action, resource) + when "before" + notifies_before(action, resource) + else + raise ArgumentError, "invalid timing: #{timing} for notifies(#{action}, #{resources.inspect}, #{timing}) resource #{self} "\ + "Valid timings are: :delayed, :immediate, :immediately, :before" + end + end + + true + end + + # + # Iterates over all immediate and delayed notifications, calling + # resolve_resource_reference on each in turn, causing them to + # resolve lazy/forward references. + def resolve_notification_references + run_context.before_notifications(self).each { |n| + n.resolve_resource_reference(run_context.resource_collection) + } + run_context.immediate_notifications(self).each { |n| + n.resolve_resource_reference(run_context.resource_collection) + } + run_context.delayed_notifications(self).each {|n| + n.resolve_resource_reference(run_context.resource_collection) + } + end + + # Helper for #notifies + def notifies_before(action, resource_spec) + run_context.notifies_before(Notification.new(resource_spec, action, self)) + end + + # Helper for #notifies + def notifies_immediately(action, resource_spec) + run_context.notifies_immediately(Notification.new(resource_spec, action, self)) + end + + # Helper for #notifies + def notifies_delayed(action, resource_spec) + run_context.notifies_delayed(Notification.new(resource_spec, action, self)) + end + + # + # Get the current actual value of this resource. + # + # This does not cache--a new value will be returned each time. + # + # @return A new copy of the resource, with values filled in from the actual + # current value. + # + def current_value + provider = provider_for_action(Array(action).first) + if provider.whyrun_mode? && !provider.whyrun_supported? + raise "Cannot retrieve #{self.class.current_resource} in why-run mode: #{provider} does not support why-run" + end + provider.load_current_resource + provider.current_resource + end + + # These methods are necessary for new resources to initialize old ones properly + attr_reader :resource_initializing + def resource_initializing=(value) + if value + @resource_initializing = value + else + remove_instance_variable(:@resource_initializing) + end + end + + if !respond_to?(:resource_name) + def self.resource_name(name=Chef::NOT_PASSED) + # Setter + if name != Chef::NOT_PASSED + # remove_canonical_dsl + + # Set the resource_name and call provides + if name + name = name.to_sym + # If our class is not already providing this name, provide it. + # Commented out: use of resource_name and provides will need to be + # mutually exclusive in this world, generally. + # if !Chef::ResourceResolver.includes_handler?(name, self) + provides name#, canonical: true + # end + @resource_name = name + else + @resource_name = nil + end + end + @resource_name + end + def self.resource_name=(name) + resource_name(name) + end + end + end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/resource/lwrp_base.rb b/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/resource/lwrp_base.rb new file mode 100644 index 0000000..5f098fd --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/resource/lwrp_base.rb @@ -0,0 +1,60 @@ +require 'chef_compat/resource/lwrp_base' +require 'chef/resource/lwrp_base' + +module ChefCompat + module Monkeypatches + # + # NOTE: LOTS OF METAPROGRAMMING HERE. NOT FOR FAINT OF HEART. + # + + # Add an empty module to Class so we can temporarily override it in build_from_file + module Class + end + class<<::Class + prepend(ChefCompat::Monkeypatches::Class) + end + + module Chef + module Resource + module LWRPBase + def build_from_file(cookbook_name, filename, run_context) + # If the cookbook this LWRP is from depends on compat_resource, fix its LWRPs up real good + if run_context.cookbook_collection[cookbook_name].metadata.dependencies.has_key?('compat_resource') + # All cookbooks do Class.new(Chef::Resource::LWRPBase). Change Class.new + # temporarily to translate Chef::Resource::LWRPBase to ChefCompat::Resource + ChefCompat::Monkeypatches::Class.module_eval do + def new(*args, &block) + # Trick it! Use ChefCompat::Resource instead of Chef::Resource::LWRPBase + if args == [ ::Chef::Resource::LWRPBase ] + ChefCompat::Monkeypatches::Class.module_eval do + remove_method(:new) if method_defined?(:new) + end + args = [ ChefCompat::Resource::LWRPBase ] + end + super(*args, &block) + end + end + + begin + + # Call the actual build_from_file + super + + ensure + class<) +# Copyright:: Copyright 2015-2016, 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. +# + +# XXX: we now have two copies of this file in the compat_resource cookbook. I'm uncertain if this is a +# bug or a feature, and I suspect it is actually a feature. The point of this file is that for all +# resources and cookbooks the global Chef::ResourceBuilder class must be upgraded to at least the +# 12.10.24 version. The point of the other copy is that for compat_resource cookbooks all their +# resources should be using the lastest version that has been sync'd. So these two files should +# diverge as times goes on. I believe that is the correct behavior and that we want to have both +# files in this cookbook. + +# NOTE: this was extracted from the Recipe DSL mixin, relevant specs are in spec/unit/recipe_spec.rb + +if Gem::Requirement.new("< 12.10.24").satisfied_by?(Gem::Version.new(Chef::VERSION)) + begin + require 'chef/resource_builder' + # we use the LoadError this creates on early 12.x to not monkeypatch chef client versions that don't have Chef::ResourceBuilder + # (it is lazily included and doesn't appear until compile time so we can't resolve the symbol during library loading) + + class Chef + class ResourceBuilder + attr_reader :type + attr_reader :name + attr_reader :created_at + attr_reader :params + attr_reader :run_context + attr_reader :cookbook_name + attr_reader :recipe_name + attr_reader :enclosing_provider + attr_reader :resource + + # FIXME (ruby-2.1 syntax): most of these are mandatory + def initialize(type:nil, name:nil, created_at: nil, params: nil, run_context: nil, cookbook_name: nil, recipe_name: nil, enclosing_provider: nil) + @type = type + @name = name + @created_at = created_at + @params = params + @run_context = run_context + @cookbook_name = cookbook_name + @recipe_name = recipe_name + @enclosing_provider = enclosing_provider + end + + def build(&block) + raise ArgumentError, "You must supply a name when declaring a #{type} resource" if name.nil? + + @resource = resource_class.new(name, run_context) + if resource.resource_name.nil? + raise Chef::Exceptions::InvalidResourceSpecification, "#{resource}.resource_name is `nil`! Did you forget to put `provides :blah` or `resource_name :blah` in your resource class?" + end + resource.source_line = created_at + resource.declared_type = type + + # If we have a resource like this one, we want to steal its state + # This behavior is very counter-intuitive and should be removed. + # See CHEF-3694, https://tickets.opscode.com/browse/CHEF-3694 + # Moved to this location to resolve CHEF-5052, https://tickets.opscode.com/browse/CHEF-5052 + if prior_resource + resource.load_from(prior_resource) + end + + resource.cookbook_name = cookbook_name + resource.recipe_name = recipe_name + # Determine whether this resource is being created in the context of an enclosing Provider + resource.enclosing_provider = enclosing_provider + + # XXX: this is required for definition params inside of the scope of a + # subresource to work correctly. + resource.params = params + + # Evaluate resource attribute DSL + if block_given? + resource.resource_initializing = true + begin + resource.instance_eval(&block) + ensure + resource.resource_initializing = false + end + end + + # emit a cloned resource warning if it is warranted + if prior_resource + if is_trivial_resource?(prior_resource) && identicalish_resources?(prior_resource, resource) + emit_harmless_cloning_debug + else + emit_cloned_resource_warning + end + end + + # Run optional resource hook + resource.after_created + + resource + end + + private + + def resource_class + # Checks the new platform => short_name => resource mapping initially + # then fall back to the older approach (Chef::Resource.const_get) for + # backward compatibility + @resource_class ||= Chef::Resource.resource_for_node(type, run_context.node) + end + + def is_trivial_resource?(resource) + identicalish_resources?(resource_class.new(name, run_context), resource) + end + + # this is an equality test specific to checking for 3694 cloning warnings + def identicalish_resources?(first, second) + skipped_ivars = [ :@source_line, :@cookbook_name, :@recipe_name, :@params, :@elapsed_time, :@declared_type ] + checked_ivars = ( first.instance_variables | second.instance_variables ) - skipped_ivars + non_matching_ivars = checked_ivars.reject do |iv| + if iv == :@action && ( [first.instance_variable_get(iv)].flatten == [:nothing] || [second.instance_variable_get(iv)].flatten == [:nothing] ) + # :nothing action on either side of the comparison always matches + true + else + first.instance_variable_get(iv) == second.instance_variable_get(iv) + end + end + Chef::Log.debug("ivars which did not match with the prior resource: #{non_matching_ivars}") + non_matching_ivars.empty? + end + + def emit_cloned_resource_warning + Chef::Log.warn("Cloning resource attributes for #{resource} from prior resource (CHEF-3694)") + Chef::Log.warn("Previous #{prior_resource}: #{prior_resource.source_line}") if prior_resource.source_line + Chef::Log.warn("Current #{resource}: #{resource.source_line}") if resource.source_line + end + + def emit_harmless_cloning_debug + Chef::Log.debug("Harmless resource cloning from #{prior_resource}:#{prior_resource.source_line} to #{resource}:#{resource.source_line}") + end + + def prior_resource + @prior_resource ||= + begin + key = "#{type}[#{name}]" + run_context.resource_collection.lookup_local(key) + rescue Chef::Exceptions::ResourceNotFound + nil + end + end + + end + end + rescue LoadError + # cool we're just on early chef 12.x, nothing to do -- we don't have to worry because there's also not parent_run_context pointer, so we don't have to + # use lookup_local to avoid resource cloning shit out of the parent run_context. the resource collection's lookup() method will always use lookup_local + # over lookup_recursive. + end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/resource_collection.rb b/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/resource_collection.rb new file mode 100644 index 0000000..4f07489 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/resource_collection.rb @@ -0,0 +1,103 @@ +# +# Author:: Adam Jacob () +# Author:: Christopher Walters () +# Copyright:: Copyright 2008-2016, 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_collection/resource_set" +require "chef/resource_collection/resource_list" +require "chef/resource_collection" +require "chef/exceptions" + +module ChefCompat + module Monkeypatches + module Chef + module ResourceCollection + module RecursiveNotificationLookup + # + # Copied verbatim from Chef 12.10.24 + # + attr_accessor :run_context + + def initialize(run_context = nil) + super() + @run_context = run_context + end + + def lookup_local(key) + resource_set.lookup(key) + end + + def find_local(*args) + resource_set.find(*args) + end + + def lookup(key) + if run_context.nil? + lookup_local(key) + else + lookup_recursive(run_context, key) + end + end + + def find(*args) + if run_context.nil? + find_local(*args) + else + find_recursive(run_context, *args) + end + end + + private + + def lookup_recursive(rc, key) + rc.resource_collection.send(:resource_set).lookup(key) + rescue ::Chef::Exceptions::ResourceNotFound + raise if !rc.respond_to?(:parent_run_context) || rc.parent_run_context.nil? + lookup_recursive(rc.parent_run_context, key) + end + + def find_recursive(rc, *args) + rc.resource_collection.send(:resource_set).find(*args) + rescue ::Chef::Exceptions::ResourceNotFound + raise if !rc.respond_to?(:parent_run_context) || rc.parent_run_context.nil? + find_recursive(rc.parent_run_context, *args) + end + end + + module DeleteResources + # + # Copied verbatim from Chef 12.10.24 + # + def delete(key) + resource_list.delete(key) + resource_set.delete(key) + end + end + end + end + end +end + + +class Chef::ResourceCollection + unless method_defined?(:lookup_local) + prepend ChefCompat::Monkeypatches::Chef::ResourceCollection::RecursiveNotificationLookup + end + unless method_defined?(:delete) + prepend ChefCompat::Monkeypatches::Chef::ResourceCollection::DeleteResources + end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/resource_collection/resource_list.rb b/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/resource_collection/resource_list.rb new file mode 100644 index 0000000..dfbd442 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/resource_collection/resource_list.rb @@ -0,0 +1,49 @@ +# +# Author:: Tyler Ball () +# Copyright:: Copyright 2014-2016, 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_collection/resource_list" +require "chef/exceptions" + +module ChefCompat + module Monkeypatches + module Chef + module ResourceCollection + module ResourceList + module DeleteResource + # Copied verbatim from Chef 12.10.4 + def delete(key) + raise ArgumentError, "Must pass a Chef::Resource or String to delete" unless key.is_a?(String) || key.is_a?(Chef::Resource) + key = key.to_s + ret = @resources.reject! { |r| r.to_s == key } + if ret.nil? + raise ::Chef::Exceptions::ResourceNotFound, "Cannot find a resource matching #{key} (did you define it first?)" + end + ret + end + end + end + end + end + end +end + +class Chef::ResourceCollection::ResourceList + unless method_defined?(:delete) + prepend ChefCompat::Monkeypatches::Chef::ResourceCollection::ResourceList::DeleteResource + end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/resource_collection/resource_set.rb b/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/resource_collection/resource_set.rb new file mode 100644 index 0000000..bcead10 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/resource_collection/resource_set.rb @@ -0,0 +1,49 @@ +# +# Author:: Tyler Ball () +# Copyright:: Copyright 2014-2016, 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_collection/resource_list" +require "chef/exceptions" + +module ChefCompat + module Monkeypatches + module Chef + module ResourceCollection + module ResourceSet + module DeleteResource + def delete(key) + raise ArgumentError, "Must pass a Chef::Resource or String to delete" unless key.is_a?(String) || key.is_a?(Chef::Resource) + key = key.to_s + res = @resources_by_key.delete(key) + + if res == @resources_by_key.default + raise Chef::Exceptions::ResourceNotFound, "Cannot find a resource matching #{key} (did you define it first?)" + end + res + end + end + end + end + end + end +end + +class Chef::ResourceCollection::ResourceSet + unless method_defined?(:delete) + prepend ChefCompat::Monkeypatches::Chef::ResourceCollection::ResourceSet::DeleteResource + end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/run_context.rb b/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/run_context.rb new file mode 100644 index 0000000..03c9d60 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/run_context.rb @@ -0,0 +1,691 @@ +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# +# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!! +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + +if Gem::Requirement.new('< 12.16.42').satisfied_by?(Gem::Version.new(Chef::VERSION)) +# +# Author:: Adam Jacob () +# Author:: Christopher Walters () +# Author:: Tim Hinderliter () +# Copyright:: Copyright 2008-2016, 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_collection" +require "chef/cookbook_version" +require "chef/node" +require "chef/role" +require "chef/log" +require "chef/recipe" +require "chef/run_context/cookbook_compiler" +require "chef/event_dispatch/events_output_stream" +require "forwardable" + +class Chef + + # == Chef::RunContext + # Value object that loads and tracks the context of a Chef run + class RunContext + # + # Global state + # + + # + # The node for this run + # + # @return [Chef::Node] + # + attr_reader :node + + # + # The set of cookbooks involved in this run + # + # @return [Chef::CookbookCollection] + # + attr_reader :cookbook_collection + + # + # Resource Definitions for this run. Populated when the files in + # +definitions/+ are evaluated (this is triggered by #load). + # + # @return [Array[Chef::ResourceDefinition]] + # + attr_reader :definitions + + # + # Event dispatcher for this run. + # + # @return [Chef::EventDispatch::Dispatcher] + # + attr_reader :events + + # + # Hash of factoids for a reboot request. + # + # @return [Hash] + # + attr_accessor :reboot_info + + # + # Scoped state + # + + # + # The parent run context. + # + # @return [Chef::RunContext] The parent run context, or `nil` if this is the + # root context. + # + attr_reader :parent_run_context + + # + # The root run context. + # + # @return [Chef::RunContext] The root run context. + # + def root_run_context + rc = self + rc = rc.parent_run_context until rc.parent_run_context.nil? + rc + end + + # + # The collection of resources intended to be converged (and able to be + # notified). + # + # @return [Chef::ResourceCollection] + # + # @see CookbookCompiler + # + attr_reader :resource_collection + + # + # The list of control groups to execute during the audit phase + # + attr_reader :audits + + # + # Notification handling + # + + # + # A Hash containing the before notifications triggered by resources + # during the converge phase of the chef run. + # + # @return [Hash[String, Array[Chef::Resource::Notification]]] A hash from + # => + # + attr_reader :before_notification_collection + + # + # A Hash containing the immediate notifications triggered by resources + # during the converge phase of the chef run. + # + # @return [Hash[String, Array[Chef::Resource::Notification]]] A hash from + # => + # + attr_reader :immediate_notification_collection + + # + # A Hash containing the delayed (end of run) notifications triggered by + # resources during the converge phase of the chef run. + # + # @return [Hash[String, Array[Chef::Resource::Notification]]] A hash from + # => + # + attr_reader :delayed_notification_collection + + # + # An Array containing the delayed (end of run) notifications triggered by + # resources during the converge phase of the chef run. + # + # @return [Array[Chef::Resource::Notification]] An array of notification objects + # + attr_reader :delayed_actions + + # Creates a new Chef::RunContext object and populates its fields. This object gets + # used by the Chef Server to generate a fully compiled recipe list for a node. + # + # @param node [Chef::Node] The node to run against. + # @param cookbook_collection [Chef::CookbookCollection] The cookbooks + # involved in this run. + # @param events [EventDispatch::Dispatcher] The event dispatcher for this + # run. + # + def initialize(node, cookbook_collection, events) + @node = node + @cookbook_collection = cookbook_collection + @events = events + + node.run_context = self + node.set_cookbook_attribute + + @definitions = Hash.new + @loaded_recipes_hash = {} + @loaded_attributes_hash = {} + @reboot_info = {} + @cookbook_compiler = nil + @delayed_actions = [] + + initialize_child_state + end + + # + # Triggers the compile phase of the chef run. + # + # @param run_list_expansion [Chef::RunList::RunListExpansion] The run list. + # @see Chef::RunContext::CookbookCompiler + # + def load(run_list_expansion) + @cookbook_compiler = CookbookCompiler.new(self, run_list_expansion, events) + cookbook_compiler.compile + end + + # + # Initialize state that applies to both Chef::RunContext and Chef::ChildRunContext + # + def initialize_child_state + @audits = {} + @resource_collection = Chef::ResourceCollection.new(self) + @before_notification_collection = Hash.new { |h, k| h[k] = [] } + @immediate_notification_collection = Hash.new { |h, k| h[k] = [] } + @delayed_notification_collection = Hash.new { |h, k| h[k] = [] } + @delayed_actions = [] + end + + # + # Adds an before notification to the +before_notification_collection+. + # + # @param [Chef::Resource::Notification] The notification to add. + # + def notifies_before(notification) + # Note for the future, notification.notifying_resource may be an instance + # of Chef::Resource::UnresolvedSubscribes when calling {Resource#subscribes} + # with a string value. + before_notification_collection[notification.notifying_resource.declared_key] << notification + end + + # + # Adds an immediate notification to the +immediate_notification_collection+. + # + # @param [Chef::Resource::Notification] The notification to add. + # + def notifies_immediately(notification) + # Note for the future, notification.notifying_resource may be an instance + # of Chef::Resource::UnresolvedSubscribes when calling {Resource#subscribes} + # with a string value. + immediate_notification_collection[notification.notifying_resource.declared_key] << notification + end + + # + # Adds a delayed notification to the +delayed_notification_collection+. + # + # @param [Chef::Resource::Notification] The notification to add. + # + def notifies_delayed(notification) + # Note for the future, notification.notifying_resource may be an instance + # of Chef::Resource::UnresolvedSubscribes when calling {Resource#subscribes} + # with a string value. + delayed_notification_collection[notification.notifying_resource.declared_key] << notification + end + + # + # Adds a delayed action to the +delayed_actions+. + # + def add_delayed_action(notification) + if delayed_actions.any? { |existing_notification| existing_notification.duplicates?(notification) } + Chef::Log.info( "#{notification.notifying_resource} not queuing delayed action #{notification.action} on #{notification.resource}"\ + " (delayed), as it's already been queued") + else + delayed_actions << notification + end + end + + # + # Get the list of before notifications sent by the given resource. + # + # @return [Array[Notification]] + # + def before_notifications(resource) + return before_notification_collection[resource.declared_key] + end + + # + # Get the list of immediate notifications sent by the given resource. + # + # @return [Array[Notification]] + # + def immediate_notifications(resource) + return immediate_notification_collection[resource.declared_key] + end + + # + # Get the list of delayed (end of run) notifications sent by the given + # resource. + # + # @return [Array[Notification]] + # + def delayed_notifications(resource) + return delayed_notification_collection[resource.declared_key] + end + + # + # Cookbook and recipe loading + # + + # + # Evaluates the recipes +recipe_names+. Used by DSL::IncludeRecipe + # + # @param recipe_names [Array[String]] The list of recipe names (e.g. + # 'my_cookbook' or 'my_cookbook::my_resource'). + # @param current_cookbook The cookbook we are currently running in. + # + # @see DSL::IncludeRecipe#include_recipe + # + def include_recipe(*recipe_names, current_cookbook: nil) + result_recipes = Array.new + recipe_names.flatten.each do |recipe_name| + if result = load_recipe(recipe_name, current_cookbook: current_cookbook) + result_recipes << result + end + end + result_recipes + end + + # + # Evaluates the recipe +recipe_name+. Used by DSL::IncludeRecipe + # + # TODO I am sort of confused why we have both this and include_recipe ... + # I don't see anything different beyond accepting and returning an + # array of recipes. + # + # @param recipe_names [Array[String]] The recipe name (e.g 'my_cookbook' or + # 'my_cookbook::my_resource'). + # @param current_cookbook The cookbook we are currently running in. + # + # @return A truthy value if the load occurred; `false` if already loaded. + # + # @see DSL::IncludeRecipe#load_recipe + # + def load_recipe(recipe_name, current_cookbook: nil) + Chef::Log.debug("Loading recipe #{recipe_name} via include_recipe") + + cookbook_name, recipe_short_name = Chef::Recipe.parse_recipe_name(recipe_name, current_cookbook: current_cookbook) + + if unreachable_cookbook?(cookbook_name) # CHEF-4367 + Chef::Log.warn(<<-ERROR_MESSAGE) +MissingCookbookDependency: +Recipe `#{recipe_name}` is not in the run_list, and cookbook '#{cookbook_name}' +is not a dependency of any cookbook in the run_list. To load this recipe, +first add a dependency on cookbook '#{cookbook_name}' in the cookbook you're +including it from in that cookbook's metadata. +ERROR_MESSAGE + end + + if loaded_fully_qualified_recipe?(cookbook_name, recipe_short_name) + Chef::Log.debug("I am not loading #{recipe_name}, because I have already seen it.") + false + else + loaded_recipe(cookbook_name, recipe_short_name) + node.loaded_recipe(cookbook_name, recipe_short_name) + cookbook = cookbook_collection[cookbook_name] + cookbook.load_recipe(recipe_short_name, self) + end + end + + # + # Load the given recipe from a filename. + # + # @param recipe_file [String] The recipe filename. + # + # @return [Chef::Recipe] The loaded recipe. + # + # @raise [Chef::Exceptions::RecipeNotFound] If the file does not exist. + # + def load_recipe_file(recipe_file) + if !File.exist?(recipe_file) + raise Chef::Exceptions::RecipeNotFound, "could not find recipe file #{recipe_file}" + end + + Chef::Log.debug("Loading recipe file #{recipe_file}") + recipe = Chef::Recipe.new("@recipe_files", recipe_file, self) + recipe.from_file(recipe_file) + recipe + end + + # + # Look up an attribute filename. + # + # @param cookbook_name [String] The cookbook name of the attribute file. + # @param attr_file_name [String] The attribute file's name (not path). + # + # @return [String] The filename. + # + # @see DSL::IncludeAttribute#include_attribute + # + # @raise [Chef::Exceptions::CookbookNotFound] If the cookbook could not be found. + # @raise [Chef::Exceptions::AttributeNotFound] If the attribute file could not be found. + # + def resolve_attribute(cookbook_name, attr_file_name) + cookbook = cookbook_collection[cookbook_name] + raise Chef::Exceptions::CookbookNotFound, "could not find cookbook #{cookbook_name} while loading attribute #{name}" unless cookbook + + attribute_filename = cookbook.attribute_filenames_by_short_filename[attr_file_name] + raise Chef::Exceptions::AttributeNotFound, "could not find filename for attribute #{attr_file_name} in cookbook #{cookbook_name}" unless attribute_filename + + attribute_filename + end + + # + # A list of all recipes that have been loaded. + # + # This is stored internally as a Hash, so ordering is predictable. + # + # TODO is the above statement true in a 1.9+ ruby world? Is it relevant? + # + # @return [Array[String]] A list of recipes in fully qualified form, e.g. + # the recipe "nginx" will be given as "nginx::default". + # + # @see #loaded_recipe? To determine if a particular recipe has been loaded. + # + def loaded_recipes + loaded_recipes_hash.keys + end + + # + # A list of all attributes files that have been loaded. + # + # Stored internally using a Hash, so order is predictable. + # + # TODO is the above statement true in a 1.9+ ruby world? Is it relevant? + # + # @return [Array[String]] A list of attribute file names in fully qualified + # form, e.g. the "nginx" will be given as "nginx::default". + # + def loaded_attributes + loaded_attributes_hash.keys + end + + # + # Find out if a given recipe has been loaded. + # + # @param cookbook [String] Cookbook name. + # @param recipe [String] Recipe name. + # + # @return [Boolean] `true` if the recipe has been loaded, `false` otherwise. + # + def loaded_fully_qualified_recipe?(cookbook, recipe) + loaded_recipes_hash.has_key?("#{cookbook}::#{recipe}") + end + + # + # Find out if a given recipe has been loaded. + # + # @param recipe [String] Recipe name. "nginx" and "nginx::default" yield + # the same results. + # + # @return [Boolean] `true` if the recipe has been loaded, `false` otherwise. + # + def loaded_recipe?(recipe) + cookbook, recipe_name = Chef::Recipe.parse_recipe_name(recipe) + loaded_fully_qualified_recipe?(cookbook, recipe_name) + end + + # + # Mark a given recipe as having been loaded. + # + # @param cookbook [String] Cookbook name. + # @param recipe [String] Recipe name. + # + def loaded_recipe(cookbook, recipe) + loaded_recipes_hash["#{cookbook}::#{recipe}"] = true + end + + # + # Find out if a given attribute file has been loaded. + # + # @param cookbook [String] Cookbook name. + # @param attribute_file [String] Attribute file name. + # + # @return [Boolean] `true` if the recipe has been loaded, `false` otherwise. + # + def loaded_fully_qualified_attribute?(cookbook, attribute_file) + loaded_attributes_hash.has_key?("#{cookbook}::#{attribute_file}") + end + + # + # Mark a given attribute file as having been loaded. + # + # @param cookbook [String] Cookbook name. + # @param attribute_file [String] Attribute file name. + # + def loaded_attribute(cookbook, attribute_file) + loaded_attributes_hash["#{cookbook}::#{attribute_file}"] = true + end + + ## + # Cookbook File Introspection + + # + # Find out if the cookbook has the given template. + # + # @param cookbook [String] Cookbook name. + # @param template_name [String] Template name. + # + # @return [Boolean] `true` if the template is in the cookbook, `false` + # otherwise. + # @see Chef::CookbookVersion#has_template_for_node? + # + def has_template_in_cookbook?(cookbook, template_name) + cookbook = cookbook_collection[cookbook] + cookbook.has_template_for_node?(node, template_name) + end + + # + # Find out if the cookbook has the given file. + # + # @param cookbook [String] Cookbook name. + # @param cb_file_name [String] File name. + # + # @return [Boolean] `true` if the file is in the cookbook, `false` + # otherwise. + # @see Chef::CookbookVersion#has_cookbook_file_for_node? + # + def has_cookbook_file_in_cookbook?(cookbook, cb_file_name) + cookbook = cookbook_collection[cookbook] + cookbook.has_cookbook_file_for_node?(node, cb_file_name) + end + + # + # Find out whether the given cookbook is in the cookbook dependency graph. + # + # @param cookbook_name [String] Cookbook name. + # + # @return [Boolean] `true` if the cookbook is reachable, `false` otherwise. + # + # @see Chef::CookbookCompiler#unreachable_cookbook? + def unreachable_cookbook?(cookbook_name) + cookbook_compiler.unreachable_cookbook?(cookbook_name) + end + + # + # Open a stream object that can be printed into and will dispatch to events + # + # @param name [String] The name of the stream. + # @param options [Hash] Other options for the stream. + # + # @return [EventDispatch::EventsOutputStream] The created stream. + # + # @yield If a block is passed, it will be run and the stream will be closed + # afterwards. + # @yieldparam stream [EventDispatch::EventsOutputStream] The created stream. + # + def open_stream(name: nil, **options) + stream = EventDispatch::EventsOutputStream.new(events, name: name, **options) + if block_given? + begin + yield stream + ensure + stream.close + end + else + stream + end + end + + # there are options for how to handle multiple calls to these functions: + # 1. first call always wins (never change reboot_info once set). + # 2. last call always wins (happily change reboot_info whenever). + # 3. raise an exception on the first conflict. + # 4. disable reboot after this run if anyone ever calls :cancel. + # 5. raise an exception on any second call. + # 6. ? + def request_reboot(reboot_info) + Chef::Log.info "Changing reboot status from #{self.reboot_info.inspect} to #{reboot_info.inspect}" + @reboot_info = reboot_info + end + + def cancel_reboot + Chef::Log.info "Changing reboot status from #{reboot_info.inspect} to {}" + @reboot_info = {} + end + + def reboot_requested? + reboot_info.size > 0 + end + + # + # Create a child RunContext. + # + def create_child + ChildRunContext.new(self) + end + + # @api private + attr_writer :resource_collection + + protected + + attr_reader :cookbook_compiler + attr_reader :loaded_attributes_hash + attr_reader :loaded_recipes_hash + + module Deprecated + ### + # These need to be settable so deploy can run a resource_collection + # independent of any cookbooks via +recipe_eval+ + def audits=(value) + Chef.log_deprecation("Setting run_context.audits will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") + @audits = value + end + + def immediate_notification_collection=(value) + Chef.log_deprecation("Setting run_context.immediate_notification_collection will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") + @immediate_notification_collection = value + end + + def delayed_notification_collection=(value) + Chef.log_deprecation("Setting run_context.delayed_notification_collection will be removed in a future Chef. Use run_context.create_child to create a new RunContext instead.") + @delayed_notification_collection = value + end + end + prepend Deprecated + + # + # A child run context. Delegates all root context calls to its parent. + # + # @api private + # + class ChildRunContext < RunContext + extend Forwardable + def_delegators :parent_run_context, *%w{ + cancel_reboot + config + cookbook_collection + cookbook_compiler + definitions + events + has_cookbook_file_in_cookbook? + has_template_in_cookbook? + load + loaded_attribute + loaded_attributes + loaded_attributes_hash + loaded_fully_qualified_attribute? + loaded_fully_qualified_recipe? + loaded_recipe + loaded_recipe? + loaded_recipes + loaded_recipes_hash + node + open_stream + reboot_info + reboot_info= + reboot_requested? + request_reboot + resolve_attribute + unreachable_cookbook? + } + + def initialize(parent_run_context) + @parent_run_context = parent_run_context + + # We don't call super, because we don't bother initializing stuff we're + # going to delegate to the parent anyway. Just initialize things that + # every instance needs. + initialize_child_state + end + + CHILD_STATE = %w{ + audits + audits= + create_child + add_delayed_action + delayed_actions + delayed_notification_collection + delayed_notification_collection= + delayed_notifications + immediate_notification_collection + immediate_notification_collection= + immediate_notifications + before_notification_collection + before_notifications + include_recipe + initialize_child_state + load_recipe + load_recipe_file + notifies_before + notifies_immediately + notifies_delayed + parent_run_context + root_run_context + resource_collection + resource_collection= + }.map { |x| x.to_sym } + + # Verify that we didn't miss any methods + unless @__skip_method_checking # hook specifically for compat_resource + missing_methods = superclass.instance_methods(false) - instance_methods(false) - CHILD_STATE + if !missing_methods.empty? + raise "ERROR: not all methods of RunContext accounted for in ChildRunContext! All methods must be marked as child methods with CHILD_STATE or delegated to the parent_run_context. Missing #{missing_methods.join(", ")}." + end + end + end + end +end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/runner.rb b/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/runner.rb new file mode 100644 index 0000000..9add7a8 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/runner.rb @@ -0,0 +1,153 @@ +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# +# THIS IS A FILE AUTOGENERATED BY 'rake update' DO NOT EDIT!!!! +# +# NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +# + +if Gem::Requirement.new('< 12.16.42').satisfied_by?(Gem::Version.new(Chef::VERSION)) +#-- +# Author:: Adam Jacob () +# Author:: Christopher Walters () +# Author:: Tim Hinderliter () +# Copyright:: Copyright 2008-2016, 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/exceptions" +require "chef/mixin/params_validate" +require "chef/node" +require "chef/resource_collection" + +class Chef + # == Chef::Runner + # This class is responsible for executing the steps in a Chef run. + class Runner + + attr_reader :run_context + + include Chef::Mixin::ParamsValidate + + def initialize(run_context) + @run_context = run_context + end + + def delayed_actions + @run_context.delayed_actions + end + + def events + @run_context.events + end + + # Determine the appropriate provider for the given resource, then + # execute it. + def run_action(resource, action, notification_type = nil, notifying_resource = nil) + # If there are any before notifications, why-run the resource + # and notify anyone who needs notifying + before_notifications = run_context.before_notifications(resource) || [] + unless before_notifications.empty? + forced_why_run do + Chef::Log.info("#{resource} running why-run #{action} action to support before action") + resource.run_action(action, notification_type, notifying_resource) + end + + if resource.updated_by_last_action? + before_notifications.each do |notification| + Chef::Log.info("#{resource} sending #{notification.action} action to #{notification.resource} (before)") + run_action(notification.resource, notification.action, :before, resource) + end + resource.updated_by_last_action(false) + end + end + + # Actually run the action for realsies + resource.run_action(action, notification_type, notifying_resource) + + # Execute any immediate and queue up any delayed notifications + # associated with the resource, but only if it was updated *this time* + # we ran an action on it. + if resource.updated_by_last_action? + run_context.immediate_notifications(resource).each do |notification| + Chef::Log.info("#{resource} sending #{notification.action} action to #{notification.resource} (immediate)") + run_action(notification.resource, notification.action, :immediate, resource) + end + + run_context.delayed_notifications(resource).each do |notification| + # send the notification to the run_context of the receiving resource + notification.resource.run_context.add_delayed_action(notification) + end + end + end + + # Iterates over the +resource_collection+ in the +run_context+ calling + # +run_action+ for each resource in turn. + def converge + # Resolve all lazy/forward references in notifications + run_context.resource_collection.each do |resource| + resource.resolve_notification_references + end + + # Execute each resource. + run_context.resource_collection.execute_each_resource do |resource| + Array(resource.action).each { |action| run_action(resource, action) } + end + + rescue Exception => e + Chef::Log.info "Running queued delayed notifications before re-raising exception" + run_delayed_notifications(e) + else + run_delayed_notifications(nil) + true + end + + private + + # Run all our :delayed actions + def run_delayed_notifications(error = nil) + collected_failures = Exceptions::MultipleFailures.new + collected_failures.client_run_failure(error) unless error.nil? + delayed_actions.each do |notification| + result = run_delayed_notification(notification) + if result.kind_of?(Exception) + collected_failures.notification_failure(result) + end + end + collected_failures.raise! + end + + def run_delayed_notification(notification) + Chef::Log.info( "#{notification.notifying_resource} sending #{notification.action}"\ + " action to #{notification.resource} (delayed)") + # Struct of resource/action to call + run_action(notification.resource, notification.action, :delayed) + true + rescue Exception => e + e + end + + # helper to run a block of code with why_run forced to true and then restore it correctly + def forced_why_run + saved = Chef::Config[:why_run] + Chef::Config[:why_run] = true + yield + ensure + Chef::Config[:why_run] = saved + end + + end +end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/property.rb b/cookbooks/compat_resource/files/lib/chef_compat/property.rb new file mode 100644 index 0000000..be21113 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/property.rb @@ -0,0 +1,6 @@ +require 'chef_compat/copied_from_chef/chef/property' + +module ChefCompat + class Property < ChefCompat::CopiedFromChef::Chef::Property + end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/recipe.rb b/cookbooks/compat_resource/files/lib/chef_compat/recipe.rb new file mode 100644 index 0000000..86e39d9 --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/recipe.rb @@ -0,0 +1,8 @@ +require 'chef/recipe' +require 'chef_compat/copied_from_chef/chef/dsl/recipe' + +module ChefCompat + class Recipe < Chef::Recipe + include ChefCompat::CopiedFromChef::Chef::DSL::Recipe::FullDSL + end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/resource.rb b/cookbooks/compat_resource/files/lib/chef_compat/resource.rb new file mode 100644 index 0000000..bcf0fdb --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/resource.rb @@ -0,0 +1,56 @@ +require 'chef_compat/monkeypatches' +require 'chef_compat/copied_from_chef/chef/resource' + +# We do NOT want action defined if chefspec is engaged +if Chef::Provider::InlineResources::ClassMethods.instance_method(:action).source_location[0] =~ /chefspec/ + ChefCompat::CopiedFromChef::Chef::Provider::InlineResources::ClassMethods.instance_eval do + remove_method(:action) + end +end + +module ChefCompat + class Resource < ChefCompat::CopiedFromChef::Chef::Resource + def initialize(*args, &block) + super + # @resource_name is used in earlier Chef versions + @resource_name = self.class.resource_name + end + # Things we'll need to define ourselves: + # 1. provider + # 2. resource_name + + def provider(*args, &block) + super || self.class.action_class + end + def provider=(arg) + provider(arg) + end + + if !respond_to?(:resource_name) + def self.resource_name(name=Chef::NOT_PASSED) + # Setter + if name != Chef::NOT_PASSED + # remove_canonical_dsl + + # Set the resource_name and call provides + if name + name = name.to_sym + # If our class is not already providing this name, provide it. + # Commented out: use of resource_name and provides will need to be + # mutually exclusive in this world, generally. + # if !Chef::ResourceResolver.includes_handler?(name, self) + provides name#, canonical: true + # end + @resource_name = name + else + @resource_name = nil + end + end + @resource_name + end + def self.resource_name=(name) + resource_name(name) + end + end + end +end diff --git a/cookbooks/compat_resource/files/lib/chef_compat/resource/lwrp_base.rb b/cookbooks/compat_resource/files/lib/chef_compat/resource/lwrp_base.rb new file mode 100644 index 0000000..2ebb98f --- /dev/null +++ b/cookbooks/compat_resource/files/lib/chef_compat/resource/lwrp_base.rb @@ -0,0 +1,44 @@ +require 'chef_compat/resource' +require 'chef_compat/copied_from_chef/chef/resource' +require 'chef/mixin/convert_to_class_name' +require 'chef/mixin/from_file' + +module ChefCompat + class Resource < ChefCompat::CopiedFromChef::Chef::Resource + class LWRPBase < ChefCompat::Resource + class<= 12.0").satisfied_by?(Gem::Version.new(Chef::VERSION)) + + require 'chef_compat/resource' + require 'chef_compat/property' + require 'chef_compat/mixin/properties' + + resources_dir = File.expand_path("chef_compat/copied_from_chef/chef/resource", File.dirname(__FILE__)) + providers_dir = File.expand_path("chef_compat/copied_from_chef/chef/provider", File.dirname(__FILE__)) + Dir["#{resources_dir}/*.rb"].each {|file| require file } + Dir["#{providers_dir}/*.rb"].each {|file| require file } +else + + class Chef + class Resource + def self.property(args, &block) + raise_chef_11_error + end + + def self.resource_name(args, &block) + raise_chef_11_error + end + + def self.action(args, &block) + raise_chef_11_error + end + + def self.raise_chef_11_error + raise "This resource is written with Chef 12.5 custom resources, and requires at least Chef 12.0 used with the compat_resource cookbook, it will not work with Chef 11.x clients, and those users must pin their cookbooks to older versions or upgrade." + end + end + end + +end diff --git a/cookbooks/compat_resource/libraries/autoload.rb b/cookbooks/compat_resource/libraries/autoload.rb new file mode 100644 index 0000000..db52cfc --- /dev/null +++ b/cookbooks/compat_resource/libraries/autoload.rb @@ -0,0 +1,31 @@ +unless Gem::Requirement.new(">= 12.0").satisfied_by?(Gem::Version.new(Chef::VERSION)) + raise "This resource is written with Chef 12.5 custom resources, and requires at least Chef 12.0 used with the compat_resource cookbook, it will not work with Chef 11.x clients, and those users must pin their cookbooks to older versions or upgrade." +end + +# If users are on old verisons of ChefDK which activates an (old) gem via cheffish before this cookbook loads, then +# we just try to monkeypatch over the top of a monkeypatch. Its possible that we have checks in this cookbook which +# will defeat that purpose and fail to monkeypatch on top of monkeypatches -- in which case those checks should be +# removed -- this cookbook needs to win when it gets into a fight with the old gem versions. +if Gem.loaded_specs["compat_resource"] + Chef.log_deprecation "using compat_resource as a gem is deprecated; please update cheffish and chef-provisioning gems (or use the latest Chef/ChefDK packages) or else manually pin your compat_resource cookbook version to the same version as the gem you are using to remove this warning" +end + +# we want to not pollute the libpath with our files until after we've done the version check +require_relative '../files/lib/chef_upstream_version' + +# on any chef client later than the one we were based off of we just turn into a no-op +if Gem::Requirement.new("< #{ChefCompat::CHEF_UPSTREAM_VERSION}").satisfied_by?(Gem::Version.new(Chef::VERSION)) + Chef::Log.debug "loading compat_resource based on chef-version #{ChefCompat::CHEF_UPSTREAM_VERSION} over chef version #{Gem::Version.new(Chef::VERSION)}" + $LOAD_PATH.unshift(File.expand_path("../files/lib", File.dirname(__FILE__))) + require 'compat_resource' +else + Chef::Log.debug "NOT LOADING compat_resource based on chef-version #{ChefCompat::CHEF_UPSTREAM_VERSION} over chef version #{Gem::Version.new(Chef::VERSION)}" + unless defined?(ChefCompat::Resource) && defined?(ChefCompat::Mixin::Properties) + module ChefCompat + Resource = Chef::Resource + module Mixin + Properties = Chef::Mixin::Properties + end + end + end +end diff --git a/cookbooks/compat_resource/metadata.json b/cookbooks/compat_resource/metadata.json new file mode 100644 index 0000000..af64b50 --- /dev/null +++ b/cookbooks/compat_resource/metadata.json @@ -0,0 +1 @@ +{"name":"compat_resource","version":"12.16.3","description":"Backports functionality introduced in the latest chef-client releases to any chef-client from 12.1 onwards","long_description":"# compat_resource cookbook\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/compat_resource.svg?branch=master)](https://travis-ci.org/chef-cookbooks/compat_resource) [![Cookbook Version](https://img.shields.io/cookbook/v/compat_resource.svg)](https://supermarket.chef.io/cookbooks/compat_resource)\n\nThis cookbook backports functionality introduced in the latest chef-client releases to any chef-client from 12.1 onwards. This includes [Custom Resource](https://docs.chef.io/custom_resources.html) functionality, notification improvements, as well as new resources added to core chef. It allows for the usage of these new resources in cookbooks without requiring the very latest Chef client release.\n\n## Backported functionality\n\n- [Custom Resources](https://docs.chef.io/custom_resources.html)\n- [apt_repository](https://docs.chef.io/resource_apt_repository.html)\n- [apt_update](https://docs.chef.io/resource_apt_update.html)\n- [systemd_unit](https://docs.chef.io/resource_systemd_unit.html)\n- [yum_repository](https://docs.chef.io/resource_yum_repository.html)\n- [:before notifications](https://docs.chef.io/resources.html#timers)\n\n## Requirements\n\n### Platforms\n\n- All platforms supported by Chef\n\n### Chef\n\n- Chef 12.1+\n\n### Cookbooks\n\n- none\n\n## Usage\n\nTo use this cookbook, put `depends 'compat_resource'` in the metadata.rb of your cookbook. Once this is done, you can use all the new custom resource features to define resources. It Just Works.\n\n## Custom Resources?\n\nCurious about how to use custom resources?\n\n- Docs: \n- Slides: \n\n## License & Authors\n\n- Author:: Lamont Granquist ([lamont@chef.io](mailto:lamont@chef.io))\n- Author:: John Keiser ([jkeiser@chef.io](mailto:jkeiser@chef.io))\n\n```text\nCopyright:: 2015-2016 Chef Software, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","maintainer":"Lamont Granquist","maintainer_email":"lamont@chef.io","license":"Apache 2.0","platforms":{},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{},"source_url":"https://github.com/chef-cookbooks/compat_resource","issues_url":"https://github.com/chef-cookbooks/compat_resource/issues","chef_version":">= 12.1","ohai_version":{}} \ No newline at end of file diff --git a/cookbooks/firewall/CHANGELOG.md b/cookbooks/firewall/CHANGELOG.md index 7282a14..bcc623c 100644 --- a/cookbooks/firewall/CHANGELOG.md +++ b/cookbooks/firewall/CHANGELOG.md @@ -2,6 +2,33 @@ firewall Cookbook CHANGELOG ======================= This file is used to list changes made in each version of the firewall cookbook. +v2.5.4 (2017-02-13) +------------------- +* Update Test Kitchen platforms to the latest +* Update copyright headers +* Allow package options to be passed through to the package install for firewall +* Define policy for Windows Firewall and use the attributes to set desired policy + +v2.5.3 (2016-10-26) +------------------- +* Don't show firewall resource as updated (#133) +* Add :off as a valid logging level (#129) +* Add support for Ubuntu 16.04 (#149) + +v2.5.2 (2016-06-02) +------------------- +* Don't issue commands when firewalld isn't active (#140) +* Install iptables-services on CentOS >= 7 (#131) +* Update Ruby version on Travis for listen gem + +v2.5.1 (2016-05-31) +------------------- +* Protocol guard incorrectly prevents "none" protocol type on UFW helper (#128) +* Fix wrongly ordered conditional for converting ports to strings using port_to_s +* Fix notify_firewall attribute crashing firewall_rule provider (#130) +* Add warning if firewall rule opens all traffic (#132) +* Add ipv6 attribute respect to Ubuntu iptables (#138) + v2.5.0 (2016-03-08) ------------------- * Don't modify parameter for port (#120) diff --git a/cookbooks/firewall/MAINTAINERS.md b/cookbooks/firewall/MAINTAINERS.md new file mode 100644 index 0000000..5db5fac --- /dev/null +++ b/cookbooks/firewall/MAINTAINERS.md @@ -0,0 +1,19 @@ + + +# Maintainers +This file lists how this cookbook project is maintained. When making changes to the system, this +file tells you who needs to review your patch - you need a simple majority of maintainers +for the relevant subsystems to provide a :+1: on your pull request. Additionally, you need +to not receive a veto from a Lieutenant or the Project Lead. + +Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) +for details on the process and how to become a maintainer or the project lead. + +# Project Maintainer +* [Martin Smith](https://github.com/martinb3) + +# Maintainers +* [Jennifer Davis](https://github.com/sigje) +* [Tim Smith](https://github.com/tas50) +* [Thom May](https://github.com/thommay) +* [Martin Smith](https://github.com/martinb3) diff --git a/cookbooks/firewall/README.md b/cookbooks/firewall/README.md index 9d08b22..532968a 100644 --- a/cookbooks/firewall/README.md +++ b/cookbooks/firewall/README.md @@ -10,7 +10,7 @@ PLEASE NOTE - The resource/providers in this cookbook are under heavy developmen Requirements ------------ -**Chef 12.4.x+** is required. We are currently testing against 12.5.1. If you need Chef 11 support, please try pinning back to a version less than 2.0, e.g.: +**Chef 12.4.x+** is required. We are currently testing against 12.8.1. If you need Chef 11 support, please try pinning back to a version less than 2.0, e.g.: ``` depends 'firewall', '< 2.0' ``` @@ -22,7 +22,7 @@ depends 'firewall', '< 2.0' * Windows Advanced Firewall - 2012 R2 Tested on: -* Ubuntu 12.04 & 14.04 with iptables, ufw +* Ubuntu 12.04, 14.04, 16.04 with iptables, ufw * Debian 7.8, 8.1 with ufw * CentOS 5.11, 6.7 with iptables * CentOS 7.1 with firewalld @@ -58,16 +58,18 @@ node.default['firewall']['iptables']['defaults'][:ruleset] = { '*filter' => 1, ':INPUT DROP' => 2, ':FORWARD DROP' => 3, - ':OUTPUT ACCEPT' => 4, + ':OUTPUT ACCEPT_FILTER' => 4, 'COMMIT_FILTER' => 100, '*nat' => 101, ':PREROUTING DROP' => 102, ':POSTROUTING DROP' => 103, - ':OUTPUT ACCEPT' => 104, + ':OUTPUT ACCEPT_NAT' => 104, 'COMMIT_NAT' => 200 } ``` +Note -- in order to support multiple hash keys containing the same rule, anything found after the underscore will be stripped for: `:OUTPUT :INPUT :POSTROUTING :PREROUTING COMMIT`. This allows an example like the above to be reduced to just repeated lines of `COMMIT` and `:OUTPUT ACCEPT` while still avoiding duplication of other things. + Then it's trivial to add additional rules to the `*nat` table using the raw parameter: ``` firewall_rule "postroute" do @@ -96,6 +98,8 @@ The default recipe creates a firewall resource with action install, and if `node * `default['firewall']['ufw']['defaults']` hash for template `/etc/default/ufw` * `default['firewall']['iptables']['defaults']` hash for default policies for 'filter' table's chains` +* `default['firewall']['windows']['defaults']` hash to define inbound / outbound firewall policy on Windows platform + * `default['firewall']['allow_established'] = true`, set to false if you don't want a related/established default rule on iptables * `default['firewall']['ipv6_enabled'] = true`, set to false if you don't want IPv6 related/established default rule on iptables (this enables ICMPv6, which is required for much of IPv6 communication) @@ -117,10 +121,11 @@ The default recipe creates a firewall resource with action install, and if `node - `disabled` (default to `false`): If set to true, all actions will no-op on this resource. This is a way to prevent included cookbooks from configuring a firewall. - `ipv6_enabled` (default to `true`): If set to false, firewall will not perform any ipv6 related work. Currently only supported in iptables. -- `log_level`: UFW only. Level of verbosity the firewall should log at. valid values are: :low, :medium, :high, :full. default is :low. +- `log_level`: UFW only. Level of verbosity the firewall should log at. valid values are: :low, :medium, :high, :full, :off. default is :low. - `rules`: This is used internally for firewall_rule resources to append their rules. You should NOT touch this value unless you plan to supply an entire firewall ruleset at once, and skip using firewall_rule resources. - `disabled_zone` (firewalld only): The zone to set on firewalld when the firewall should be disabled. Can be any string in symbol form, e.g. :public, :drop, etc. Defaults to `:public.` - `enabled_zone` (firewalld only): The zone to set on firewalld when the firewall should be enabled. Can be any string in symbol form, e.g. :public, :drop, etc. Defaults to `:drop.` +- `package_options`: Used to pass options to the package install of firewall #### Examples diff --git a/cookbooks/firewall/attributes/windows.rb b/cookbooks/firewall/attributes/windows.rb new file mode 100644 index 0000000..68c6c05 --- /dev/null +++ b/cookbooks/firewall/attributes/windows.rb @@ -0,0 +1,8 @@ +# Windows platform defult settings: block undefined inbould traffic, allow all outgoing traffic + +default['firewall']['windows']['defaults'] = { + policy: { + input: 'blockinbound', + output: 'allowoutbound' + } +} diff --git a/cookbooks/firewall/libraries/helpers.rb b/cookbooks/firewall/libraries/helpers.rb index abc7c0d..38a8fad 100644 --- a/cookbooks/firewall/libraries/helpers.rb +++ b/cookbooks/firewall/libraries/helpers.rb @@ -78,8 +78,9 @@ module FirewallCookbook contents << "# position #{sorted_value}" rules.each do |k, v| next unless v == sorted_value - contents << if k.start_with?('COMMIT') - 'COMMIT' + + contents << if repeatable_directives(k) + k[/[^_]+/] else k end @@ -87,5 +88,13 @@ module FirewallCookbook end "#{contents.join("\n")}\n" end + + def repeatable_directives(s) + %w(:OUTPUT :INPUT :POSTROUTING :PREROUTING COMMIT).each do |special| + return true if s.start_with?(special) + end + + false + end end end diff --git a/cookbooks/firewall/libraries/helpers_firewalld.rb b/cookbooks/firewall/libraries/helpers_firewalld.rb index 6245b87..aa3019f 100644 --- a/cookbooks/firewall/libraries/helpers_firewalld.rb +++ b/cookbooks/firewall/libraries/helpers_firewalld.rb @@ -18,11 +18,15 @@ module FirewallCookbook end def firewalld_default_zone?(z) + raise false unless firewalld_active? + cmd = shell_out('firewall-cmd', '--get-default-zone') cmd.stdout =~ /^#{z.to_s}$/ end def firewalld_default_zone!(z) + raise 'firewall not active' unless firewalld_active? + shell_out!('firewall-cmd', "--set-default-zone=#{z}") end @@ -31,6 +35,8 @@ module FirewallCookbook end def firewalld_flush! + raise 'firewall not active' unless firewalld_active? + shell_out!('firewall-cmd', '--direct', '--remove-rules', 'ipv4', 'filter', 'INPUT') shell_out!('firewall-cmd', '--direct', '--remove-rules', 'ipv4', 'filter', 'OUTPUT') shell_out!('firewall-cmd', '--direct', '--permanent', '--remove-rules', 'ipv4', 'filter', 'INPUT') @@ -38,12 +44,16 @@ module FirewallCookbook end def firewalld_all_rules_permanent! + raise 'firewall not active' unless firewalld_active? + rules = shell_out!('firewall-cmd', '--direct', '--get-all-rules').stdout perm_rules = shell_out!('firewall-cmd', '--direct', '--permanent', '--get-all-rules').stdout rules == perm_rules end def firewalld_save! + raise 'firewall not active' unless firewalld_active? + shell_out!('firewall-cmd', '--direct', '--permanent', '--remove-rules', 'ipv4', 'filter', 'INPUT') shell_out!('firewall-cmd', '--direct', '--permanent', '--remove-rules', 'ipv4', 'filter', 'OUTPUT') shell_out!('firewall-cmd', '--direct', '--get-all-rules').stdout.lines do |line| diff --git a/cookbooks/firewall/libraries/helpers_iptables.rb b/cookbooks/firewall/libraries/helpers_iptables.rb index 44c1c7d..5797d17 100644 --- a/cookbooks/firewall/libraries/helpers_iptables.rb +++ b/cookbooks/firewall/libraries/helpers_iptables.rb @@ -49,11 +49,18 @@ module FirewallCookbook end def iptables_packages(new_resource) - if ipv6_enabled?(new_resource) - %w(iptables iptables-ipv6) - else - %w(iptables) + packages = if ipv6_enabled?(new_resource) + %w(iptables iptables-ipv6) + else + %w(iptables) + end + + # centos 7 requires extra service + if !ubuntu?(node) && node['platform_version'].to_i >= 7 + packages << %w(iptables-services) end + + packages.flatten end def iptables_commands(new_resource) diff --git a/cookbooks/firewall/libraries/helpers_ufw.rb b/cookbooks/firewall/libraries/helpers_ufw.rb index 7b94976..3844272 100644 --- a/cookbooks/firewall/libraries/helpers_ufw.rb +++ b/cookbooks/firewall/libraries/helpers_ufw.rb @@ -46,7 +46,7 @@ module FirewallCookbook end # if we don't do this, ufw will fail as it does not support protocol numbers, so we'll only allow it to run if specifying icmp/tcp/udp protocol types - if new_resource.protocol && !new_resource.protocol.to_s.downcase.match('^(tcp|udp|icmp)$') + if new_resource.protocol && !new_resource.protocol.to_s.downcase.match('^(tcp|udp|icmp|esp|ah|ipv6|none)$') msg = '' msg << "firewall_rule[#{new_resource.name}] was asked to " msg << "#{new_resource.command} a rule using protocol #{new_resource.protocol} " @@ -74,7 +74,13 @@ module FirewallCookbook rule << rule_proto(new_resource) rule << rule_dest_port(new_resource) rule << rule_source_port(new_resource) - rule.strip + rule = rule.strip + + if rule == 'ufw allow in proto tcp to any from any' + Chef::Log.warn("firewall_rule[#{new_resource.name}] produced a rule that opens all traffic. This may be a logic error in your cookbook.") + end + + rule end def rule_interface(new_resource) diff --git a/cookbooks/firewall/libraries/helpers_windows.rb b/cookbooks/firewall/libraries/helpers_windows.rb index 5fdde3e..391581b 100644 --- a/cookbooks/firewall/libraries/helpers_windows.rb +++ b/cookbooks/firewall/libraries/helpers_windows.rb @@ -60,7 +60,7 @@ module FirewallCookbook parameters['dir'] = new_resource.direction new_resource.program && parameters['program'] = new_resource.program - parameters['service'] = new_resource.service ? new_resource.service : 'any' + new_resource.service && parameters['service'] = new_resource.service parameters['protocol'] = new_resource.protocol if new_resource.direction.to_sym == :out @@ -68,7 +68,7 @@ module FirewallCookbook parameters['localport'] = new_resource.source_port ? port_to_s(new_resource.source_port) : 'any' parameters['interfacetype'] = new_resource.interface ? new_resource.interface : 'any' parameters['remoteip'] = new_resource.destination ? fixup_cidr(new_resource.destination) : 'any' - parameters['remoteport'] = port_to_s(new_resource.dest_port) ? new_resource.dest_port : 'any' + parameters['remoteport'] = new_resource.dest_port ? port_to_s(new_resource.dest_port) : 'any' else parameters['localip'] = new_resource.destination ? new_resource.destination : 'any' parameters['localport'] = dport_calc(new_resource) ? port_to_s(dport_calc(new_resource)) : 'any' diff --git a/cookbooks/firewall/libraries/provider_firewall_firewalld.rb b/cookbooks/firewall/libraries/provider_firewall_firewalld.rb index 84c97f7..0a9fb40 100644 --- a/cookbooks/firewall/libraries/provider_firewall_firewalld.rb +++ b/cookbooks/firewall/libraries/provider_firewall_firewalld.rb @@ -1,6 +1,6 @@ # # Author:: Ronald Doorn () -# Cookbook Name:: firewall +# Cookbook:: firewall # Resource:: default # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -33,6 +33,7 @@ class Chef converge_by('install firewalld, create template for /etc/sysconfig') do package 'firewalld' do action :install + options new_resource.package_options end service 'firewalld' do @@ -88,9 +89,13 @@ class Chef firewalld_file.content build_rule_file(new_resource.rules['firewalld']) firewalld_file.run_action(:create) - # ensure the service is running - service 'firewalld' do - action [:enable, :start] + # ensure the service is running without waiting. + firewall_service = service 'firewalld' do + action :nothing + end + [:enable, :start].each do |a| + firewall_service.run_action(a) + new_resource.updated_by_last_action(firewall_service.updated_by_last_action?) end # mark updated if we changed the zone @@ -115,9 +120,11 @@ class Chef action :disable do next if disabled?(new_resource) - firewalld_flush! - firewalld_default_zone!(new_resource.disabled_zone) - new_resource.updated_by_last_action(true) + if firewalld_active? + firewalld_flush! + firewalld_default_zone!(new_resource.disabled_zone) + new_resource.updated_by_last_action(true) + end service 'firewalld' do action [:disable, :stop] @@ -132,6 +139,7 @@ class Chef action :flush do next if disabled?(new_resource) + next unless firewalld_active? firewalld_flush! new_resource.updated_by_last_action(true) diff --git a/cookbooks/firewall/libraries/provider_firewall_iptables.rb b/cookbooks/firewall/libraries/provider_firewall_iptables.rb index a699e9b..afa90af 100644 --- a/cookbooks/firewall/libraries/provider_firewall_iptables.rb +++ b/cookbooks/firewall/libraries/provider_firewall_iptables.rb @@ -1,9 +1,9 @@ # # Author:: Seth Chisamore () -# Cookbook Name:: firewall +# Cookbook:: firewall # Resource:: default # -# Copyright:: 2011, Opscode, Inc. +# Copyright:: 2011-2016, 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/cookbooks/firewall/libraries/provider_firewall_iptables_ubuntu.rb b/cookbooks/firewall/libraries/provider_firewall_iptables_ubuntu.rb index 10c8b89..4491991 100644 --- a/cookbooks/firewall/libraries/provider_firewall_iptables_ubuntu.rb +++ b/cookbooks/firewall/libraries/provider_firewall_iptables_ubuntu.rb @@ -1,9 +1,9 @@ # # Author:: Seth Chisamore () -# Cookbook Name:: firewall +# Cookbook:: firewall # Resource:: default # -# Copyright:: 2011, Opscode, Inc. +# Copyright:: 2011-2016, 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. @@ -23,7 +23,7 @@ class Chef include FirewallCookbook::Helpers::Iptables provides :firewall, os: 'linux', platform_family: %w(debian) do |node| - node['firewall'] && node['firewall']['ubuntu_iptables'] + node['platform_version'].to_f > 14.04 && node['firewall'] && node['firewall']['ubuntu_iptables'] end def whyrun_supported? @@ -41,7 +41,9 @@ class Chef end end - %w(rules.v4 rules.v6).each do |svc| + rule_files = %w(rules.v4) + rule_files << 'rules.v6' if ipv6_enabled?(new_resource) + rule_files.each do |svc| # must create empty file for service to start file "create empty /etc/iptables/#{svc}" do path "/etc/iptables/#{svc}" @@ -50,8 +52,9 @@ class Chef end end - service 'iptables-persistent' do + service 'netfilter-persistent' do action [:enable, :start] + status_command 'true' # netfilter-persistent isn't a real service end end end @@ -90,7 +93,10 @@ class Chef end end - %w(iptables ip6tables).each do |iptables_type| + rule_files = %w(iptables) + rule_files << 'ip6tables' if ipv6_enabled?(new_resource) + + rule_files.each do |iptables_type| iptables_filename = if iptables_type == 'ip6tables' '/etc/iptables/rules.v6' else @@ -110,7 +116,7 @@ class Chef # if the file was changed, restart iptables next unless iptables_file.updated_by_last_action? - service_affected = service 'iptables-persistent' do + service_affected = service 'netfilter-persistent' do action :nothing end @@ -126,7 +132,7 @@ class Chef iptables_default_allow!(new_resource) new_resource.updated_by_last_action(true) - service 'iptables-persistent' do + service 'netfilter-persistent' do action [:disable, :stop] end @@ -146,7 +152,9 @@ class Chef iptables_flush!(new_resource) new_resource.updated_by_last_action(true) - %w(rules.v4 rules.v6).each do |svc| + rule_files = %w(rules.v4) + rule_files << 'rules.v6' if ipv6_enabled?(new_resource) + rule_files.each do |svc| # must create empty file for service to start file "create empty /etc/iptables/#{svc}" do path "/etc/iptables/#{svc}" diff --git a/cookbooks/firewall/libraries/provider_firewall_iptables_ubuntu1404.rb b/cookbooks/firewall/libraries/provider_firewall_iptables_ubuntu1404.rb new file mode 100644 index 0000000..b4c0200 --- /dev/null +++ b/cookbooks/firewall/libraries/provider_firewall_iptables_ubuntu1404.rb @@ -0,0 +1,166 @@ +# +# Author:: Seth Chisamore () +# Cookbook Name:: firewall +# Resource:: default +# +# Copyright:: 2011, Opscode, Inc. +# +# 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. +# +class Chef + class Provider::FirewallIptablesUbuntu1404 < Chef::Provider::LWRPBase + include FirewallCookbook::Helpers + include FirewallCookbook::Helpers::Iptables + + provides :firewall, os: 'linux', platform_family: %w(debian) do |node| + node['platform_version'].to_f <= 14.04 && node['firewall'] && node['firewall']['ubuntu_iptables'] + end + + def whyrun_supported? + false + end + + action :install do + next if disabled?(new_resource) + + converge_by('install iptables and enable/start services') do + # Can't pass an array without breaking chef 11 support + %w(iptables-persistent).each do |p| + package p do + action :install + end + end + + rule_files = %w(rules.v4) + rule_files << 'rules.v6' if ipv6_enabled?(new_resource) + rule_files.each do |svc| + # must create empty file for service to start + file "create empty /etc/iptables/#{svc}" do + path "/etc/iptables/#{svc}" + content '# created by chef to allow service to start' + not_if { ::File.exist?("/etc/iptables/#{svc}") } + end + end + + service 'iptables-persistent' do + action [:enable, :start] + status_command 'true' # iptables-persistent isn't a real service + end + end + end + + action :restart do + next if disabled?(new_resource) + + # prints all the firewall rules + log_iptables(new_resource) + + # ensure it's initialized + new_resource.rules({}) unless new_resource.rules + ensure_default_rules_exist(node, new_resource) + + # this populates the hash of rules from firewall_rule resources + firewall_rules = run_context.resource_collection.select { |item| item.is_a?(Chef::Resource::FirewallRule) } + firewall_rules.each do |firewall_rule| + next unless firewall_rule.action.include?(:create) && !firewall_rule.should_skip?(:create) + + types = if ipv6_rule?(firewall_rule) # an ip4 specific rule + %w(ip6tables) + elsif ipv4_rule?(firewall_rule) # an ip6 specific rule + %w(iptables) + else # or not specific + %w(iptables ip6tables) + end + + types.each do |iptables_type| + # build rules to apply with weight + k = build_firewall_rule(node, firewall_rule, iptables_type == 'ip6tables') + v = firewall_rule.position + + # unless we're adding them for the first time.... bail out. + next if new_resource.rules[iptables_type].key?(k) && new_resource.rules[iptables_type][k] == v + new_resource.rules[iptables_type][k] = v + end + end + + rule_files = %w(iptables) + rule_files << 'ip6tables' if ipv6_enabled?(new_resource) + + rule_files.each do |iptables_type| + iptables_filename = if iptables_type == 'ip6tables' + '/etc/iptables/rules.v6' + else + '/etc/iptables/rules.v4' + end + + # ensure a file resource exists with the current iptables rules + begin + iptables_file = run_context.resource_collection.find(file: iptables_filename) + rescue + iptables_file = file iptables_filename do + action :nothing + end + end + iptables_file.content build_rule_file(new_resource.rules[iptables_type]) + iptables_file.run_action(:create) + + # if the file was changed, restart iptables + next unless iptables_file.updated_by_last_action? + service_affected = service 'iptables-persistent' do + action :nothing + end + + new_resource.notifies(:restart, service_affected, :delayed) + new_resource.updated_by_last_action(true) + end + end + + action :disable do + next if disabled?(new_resource) + + iptables_flush!(new_resource) + iptables_default_allow!(new_resource) + new_resource.updated_by_last_action(true) + + service 'iptables-persistent' do + action [:disable, :stop] + end + + %w(rules.v4 rules.v6).each do |svc| + # must create empty file for service to start + file "create empty /etc/iptables/#{svc}" do + path "/etc/iptables/#{svc}" + content '# created by chef to allow service to start' + action :create + end + end + end + + action :flush do + next if disabled?(new_resource) + + iptables_flush!(new_resource) + new_resource.updated_by_last_action(true) + + rule_files = %w(rules.v4) + rule_files << 'rules.v6' if ipv6_enabled?(new_resource) + rule_files.each do |svc| + # must create empty file for service to start + file "create empty /etc/iptables/#{svc}" do + path "/etc/iptables/#{svc}" + content '# created by chef to allow service to start' + end + end + end + end +end diff --git a/cookbooks/firewall/libraries/provider_firewall_rule.rb b/cookbooks/firewall/libraries/provider_firewall_rule.rb index 8018a52..f448610 100644 --- a/cookbooks/firewall/libraries/provider_firewall_rule.rb +++ b/cookbooks/firewall/libraries/provider_firewall_rule.rb @@ -1,9 +1,9 @@ # # Author:: Ronald Doorn () -# Cookbook Name:: firewall +# Cookbook:: firewall # Provider:: rule_iptables # -# Copyright 2015, computerlyrik +# Copyright:: 2015-2016, computerlyrik # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -22,13 +22,13 @@ class Chef provides :firewall_rule action :create do - return unless new_resource.notify_firewall + if new_resource.notify_firewall + firewall_resource = run_context.resource_collection.find(firewall: new_resource.firewall_name) + raise 'could not find a firewall resource' unless firewall_resource - firewall_resource = run_context.resource_collection.find(firewall: new_resource.firewall_name) - raise 'could not find a firewall resource' unless firewall_resource - - new_resource.notifies(:restart, firewall_resource, :delayed) - new_resource.updated_by_last_action(true) + new_resource.notifies(:restart, firewall_resource, :delayed) + new_resource.updated_by_last_action(true) + end end end end diff --git a/cookbooks/firewall/libraries/provider_firewall_ufw.rb b/cookbooks/firewall/libraries/provider_firewall_ufw.rb index 3299a7b..25e5a12 100644 --- a/cookbooks/firewall/libraries/provider_firewall_ufw.rb +++ b/cookbooks/firewall/libraries/provider_firewall_ufw.rb @@ -1,9 +1,9 @@ # # Author:: Seth Chisamore () -# Cookbook Name:: firewall +# Cookbook:: firewall # Resource:: default # -# Copyright:: 2011, Opscode, Inc. +# Copyright:: 2011-2016, 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/cookbooks/firewall/libraries/provider_firewall_windows.rb b/cookbooks/firewall/libraries/provider_firewall_windows.rb index 3fcf0e3..0d242b2 100644 --- a/cookbooks/firewall/libraries/provider_firewall_windows.rb +++ b/cookbooks/firewall/libraries/provider_firewall_windows.rb @@ -1,6 +1,6 @@ # # Author:: Sander van Harmelen () -# Cookbook Name:: firewall +# Cookbook:: firewall # Provider:: windows # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -29,10 +29,13 @@ class Chef action :install do next if disabled?(new_resource) - converge_by('enable and start Windows Firewall service') do - service 'MpsSvc' do - action [:enable, :start] - end + svc = service 'MpsSvc' do + action :nothing + end + + [:enable, :start].each do |act| + svc.run_action(act) + new_resource.updated_by_last_action(true) if svc.updated_by_last_action? end end @@ -57,6 +60,13 @@ class Chef end end + input_policy = node['firewall']['windows']['defaults']['policy']['input'] + output_policy = node['firewall']['windows']['defaults']['policy']['output'] + unless new_resource.rules['windows'].key?("set currentprofile firewallpolicy #{input_policy},#{output_policy}") + # Make this the possible last rule in the list + new_resource.rules['windows']["set currentprofile firewallpolicy #{input_policy},#{output_policy}"] = 99999 + end + # ensure a file resource exists with the current rules begin windows_file = run_context.resource_collection.find(file: windows_rules_filename) @@ -87,18 +97,21 @@ class Chef action :disable do next if disabled?(new_resource) - converge_by('disable and stop Windows Firewall service') do - if active? - disable! - Chef::Log.info("#{new_resource} disabled.") - new_resource.updated_by_last_action(true) - else - Chef::Log.debug("#{new_resource} already disabled.") - end + if active? + disable! + Chef::Log.info("#{new_resource} disabled.") + new_resource.updated_by_last_action(true) + else + Chef::Log.debug("#{new_resource} already disabled.") + end - service 'MpsSvc' do - action [:disable, :stop] - end + svc = service 'MpsSvc' do + action :nothing + end + + [:disable, :stop].each do |act| + svc.run_action(act) + new_resource.updated_by_last_action(true) if svc.updated_by_last_action? end end @@ -107,6 +120,7 @@ class Chef reset! Chef::Log.info("#{new_resource} reset.") + new_resource.updated_by_last_action(true) end end end diff --git a/cookbooks/firewall/libraries/resource_firewall.rb b/cookbooks/firewall/libraries/resource_firewall.rb index 0959e1c..3920f8f 100644 --- a/cookbooks/firewall/libraries/resource_firewall.rb +++ b/cookbooks/firewall/libraries/resource_firewall.rb @@ -10,7 +10,7 @@ class Chef attribute(:disabled, kind_of: [TrueClass, FalseClass], default: false) attribute(:enabled, kind_of: [TrueClass, FalseClass], default: true) - attribute(:log_level, kind_of: Symbol, equal_to: [:low, :medium, :high, :full], default: :low) + attribute(:log_level, kind_of: Symbol, equal_to: [:low, :medium, :high, :full, :off], default: :low) attribute(:rules, kind_of: Hash) # for firewalld, specify the zone when firewall is disable and enabled @@ -19,5 +19,8 @@ class Chef # for firewall implementations where ipv6 can be skipped (currently iptables-specific) attribute(:ipv6_enabled, kind_of: [TrueClass, FalseClass], default: true) + + # allow override of package options for firewalld package + attribute(:package_options, kind_of: String, default: nil) end end diff --git a/cookbooks/firewall/libraries/resource_firewall_rule.rb b/cookbooks/firewall/libraries/resource_firewall_rule.rb index 274a874..cbf8480 100644 --- a/cookbooks/firewall/libraries/resource_firewall_rule.rb +++ b/cookbooks/firewall/libraries/resource_firewall_rule.rb @@ -15,10 +15,8 @@ class Chef attribute(:protocol, kind_of: [Integer, Symbol], default: :tcp, callbacks: { 'must be either :tcp, :udp, :icmp, :\'ipv6-icmp\', :icmpv6, :none, or a valid IP protocol number' => lambda do |p| - !!(p.to_s =~ /(udp|tcp|icmp|icmpv6|ipv6-icmp|none)/ || (p.to_s =~ /^\d+$/ && p.between?(0, 142))) - end - } - ) + !!(p.to_s =~ /(udp|tcp|icmp|icmpv6|ipv6-icmp|esp|ah|ipv6|none)/ || (p.to_s =~ /^\d+$/ && p.between?(0, 142))) + end }) attribute(:direction, kind_of: Symbol, equal_to: [:in, :out, :pre, :post], default: :in) attribute(:logging, kind_of: Symbol, equal_to: [:connections, :packets]) diff --git a/cookbooks/firewall/metadata.json b/cookbooks/firewall/metadata.json index e476997..6381404 100644 --- a/cookbooks/firewall/metadata.json +++ b/cookbooks/firewall/metadata.json @@ -1 +1 @@ -{"name":"firewall","version":"2.5.0","description":"Provides a set of primitives for managing firewalls and associated rules.","long_description":"firewall Cookbook\n=================\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/firewall.svg?branch=master)](http://travis-ci.org/chef-cookbooks/firewall)\n[![Cookbook Version](https://img.shields.io/cookbook/v/firewall.svg)](https://supermarket.chef.io/cookbooks/firewall)\n\nProvides a set of primitives for managing firewalls and associated rules.\n\nPLEASE NOTE - The resource/providers in this cookbook are under heavy development. An attempt is being made to keep the resource simple/stupid by starting with less sophisticated firewall implementations first and refactor/vet the resource definition with each successive provider.\n\nRequirements\n------------\n**Chef 12.4.x+** is required. We are currently testing against 12.5.1. If you need Chef 11 support, please try pinning back to a version less than 2.0, e.g.:\n```\ndepends 'firewall', '< 2.0'\n```\n\n### Supported firewalls and platforms\n* UFW - Ubuntu, Debian\n* IPTables - Red Hat & CentOS, Ubuntu\n* FirewallD - Red Hat & CentOS >= 7.0 (IPv4 only support, [needs contributions/testing](https://github.com/chef-cookbooks/firewall/issues/86))\n* Windows Advanced Firewall - 2012 R2\n\nTested on:\n* Ubuntu 12.04 & 14.04 with iptables, ufw\n* Debian 7.8, 8.1 with ufw\n* CentOS 5.11, 6.7 with iptables\n* CentOS 7.1 with firewalld\n* Windows Server 2012r2 with Windows Advanced Firewall\n\nBy default, Ubuntu chooses ufw. To switch to iptables, set this in an attribute file:\n```\ndefault['firewall']['ubuntu_iptables'] = true\n```\n\nBy default, Red Hat & CentOS >= 7.0 chooses firewalld. To switch to iptables, set this in an attribute file:\n```\ndefault['firewall']['redhat7_iptables'] = true\n```\n\n# Considerations that apply to all firewall providers and resources\n\nThis cookbook comes with two resources, firewall and firewall rule. The typical usage scenario is as follows:\n\n- run the `:install` action on the `firewall` resource named 'default', which installs appropriate packages and configures services to start on boot and starts them\n\n- run the `:create` action on every `firewall_rule` resource, which adds to the list of rules that should be configured on the firewall. `firewall_rule` then automatically sends a delayed notification to the `firewall['default']` resource to run the `:restart` action.\n\n- run the delayed notification with action `:restart` on the `firewall` resource. if any rules are different than the last run, the provider will update the current state of the firewall rules to match the expected rules.\n\nThere is a fundamental mismatch between the idea of a chef action and the action that should be taken on a firewall rule. For this reason, the chef action for a firewall_rule may be `:nothing` (the rule should not be present in the firewall) or `:create` (the rule should be present in the firewall), but the action taken on a packet in a firewall (`DROP`, `ACCEPT`, etc) is denoted as a `command` parameter on the `firewall_rule` resource.\n\n# iptables considerations\n\nIf you need to use a table other than `*filter`, the best way to do so is like so:\n```\nnode.default['firewall']['iptables']['defaults'][:ruleset] = {\n '*filter' => 1,\n ':INPUT DROP' => 2,\n ':FORWARD DROP' => 3,\n ':OUTPUT ACCEPT' => 4,\n 'COMMIT_FILTER' => 100,\n '*nat' => 101,\n ':PREROUTING DROP' => 102,\n ':POSTROUTING DROP' => 103,\n ':OUTPUT ACCEPT' => 104,\n 'COMMIT_NAT' => 200\n}\n```\n\nThen it's trivial to add additional rules to the `*nat` table using the raw parameter:\n```\nfirewall_rule \"postroute\" do\n raw \"-A POSTROUTING -o eth1 -p tcp -d 172.28.128.21 -j SNAT --to-source 172.28.128.6\"\n position 150\nend\n```\n\nNote that any line starting with `COMMIT` will become just `COMMIT`, as hash\nkeys must be unique but we need multiple commit lines.\n\n# Recipes\n\n### default\nThe default recipe creates a firewall resource with action install, and if `node['firewall']['allow_ssh']`, opens port 22 from the world.\n\n# Attributes\n\n* `default['firewall']['allow_ssh'] = false`, set true to open port 22 for SSH when the default recipe runs\n* `default['firewall']['allow_mosh'] = false`, set to true to open UDP ports 60000 - 61000 for [Mosh][0] when the default recipe runs\n* `default['firewall']['allow_winrm'] = false`, set true to open port 5989 for WinRM when the default recipe runs\n\n* `default['firewall']['ubuntu_iptables'] = false`, set to true to use iptables on Ubuntu / Debian when using the default recipe\n* `default['firewall']['redhat7_iptables'] = false`, set to true to use iptables on Red Hat / CentOS 7 when using the default recipe\n\n* `default['firewall']['ufw']['defaults']` hash for template `/etc/default/ufw`\n* `default['firewall']['iptables']['defaults']` hash for default policies for 'filter' table's chains`\n\n* `default['firewall']['allow_established'] = true`, set to false if you don't want a related/established default rule on iptables\n* `default['firewall']['ipv6_enabled'] = true`, set to false if you don't want IPv6 related/established default rule on iptables (this enables ICMPv6, which is required for much of IPv6 communication)\n\n* `default['firewall']['firewalld']['permanent'] = false`, set to true if you want firewalld rules to be added with `--permanent` so they survive a reboot. This will be changed to `true` by default in a future major version release.\n\n# Resources\n\n### firewall\n\n***NB***: The name 'default' of this resource is important as it is used for firewall_rule providers to locate the firewall resource. If you change it, you must also supply the same value to any firewall_rule resources using the `firewall_name` parameter.\n\n#### Actions\n- `:install` (*default action*): Install and Enable the firewall. This will ensure the appropriate packages are installed and that any services have been started.\n- `:disable`: Disable the firewall. Drop any rules and put the node in an unprotected state. Flush all current rules. Also erase any internal state used to detect when rules should be applied.\n- `:flush`: Flush all current rules. Also erase any internal state used to detect when rules should be applied.\n- `:save`: Ensure all rules are added permanently under firewalld using `--permanent`. Not supported on ufw, iptables. You must notify this action at the end of the chef run if you want permanent firewalld rules (they are not persistent by default).\n\n#### Parameters\n\n- `disabled` (default to `false`): If set to true, all actions will no-op on this resource. This is a way to prevent included cookbooks from configuring a firewall.\n- `ipv6_enabled` (default to `true`): If set to false, firewall will not perform any ipv6 related work. Currently only supported in iptables.\n- `log_level`: UFW only. Level of verbosity the firewall should log at. valid values are: :low, :medium, :high, :full. default is :low.\n- `rules`: This is used internally for firewall_rule resources to append their rules. You should NOT touch this value unless you plan to supply an entire firewall ruleset at once, and skip using firewall_rule resources.\n- `disabled_zone` (firewalld only): The zone to set on firewalld when the firewall should be disabled. Can be any string in symbol form, e.g. :public, :drop, etc. Defaults to `:public.`\n- `enabled_zone` (firewalld only): The zone to set on firewalld when the firewall should be enabled. Can be any string in symbol form, e.g. :public, :drop, etc. Defaults to `:drop.`\n\n#### Examples\n\n```ruby\n# all defaults\nfirewall 'default'\n\n# enable platform default firewall\nfirewall 'default' do\n action :install\nend\n\n# increase logging past default of 'low'\nfirewall 'default' do\n log_level :high\n action :install\nend\n```\n\n### firewall_rule\n\n#### Actions\n- `:create` (_default action_): If a firewall_rule runs this action, the rule will be recorded in a chef resource's internal state, and applied when providers automatically notify the firewall resource with action `:reload`. The notification happens automatically.\n\n#### Parameters\n\n- `firewall_name`: the matching firewall resource that this rule applies to. Default value: `default`\n\n- `raw`: Used to pass an entire rule as a string, omitting all other parameters. This line will be directly loaded by `iptables-restore`, fed directly into `ufw` on the command line, or run using `firewall-cmd`.\n\n- `description` (_default: same as rule name_): Used to provide a comment that will be included when adding the firewall rule.\n\n- `position` (_default: 50_): **relative** position to insert rule at. Position may be any integer between 0 < n < 100 (exclusive), and more than one rule may specify the same position.\n\n- `command`: What action to take on a particular packet\n\n - `:allow` (_default action_): the rule should allow matching packets\n - `:deny`: the rule should deny matching packets\n - `:reject`: the rule should reject matching packets\n - `:masqerade`: Masquerade the matching packets\n - `:redirect`: Redirect the matching packets\n - `:log`: Configure logging\n\n- `stateful`: a symbol or array of symbols, such as ``[:related, :established]` that will be passed to the state module in iptables or firewalld.\n\n- `protocol`: `:tcp` (_default_), `:udp`, `:icmp`, `:none` or protocol number. Using protocol numbers is not supported using the ufw provider (default for debian/ubuntu systems).\n\n- `direction`: For ufw, direction of the rule. valid values are: `:in` (_default_), `:out`, `:pre`, `:post`.\n\n- `source` (_Default is `0.0.0.0/0` or `Anywhere`_): source ip address or subnet to filter.\n\n- `source_port` (_Default is nil_): source port for filtering packets.\n\n- `destination`: ip address or subnet to filter on packet destination, must be a valid IP\n\n- `port` or `dest_port`: target port number (ie. 22 to allow inbound SSH), or an array of incoming port numbers (ie. [80,443] to allow inbound HTTP & HTTPS).\n\n NOTE: `protocol` attribute is required with multiple ports, or a range of incoming port numbers (ie. 60000..61000 to allow inbound mobile-shell. NOTE: `protocol`, or an attribute is required with a range of ports.\n\n- `interface`: (source) interface to apply rule (ie. `eth0`).\n\n- `dest_interface`: interface where packets may be destined to go\n\n- `redirect_port`: redirected port for rules with command `:redirect`\n\n- `logging`: may be added to enable logging for a particular rule. valid values are: `:connections`, `:packets`. In the ufw provider, `:connections` logs new connections while `:packets` logs all packets.\n\n#### Examples\n\n```ruby\n# open standard ssh port\nfirewall_rule 'ssh' do\n port 22\n command :allow\nend\n\n# open standard http port to tcp traffic only; insert as first rule\nfirewall_rule 'http' do\n port 80\n protocol :tcp\n position 1\n command :allow\nend\n\n# restrict port 13579 to 10.0.111.0/24 on eth0\nfirewall_rule 'myapplication' do\n port 13579\n source '10.0.111.0/24'\n direction :in\n interface 'eth0'\n command :allow\nend\n\n# specify a protocol number (supported on centos/redhat)\nfirewall_rule 'vrrp' do\n protocol 112\n command :allow\nend\n\n# use the iptables provider to specify protocol number on debian/ubuntu\nfirewall_rule 'vrrp' do\n provider Chef::Provider::FirewallRuleIptables\n protocol 112\n command :allow\nend\n\n# can use :raw command with UFW provider for VRRP\nfirewall_rule \"VRRP\" do\n command :allow\n raw \"allow to 224.0.0.18\"\nend\n\n# open UDP ports 60000..61000 for mobile shell (mosh.mit.edu), note\n# that the protocol attribute is required when using port_range\nfirewall_rule 'mosh' do\n protocol :udp\n port 60000..61000\n command :allow\nend\n\n# open multiple ports for http/https, note that the protocol\n# attribute is required when using ports\nfirewall_rule 'http/https' do\n protocol :tcp\n port [80, 443]\n command :allow\nend\n\nfirewall 'default' do\n enabled false\n action :nothing\nend\n```\n\n#### Providers\n\n- See `libraries/z_provider_mapping.rb` for a full list of providers for each platform and version.\n\nDifferent providers will determine the current state of the rules differently -- parsing the output of a command, maintaining the state in a file, or some other way. If the firewall is adjusted from outside of chef (non-idempotent), it's possible that chef may be caught unaware of the current state of the firewall. The best workaround is to add a `:flush` action to the firewall resource as early as possible in the chef run, if you plan to modify the firewall state outside of chef.\n\n# Troubleshooting\n\nTo figure out what the position values are for current rules, print the hash that contains the weights:\n```\nrequire pp\ndefault_firewall = resources(:firewall, 'default')\npp default_firewall.rules\n```\n\n# Development\nThis section details \"quick development\" steps. For a detailed explanation, see [[Contributing.md]].\n\n1. Clone this repository from GitHub:\n\n $ git clone git@github.com:chef-cookbooks/firewall.git\n\n2. Create a git branch\n\n $ git checkout -b my_bug_fix\n\n3. Install dependencies:\n\n $ bundle install\n\n4. Make your changes/patches/fixes, committing appropiately\n5. **Write tests**\n6. Run the tests:\n - `bundle exec foodcritic -f any .`\n - `bundle exec rspec`\n - `bundle exec rubocop`\n - `bundle exec kitchen test`\n\n In detail:\n - Foodcritic will catch any Chef-specific style errors\n - RSpec will run the unit tests\n - Rubocop will check for Ruby-specific style errors\n - Test Kitchen will run and converge the recipes\n\n\n# License & Authors\n\n- Author:: Seth Chisamore ()\n- Author:: Ronald Doorn ()\n- Author:: Martin Smith ()\n- Author:: Sander van Harmelen ()\n\n```text\nCopyright:: 2011-2015, Chef Software, Inc\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n\n[0]: https://mosh.mit.edu/\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{"amazon":">= 0.0.0","centos":">= 0.0.0","debian":">= 0.0.0","fedora":">= 0.0.0","oracle":">= 0.0.0","redhat":">= 0.0.0","scientific":">= 0.0.0","ubuntu":">= 0.0.0"},"dependencies":{"chef-sugar":">= 0.0.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{}} \ No newline at end of file +{"name":"firewall","version":"2.5.4","description":"Provides a set of primitives for managing firewalls and associated rules.","long_description":"firewall Cookbook\n=================\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/firewall.svg?branch=master)](http://travis-ci.org/chef-cookbooks/firewall)\n[![Cookbook Version](https://img.shields.io/cookbook/v/firewall.svg)](https://supermarket.chef.io/cookbooks/firewall)\n\nProvides a set of primitives for managing firewalls and associated rules.\n\nPLEASE NOTE - The resource/providers in this cookbook are under heavy development. An attempt is being made to keep the resource simple/stupid by starting with less sophisticated firewall implementations first and refactor/vet the resource definition with each successive provider.\n\nRequirements\n------------\n**Chef 12.4.x+** is required. We are currently testing against 12.8.1. If you need Chef 11 support, please try pinning back to a version less than 2.0, e.g.:\n```\ndepends 'firewall', '< 2.0'\n```\n\n### Supported firewalls and platforms\n* UFW - Ubuntu, Debian\n* IPTables - Red Hat & CentOS, Ubuntu\n* FirewallD - Red Hat & CentOS >= 7.0 (IPv4 only support, [needs contributions/testing](https://github.com/chef-cookbooks/firewall/issues/86))\n* Windows Advanced Firewall - 2012 R2\n\nTested on:\n* Ubuntu 12.04, 14.04, 16.04 with iptables, ufw\n* Debian 7.8, 8.1 with ufw\n* CentOS 5.11, 6.7 with iptables\n* CentOS 7.1 with firewalld\n* Windows Server 2012r2 with Windows Advanced Firewall\n\nBy default, Ubuntu chooses ufw. To switch to iptables, set this in an attribute file:\n```\ndefault['firewall']['ubuntu_iptables'] = true\n```\n\nBy default, Red Hat & CentOS >= 7.0 chooses firewalld. To switch to iptables, set this in an attribute file:\n```\ndefault['firewall']['redhat7_iptables'] = true\n```\n\n# Considerations that apply to all firewall providers and resources\n\nThis cookbook comes with two resources, firewall and firewall rule. The typical usage scenario is as follows:\n\n- run the `:install` action on the `firewall` resource named 'default', which installs appropriate packages and configures services to start on boot and starts them\n\n- run the `:create` action on every `firewall_rule` resource, which adds to the list of rules that should be configured on the firewall. `firewall_rule` then automatically sends a delayed notification to the `firewall['default']` resource to run the `:restart` action.\n\n- run the delayed notification with action `:restart` on the `firewall` resource. if any rules are different than the last run, the provider will update the current state of the firewall rules to match the expected rules.\n\nThere is a fundamental mismatch between the idea of a chef action and the action that should be taken on a firewall rule. For this reason, the chef action for a firewall_rule may be `:nothing` (the rule should not be present in the firewall) or `:create` (the rule should be present in the firewall), but the action taken on a packet in a firewall (`DROP`, `ACCEPT`, etc) is denoted as a `command` parameter on the `firewall_rule` resource.\n\n# iptables considerations\n\nIf you need to use a table other than `*filter`, the best way to do so is like so:\n```\nnode.default['firewall']['iptables']['defaults'][:ruleset] = {\n '*filter' => 1,\n ':INPUT DROP' => 2,\n ':FORWARD DROP' => 3,\n ':OUTPUT ACCEPT_FILTER' => 4,\n 'COMMIT_FILTER' => 100,\n '*nat' => 101,\n ':PREROUTING DROP' => 102,\n ':POSTROUTING DROP' => 103,\n ':OUTPUT ACCEPT_NAT' => 104,\n 'COMMIT_NAT' => 200\n}\n```\n\nNote -- in order to support multiple hash keys containing the same rule, anything found after the underscore will be stripped for: `:OUTPUT :INPUT :POSTROUTING :PREROUTING COMMIT`. This allows an example like the above to be reduced to just repeated lines of `COMMIT` and `:OUTPUT ACCEPT` while still avoiding duplication of other things.\n\nThen it's trivial to add additional rules to the `*nat` table using the raw parameter:\n```\nfirewall_rule \"postroute\" do\n raw \"-A POSTROUTING -o eth1 -p tcp -d 172.28.128.21 -j SNAT --to-source 172.28.128.6\"\n position 150\nend\n```\n\nNote that any line starting with `COMMIT` will become just `COMMIT`, as hash\nkeys must be unique but we need multiple commit lines.\n\n# Recipes\n\n### default\nThe default recipe creates a firewall resource with action install, and if `node['firewall']['allow_ssh']`, opens port 22 from the world.\n\n# Attributes\n\n* `default['firewall']['allow_ssh'] = false`, set true to open port 22 for SSH when the default recipe runs\n* `default['firewall']['allow_mosh'] = false`, set to true to open UDP ports 60000 - 61000 for [Mosh][0] when the default recipe runs\n* `default['firewall']['allow_winrm'] = false`, set true to open port 5989 for WinRM when the default recipe runs\n\n* `default['firewall']['ubuntu_iptables'] = false`, set to true to use iptables on Ubuntu / Debian when using the default recipe\n* `default['firewall']['redhat7_iptables'] = false`, set to true to use iptables on Red Hat / CentOS 7 when using the default recipe\n\n* `default['firewall']['ufw']['defaults']` hash for template `/etc/default/ufw`\n* `default['firewall']['iptables']['defaults']` hash for default policies for 'filter' table's chains`\n\n* `default['firewall']['windows']['defaults']` hash to define inbound / outbound firewall policy on Windows platform\n\n* `default['firewall']['allow_established'] = true`, set to false if you don't want a related/established default rule on iptables\n* `default['firewall']['ipv6_enabled'] = true`, set to false if you don't want IPv6 related/established default rule on iptables (this enables ICMPv6, which is required for much of IPv6 communication)\n\n* `default['firewall']['firewalld']['permanent'] = false`, set to true if you want firewalld rules to be added with `--permanent` so they survive a reboot. This will be changed to `true` by default in a future major version release.\n\n# Resources\n\n### firewall\n\n***NB***: The name 'default' of this resource is important as it is used for firewall_rule providers to locate the firewall resource. If you change it, you must also supply the same value to any firewall_rule resources using the `firewall_name` parameter.\n\n#### Actions\n- `:install` (*default action*): Install and Enable the firewall. This will ensure the appropriate packages are installed and that any services have been started.\n- `:disable`: Disable the firewall. Drop any rules and put the node in an unprotected state. Flush all current rules. Also erase any internal state used to detect when rules should be applied.\n- `:flush`: Flush all current rules. Also erase any internal state used to detect when rules should be applied.\n- `:save`: Ensure all rules are added permanently under firewalld using `--permanent`. Not supported on ufw, iptables. You must notify this action at the end of the chef run if you want permanent firewalld rules (they are not persistent by default).\n\n#### Parameters\n\n- `disabled` (default to `false`): If set to true, all actions will no-op on this resource. This is a way to prevent included cookbooks from configuring a firewall.\n- `ipv6_enabled` (default to `true`): If set to false, firewall will not perform any ipv6 related work. Currently only supported in iptables.\n- `log_level`: UFW only. Level of verbosity the firewall should log at. valid values are: :low, :medium, :high, :full, :off. default is :low.\n- `rules`: This is used internally for firewall_rule resources to append their rules. You should NOT touch this value unless you plan to supply an entire firewall ruleset at once, and skip using firewall_rule resources.\n- `disabled_zone` (firewalld only): The zone to set on firewalld when the firewall should be disabled. Can be any string in symbol form, e.g. :public, :drop, etc. Defaults to `:public.`\n- `enabled_zone` (firewalld only): The zone to set on firewalld when the firewall should be enabled. Can be any string in symbol form, e.g. :public, :drop, etc. Defaults to `:drop.`\n- `package_options`: Used to pass options to the package install of firewall\n\n#### Examples\n\n```ruby\n# all defaults\nfirewall 'default'\n\n# enable platform default firewall\nfirewall 'default' do\n action :install\nend\n\n# increase logging past default of 'low'\nfirewall 'default' do\n log_level :high\n action :install\nend\n```\n\n### firewall_rule\n\n#### Actions\n- `:create` (_default action_): If a firewall_rule runs this action, the rule will be recorded in a chef resource's internal state, and applied when providers automatically notify the firewall resource with action `:reload`. The notification happens automatically.\n\n#### Parameters\n\n- `firewall_name`: the matching firewall resource that this rule applies to. Default value: `default`\n\n- `raw`: Used to pass an entire rule as a string, omitting all other parameters. This line will be directly loaded by `iptables-restore`, fed directly into `ufw` on the command line, or run using `firewall-cmd`.\n\n- `description` (_default: same as rule name_): Used to provide a comment that will be included when adding the firewall rule.\n\n- `position` (_default: 50_): **relative** position to insert rule at. Position may be any integer between 0 < n < 100 (exclusive), and more than one rule may specify the same position.\n\n- `command`: What action to take on a particular packet\n\n - `:allow` (_default action_): the rule should allow matching packets\n - `:deny`: the rule should deny matching packets\n - `:reject`: the rule should reject matching packets\n - `:masqerade`: Masquerade the matching packets\n - `:redirect`: Redirect the matching packets\n - `:log`: Configure logging\n\n- `stateful`: a symbol or array of symbols, such as ``[:related, :established]` that will be passed to the state module in iptables or firewalld.\n\n- `protocol`: `:tcp` (_default_), `:udp`, `:icmp`, `:none` or protocol number. Using protocol numbers is not supported using the ufw provider (default for debian/ubuntu systems).\n\n- `direction`: For ufw, direction of the rule. valid values are: `:in` (_default_), `:out`, `:pre`, `:post`.\n\n- `source` (_Default is `0.0.0.0/0` or `Anywhere`_): source ip address or subnet to filter.\n\n- `source_port` (_Default is nil_): source port for filtering packets.\n\n- `destination`: ip address or subnet to filter on packet destination, must be a valid IP\n\n- `port` or `dest_port`: target port number (ie. 22 to allow inbound SSH), or an array of incoming port numbers (ie. [80,443] to allow inbound HTTP & HTTPS).\n\n NOTE: `protocol` attribute is required with multiple ports, or a range of incoming port numbers (ie. 60000..61000 to allow inbound mobile-shell. NOTE: `protocol`, or an attribute is required with a range of ports.\n\n- `interface`: (source) interface to apply rule (ie. `eth0`).\n\n- `dest_interface`: interface where packets may be destined to go\n\n- `redirect_port`: redirected port for rules with command `:redirect`\n\n- `logging`: may be added to enable logging for a particular rule. valid values are: `:connections`, `:packets`. In the ufw provider, `:connections` logs new connections while `:packets` logs all packets.\n\n#### Examples\n\n```ruby\n# open standard ssh port\nfirewall_rule 'ssh' do\n port 22\n command :allow\nend\n\n# open standard http port to tcp traffic only; insert as first rule\nfirewall_rule 'http' do\n port 80\n protocol :tcp\n position 1\n command :allow\nend\n\n# restrict port 13579 to 10.0.111.0/24 on eth0\nfirewall_rule 'myapplication' do\n port 13579\n source '10.0.111.0/24'\n direction :in\n interface 'eth0'\n command :allow\nend\n\n# specify a protocol number (supported on centos/redhat)\nfirewall_rule 'vrrp' do\n protocol 112\n command :allow\nend\n\n# use the iptables provider to specify protocol number on debian/ubuntu\nfirewall_rule 'vrrp' do\n provider Chef::Provider::FirewallRuleIptables\n protocol 112\n command :allow\nend\n\n# can use :raw command with UFW provider for VRRP\nfirewall_rule \"VRRP\" do\n command :allow\n raw \"allow to 224.0.0.18\"\nend\n\n# open UDP ports 60000..61000 for mobile shell (mosh.mit.edu), note\n# that the protocol attribute is required when using port_range\nfirewall_rule 'mosh' do\n protocol :udp\n port 60000..61000\n command :allow\nend\n\n# open multiple ports for http/https, note that the protocol\n# attribute is required when using ports\nfirewall_rule 'http/https' do\n protocol :tcp\n port [80, 443]\n command :allow\nend\n\nfirewall 'default' do\n enabled false\n action :nothing\nend\n```\n\n#### Providers\n\n- See `libraries/z_provider_mapping.rb` for a full list of providers for each platform and version.\n\nDifferent providers will determine the current state of the rules differently -- parsing the output of a command, maintaining the state in a file, or some other way. If the firewall is adjusted from outside of chef (non-idempotent), it's possible that chef may be caught unaware of the current state of the firewall. The best workaround is to add a `:flush` action to the firewall resource as early as possible in the chef run, if you plan to modify the firewall state outside of chef.\n\n# Troubleshooting\n\nTo figure out what the position values are for current rules, print the hash that contains the weights:\n```\nrequire pp\ndefault_firewall = resources(:firewall, 'default')\npp default_firewall.rules\n```\n\n# Development\nThis section details \"quick development\" steps. For a detailed explanation, see [[Contributing.md]].\n\n1. Clone this repository from GitHub:\n\n $ git clone git@github.com:chef-cookbooks/firewall.git\n\n2. Create a git branch\n\n $ git checkout -b my_bug_fix\n\n3. Install dependencies:\n\n $ bundle install\n\n4. Make your changes/patches/fixes, committing appropiately\n5. **Write tests**\n6. Run the tests:\n - `bundle exec foodcritic -f any .`\n - `bundle exec rspec`\n - `bundle exec rubocop`\n - `bundle exec kitchen test`\n\n In detail:\n - Foodcritic will catch any Chef-specific style errors\n - RSpec will run the unit tests\n - Rubocop will check for Ruby-specific style errors\n - Test Kitchen will run and converge the recipes\n\n\n# License & Authors\n\n- Author:: Seth Chisamore ()\n- Author:: Ronald Doorn ()\n- Author:: Martin Smith ()\n- Author:: Sander van Harmelen ()\n\n```text\nCopyright:: 2011-2015, Chef Software, Inc\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n\n[0]: https://mosh.mit.edu/\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{"amazon":">= 0.0.0","centos":">= 0.0.0","debian":">= 0.0.0","fedora":">= 0.0.0","oracle":">= 0.0.0","redhat":">= 0.0.0","scientific":">= 0.0.0","ubuntu":">= 0.0.0","windows":">= 0.0.0"},"dependencies":{"chef-sugar":">= 0.0.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{}} \ No newline at end of file diff --git a/cookbooks/firewall/recipes/default.rb b/cookbooks/firewall/recipes/default.rb index 7eb3fdf..c85d5f5 100644 --- a/cookbooks/firewall/recipes/default.rb +++ b/cookbooks/firewall/recipes/default.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: firewall +# Cookbook:: firewall # Recipe:: default # -# Copyright 2011, Opscode, Inc. +# Copyright:: 2011-2016, 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/cookbooks/hostname/.kitchen.yml b/cookbooks/hostname/.kitchen.yml index e63cddd..8bda6a3 100644 --- a/cookbooks/hostname/.kitchen.yml +++ b/cookbooks/hostname/.kitchen.yml @@ -4,6 +4,10 @@ driver_config: require_chef_omnibus: true platforms: +- name: ubuntu-14.04 + driver_config: + box: opscode_ubuntu-14.04_provisionerless + box_url: https://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_ubuntu-14.04_chef-provisionerless.box - name: ubuntu-12.04 driver_config: box: opscode_ubuntu-12.04_provisionerless diff --git a/cookbooks/hostname/.rubocop.yml b/cookbooks/hostname/.rubocop.yml index 00d809d..1391b04 100644 --- a/cookbooks/hostname/.rubocop.yml +++ b/cookbooks/hostname/.rubocop.yml @@ -1,5 +1,5 @@ AllCops: - Excludes: + Exclude: - tmp/** Documentation: @@ -7,3 +7,6 @@ Documentation: LineLength: Enabled: false + +SingleSpaceBeforeFirstArg: + Enabled: false diff --git a/cookbooks/hostname/Berksfile b/cookbooks/hostname/Berksfile index f25cd60..454fbaf 100644 --- a/cookbooks/hostname/Berksfile +++ b/cookbooks/hostname/Berksfile @@ -1,5 +1,5 @@ # -*- ruby -*- -site :opscode +source "https://supermarket.getchef.com" metadata diff --git a/cookbooks/hostname/CHANGELOG.md b/cookbooks/hostname/CHANGELOG.md index 9c53865..7985bfc 100644 --- a/cookbooks/hostname/CHANGELOG.md +++ b/cookbooks/hostname/CHANGELOG.md @@ -1,7 +1,13 @@ # Change History -0.3.0 -===== +0.4.0 (2015-03-16) +================== + - #40: Use file resources with lazy eval and notifies to prevent network restarts from occurring on every chef run (Matt Kasa) + - Add box with Ubuntu 14.04 for kitchen tests + - #27: Update default recipe to reload only the hostname plugin instead of ohai (Jonathan Serafini) + +0.3.0 (2014-05-20) +================== - Fixed (and tested) FreeBSD support - #17: added support for RedHat & CentOS (Damien Roche, Marta Paciorkowska) - added instructions on manual testing with reboot (Marta Paciorkowska) diff --git a/cookbooks/hostname/Strainerfile b/cookbooks/hostname/Strainerfile index 23dc97f..f0aafd1 100644 --- a/cookbooks/hostname/Strainerfile +++ b/cookbooks/hostname/Strainerfile @@ -1,4 +1,4 @@ rubocop: rubocop $COOKBOOK knife test: knife cookbook test $COOKBOOK -foodcritic: foodcritic --tags ~FC015 --epic-fail any $SANDBOX/$COOKBOOK +foodcritic: foodcritic -c 11.6.0 --tags ~FC015 --epic-fail any $SANDBOX/$COOKBOOK chefspec: rspec $SANDBOX/$COOKBOOK diff --git a/cookbooks/hostname/metadata.rb b/cookbooks/hostname/metadata.rb index ea14333..cef053a 100644 --- a/cookbooks/hostname/metadata.rb +++ b/cookbooks/hostname/metadata.rb @@ -6,7 +6,7 @@ maintainer_email 'maciej@3ofcoins.net' license 'MIT' description 'Configures hostname and FQDN' long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -version '0.3.0' +version '0.4.0' supports 'debian' supports 'ubuntu' diff --git a/cookbooks/hostname/recipes/default.rb b/cookbooks/hostname/recipes/default.rb index b1e23b4..ef05790 100644 --- a/cookbooks/hostname/recipes/default.rb +++ b/cookbooks/hostname/recipes/default.rb @@ -53,48 +53,47 @@ if fqdn execute "hostname #{fqdn}" do only_if { node['fqdn'] != fqdn } - notifies :reload, 'ohai[reload]', :immediately + notifies :reload, 'ohai[reload_hostname]', :immediately end when 'centos', 'redhat', 'amazon', 'scientific' + service 'network' do + action :nothing + end hostfile = '/etc/sysconfig/network' - ruby_block "Update #{hostfile}" do - block do - file = Chef::Util::FileEdit.new(hostfile) - file.search_file_replace_line('^HOSTNAME', "HOSTNAME=#{fqdn}") - file.write_file - end - notifies :reload, 'ohai[reload]', :immediately + file hostfile do + action :create + content lazy { + ::IO.read(hostfile).gsub(/^HOSTNAME=.*$/, "HOSTNAME=#{fqdn}") + } + notifies :reload, 'ohai[reload_hostname]', :immediately + notifies :restart, 'service[network]', :delayed end # this is to persist the correct hostname after machine reboot sysctl = '/etc/sysctl.conf' - ruby_block "Update #{sysctl}" do - block do - file = Chef::Util::FileEdit.new(sysctl) - file.insert_line_if_no_match("kernel.hostname=#{hostname}", \ - "kernel.hostname=#{hostname}") - file.write_file - end - notifies :reload, 'ohai[reload]', :immediately + file sysctl do + action :create + content lazy { + ::IO.read(sysctl) + "kernel.hostname=#{hostname}\n" + } + not_if { ::IO.read(sysctl) =~ /^kernel\.hostname=#{hostname}$/ } + notifies :reload, 'ohai[reload_hostname]', :immediately + notifies :restart, 'service[network]', :delayed end execute "hostname #{hostname}" do only_if { node['hostname'] != hostname } - notifies :reload, 'ohai[reload]', :immediately + notifies :reload, 'ohai[reload_hostname]', :immediately end - service 'network' do - action :restart - end - else file '/etc/hostname' do content "#{hostname}\n" mode '0644' - notifies :reload, 'ohai[reload]', :immediately + notifies :reload, 'ohai[reload_hostname]', :immediately end execute "hostname #{hostname}" do only_if { node['hostname'] != hostname } - notifies :reload, 'ohai[reload]', :immediately + notifies :reload, 'ohai[reload_hostname]', :immediately end end @@ -109,10 +108,11 @@ if fqdn hostname fqdn aliases [hostname] action :create - notifies :reload, 'ohai[reload]', :immediately + notifies :reload, 'ohai[reload_hostname]', :immediately end - ohai 'reload' do + ohai 'reload_hostname' do + plugin 'hostname' action :nothing end else diff --git a/cookbooks/iis/.foodcritic b/cookbooks/iis/.foodcritic new file mode 100644 index 0000000..6c2ff5a --- /dev/null +++ b/cookbooks/iis/.foodcritic @@ -0,0 +1 @@ +~FC059 diff --git a/cookbooks/iis/CHANGELOG.md b/cookbooks/iis/CHANGELOG.md index ef955cd..4b45c2b 100644 --- a/cookbooks/iis/CHANGELOG.md +++ b/cookbooks/iis/CHANGELOG.md @@ -1,22 +1,87 @@ # iis Cookbook CHANGELOG + This file is used to list changes made in each version of the iis cookbook. +## 5.0.8 (2017-03-13) +- [iis-root default_documents broke from last fix](#306) + +## 5.0.7 (2017-03-07) +- [iis-root default_documents deleted every chef run](#306) + +## 5.0.6 (2017-02-24) +- [iis_version is not evaluated properly on if statement](#308) + +## 5.0.5 (2016-11-21) +- [Fixed no_managed_code idempotency](#301) + +## 5.0.4 (2016-10-11) +- fixed adding an app pool to a site - This fixes a bug where adding an app pool to a site causes an error. This was using the 'add app' where we are working with a site and the syntax is slightly different according to this [documentation](https://technet.microsoft.com/en-us/library/cc732992%28v=ws.10%29.aspx). + +## 5.0.3 (2016-10-10) +- Log event on recycle - This allows you to specify which events you want to log on recycle. This also changes this so that it defaults to the standard nothing, which means you will need to add this attribute if you are depending on it. + +## 5.0.2 (2016-10-07) +- [Minor over oversight in IIS::mod_aspnet 5.0.1](#296) +- [IIS Pool resource thirty_two_bit false doesn't](#292) + +## 5.0.1 (2016-09-21) +- Fix mod_management to include dependencies (#293) + +## 5.0.0 (2016-09-06) +- Adding 2k12 version flag to the windows_feature resource (#291) +- Testing updates +- Avoid deprecation warnings in the specs +- Require Chef 12+ + +## 4.2.0 (2016-08-09) +- Feature pool recycle virtual memory (#288) + +## v4.1.10 (2016-06-29) + +- Resolves [Issue with error 50 when installing mod_aspnet](https://github.com/chef-cookbooks/iis/issues/285) + +## v4.1.9 (2016-06-26) + +- Resolves [Add deprecation warnings for iis_config in 4.2](https://github.com/chef-cookbooks/iis/issues/284) +- Resolves [iis_pool is not idempotent when recycle_at_time is specified and is not changed](https://github.com/chef-cookbooks/iis/issues/279) + +## v4.1.8 (2016-04-15) + +- Fixed smp_processor_affinity_mask throwing deprecation warnings +- Added additional chefspec tests +- Updated testing dependencies to the latests +- Disabled FC059 rule for now + +## v4.1.7 (2016-03-25) + +- Resolves [smp_processor_affinity_mask is wrong value type](https://github.com/chef-cookbooks/iis/issues/266) +- Resolves [Not a valid unsigned integer](https://github.com/chef-cookbooks/iis/issues/261) +- Resolves [Deprecated features used](https://github.com/chef-cookbooks/iis/issues/259) +- Resolves [Deprecated feature used, fix before chef 13](https://github.com/chef-cookbooks/iis/issues/253) +- Resolves [iis_site :config action not idempotent (Windows 2012 R2/IIS 8.5)](https://github.com/chef-cookbooks/iis/issues/249) +- Resolves [Can't set recycle_at_time to default](https://github.com/chef-cookbooks/iis/issues/247) + ## v4.1.6 (2016-02-01) + - Resolves issues with [Unable to set app pool to be "No Managed Code"](https://github.com/chef-cookbooks/iis/issues/240) - Resolves [Add_mime_maps is throwing compile error](https://github.com/chef-cookbooks/iis/issues/238) - Resolves [FATAL: NameError: iis_root "xxx" had an error: NameError: No resource, method, or local variable named `was _updated' for`LWRP provider iis_root from cookbook iis](https://github.com/chef-cookbooks/iis/issues/236) ## v4.1.5 (2015-11-18) + - Resolves issues with `iis_root` [#222](https://github.com/chef-cookbooks/iis/issues/222) ## v4.1.4 (2015-11-2) + - Re-added functionality for iis_pool auto_start, this was a breaking change ## v4.1.3 (2015-10-30) + - Resolves Robucop issues - Bug Fix for [#217](https://github.com/chef-cookbooks/iis/issues/217) ## v4.1.2 (2015-10-21) + - Bug fixes for application pool provider and site provider - Added the ability to detect the IIS Version, allowing for some properties to only exist for specific IIS versions - Fixed issue with Win32 being required on linux @@ -24,6 +89,7 @@ This file is used to list changes made in each version of the iis cookbook. - Added iis config set and clear abilities ## v4.1.1 (2015-05-07) + - Detects changes in the physical path of apps. - Adds support for gMSA identity. - Performing add on a site will now reconfigure it if necessary. @@ -31,6 +97,7 @@ This file is used to list changes made in each version of the iis cookbook. - Fix issue where popeline_mode was ignored during configuration of a pool. ## v4.1.0 (2015-03-04) + - Removed iis_pool attribute 'set_profile_environment' incompatible with < IIS-8. - Added pester test framework. - Condensed and fixed change-log to show public releases only. @@ -38,7 +105,9 @@ This file is used to list changes made in each version of the iis cookbook. - Code-cleanup and cosmetic fixes. ## v4.0.0 (2015-02-12) + - [#91](https://github.com/chef-cookbooks/iis/pull/91) - bulk addition of new features + - Virtual Directory Support (allows virtual directories to be added to both websites and to webapplications under sites). - section unlock and lock support (this is used to allow for the web.config of a site to define the authentication methods). - fixed issue with :add on pool provider not running all config (this was a known issue and is now resolved). @@ -46,9 +115,13 @@ This file is used to list changes made in each version of the iis cookbook. - moved to better method for XML checking of previous settings to detect changes (changed all check to use xml searching with appcmd instead of the previous method [none]). - Improved pool resource with many more apppool properties that can be set. + - Fixed bug with default attribute inheritance. + - New recipe to enable ASP.NET 4.5. + - Skeleton serverspec+test-kitchen framework. + - Added Berksfile, Gemfile and .kitchen.yml to assist developers. - Fixed issue [#107] function is_new_or_empty was returning reverse results. - Removed dependency on "chef-client", ">= 3.7.0". @@ -58,65 +131,89 @@ This file is used to list changes made in each version of the iis cookbook. - added backwards compatibility for chef-client < 12.x.x Chef::Util::PathHelper. ## v2.1.6 (2014-11-12) + - [#78] Adds new_resource.updated_by_last_action calls ## v2.1.5 (2014-09-15) + - [#68] Add win_friendly_path to all appcmd.exe /physicalPath arguments ## v2.1.4 (2014-09-13) + - [#72] Adds chefspec matchers - [#57] Fixes site_id not being updated on a :config action ## v2.1.2 (2014-04-23) + - [COOK-4559] Remove invalid UTF-8 characters ## v2.1.0 (2014-03-25) -[COOK-4426] - feature order correction for proper installation [COOK-4428] - Add IIS FTP Feature Installation + +[COOK-4426] - feature order correction for proper installation [COOK-4428] - Add IIS FTP Feature Installation ## v2.0.4 (2014-03-18) + - [COOK-4420] Corrected incorrect feature names for mod_security ## v2.0.2 (2014-02-25) + - [COOK-4108] - Add documentation for the 'bindings' attribute in 'iis_site' LWRP ## v2.0.0 (2014-01-03) + Major version bump ## v1.6.6 + Adding extra windows platform checks to helper library ## v1.6.4 + ### Bug + - **[COOK-4138](https://tickets.chef.io/browse/COOK-4138)** - iis cookbook won't load on non-Windows platforms ## v1.6.2 + ### Improvement + - **[COOK-3634](https://tickets.chef.io/browse/COOK-3634)** - provide ability to set app pool managedRuntimeVersion to "No Managed Code" ## v1.6.0 + ### Improvement + - **[COOK-3922](https://tickets.chef.io/browse/COOK-3922)** - refactor IIS cookbook to not require WebPI ## v1.5.6 + ### Improvement + - **[COOK-3770](https://tickets.chef.io/browse/COOK-3770)** - Add Enabled Protocols to IIS App Recipe ## v1.5.4 + ### New Feature + - **[COOK-3675](https://tickets.chef.io/browse/COOK-3675)** - Add recipe for CGI module ## v1.5.2 + ### Bug + - **[COOK-3232](https://tickets.chef.io/browse/COOK-3232)** - Allow `iis_app` resource `:config` action with a virtual path ## v1.5.0 + ### Improvement + - [COOK-2370]: add MVC2, escape `application_pool` and add options for - recycling - [COOK-2694]: update iis documentation to show that Windows 2012 and - Windows 8 are supported ### Bug + - [COOK-2325]: `load_current_resource` does not load state of pool - correctly, always sets running to false - [COOK-2526]: Installing IIS after .NET framework will leave @@ -125,25 +222,31 @@ Adding extra windows platform checks to helper library - not accepted ## v1.4.0 + - [COOK-2181] -Adding full module support to iis cookbook ## v1.3.6 + - [COOK-2084] - Add support for additional options during site creation - [COOK-2152] - Add recipe for IIS6 metabase compatibility ## v1.3.4 + - [COOK-2050] - IIS cookbook does not have returns resource defined ## v1.3.2 + - [COOK-1251] - Fix LWRP "NotImplementedError" ## v1.3.0 + - [COOK-1301] - Add a recycle action to the iis_pool resource - [COOK-1665] - app pool identity and new node[iis][component] attribute - [COOK-1666] - Recipe to remove default site and app pool - [COOK-1858] - Recipe misspelled ## v1.2.0 + - [COOK-1061] - `iis_site` doesn't allow setting the pool - [COOK-1078] - handle advanced bindings - [COOK-1283] - typo on pool @@ -154,6 +257,7 @@ Adding extra windows platform checks to helper library - [COOK-1647] - mod_ApplicationInitialization isn't RC ## v1.1.0 + - [COOK-1012] - support adding apps - [COOK-1028] - support for config command - [COOK-1041] - fix removal in app pools @@ -161,8 +265,10 @@ Adding extra windows platform checks to helper library - [COOK-950] - documentation correction for version of IIS/OS ## v1.0.2 + - Ruby 1.9 compat fixes - ensure carriage returns are removed before applying regex ## v1.0.0 + - [COOK-718] initial release diff --git a/cookbooks/iis/MAINTAINERS.md b/cookbooks/iis/MAINTAINERS.md index 7a42dae..af785a2 100644 --- a/cookbooks/iis/MAINTAINERS.md +++ b/cookbooks/iis/MAINTAINERS.md @@ -1,25 +1,20 @@ # Maintainers -This file lists how this cookbook project is maintained. When making changes to the system, this -file tells you who needs to review your patch - you need a simple majority of maintainers -for the relevant subsystems to provide a :+1: on your pull request. Additionally, you need -to not receive a veto from a Lieutenant or the Project Lead. +This file lists how this cookbook project is maintained. When making changes to the system, this file tells you who needs to review your patch - you need a review from an existing maintainer for the cookbook to provide a :+1: on your pull request. Additionally, you need to not receive a veto from a Lieutenant or the Project Lead. -Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) -for details on the process and how to become a maintainer or the project lead. +Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) for details on the process and how to become a maintainer or the project lead. # Project Maintainer * [Adam Edwards](https://github.com/adamedx) # Maintainers -* [Adam Edwards](https://github.com/adamedx) -* [Kartik Null Cating-Subramanian](https://github.com/ksubrama) -* [Steven Murawski](https://github.com/smurawski) -* [Matt Wrock](https://github.com/mwrock) -* [Jay Mundrawala](https://github.com/jaym) -* [Claire McQuin](https://github.com/mcquin) * [Salim Alam](https://github.com/chefsalim) -* [Sean OMeara](https://github.com/someara) -* [Tim Smith](https://github.com/tas50) * [Jennifer Davis](https://github.com/sigje) +* [Adam Edwards](https://github.com/adamedx) +* [Claire McQuin](https://github.com/mcquin) +* [Steven Murawski](https://github.com/smurawski) +* [Kartik Null Cating-Subramanian](https://github.com/ksubrama) +* [Justin Schuhmann](https://github.com/EasyAsABC123) +* [Tim Smith](https://github.com/tas50) +* [Matt Wrock](https://github.com/mwrock) \ No newline at end of file diff --git a/cookbooks/iis/README.md b/cookbooks/iis/README.md index 222c14e..a52b6e4 100644 --- a/cookbooks/iis/README.md +++ b/cookbooks/iis/README.md @@ -1,89 +1,94 @@ -iis Cookbook -============ +# iis Cookbook -[![Build Status](https://travis-ci.org/chef-cookbooks/iis.svg?branch=master)](https://travis-ci.org/chef-cookbooks/iis) -[![Cookbook Version](https://img.shields.io/cookbook/v/iis.svg)](https://supermarket.chef.io/cookbooks/iis) +[![Build Status](https://travis-ci.org/chef-cookbooks/iis.svg?branch=master)](https://travis-ci.org/chef-cookbooks/iis) [![Cookbook Version](https://img.shields.io/cookbook/v/iis.svg)](https://supermarket.chef.io/cookbooks/iis) Installs and configures Microsoft Internet Information Services (IIS) 7.0 and later -Contents -======== +## Contents - * [Attributes](#attributes) - * [Resource/Provider](#resourceprovider) - * [iis_root](#iis_root) Allows for easy management of the IIS Root Machine settings - * [iis_site](#iis_site) Allows for easy management of IIS virtual sites (ie vhosts). - * [iis_config](#iis_config) Runs a config command on your IIS instance. - * [iis_pool](#iis_pool) Creates an application pool in IIS. - * [iis_app](#iis_app) Creates an application in IIS. - * [iis_vdir](#iis_vdir) Allows easy management of IIS virtual directories (i.e. vdirs). - * [iis_section](#iis_section) Allows for the locking/unlocking of application web.config sections. - * [iis_module](#iis_module) Manages modules globally or on a per site basis. - * [Usage](#usage) - * [default](#default) Default recipe - * [mod\_\*](#mod_) Recipes for installing individual IIS modules (extensions). - * [Alternatives ](#alternatives) - * [License and Author](#license-and-author) +- [Attributes](#attributes) +- [Resource/Provider](#resourceprovider) -Requirements -============ + - [iis_root](#iis_root) Allows for easy management of the IIS Root Machine settings + - [iis_site](#iis_site) Allows for easy management of IIS virtual sites (ie vhosts). + - [iis_config](#iis_config) Runs a config command on your IIS instance. + - [iis_pool](#iis_pool) Creates an application pool in IIS. + - [iis_app](#iis_app) Creates an application in IIS. + - [iis_vdir](#iis_vdir) Allows easy management of IIS virtual directories (i.e. vdirs). + - [iis_section](#iis_section) Allows for the locking/unlocking of application web.config sections. + - [iis_module](#iis_module) Manages modules globally or on a per site basis. -Platform --------- +- [Usage](#usage) -* Windows Vista -* Windows 7 -* Windows 8 -* Windows Server 2008 (R1, R2) -* Windows Server 2012 -* Windows Server 2012R2 + - [default](#default) Default recipe + - [mod_*](#mod_) Recipes for installing individual IIS modules (extensions). -Windows 2003R2 is *not* supported because it lacks Add/Remove Features. +- [Alternatives](#alternative-cookbooks) -Cookbooks ---------- +- [License and Author](#license-and-author) -* windows +## Requirements -Attributes -========== +### Platforms -* `node['iis']['home']` - IIS main home directory. default is `%WINDIR%\System32\inetsrv` -* `node['iis']['conf_dir']` - location where main IIS configs lives. default is `%WINDIR%\System32\inetsrv\config` -* `node['iis']['pubroot']` - . default is `%SYSTEMDRIVE%\inetpub` -* `node['iis']['docroot']` - IIS web site home directory. default is `%SYSTEMDRIVE%\inetpub\wwwroot` -* `node['iis']['log_dir']` - location of IIS logs. default is `%SYSTEMDRIVE%\inetpub\logs\LogFiles` -* `node['iis']['cache_dir']` - location of cached data. default is `%SYSTEMDRIVE%\inetpub\temp` +- Windows Vista +- Windows 7 +- Windows 8, 8.1 +- Windows Server 2008 (R1, R2) +- Windows Server 2012 (R1, R2) -Resource/Provider -================= +Windows 2003R2 is _not_ supported because it lacks Add/Remove Features. -iis_root ---------- +### Chef + +- Chef 12.1+ + +### Cookbooks + +- windows + +## Attributes + +- `node['iis']['home']` - IIS main home directory. default is `%WINDIR%\System32\inetsrv` +- `node['iis']['conf_dir']` - location where main IIS configs lives. default is `%WINDIR%\System32\inetsrv\config` +- `node['iis']['pubroot']` - . default is `%SYSTEMDRIVE%\inetpub` +- `node['iis']['docroot']` - IIS web site home directory. default is `%SYSTEMDRIVE%\inetpub\wwwroot` +- `node['iis']['log_dir']` - location of IIS logs. default is `%SYSTEMDRIVE%\inetpub\logs\LogFiles` +- `node['iis']['cache_dir']` - location of cached data. default is `%SYSTEMDRIVE%\inetpub\temp` + +## Resource/Provider + +### iis_root Allows for easy management of the IIS Root Machine settings -### Actions +#### Actions + `default` = `:config` - `:add` - only does addition operations will not delete anything to an Array object - `:delete` - only does deletion operations will not add anything to an Array object - `:config` - does both addition and deletion make sure your Array objects contain everything you want -### Attribute Parameters +#### Properties - `default_documents_enabled` - Enables or disables default_documents for the root machine, Valid Values: true, false default: `true` - `default_documents` - The items you want to set as the default document collection, only used during `:config`. Array of strings, default: `['Default.htm', 'Default.asp', 'index.htm', 'index.html', 'iisstart.htm', 'default.aspx']` - `mime_maps` - The items you want to set as the mime-maps or mime-types collection, only used during `:config`. Array of strings, default: -```ruby -["fileExtension='.323',mimeType='text/h323'", "fileExtension='.3g2',mimeType='video/3gpp2'", "fileExtension='.3gp2',mimeType='video/3gpp2'", "fileExtension='.3gp',mimeType='video/3gpp'", "fileExtension='.3gpp',mimeType='video/3gpp'", "fileExtension='.aaf',mimeType='application/octet-stream'", "fileExtension='.aac',mimeType='audio/aac'", "fileExtension='.aca',mimeType='application/octet-stream'", "fileExtension='.accdb',mimeType='application/msaccess'", "fileExtension='.accde',mimeType='application/msaccess'", "fileExtension='.accdt',mimeType='application/msaccess'", "fileExtension='.acx',mimeType='application/internet-property-stream'", "fileExtension='.adt',mimeType='audio/vnd.dlna.adts'", "fileExtension='.adts',mimeType='audio/vnd.dlna.adts'", "fileExtension='.afm',mimeType='application/octet-stream'", "fileExtension='.ai',mimeType='application/postscript'", "fileExtension='.aif',mimeType='audio/x-aiff'", "fileExtension='.aifc',mimeType='audio/aiff'", "fileExtension='.aiff',mimeType='audio/aiff'", "fileExtension='.application',mimeType='application/x-ms-application'", "fileExtension='.art',mimeType='image/x-jg'", "fileExtension='.asd',mimeType='application/octet-stream'", "fileExtension='.asf',mimeType='video/x-ms-asf'", "fileExtension='.asi',mimeType='application/octet-stream'", "fileExtension='.asm',mimeType='text/plain'", "fileExtension='.asr',mimeType='video/x-ms-asf'", "fileExtension='.asx',mimeType='video/x-ms-asf'", "fileExtension='.atom',mimeType='application/atom+xml'", "fileExtension='.au',mimeType='audio/basic'", "fileExtension='.avi',mimeType='video/avi'", "fileExtension='.axs',mimeType='application/olescript'", "fileExtension='.bas',mimeType='text/plain'", "fileExtension='.bcpio',mimeType='application/x-bcpio'", "fileExtension='.bin',mimeType='application/octet-stream'", "fileExtension='.bmp',mimeType='image/bmp'", "fileExtension='.c',mimeType='text/plain'", "fileExtension='.cab',mimeType='application/vnd.ms-cab-compressed'", "fileExtension='.calx',mimeType='application/vnd.ms-office.calx'", "fileExtension='.cat',mimeType='application/vnd.ms-pki.seccat'", "fileExtension='.cdf',mimeType='application/x-cdf'", "fileExtension='.chm',mimeType='application/octet-stream'", "fileExtension='.class',mimeType='application/x-java-applet'", "fileExtension='.clp',mimeType='application/x-msclip'", "fileExtension='.cmx',mimeType='image/x-cmx'", "fileExtension='.cnf',mimeType='text/plain'", "fileExtension='.cod',mimeType='image/cis-cod'", "fileExtension='.cpio',mimeType='application/x-cpio'", "fileExtension='.cpp',mimeType='text/plain'", "fileExtension='.crd',mimeType='application/x-mscardfile'", "fileExtension='.crl',mimeType='application/pkix-crl'", "fileExtension='.crt',mimeType='application/x-x509-ca-cert'", "fileExtension='.csh',mimeType='application/x-csh'", "fileExtension='.css',mimeType='text/css'", "fileExtension='.csv',mimeType='application/octet-stream'", "fileExtension='.cur',mimeType='application/octet-stream'", "fileExtension='.dcr',mimeType='application/x-director'", "fileExtension='.deploy',mimeType='application/octet-stream'", "fileExtension='.der',mimeType='application/x-x509-ca-cert'", "fileExtension='.dib',mimeType='image/bmp'", "fileExtension='.dir',mimeType='application/x-director'", "fileExtension='.disco',mimeType='text/xml'", "fileExtension='.dll',mimeType='application/x-msdownload'", "fileExtension='.dll.config',mimeType='text/xml'", "fileExtension='.dlm',mimeType='text/dlm'", "fileExtension='.doc',mimeType='application/msword'", "fileExtension='.docm',mimeType='application/vnd.ms-word.document.macroEnabled.12'", "fileExtension='.docx',mimeType='application/vnd.openxmlformats-officedocument.wordprocessingml.document'", "fileExtension='.dot',mimeType='application/msword'", "fileExtension='.dotm',mimeType='application/vnd.ms-word.template.macroEnabled.12'", "fileExtension='.dotx',mimeType='application/vnd.openxmlformats-officedocument.wordprocessingml.template'", "fileExtension='.dsp',mimeType='application/octet-stream'", "fileExtension='.dtd',mimeType='text/xml'", "fileExtension='.dvi',mimeType='application/x-dvi'", "fileExtension='.dvr-ms',mimeType='video/x-ms-dvr'", "fileExtension='.dwf',mimeType='drawing/x-dwf'", "fileExtension='.dwp',mimeType='application/octet-stream'", "fileExtension='.dxr',mimeType='application/x-director'", "fileExtension='.eml',mimeType='message/rfc822'", "fileExtension='.emz',mimeType='application/octet-stream'", "fileExtension='.eot',mimeType='application/vnd.ms-fontobject'", "fileExtension='.eps',mimeType='application/postscript'", "fileExtension='.etx',mimeType='text/x-setext'", "fileExtension='.evy',mimeType='application/envoy'", "fileExtension='.exe',mimeType='application/octet-stream'", "fileExtension='.exe.config',mimeType='text/xml'", "fileExtension='.fdf',mimeType='application/vnd.fdf'", "fileExtension='.fif',mimeType='application/fractals'", "fileExtension='.fla',mimeType='application/octet-stream'", "fileExtension='.flr',mimeType='x-world/x-vrml'", "fileExtension='.flv',mimeType='video/x-flv'", "fileExtension='.gif',mimeType='image/gif'", "fileExtension='.gtar',mimeType='application/x-gtar'", "fileExtension='.gz',mimeType='application/x-gzip'", "fileExtension='.h',mimeType='text/plain'", "fileExtension='.hdf',mimeType='application/x-hdf'", "fileExtension='.hdml',mimeType='text/x-hdml'", "fileExtension='.hhc',mimeType='application/x-oleobject'", "fileExtension='.hhk',mimeType='application/octet-stream'", "fileExtension='.hhp',mimeType='application/octet-stream'", "fileExtension='.hlp',mimeType='application/winhlp'", "fileExtension='.hqx',mimeType='application/mac-binhex40'", "fileExtension='.hta',mimeType='application/hta'", "fileExtension='.htc',mimeType='text/x-component'", "fileExtension='.htm',mimeType='text/html'", "fileExtension='.html',mimeType='text/html'", "fileExtension='.htt',mimeType='text/webviewhtml'", "fileExtension='.hxt',mimeType='text/html'", "fileExtension='.ico',mimeType='image/x-icon'", "fileExtension='.ics',mimeType='text/calendar'", "fileExtension='.ief',mimeType='image/ief'", "fileExtension='.iii',mimeType='application/x-iphone'", "fileExtension='.inf',mimeType='application/octet-stream'", "fileExtension='.ins',mimeType='application/x-internet-signup'", "fileExtension='.isp',mimeType='application/x-internet-signup'", "fileExtension='.IVF',mimeType='video/x-ivf'", "fileExtension='.jar',mimeType='application/java-archive'", "fileExtension='.java',mimeType='application/octet-stream'", "fileExtension='.jck',mimeType='application/liquidmotion'", "fileExtension='.jcz',mimeType='application/liquidmotion'", "fileExtension='.jfif',mimeType='image/pjpeg'", "fileExtension='.jpb',mimeType='application/octet-stream'", "fileExtension='.jpe',mimeType='image/jpeg'", "fileExtension='.jpeg',mimeType='image/jpeg'", "fileExtension='.jpg',mimeType='image/jpeg'", "fileExtension='.js',mimeType='application/javascript'", "fileExtension='.json',mimeType='application/json'", "fileExtension='.jsx',mimeType='text/jscript'", "fileExtension='.latex',mimeType='application/x-latex'", "fileExtension='.lit',mimeType='application/x-ms-reader'", "fileExtension='.lpk',mimeType='application/octet-stream'", "fileExtension='.lsf',mimeType='video/x-la-asf'", "fileExtension='.lsx',mimeType='video/x-la-asf'", "fileExtension='.lzh',mimeType='application/octet-stream'", "fileExtension='.m13',mimeType='application/x-msmediaview'", "fileExtension='.m14',mimeType='application/x-msmediaview'", "fileExtension='.m1v',mimeType='video/mpeg'", "fileExtension='.m2ts',mimeType='video/vnd.dlna.mpeg-tts'", "fileExtension='.m3u',mimeType='audio/x-mpegurl'", "fileExtension='.m4a',mimeType='audio/mp4'", "fileExtension='.m4v',mimeType='video/mp4'", "fileExtension='.man',mimeType='application/x-troff-man'", "fileExtension='.manifest',mimeType='application/x-ms-manifest'", "fileExtension='.map',mimeType='text/plain'", "fileExtension='.mdb',mimeType='application/x-msaccess'", "fileExtension='.mdp',mimeType='application/octet-stream'", "fileExtension='.me',mimeType='application/x-troff-me'", "fileExtension='.mht',mimeType='message/rfc822'", "fileExtension='.mhtml',mimeType='message/rfc822'", "fileExtension='.mid',mimeType='audio/mid'", "fileExtension='.midi',mimeType='audio/mid'", "fileExtension='.mix',mimeType='application/octet-stream'", "fileExtension='.mmf',mimeType='application/x-smaf'", "fileExtension='.mno',mimeType='text/xml'", "fileExtension='.mny',mimeType='application/x-msmoney'", "fileExtension='.mov',mimeType='video/quicktime'", "fileExtension='.movie',mimeType='video/x-sgi-movie'", "fileExtension='.mp2',mimeType='video/mpeg'", "fileExtension='.mp3',mimeType='audio/mpeg'", "fileExtension='.mp4',mimeType='video/mp4'", "fileExtension='.mp4v',mimeType='video/mp4'", "fileExtension='.mpa',mimeType='video/mpeg'", "fileExtension='.mpe',mimeType='video/mpeg'", "fileExtension='.mpeg',mimeType='video/mpeg'", "fileExtension='.mpg',mimeType='video/mpeg'", "fileExtension='.mpp',mimeType='application/vnd.ms-project'", "fileExtension='.mpv2',mimeType='video/mpeg'", "fileExtension='.ms',mimeType='application/x-troff-ms'", "fileExtension='.msi',mimeType='application/octet-stream'", "fileExtension='.mso',mimeType='application/octet-stream'", "fileExtension='.mvb',mimeType='application/x-msmediaview'", "fileExtension='.mvc',mimeType='application/x-miva-compiled'", "fileExtension='.nc',mimeType='application/x-netcdf'", "fileExtension='.nsc',mimeType='video/x-ms-asf'", "fileExtension='.nws',mimeType='message/rfc822'", "fileExtension='.ocx',mimeType='application/octet-stream'", "fileExtension='.oda',mimeType='application/oda'", "fileExtension='.odc',mimeType='text/x-ms-odc'", "fileExtension='.ods',mimeType='application/oleobject'", "fileExtension='.oga',mimeType='audio/ogg'", "fileExtension='.ogg',mimeType='video/ogg'", "fileExtension='.ogv',mimeType='video/ogg'", "fileExtension='.one',mimeType='application/onenote'", "fileExtension='.onea',mimeType='application/onenote'", "fileExtension='.onetoc',mimeType='application/onenote'", "fileExtension='.onetoc2',mimeType='application/onenote'", "fileExtension='.onetmp',mimeType='application/onenote'", "fileExtension='.onepkg',mimeType='application/onenote'", "fileExtension='.osdx',mimeType='application/opensearchdescription+xml'", "fileExtension='.otf',mimeType='font/otf'", "fileExtension='.p10',mimeType='application/pkcs10'", "fileExtension='.p12',mimeType='application/x-pkcs12'", "fileExtension='.p7b',mimeType='application/x-pkcs7-certificates'", "fileExtension='.p7c',mimeType='application/pkcs7-mime'", "fileExtension='.p7m',mimeType='application/pkcs7-mime'", "fileExtension='.p7r',mimeType='application/x-pkcs7-certreqresp'", "fileExtension='.p7s',mimeType='application/pkcs7-signature'", "fileExtension='.pbm',mimeType='image/x-portable-bitmap'", "fileExtension='.pcx',mimeType='application/octet-stream'", "fileExtension='.pcz',mimeType='application/octet-stream'", "fileExtension='.pdf',mimeType='application/pdf'", "fileExtension='.pfb',mimeType='application/octet-stream'", "fileExtension='.pfm',mimeType='application/octet-stream'", "fileExtension='.pfx',mimeType='application/x-pkcs12'", "fileExtension='.pgm',mimeType='image/x-portable-graymap'", "fileExtension='.pko',mimeType='application/vnd.ms-pki.pko'", "fileExtension='.pma',mimeType='application/x-perfmon'", "fileExtension='.pmc',mimeType='application/x-perfmon'", "fileExtension='.pml',mimeType='application/x-perfmon'", "fileExtension='.pmr',mimeType='application/x-perfmon'", "fileExtension='.pmw',mimeType='application/x-perfmon'", "fileExtension='.png',mimeType='image/png'", "fileExtension='.pnm',mimeType='image/x-portable-anymap'", "fileExtension='.pnz',mimeType='image/png'", "fileExtension='.pot',mimeType='application/vnd.ms-powerpoint'", "fileExtension='.potm',mimeType='application/vnd.ms-powerpoint.template.macroEnabled.12'", "fileExtension='.potx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.template'", "fileExtension='.ppam',mimeType='application/vnd.ms-powerpoint.addin.macroEnabled.12'", "fileExtension='.ppm',mimeType='image/x-portable-pixmap'", "fileExtension='.pps',mimeType='application/vnd.ms-powerpoint'", "fileExtension='.ppsm',mimeType='application/vnd.ms-powerpoint.slideshow.macroEnabled.12'", "fileExtension='.ppsx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.slideshow'", "fileExtension='.ppt',mimeType='application/vnd.ms-powerpoint'", "fileExtension='.pptm',mimeType='application/vnd.ms-powerpoint.presentation.macroEnabled.12'", "fileExtension='.pptx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.presentation'", "fileExtension='.prf',mimeType='application/pics-rules'", "fileExtension='.prm',mimeType='application/octet-stream'", "fileExtension='.prx',mimeType='application/octet-stream'", "fileExtension='.ps',mimeType='application/postscript'", "fileExtension='.psd',mimeType='application/octet-stream'", "fileExtension='.psm',mimeType='application/octet-stream'", "fileExtension='.psp',mimeType='application/octet-stream'", "fileExtension='.pub',mimeType='application/x-mspublisher'", "fileExtension='.qt',mimeType='video/quicktime'", "fileExtension='.qtl',mimeType='application/x-quicktimeplayer'", "fileExtension='.qxd',mimeType='application/octet-stream'", "fileExtension='.ra',mimeType='audio/x-pn-realaudio'", "fileExtension='.ram',mimeType='audio/x-pn-realaudio'", "fileExtension='.rar',mimeType='application/octet-stream'", "fileExtension='.ras',mimeType='image/x-cmu-raster'", "fileExtension='.rf',mimeType='image/vnd.rn-realflash'", "fileExtension='.rgb',mimeType='image/x-rgb'", "fileExtension='.rm',mimeType='application/vnd.rn-realmedia'", "fileExtension='.rmi',mimeType='audio/mid'", "fileExtension='.roff',mimeType='application/x-troff'", "fileExtension='.rpm',mimeType='audio/x-pn-realaudio-plugin'", "fileExtension='.rtf',mimeType='application/rtf'", "fileExtension='.rtx',mimeType='text/richtext'", "fileExtension='.scd',mimeType='application/x-msschedule'", "fileExtension='.sct',mimeType='text/scriptlet'", "fileExtension='.sea',mimeType='application/octet-stream'", "fileExtension='.setpay',mimeType='application/set-payment-initiation'", "fileExtension='.setreg',mimeType='application/set-registration-initiation'", "fileExtension='.sgml',mimeType='text/sgml'", "fileExtension='.sh',mimeType='application/x-sh'", "fileExtension='.shar',mimeType='application/x-shar'", "fileExtension='.sit',mimeType='application/x-stuffit'", "fileExtension='.sldm',mimeType='application/vnd.ms-powerpoint.slide.macroEnabled.12'", "fileExtension='.sldx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.slide'", "fileExtension='.smd',mimeType='audio/x-smd'", "fileExtension='.smi',mimeType='application/octet-stream'", "fileExtension='.smx',mimeType='audio/x-smd'", "fileExtension='.smz',mimeType='audio/x-smd'", "fileExtension='.snd',mimeType='audio/basic'", "fileExtension='.snp',mimeType='application/octet-stream'", "fileExtension='.spc',mimeType='application/x-pkcs7-certificates'", "fileExtension='.spl',mimeType='application/futuresplash'", "fileExtension='.spx',mimeType='audio/ogg'", "fileExtension='.src',mimeType='application/x-wais-source'", "fileExtension='.ssm',mimeType='application/streamingmedia'", "fileExtension='.sst',mimeType='application/vnd.ms-pki.certstore'", "fileExtension='.stl',mimeType='application/vnd.ms-pki.stl'", "fileExtension='.sv4cpio',mimeType='application/x-sv4cpio'", "fileExtension='.sv4crc',mimeType='application/x-sv4crc'", "fileExtension='.svg',mimeType='image/svg+xml'", "fileExtension='.svgz',mimeType='image/svg+xml'", "fileExtension='.swf',mimeType='application/x-shockwave-flash'", "fileExtension='.t',mimeType='application/x-troff'", "fileExtension='.tar',mimeType='application/x-tar'", "fileExtension='.tcl',mimeType='application/x-tcl'", "fileExtension='.tex',mimeType='application/x-tex'", "fileExtension='.texi',mimeType='application/x-texinfo'", "fileExtension='.texinfo',mimeType='application/x-texinfo'", "fileExtension='.tgz',mimeType='application/x-compressed'", "fileExtension='.thmx',mimeType='application/vnd.ms-officetheme'", "fileExtension='.thn',mimeType='application/octet-stream'", "fileExtension='.tif',mimeType='image/tiff'", "fileExtension='.tiff',mimeType='image/tiff'", "fileExtension='.toc',mimeType='application/octet-stream'", "fileExtension='.tr',mimeType='application/x-troff'", "fileExtension='.trm',mimeType='application/x-msterminal'", "fileExtension='.ts',mimeType='video/vnd.dlna.mpeg-tts'", "fileExtension='.tsv',mimeType='text/tab-separated-values'", "fileExtension='.ttf',mimeType='application/octet-stream'", "fileExtension='.tts',mimeType='video/vnd.dlna.mpeg-tts'", "fileExtension='.txt',mimeType='text/plain'", "fileExtension='.u32',mimeType='application/octet-stream'", "fileExtension='.uls',mimeType='text/iuls'", "fileExtension='.ustar',mimeType='application/x-ustar'", "fileExtension='.vbs',mimeType='text/vbscript'", "fileExtension='.vcf',mimeType='text/x-vcard'", "fileExtension='.vcs',mimeType='text/plain'", "fileExtension='.vdx',mimeType='application/vnd.ms-visio.viewer'", "fileExtension='.vml',mimeType='text/xml'", "fileExtension='.vsd',mimeType='application/vnd.visio'", "fileExtension='.vss',mimeType='application/vnd.visio'", "fileExtension='.vst',mimeType='application/vnd.visio'", "fileExtension='.vsto',mimeType='application/x-ms-vsto'", "fileExtension='.vsw',mimeType='application/vnd.visio'", "fileExtension='.vsx',mimeType='application/vnd.visio'", "fileExtension='.vtx',mimeType='application/vnd.visio'", "fileExtension='.wav',mimeType='audio/wav'", "fileExtension='.wax',mimeType='audio/x-ms-wax'", "fileExtension='.wbmp',mimeType='image/vnd.wap.wbmp'", "fileExtension='.wcm',mimeType='application/vnd.ms-works'", "fileExtension='.wdb',mimeType='application/vnd.ms-works'", "fileExtension='.webm',mimeType='video/webm'", "fileExtension='.wks',mimeType='application/vnd.ms-works'", "fileExtension='.wm',mimeType='video/x-ms-wm'", "fileExtension='.wma',mimeType='audio/x-ms-wma'", "fileExtension='.wmd',mimeType='application/x-ms-wmd'", "fileExtension='.wmf',mimeType='application/x-msmetafile'", "fileExtension='.wml',mimeType='text/vnd.wap.wml'", "fileExtension='.wmlc',mimeType='application/vnd.wap.wmlc'", "fileExtension='.wmls',mimeType='text/vnd.wap.wmlscript'", "fileExtension='.wmlsc',mimeType='application/vnd.wap.wmlscriptc'", "fileExtension='.wmp',mimeType='video/x-ms-wmp'", "fileExtension='.wmv',mimeType='video/x-ms-wmv'", "fileExtension='.wmx',mimeType='video/x-ms-wmx'", "fileExtension='.wmz',mimeType='application/x-ms-wmz'", "fileExtension='.woff',mimeType='font/x-woff'", "fileExtension='.wps',mimeType='application/vnd.ms-works'", "fileExtension='.wri',mimeType='application/x-mswrite'", "fileExtension='.wrl',mimeType='x-world/x-vrml'", "fileExtension='.wrz',mimeType='x-world/x-vrml'", "fileExtension='.wsdl',mimeType='text/xml'", "fileExtension='.wtv',mimeType='video/x-ms-wtv'", "fileExtension='.wvx',mimeType='video/x-ms-wvx'", "fileExtension='.x',mimeType='application/directx'", "fileExtension='.xaf',mimeType='x-world/x-vrml'", "fileExtension='.xaml',mimeType='application/xaml+xml'", "fileExtension='.xap',mimeType='application/x-silverlight-app'", "fileExtension='.xbap',mimeType='application/x-ms-xbap'", "fileExtension='.xbm',mimeType='image/x-xbitmap'", "fileExtension='.xdr',mimeType='text/plain'", "fileExtension='.xht',mimeType='application/xhtml+xml'", "fileExtension='.xhtml',mimeType='application/xhtml+xml'", "fileExtension='.xla',mimeType='application/vnd.ms-excel'", "fileExtension='.xlam',mimeType='application/vnd.ms-excel.addin.macroEnabled.12'", "fileExtension='.xlc',mimeType='application/vnd.ms-excel'", "fileExtension='.xlm',mimeType='application/vnd.ms-excel'", "fileExtension='.xls',mimeType='application/vnd.ms-excel'", "fileExtension='.xlsb',mimeType='application/vnd.ms-excel.sheet.binary.macroEnabled.12'", "fileExtension='.xlsm',mimeType='application/vnd.ms-excel.sheet.macroEnabled.12'", "fileExtension='.xlsx',mimeType='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'", "fileExtension='.xlt',mimeType='application/vnd.ms-excel'", "fileExtension='.xltm',mimeType='application/vnd.ms-excel.template.macroEnabled.12'", "fileExtension='.xltx',mimeType='application/vnd.openxmlformats-officedocument.spreadsheetml.template'", "fileExtension='.xlw',mimeType='application/vnd.ms-excel'", "fileExtension='.xml',mimeType='text/xml'", "fileExtension='.xof',mimeType='x-world/x-vrml'", "fileExtension='.xpm',mimeType='image/x-xpixmap'", "fileExtension='.xps',mimeType='application/vnd.ms-xpsdocument'", "fileExtension='.xsd',mimeType='text/xml'", "fileExtension='.xsf',mimeType='text/xml'", "fileExtension='.xsl',mimeType='text/xml'", "fileExtension='.xslt',mimeType='text/xml'", "fileExtension='.xsn',mimeType='application/octet-stream'", "fileExtension='.xtp',mimeType='application/octet-stream'", "fileExtension='.xwd',mimeType='image/x-xwindowdump'", "fileExtension='.z',mimeType='application/x-compress'", "fileExtension='.zip',mimeType='application/x-zip-compressed'"] -``` + + ```ruby + ["fileExtension='.323',mimeType='text/h323'", "fileExtension='.3g2',mimeType='video/3gpp2'", "fileExtension='.3gp2',mimeType='video/3gpp2'", "fileExtension='.3gp',mimeType='video/3gpp'", "fileExtension='.3gpp',mimeType='video/3gpp'", "fileExtension='.aaf',mimeType='application/octet-stream'", "fileExtension='.aac',mimeType='audio/aac'", "fileExtension='.aca',mimeType='application/octet-stream'", "fileExtension='.accdb',mimeType='application/msaccess'", "fileExtension='.accde',mimeType='application/msaccess'", "fileExtension='.accdt',mimeType='application/msaccess'", "fileExtension='.acx',mimeType='application/internet-property-stream'", "fileExtension='.adt',mimeType='audio/vnd.dlna.adts'", "fileExtension='.adts',mimeType='audio/vnd.dlna.adts'", "fileExtension='.afm',mimeType='application/octet-stream'", "fileExtension='.ai',mimeType='application/postscript'", "fileExtension='.aif',mimeType='audio/x-aiff'", "fileExtension='.aifc',mimeType='audio/aiff'", "fileExtension='.aiff',mimeType='audio/aiff'", "fileExtension='.application',mimeType='application/x-ms-application'", "fileExtension='.art',mimeType='image/x-jg'", "fileExtension='.asd',mimeType='application/octet-stream'", "fileExtension='.asf',mimeType='video/x-ms-asf'", "fileExtension='.asi',mimeType='application/octet-stream'", "fileExtension='.asm',mimeType='text/plain'", "fileExtension='.asr',mimeType='video/x-ms-asf'", "fileExtension='.asx',mimeType='video/x-ms-asf'", "fileExtension='.atom',mimeType='application/atom+xml'", "fileExtension='.au',mimeType='audio/basic'", "fileExtension='.avi',mimeType='video/avi'", "fileExtension='.axs',mimeType='application/olescript'", "fileExtension='.bas',mimeType='text/plain'", "fileExtension='.bcpio',mimeType='application/x-bcpio'", "fileExtension='.bin',mimeType='application/octet-stream'", "fileExtension='.bmp',mimeType='image/bmp'", "fileExtension='.c',mimeType='text/plain'", "fileExtension='.cab',mimeType='application/vnd.ms-cab-compressed'", "fileExtension='.calx',mimeType='application/vnd.ms-office.calx'", "fileExtension='.cat',mimeType='application/vnd.ms-pki.seccat'", "fileExtension='.cdf',mimeType='application/x-cdf'", "fileExtension='.chm',mimeType='application/octet-stream'", "fileExtension='.class',mimeType='application/x-java-applet'", "fileExtension='.clp',mimeType='application/x-msclip'", "fileExtension='.cmx',mimeType='image/x-cmx'", "fileExtension='.cnf',mimeType='text/plain'", "fileExtension='.cod',mimeType='image/cis-cod'", "fileExtension='.cpio',mimeType='application/x-cpio'", "fileExtension='.cpp',mimeType='text/plain'", "fileExtension='.crd',mimeType='application/x-mscardfile'", "fileExtension='.crl',mimeType='application/pkix-crl'", "fileExtension='.crt',mimeType='application/x-x509-ca-cert'", "fileExtension='.csh',mimeType='application/x-csh'", "fileExtension='.css',mimeType='text/css'", "fileExtension='.csv',mimeType='application/octet-stream'", "fileExtension='.cur',mimeType='application/octet-stream'", "fileExtension='.dcr',mimeType='application/x-director'", "fileExtension='.deploy',mimeType='application/octet-stream'", "fileExtension='.der',mimeType='application/x-x509-ca-cert'", "fileExtension='.dib',mimeType='image/bmp'", "fileExtension='.dir',mimeType='application/x-director'", "fileExtension='.disco',mimeType='text/xml'", "fileExtension='.dll',mimeType='application/x-msdownload'", "fileExtension='.dll.config',mimeType='text/xml'", "fileExtension='.dlm',mimeType='text/dlm'", "fileExtension='.doc',mimeType='application/msword'", "fileExtension='.docm',mimeType='application/vnd.ms-word.document.macroEnabled.12'", "fileExtension='.docx',mimeType='application/vnd.openxmlformats-officedocument.wordprocessingml.document'", "fileExtension='.dot',mimeType='application/msword'", "fileExtension='.dotm',mimeType='application/vnd.ms-word.template.macroEnabled.12'", "fileExtension='.dotx',mimeType='application/vnd.openxmlformats-officedocument.wordprocessingml.template'", "fileExtension='.dsp',mimeType='application/octet-stream'", "fileExtension='.dtd',mimeType='text/xml'", "fileExtension='.dvi',mimeType='application/x-dvi'", "fileExtension='.dvr-ms',mimeType='video/x-ms-dvr'", "fileExtension='.dwf',mimeType='drawing/x-dwf'", "fileExtension='.dwp',mimeType='application/octet-stream'", "fileExtension='.dxr',mimeType='application/x-director'", "fileExtension='.eml',mimeType='message/rfc822'", "fileExtension='.emz',mimeType='application/octet-stream'", "fileExtension='.eot',mimeType='application/vnd.ms-fontobject'", "fileExtension='.eps',mimeType='application/postscript'", "fileExtension='.etx',mimeType='text/x-setext'", "fileExtension='.evy',mimeType='application/envoy'", "fileExtension='.exe',mimeType='application/octet-stream'", "fileExtension='.exe.config',mimeType='text/xml'", "fileExtension='.fdf',mimeType='application/vnd.fdf'", "fileExtension='.fif',mimeType='application/fractals'", "fileExtension='.fla',mimeType='application/octet-stream'", "fileExtension='.flr',mimeType='x-world/x-vrml'", "fileExtension='.flv',mimeType='video/x-flv'", "fileExtension='.gif',mimeType='image/gif'", "fileExtension='.gtar',mimeType='application/x-gtar'", "fileExtension='.gz',mimeType='application/x-gzip'", "fileExtension='.h',mimeType='text/plain'", "fileExtension='.hdf',mimeType='application/x-hdf'", "fileExtension='.hdml',mimeType='text/x-hdml'", "fileExtension='.hhc',mimeType='application/x-oleobject'", "fileExtension='.hhk',mimeType='application/octet-stream'", "fileExtension='.hhp',mimeType='application/octet-stream'", "fileExtension='.hlp',mimeType='application/winhlp'", "fileExtension='.hqx',mimeType='application/mac-binhex40'", "fileExtension='.hta',mimeType='application/hta'", "fileExtension='.htc',mimeType='text/x-component'", "fileExtension='.htm',mimeType='text/html'", "fileExtension='.html',mimeType='text/html'", "fileExtension='.htt',mimeType='text/webviewhtml'", "fileExtension='.hxt',mimeType='text/html'", "fileExtension='.ico',mimeType='image/x-icon'", "fileExtension='.ics',mimeType='text/calendar'", "fileExtension='.ief',mimeType='image/ief'", "fileExtension='.iii',mimeType='application/x-iphone'", "fileExtension='.inf',mimeType='application/octet-stream'", "fileExtension='.ins',mimeType='application/x-internet-signup'", "fileExtension='.isp',mimeType='application/x-internet-signup'", "fileExtension='.IVF',mimeType='video/x-ivf'", "fileExtension='.jar',mimeType='application/java-archive'", "fileExtension='.java',mimeType='application/octet-stream'", "fileExtension='.jck',mimeType='application/liquidmotion'", "fileExtension='.jcz',mimeType='application/liquidmotion'", "fileExtension='.jfif',mimeType='image/pjpeg'", "fileExtension='.jpb',mimeType='application/octet-stream'", "fileExtension='.jpe',mimeType='image/jpeg'", "fileExtension='.jpeg',mimeType='image/jpeg'", "fileExtension='.jpg',mimeType='image/jpeg'", "fileExtension='.js',mimeType='application/javascript'", "fileExtension='.json',mimeType='application/json'", "fileExtension='.jsx',mimeType='text/jscript'", "fileExtension='.latex',mimeType='application/x-latex'", "fileExtension='.lit',mimeType='application/x-ms-reader'", "fileExtension='.lpk',mimeType='application/octet-stream'", "fileExtension='.lsf',mimeType='video/x-la-asf'", "fileExtension='.lsx',mimeType='video/x-la-asf'", "fileExtension='.lzh',mimeType='application/octet-stream'", "fileExtension='.m13',mimeType='application/x-msmediaview'", "fileExtension='.m14',mimeType='application/x-msmediaview'", "fileExtension='.m1v',mimeType='video/mpeg'", "fileExtension='.m2ts',mimeType='video/vnd.dlna.mpeg-tts'", "fileExtension='.m3u',mimeType='audio/x-mpegurl'", "fileExtension='.m4a',mimeType='audio/mp4'", "fileExtension='.m4v',mimeType='video/mp4'", "fileExtension='.man',mimeType='application/x-troff-man'", "fileExtension='.manifest',mimeType='application/x-ms-manifest'", "fileExtension='.map',mimeType='text/plain'", "fileExtension='.mdb',mimeType='application/x-msaccess'", "fileExtension='.mdp',mimeType='application/octet-stream'", "fileExtension='.me',mimeType='application/x-troff-me'", "fileExtension='.mht',mimeType='message/rfc822'", "fileExtension='.mhtml',mimeType='message/rfc822'", "fileExtension='.mid',mimeType='audio/mid'", "fileExtension='.midi',mimeType='audio/mid'", "fileExtension='.mix',mimeType='application/octet-stream'", "fileExtension='.mmf',mimeType='application/x-smaf'", "fileExtension='.mno',mimeType='text/xml'", "fileExtension='.mny',mimeType='application/x-msmoney'", "fileExtension='.mov',mimeType='video/quicktime'", "fileExtension='.movie',mimeType='video/x-sgi-movie'", "fileExtension='.mp2',mimeType='video/mpeg'", "fileExtension='.mp3',mimeType='audio/mpeg'", "fileExtension='.mp4',mimeType='video/mp4'", "fileExtension='.mp4v',mimeType='video/mp4'", "fileExtension='.mpa',mimeType='video/mpeg'", "fileExtension='.mpe',mimeType='video/mpeg'", "fileExtension='.mpeg',mimeType='video/mpeg'", "fileExtension='.mpg',mimeType='video/mpeg'", "fileExtension='.mpp',mimeType='application/vnd.ms-project'", "fileExtension='.mpv2',mimeType='video/mpeg'", "fileExtension='.ms',mimeType='application/x-troff-ms'", "fileExtension='.msi',mimeType='application/octet-stream'", "fileExtension='.mso',mimeType='application/octet-stream'", "fileExtension='.mvb',mimeType='application/x-msmediaview'", "fileExtension='.mvc',mimeType='application/x-miva-compiled'", "fileExtension='.nc',mimeType='application/x-netcdf'", "fileExtension='.nsc',mimeType='video/x-ms-asf'", "fileExtension='.nws',mimeType='message/rfc822'", "fileExtension='.ocx',mimeType='application/octet-stream'", "fileExtension='.oda',mimeType='application/oda'", "fileExtension='.odc',mimeType='text/x-ms-odc'", "fileExtension='.ods',mimeType='application/oleobject'", "fileExtension='.oga',mimeType='audio/ogg'", "fileExtension='.ogg',mimeType='video/ogg'", "fileExtension='.ogv',mimeType='video/ogg'", "fileExtension='.one',mimeType='application/onenote'", "fileExtension='.onea',mimeType='application/onenote'", "fileExtension='.onetoc',mimeType='application/onenote'", "fileExtension='.onetoc2',mimeType='application/onenote'", "fileExtension='.onetmp',mimeType='application/onenote'", "fileExtension='.onepkg',mimeType='application/onenote'", "fileExtension='.osdx',mimeType='application/opensearchdescription+xml'", "fileExtension='.otf',mimeType='font/otf'", "fileExtension='.p10',mimeType='application/pkcs10'", "fileExtension='.p12',mimeType='application/x-pkcs12'", "fileExtension='.p7b',mimeType='application/x-pkcs7-certificates'", "fileExtension='.p7c',mimeType='application/pkcs7-mime'", "fileExtension='.p7m',mimeType='application/pkcs7-mime'", "fileExtension='.p7r',mimeType='application/x-pkcs7-certreqresp'", "fileExtension='.p7s',mimeType='application/pkcs7-signature'", "fileExtension='.pbm',mimeType='image/x-portable-bitmap'", "fileExtension='.pcx',mimeType='application/octet-stream'", "fileExtension='.pcz',mimeType='application/octet-stream'", "fileExtension='.pdf',mimeType='application/pdf'", "fileExtension='.pfb',mimeType='application/octet-stream'", "fileExtension='.pfm',mimeType='application/octet-stream'", "fileExtension='.pfx',mimeType='application/x-pkcs12'", "fileExtension='.pgm',mimeType='image/x-portable-graymap'", "fileExtension='.pko',mimeType='application/vnd.ms-pki.pko'", "fileExtension='.pma',mimeType='application/x-perfmon'", "fileExtension='.pmc',mimeType='application/x-perfmon'", "fileExtension='.pml',mimeType='application/x-perfmon'", "fileExtension='.pmr',mimeType='application/x-perfmon'", "fileExtension='.pmw',mimeType='application/x-perfmon'", "fileExtension='.png',mimeType='image/png'", "fileExtension='.pnm',mimeType='image/x-portable-anymap'", "fileExtension='.pnz',mimeType='image/png'", "fileExtension='.pot',mimeType='application/vnd.ms-powerpoint'", "fileExtension='.potm',mimeType='application/vnd.ms-powerpoint.template.macroEnabled.12'", "fileExtension='.potx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.template'", "fileExtension='.ppam',mimeType='application/vnd.ms-powerpoint.addin.macroEnabled.12'", "fileExtension='.ppm',mimeType='image/x-portable-pixmap'", "fileExtension='.pps',mimeType='application/vnd.ms-powerpoint'", "fileExtension='.ppsm',mimeType='application/vnd.ms-powerpoint.slideshow.macroEnabled.12'", "fileExtension='.ppsx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.slideshow'", "fileExtension='.ppt',mimeType='application/vnd.ms-powerpoint'", "fileExtension='.pptm',mimeType='application/vnd.ms-powerpoint.presentation.macroEnabled.12'", "fileExtension='.pptx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.presentation'", "fileExtension='.prf',mimeType='application/pics-rules'", "fileExtension='.prm',mimeType='application/octet-stream'", "fileExtension='.prx',mimeType='application/octet-stream'", "fileExtension='.ps',mimeType='application/postscript'", "fileExtension='.psd',mimeType='application/octet-stream'", "fileExtension='.psm',mimeType='application/octet-stream'", "fileExtension='.psp',mimeType='application/octet-stream'", "fileExtension='.pub',mimeType='application/x-mspublisher'", "fileExtension='.qt',mimeType='video/quicktime'", "fileExtension='.qtl',mimeType='application/x-quicktimeplayer'", "fileExtension='.qxd',mimeType='application/octet-stream'", "fileExtension='.ra',mimeType='audio/x-pn-realaudio'", "fileExtension='.ram',mimeType='audio/x-pn-realaudio'", "fileExtension='.rar',mimeType='application/octet-stream'", "fileExtension='.ras',mimeType='image/x-cmu-raster'", "fileExtension='.rf',mimeType='image/vnd.rn-realflash'", "fileExtension='.rgb',mimeType='image/x-rgb'", "fileExtension='.rm',mimeType='application/vnd.rn-realmedia'", "fileExtension='.rmi',mimeType='audio/mid'", "fileExtension='.roff',mimeType='application/x-troff'", "fileExtension='.rpm',mimeType='audio/x-pn-realaudio-plugin'", "fileExtension='.rtf',mimeType='application/rtf'", "fileExtension='.rtx',mimeType='text/richtext'", "fileExtension='.scd',mimeType='application/x-msschedule'", "fileExtension='.sct',mimeType='text/scriptlet'", "fileExtension='.sea',mimeType='application/octet-stream'", "fileExtension='.setpay',mimeType='application/set-payment-initiation'", "fileExtension='.setreg',mimeType='application/set-registration-initiation'", "fileExtension='.sgml',mimeType='text/sgml'", "fileExtension='.sh',mimeType='application/x-sh'", "fileExtension='.shar',mimeType='application/x-shar'", "fileExtension='.sit',mimeType='application/x-stuffit'", "fileExtension='.sldm',mimeType='application/vnd.ms-powerpoint.slide.macroEnabled.12'", "fileExtension='.sldx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.slide'", "fileExtension='.smd',mimeType='audio/x-smd'", "fileExtension='.smi',mimeType='application/octet-stream'", "fileExtension='.smx',mimeType='audio/x-smd'", "fileExtension='.smz',mimeType='audio/x-smd'", "fileExtension='.snd',mimeType='audio/basic'", "fileExtension='.snp',mimeType='application/octet-stream'", "fileExtension='.spc',mimeType='application/x-pkcs7-certificates'", "fileExtension='.spl',mimeType='application/futuresplash'", "fileExtension='.spx',mimeType='audio/ogg'", "fileExtension='.src',mimeType='application/x-wais-source'", "fileExtension='.ssm',mimeType='application/streamingmedia'", "fileExtension='.sst',mimeType='application/vnd.ms-pki.certstore'", "fileExtension='.stl',mimeType='application/vnd.ms-pki.stl'", "fileExtension='.sv4cpio',mimeType='application/x-sv4cpio'", "fileExtension='.sv4crc',mimeType='application/x-sv4crc'", "fileExtension='.svg',mimeType='image/svg+xml'", "fileExtension='.svgz',mimeType='image/svg+xml'", "fileExtension='.swf',mimeType='application/x-shockwave-flash'", "fileExtension='.t',mimeType='application/x-troff'", "fileExtension='.tar',mimeType='application/x-tar'", "fileExtension='.tcl',mimeType='application/x-tcl'", "fileExtension='.tex',mimeType='application/x-tex'", "fileExtension='.texi',mimeType='application/x-texinfo'", "fileExtension='.texinfo',mimeType='application/x-texinfo'", "fileExtension='.tgz',mimeType='application/x-compressed'", "fileExtension='.thmx',mimeType='application/vnd.ms-officetheme'", "fileExtension='.thn',mimeType='application/octet-stream'", "fileExtension='.tif',mimeType='image/tiff'", "fileExtension='.tiff',mimeType='image/tiff'", "fileExtension='.toc',mimeType='application/octet-stream'", "fileExtension='.tr',mimeType='application/x-troff'", "fileExtension='.trm',mimeType='application/x-msterminal'", "fileExtension='.ts',mimeType='video/vnd.dlna.mpeg-tts'", "fileExtension='.tsv',mimeType='text/tab-separated-values'", "fileExtension='.ttf',mimeType='application/octet-stream'", "fileExtension='.tts',mimeType='video/vnd.dlna.mpeg-tts'", "fileExtension='.txt',mimeType='text/plain'", "fileExtension='.u32',mimeType='application/octet-stream'", "fileExtension='.uls',mimeType='text/iuls'", "fileExtension='.ustar',mimeType='application/x-ustar'", "fileExtension='.vbs',mimeType='text/vbscript'", "fileExtension='.vcf',mimeType='text/x-vcard'", "fileExtension='.vcs',mimeType='text/plain'", "fileExtension='.vdx',mimeType='application/vnd.ms-visio.viewer'", "fileExtension='.vml',mimeType='text/xml'", "fileExtension='.vsd',mimeType='application/vnd.visio'", "fileExtension='.vss',mimeType='application/vnd.visio'", "fileExtension='.vst',mimeType='application/vnd.visio'", "fileExtension='.vsto',mimeType='application/x-ms-vsto'", "fileExtension='.vsw',mimeType='application/vnd.visio'", "fileExtension='.vsx',mimeType='application/vnd.visio'", "fileExtension='.vtx',mimeType='application/vnd.visio'", "fileExtension='.wav',mimeType='audio/wav'", "fileExtension='.wax',mimeType='audio/x-ms-wax'", "fileExtension='.wbmp',mimeType='image/vnd.wap.wbmp'", "fileExtension='.wcm',mimeType='application/vnd.ms-works'", "fileExtension='.wdb',mimeType='application/vnd.ms-works'", "fileExtension='.webm',mimeType='video/webm'", "fileExtension='.wks',mimeType='application/vnd.ms-works'", "fileExtension='.wm',mimeType='video/x-ms-wm'", "fileExtension='.wma',mimeType='audio/x-ms-wma'", "fileExtension='.wmd',mimeType='application/x-ms-wmd'", "fileExtension='.wmf',mimeType='application/x-msmetafile'", "fileExtension='.wml',mimeType='text/vnd.wap.wml'", "fileExtension='.wmlc',mimeType='application/vnd.wap.wmlc'", "fileExtension='.wmls',mimeType='text/vnd.wap.wmlscript'", "fileExtension='.wmlsc',mimeType='application/vnd.wap.wmlscriptc'", "fileExtension='.wmp',mimeType='video/x-ms-wmp'", "fileExtension='.wmv',mimeType='video/x-ms-wmv'", "fileExtension='.wmx',mimeType='video/x-ms-wmx'", "fileExtension='.wmz',mimeType='application/x-ms-wmz'", "fileExtension='.woff',mimeType='font/x-woff'", "fileExtension='.wps',mimeType='application/vnd.ms-works'", "fileExtension='.wri',mimeType='application/x-mswrite'", "fileExtension='.wrl',mimeType='x-world/x-vrml'", "fileExtension='.wrz',mimeType='x-world/x-vrml'", "fileExtension='.wsdl',mimeType='text/xml'", "fileExtension='.wtv',mimeType='video/x-ms-wtv'", "fileExtension='.wvx',mimeType='video/x-ms-wvx'", "fileExtension='.x',mimeType='application/directx'", "fileExtension='.xaf',mimeType='x-world/x-vrml'", "fileExtension='.xaml',mimeType='application/xaml+xml'", "fileExtension='.xap',mimeType='application/x-silverlight-app'", "fileExtension='.xbap',mimeType='application/x-ms-xbap'", "fileExtension='.xbm',mimeType='image/x-xbitmap'", "fileExtension='.xdr',mimeType='text/plain'", "fileExtension='.xht',mimeType='application/xhtml+xml'", "fileExtension='.xhtml',mimeType='application/xhtml+xml'", "fileExtension='.xla',mimeType='application/vnd.ms-excel'", "fileExtension='.xlam',mimeType='application/vnd.ms-excel.addin.macroEnabled.12'", "fileExtension='.xlc',mimeType='application/vnd.ms-excel'", "fileExtension='.xlm',mimeType='application/vnd.ms-excel'", "fileExtension='.xls',mimeType='application/vnd.ms-excel'", "fileExtension='.xlsb',mimeType='application/vnd.ms-excel.sheet.binary.macroEnabled.12'", "fileExtension='.xlsm',mimeType='application/vnd.ms-excel.sheet.macroEnabled.12'", "fileExtension='.xlsx',mimeType='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'", "fileExtension='.xlt',mimeType='application/vnd.ms-excel'", "fileExtension='.xltm',mimeType='application/vnd.ms-excel.template.macroEnabled.12'", "fileExtension='.xltx',mimeType='application/vnd.openxmlformats-officedocument.spreadsheetml.template'", "fileExtension='.xlw',mimeType='application/vnd.ms-excel'", "fileExtension='.xml',mimeType='text/xml'", "fileExtension='.xof',mimeType='x-world/x-vrml'", "fileExtension='.xpm',mimeType='image/x-xpixmap'", "fileExtension='.xps',mimeType='application/vnd.ms-xpsdocument'", "fileExtension='.xsd',mimeType='text/xml'", "fileExtension='.xsf',mimeType='text/xml'", "fileExtension='.xsl',mimeType='text/xml'", "fileExtension='.xslt',mimeType='text/xml'", "fileExtension='.xsn',mimeType='application/octet-stream'", "fileExtension='.xtp',mimeType='application/octet-stream'", "fileExtension='.xwd',mimeType='image/x-xwindowdump'", "fileExtension='.z',mimeType='application/x-compress'", "fileExtension='.zip',mimeType='application/x-zip-compressed'"] + ``` + - `add_default_documents` - The items you want to add to the default document collection, only used during `:add`. Array of strings, default: `[]` + - `add_mime_maps` - The items you want to add to the mime-map/mime-type collection, only used during `:add`. Array of strings, default: `[]` + - `delete_default_documents` - The items you want to delete from the default document collection, only used during `:delete`. Array of strings, default: `[]` + - `delete_mime_maps` - The items you want to delete from the mime-map/mime-type collection, only used during `:delete`. Array of strings, default: `[]` -### Examples +#### Examples ```ruby # Add foo.html to default documents, and add '.dmg' as mime type extension at root level @@ -93,6 +98,7 @@ iis_root 'add stuff' do action :add end ``` + ```ruby # Remove index.html from default document and .323 as a mime type at root level iis_root 'delete stuff' do @@ -101,12 +107,12 @@ iis_root 'delete stuff' do action :delete end ``` -iis_site ---------- + +### iis_site Allows for easy management of IIS virtual sites (ie vhosts). -### Actions +#### Actions - `:add` - add a new virtual site - `:config` - apply configuration to an existing virtual site @@ -115,7 +121,7 @@ Allows for easy management of IIS virtual sites (ie vhosts). - `:stop` - stop a virtual site - `:restart` - restart a virtual site -### Attribute Parameters +#### Properties - `site_name` - name attribute. - `site_id` - if not given IIS generates a unique ID for the site @@ -124,14 +130,14 @@ Allows for easy management of IIS virtual sites (ie vhosts). - `port` - port site will listen on. default is 80 - `host_header` - host header (also known as domains or host names) the site should map to. default is all host headers - `options` - additional options to configure the site -- `bindings` - Advanced options to configure the information required for requests to communicate with a Web site. See http://www.iis.net/configreference/system.applicationhost/sites/site/bindings/binding for parameter format. When binding is used, port protocol and host_header should not be used. +- `bindings` - Advanced options to configure the information required for requests to communicate with a Web site. See for parameter format. When binding is used, port protocol and host_header should not be used. - `application_pool` - set the application pool of the site - `options` - support for additional options -logDir, -limits, -ftpServer, etc... - `log_directory` - specifies the logging directory, where the log file and logging-related support files are stored. - `log_period` - specifies how often iis creates a new log file - `log_truncsize` - specifies the maximum size of the log file (in bytes) after which to create a new log file. -### Examples +#### Examples ```ruby # stop and delete the default site @@ -195,21 +201,21 @@ iis_site 'FooBar Site' do end ``` -iis_config ------------ +### iis_config + Runs a config command on your IIS instance. -### Actions +#### Actions - `:set` - Edit configuration section (appcmd set config) - `:clear` - Clear the section configuration (appcmd clear config) - `:config` - [ DEPRECATED ] use `:set` instead -### Attribute Parameters +#### Properties - `cfg_cmd` - name attribute. What ever command you would pass in after "appcmd.exe set config" -### Example +#### Example ```ruby # Sets up logging @@ -237,7 +243,6 @@ end iis_config "\"MyWebsite/aSite\" -section:system.webServer/security/authentication/anonymousAuthentication /enabled:\"True\" /userName:\"\" /commit:apphost" do action :set end - ``` ```ruby @@ -259,17 +264,16 @@ end ```ruby # Remove machine key -iis_config "MySite /commit:site /section:machineKey" +iis_config "MySite /commit:site /section:machineKey" do action :clear end ``` +### iis_pool -iis_pool ---------- Creates an application pool in IIS. -### Actions +#### Actions - `:add` - add a new application pool - `:config` - apply configuration to an existing application pool @@ -279,21 +283,24 @@ Creates an application pool in IIS. - `:restart` - restart a application pool - `:recycle` - recycle an application pool -### Attribute Parameters +#### Properties + +##### Root Items -#### Root Items - `pool_name` - name attribute. Specifies the name of the pool to create. - `runtime_version` - specifies what .NET version of the runtime to use. - `pipeline_mode` - specifies what pipeline mode to create the pool with, valid values are :Integrated or :Classic, the default is :Integrated - `no_managed_code` - allow Unmanaged Code in setting up IIS app pools is shutting down. - default is true - optional -#### Add Items +##### Add Items + - `start_mode` - Specifies the startup type for the application pool - default :OnDemand (:OnDemand, :AlwaysRunning) - optional - `auto_start` - When true, indicates to the World Wide Web Publishing Service (W3SVC) that the application pool should be automatically started when it is created or when IIS is started. - boolean: default true - optional - `queue_length` - Indicates to HTTP.sys how many requests to queue for an application pool before rejecting future requests. - default is 1000 - optional - `thirty_two_bit` - set the pool to run in 32 bit mode, valid values are true or false, default is false - optional -#### Process Model Items +##### Process Model Items + - `max_proc` - specifies the number of worker processes associated with the pool. - `load_user_profile` - This property is used only when a service starts in a named user account. - Default is false - optional - `pool_identity` - the account identity that they app pool will run as, valid values are :SpecificUser, :NetworkService, :LocalService, :LocalSystem, :ApplicationPoolIdentity @@ -309,14 +316,19 @@ Creates an application pool in IIS. - `ping_interval` - Specifies the time between health-monitoring pings that the WWW service sends to a worker process - default is '00:00:30' - optional - `ping_response_time` - Specifies the time that a worker process is given to respond to a health-monitoring ping. After the time limit is exceeded, the WWW service terminates the worker process - default is '00:01:30' - optional -#### Recycling Items +##### Recycling Items + - `disallow_rotation_on_config_change` - The DisallowRotationOnConfigChange property specifies whether or not the World Wide Web Publishing Service (WWW Service) should rotate worker processes in an application pool when the configuration has changed. - Default is false - optional - `disallow_overlapping_rotation` - Specifies whether the WWW Service should start another worker process to replace the existing worker process while that process +- `log_event_on_recycle` - configure IIS to log an event when one or more of the following configured events cause an application pool to recycle (for additional information about [logging events] (https://technet.microsoft.com/en-us/library/cc771318%28v=ws.10%29.aspx). - default is 'Time, Requests, Schedule, Memory, IsapiUnhealthy, OnDemand, ConfigChange, PrivateMemory' - optional +- `recycle_schedule_clear` - specifies a pool to clear all scheduled recycle times, [true,false] Default is false - optional - `recycle_after_time` - specifies a pool to recycle at regular time intervals, d.hh:mm:ss, d optional - `recycle_at_time` - schedule a pool to recycle at a specific time, d.hh:mm:ss, d optional - `private_mem` - specifies the amount of private memory (in kilobytes) after which you want the pool to recycle +- `virtual_mem` - specifies the amount of virtual memory (in kilobytes) after which you want the pool to recycle #### Failure Items + - `load_balancer_capabilities` - Specifies behavior when a worker process cannot be started, such as when the request queue is full or an application pool is in rapid-fail protection. - default is :HttpLevel - optional - `orphan_worker_process` - Specifies whether to assign a worker process to an orphan state instead of terminating it when an application pool fails. - default is false - optional - `orphan_action_exe` - Specifies an executable to run when the WWW service orphans a worker process (if the orphanWorkerProcess attribute is set to true). You can use the orphanActionParams attribute to send parameters to the executable. - optional @@ -327,7 +339,8 @@ Creates an application pool in IIS. - `auto_shutdown_exe` - Specifies an executable to run when the WWW service shuts down an application pool. - optional - `auto_shutdown_params` - Specifies command-line parameters for the executable that is specified in the autoShutdownExe attribute. - optional -#### CPU Items +##### CPU Items + - `cpu_action` - Configures the action that IIS takes when a worker process exceeds its configured CPU limit. The action attribute is configured on a per-application pool basis. - Available options [:NoAction, :KillW3wp, :Throttle, :ThrottleUnderLoad] - default is :NoAction - optional - `cpu_limit` - Configures the maximum percentage of CPU time (in 1/1000ths of one percent) that the worker processes in an application pool are allowed to consume over a period of time as indicated by the resetInterval attribute. If the limit set by the limit attribute is exceeded, an event is written to the event log and an optional set of events can be triggered. These optional events are determined by the action attribute. - default is 0 - optional - `cpu_reset_interval` - Specifies the reset period (in minutes) for CPU monitoring and throttling limits on an application pool. When the number of minutes elapsed since the last process accounting reset equals the number specified by this property, IIS resets the CPU timers for both the logging and limit intervals. - default is '00:05:00' - optional @@ -335,7 +348,7 @@ Creates an application pool in IIS. - `smp_processor_affinity_mask` - Specifies the hexadecimal processor mask for multi-processor computers, which indicates to which CPU the worker processes in an application pool should be bound. Before this property takes effect, the smpAffinitized attribute must be set to true for the application pool. - default is 4294967295 - optional - `smp_processor_affinity_mask_2` - Specifies the high-order DWORD hexadecimal processor mask for 64-bit multi-processor computers, which indicates to which CPU the worker processes in an application pool should be bound. Before this property takes effect, the smpAffinitized attribute must be set to true for the application pool. - default is 4294967295 - optional -### Example +#### Example ```ruby # creates a new app pool @@ -346,18 +359,17 @@ iis_pool 'myAppPool_v1_1' do end ``` -iis_app --------- +### iis_app Creates an application in IIS. -### Actions +#### Actions - `:add` - add a new application pool - `:delete` - delete an existing application pool - `:config` - configures an existing application pool -### Attribute Parameters +#### Properties - `site_name` - name attribute. The name of the site to add this app to - `path` -The virtual path for this application @@ -365,7 +377,7 @@ Creates an application in IIS. - `physical_path` - The physical path where this app resides. - `enabled_protocols` - The enabled protocols that this app provides (http, https, net.pipe, net.tcp, etc) -### Example +#### Example ```ruby # creates a new app @@ -378,20 +390,19 @@ iis_app "myApp" do end ``` -iis_vdir ---------- +### iis_vdir Allows easy management of IIS virtual directories (i.e. vdirs). -### Actions +#### Actions - :add: - add a new virtual directory - :delete: - delete an existing virtual directory - :config: - configure a virtual directory -### Attribute Parameters +#### Attribute Parameters -- `application_name`: name attribute. Specifies the name of the application attribute. This is the name of the website or application you are adding it to. +- `application_name`: name attribute. Specifies the name of the application attribute. This is the name of the website or application you are adding it to. - `path`: The virtual directory path on the site. - `physical_path`: The physical path of the virtual directory on the disk. - `username`: (optional) The username required to logon to the physical_path. If set to "" will clear username and password. @@ -399,7 +410,7 @@ Allows easy management of IIS virtual directories (i.e. vdirs). - `logon_method`: (optional, default: :ClearText) The method used to logon (:Interactive, :Batch, :Network, :ClearText). For more information on these types, see "LogonUser Function", Read more at [MSDN](http://msdn2.microsoft.com/en-us/library/aa378184.aspx) - `allow_sub_dir_config`: (optional, default: true) Boolean that specifies whether or not the Web server will look for configuration files located in the subdirectories of this virtual directory. Setting this to false can improve performance on servers with very large numbers of web.config files, but doing so prevents IIS configuration from being read in subdirectories. -### Examples +#### Examples ```ruby # add a virtual directory to default application @@ -446,24 +457,23 @@ iis_vdir 'Default Web Site/' do end ``` -iis_section ---------- +### iis_section -Allows for the locking/unlocking of sections ([listed here](http://www.iis.net/configreference) or via the command `appcmd list config \"\" /config:* /xml`) +Allows for the locking/unlocking of sections ([listed here](http://www.iis.net/configreference) or via the command `appcmd list config \"\" /config:* /xml`) This is valuable to allow the `web.config` of an individual application/website control it's own settings. -### Actions +#### Actions - `:lock`: - locks the `section` passed - `:unlock`: - unlocks the `section` passed -### Attribute Parameters +#### Attribute Parameters - `section`: The name of the section to lock. - `returns`: The result of the `shell_out` command. -### Examples +#### Examples ```ruby # Sets the IIS global windows authentication to be locked globally @@ -497,19 +507,18 @@ iis_section 'unlocked web.config globally for Basic auth' do end ``` -iis_module --------- +### iis_module Manages modules globally or on a per site basis. -### Actions +#### Actions - `:add` - add a new module - `:delete` - delete a module - `:install` - install a native module from the filesystem (.dll) - `:uninstall` - uninstall a native module -### Attribute Parameters +#### Attribute Parameters - `module_name` - The name of the module to add or delete - `type` - The type of module @@ -518,7 +527,7 @@ Manages modules globally or on a per site basis. - `add` - Whether the module you install has to be globally added - `image` - Location of the DLL of the module to install -### Example +#### Example ```ruby # Adds a module called "My 3rd Party Module" to mySite/ @@ -534,48 +543,44 @@ end iis_module "MyModule" ``` +## Usage -Usage -===== - -default -------- +### default recipe Installs and configures IIS 7.0/7.5/8.0 using the default configuration. -mod_* ------ +### mod_* recipes -This cookbook also contains recipes for installing individual IIS modules (extensions). These recipes can be included in a node's run_list to build the minimal desired custom IIS installation. +This cookbook also contains recipes for installing individual IIS modules (extensions). These recipes can be included in a node's run_list to build the minimal desired custom IIS installation. -* `mod_aspnet` - installs ASP.NET runtime components -* `mod_aspnet45` - installs ASP.NET 4.5 runtime components -* `mod_auth_basic` - installs Basic Authentication support -* `mod_auth_windows` - installs Windows Authentication (authenticate clients by using NTLM or Kerberos) support -* `mod_compress_dynamic` - installs dynamic content compression support. *PLEASE NOTE* - enabling dynamic compression always gives you more efficient use of bandwidth, but if your server's processor utilization is already very high, the CPU load imposed by dynamic compression might make your site perform more slowly. -* `mod_compress_static` - installs static content compression support -* `mod_iis6_metabase_compat` - installs IIS 6 Metabase Compatibility component. -* `mod_isapi` - installs ISAPI (Internet Server Application Programming Interface) extension and filter support. -* `mod_logging` - installs and enables HTTP Logging (logging of Web site activity), Logging Tools (logging tools and scripts) and Custom Logging (log any of the HTTP request/response headers, IIS server variables, and client-side fields with simple configuration) support -* `mod_management` - installs Web server Management Console which supports management of local and remote Web servers -* `mod_security` - installs URL Authorization (Authorizes client access to the URLs that comprise a Web application), Request Filtering (configures rules to block selected client requests) and IP Security (allows or denies content access based on IP address or domain name) support. -* `mod_tracing` - installs support for tracing ASP.NET applications and failed requests. +- `mod_aspnet` - installs ASP.NET runtime components +- `mod_aspnet45` - installs ASP.NET 4.5 runtime components +- `mod_auth_basic` - installs Basic Authentication support +- `mod_auth_windows` - installs Windows Authentication (authenticate clients by using NTLM or Kerberos) support +- `mod_compress_dynamic` - installs dynamic content compression support. _PLEASE NOTE_ - enabling dynamic compression always gives you more efficient use of bandwidth, but if your server's processor utilization is already very high, the CPU load imposed by dynamic compression might make your site perform more slowly. +- `mod_compress_static` - installs static content compression support +- `mod_iis6_metabase_compat` - installs IIS 6 Metabase Compatibility component. +- `mod_isapi` - installs ISAPI (Internet Server Application Programming Interface) extension and filter support. +- `mod_logging` - installs and enables HTTP Logging (logging of Web site activity), Logging Tools (logging tools and scripts) and Custom Logging (log any of the HTTP request/response headers, IIS server variables, and client-side fields with simple configuration) support +- `mod_management` - installs Web server Management Console which supports management of local and remote Web servers +- `mod_security` - installs URL Authorization (Authorizes client access to the URLs that comprise a Web application), Request Filtering (configures rules to block selected client requests) and IP Security (allows or denies content access based on IP address or domain name) support. +- `mod_tracing` - installs support for tracing ASP.NET applications and failed requests. -Note: Not every possible IIS module has a corresponding recipe. The foregoing recipes are included for convenience, but users may also place additional IIS modules that are installable as Windows features into the ``node['iis']['components']`` array. +Note: Not every possible IIS module has a corresponding recipe. The foregoing recipes are included for convenience, but users may also place additional IIS modules that are installable as Windows features into the `node['iis']['components']` array. -Alternatives -===== -* [Powershell based IIS Cookbook (Pre-DSC)](https://github.com/ebsco/iisposh) -* DSC Based- [CWebAdministration](https://github.com/PowerShellOrg/cWebAdministration) / [XWebadministration](https://github.com/PowerShell/xWebAdministration) Powershell Module(s) +## Alternative Cookbooks -License and Author -================== +- [Powershell based IIS Cookbook (Pre-DSC)](https://github.com/ebsco/iisposh) +- DSC Based- [CWebAdministration](https://github.com/PowerShellOrg/cWebAdministration) / [XWebadministration](https://github.com/PowerShell/xWebAdministration) Powershell Module(s) -* Author:: Seth Chisamore () -* Author:: Julian Dunn () -* Author:: Justin Schuhmann () +## License and Author -Copyright:: 2011-2015, Chef Software, Inc. +- Author:: Seth Chisamore ([schisamo@chef.io](mailto:schisamo@chef.io)) +- Author:: Julian Dunn ([jdunn@chef.io](mailto:jdunn@chef.io)) +- Author:: Justin Schuhmann ([jmschu02@gmail.com](mailto:jmschu02@gmail.com)) + +```text +Copyright 2011-2016, 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. @@ -588,3 +593,4 @@ 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. +``` diff --git a/cookbooks/iis/attributes/default.rb b/cookbooks/iis/attributes/default.rb index c4cfc98..47db072 100644 --- a/cookbooks/iis/attributes/default.rb +++ b/cookbooks/iis/attributes/default.rb @@ -1,9 +1,9 @@ # # Author:: Seth Chisamore () -# Cookbook Name:: iis +# Cookbook:: iis # Attribute:: default # -# Copyright:: Copyright (c) 2011 Chef Software, Inc. +# Copyright:: 2011-2016, 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. @@ -27,3 +27,5 @@ default['iis']['cache_dir'] = "#{ENV['SYSTEMDRIVE']}\\inetpub\\temp" default['iis']['components'] = [] default['iis']['source'] = nil + +default['iis']['recycle']['log_events'] = 'Time, Requests, Schedule, Memory, IsapiUnhealthy, OnDemand, ConfigChange, PrivateMemory' diff --git a/cookbooks/iis/libraries/helper.rb b/cookbooks/iis/libraries/helper.rb index 0cb3c69..22a5e89 100644 --- a/cookbooks/iis/libraries/helper.rb +++ b/cookbooks/iis/libraries/helper.rb @@ -1,11 +1,11 @@ # -# Cookbook Name:: iis +# Cookbook:: iis # Library:: helper # # Author:: Julian C. Dunn # Author:: Justin Schuhmann # -# Copyright 2013, Chef Software, Inc. +# Copyright:: 2013-2016, 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. @@ -67,11 +67,11 @@ module Opscode end def windows_cleanpath(path) - if !defined?(Chef::Util::PathHelper.cleanpath).nil? - path = Chef::Util::PathHelper.cleanpath(path) - else - path = win_friendly_path(path) - end + path = if defined?(Chef::Util::PathHelper.cleanpath).nil? + win_friendly_path(path) + else + Chef::Util::PathHelper.cleanpath(path) + end # Remove any trailing slashes to prevent them from accidentally escaping any quotes. path.chomp('/').chomp('\\') end @@ -96,7 +96,7 @@ module Opscode version_string.slice! 'Version ' @iis_version = version_string end - @iis_version + @iis_version.to_f end end end diff --git a/cookbooks/iis/libraries/matcher.rb b/cookbooks/iis/libraries/matcher.rb index ef82295..04c72ed 100644 --- a/cookbooks/iis/libraries/matcher.rb +++ b/cookbooks/iis/libraries/matcher.rb @@ -1,7 +1,10 @@ if defined?(ChefSpec) - def config_iis_config(command) - ChefSpec::Matchers::ResourceMatcher.new(:iis_config, :config, command) + [:set, :clear, :config].each do |action| + self.class.send(:define_method, "#{action}_iis_config", proc do |config_name| + ChefSpec::Matchers::ResourceMatcher.new(:iis_config, action, config_name) + end + ) end [:config, :add, :delete].each do |action| @@ -53,11 +56,11 @@ if defined?(ChefSpec) ) end - if Gem.loaded_specs['chefspec'].version < Gem::Version.new('4.1.0') - define_method = ChefSpec::Runner.method(:define_runner_method) - else - define_method = ChefSpec.method(:define_matcher) - end + define_method = if Gem.loaded_specs['chefspec'].version < Gem::Version.new('4.1.0') + ChefSpec::Runner.method(:define_runner_method) + else + ChefSpec.method(:define_matcher) + end define_method.call :iis_app define_method.call :iis_config diff --git a/cookbooks/iis/libraries/processors.rb b/cookbooks/iis/libraries/processors.rb index b610671..dcb1158 100644 --- a/cookbooks/iis/libraries/processors.rb +++ b/cookbooks/iis/libraries/processors.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: iis +# Cookbook:: iis # Library:: helper # # Author:: Justin Schuhmann # -# Copyright 2013, Chef Software, Inc. +# Copyright:: 2013-2016, 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. @@ -37,21 +37,19 @@ module Opscode cmd << " /enabled:#{default_documents_enabled}" end - if add || remove - default_document.each do |document| - if !current_default_documents.include?(document) && add - cmd << " /+files.[value='#{document}']" - elsif current_default_documents.include?(document) && remove - cmd << " /-files.[value='#{document}']" - end + if add + (default_document - current_default_documents).each do |document| + cmd << " /+files.[value='#{document}']" end end - - if add && remove - current_default_documents.each do |document| - unless default_document.include? document - cmd << " /-files.[value='#{document}']" - end + if remove && !add + (default_document - current_default_documents).each do |document| + cmd << " /-files.[value='#{document}']" + end + end + if remove && add + (current_default_documents - default_document).each do |document| + cmd << " /-files.[value='#{document}']" end end @@ -68,28 +66,25 @@ module Opscode xml = cmd.stdout doc = REXML::Document.new xml current_mime_maps = REXML::XPath.match(doc.root, 'CONFIG/system.webServer-staticContent/mimeMap').map { |x| "fileExtension='#{x.attribute 'fileExtension'}',mimeType='#{x.attribute 'mimeType'}'" } - cmd = mime_map_command specifier - if add || remove - new_resource_mime_maps.each do |mime_map| - if !current_mime_maps.include?(mime_map) && add - cmd << " /+\"[#{mime_map}]\"" - elsif current_mime_maps.include?(mime_map) && remove - cmd << " /-\"[#{mime_map}]\"" - end + if add + (new_resource_mime_maps - current_mime_maps).each do |mime_map| + cmd << " /+\"[#{mime_map}]\"" + end + end + if remove && !add + (new_resource_mime_maps - current_mime_maps).each do |mime_map| + cmd << " /-\"[#{mime_map}]\"" + end + end + if remove && add + (current_mime_maps - new_resource_mime_maps).each do |mime_map| + cmd << " /-\"[#{mime_map}]\"" end end - if add && remove - current_mime_maps.each do |mime_map| - unless new_resource_mime_maps.include? mime_map - cmd << " /-\"[#{mime_map}]\"" - end - end - end - - return unless (cmd != mime_map_command(specifier)) + return unless cmd != mime_map_command(specifier) shell_out! cmd Chef::Log.info('mime maps updated') @was_updated = true diff --git a/cookbooks/iis/metadata.json b/cookbooks/iis/metadata.json index b521f57..e579ab4 100644 --- a/cookbooks/iis/metadata.json +++ b/cookbooks/iis/metadata.json @@ -1 +1 @@ -{"name":"iis","version":"4.1.6","description":"Installs/Configures Microsoft Internet Information Services","long_description":"iis Cookbook\n============\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/iis.svg?branch=master)](https://travis-ci.org/chef-cookbooks/iis)\n[![Cookbook Version](https://img.shields.io/cookbook/v/iis.svg)](https://supermarket.chef.io/cookbooks/iis)\n\nInstalls and configures Microsoft Internet Information Services (IIS) 7.0 and later\n\nContents\n========\n\n * [Attributes](#attributes)\n * [Resource/Provider](#resourceprovider)\n * [iis_root](#iis_root) Allows for easy management of the IIS Root Machine settings\n * [iis_site](#iis_site) Allows for easy management of IIS virtual sites (ie vhosts).\n * [iis_config](#iis_config) Runs a config command on your IIS instance.\n * [iis_pool](#iis_pool) Creates an application pool in IIS.\n * [iis_app](#iis_app) Creates an application in IIS.\n * [iis_vdir](#iis_vdir) Allows easy management of IIS virtual directories (i.e. vdirs).\n * [iis_section](#iis_section) Allows for the locking/unlocking of application web.config sections.\n * [iis_module](#iis_module) Manages modules globally or on a per site basis.\n * [Usage](#usage)\n * [default](#default) Default recipe\n * [mod\\_\\*](#mod_) Recipes for installing individual IIS modules (extensions).\n * [Alternatives ](#alternatives)\n * [License and Author](#license-and-author)\n\nRequirements\n============\n\nPlatform\n--------\n\n* Windows Vista\n* Windows 7\n* Windows 8\n* Windows Server 2008 (R1, R2)\n* Windows Server 2012\n* Windows Server 2012R2\n\nWindows 2003R2 is *not* supported because it lacks Add/Remove Features.\n\nCookbooks\n---------\n\n* windows\n\nAttributes\n==========\n\n* `node['iis']['home']` - IIS main home directory. default is `%WINDIR%\\System32\\inetsrv`\n* `node['iis']['conf_dir']` - location where main IIS configs lives. default is `%WINDIR%\\System32\\inetsrv\\config`\n* `node['iis']['pubroot']` - . default is `%SYSTEMDRIVE%\\inetpub`\n* `node['iis']['docroot']` - IIS web site home directory. default is `%SYSTEMDRIVE%\\inetpub\\wwwroot`\n* `node['iis']['log_dir']` - location of IIS logs. default is `%SYSTEMDRIVE%\\inetpub\\logs\\LogFiles`\n* `node['iis']['cache_dir']` - location of cached data. default is `%SYSTEMDRIVE%\\inetpub\\temp`\n\nResource/Provider\n=================\n\niis_root\n---------\n\nAllows for easy management of the IIS Root Machine settings\n\n### Actions\n`default` = `:config`\n\n- `:add` - only does addition operations will not delete anything to an Array object\n- `:delete` - only does deletion operations will not add anything to an Array object\n- `:config` - does both addition and deletion make sure your Array objects contain everything you want\n\n### Attribute Parameters\n\n- `default_documents_enabled` - Enables or disables default_documents for the root machine, Valid Values: true, false default: `true`\n- `default_documents` - The items you want to set as the default document collection, only used during `:config`. Array of strings, default: `['Default.htm', 'Default.asp', 'index.htm', 'index.html', 'iisstart.htm', 'default.aspx']`\n- `mime_maps` - The items you want to set as the mime-maps or mime-types collection, only used during `:config`. Array of strings, default:\n```ruby\n[\"fileExtension='.323',mimeType='text/h323'\", \"fileExtension='.3g2',mimeType='video/3gpp2'\", \"fileExtension='.3gp2',mimeType='video/3gpp2'\", \"fileExtension='.3gp',mimeType='video/3gpp'\", \"fileExtension='.3gpp',mimeType='video/3gpp'\", \"fileExtension='.aaf',mimeType='application/octet-stream'\", \"fileExtension='.aac',mimeType='audio/aac'\", \"fileExtension='.aca',mimeType='application/octet-stream'\", \"fileExtension='.accdb',mimeType='application/msaccess'\", \"fileExtension='.accde',mimeType='application/msaccess'\", \"fileExtension='.accdt',mimeType='application/msaccess'\", \"fileExtension='.acx',mimeType='application/internet-property-stream'\", \"fileExtension='.adt',mimeType='audio/vnd.dlna.adts'\", \"fileExtension='.adts',mimeType='audio/vnd.dlna.adts'\", \"fileExtension='.afm',mimeType='application/octet-stream'\", \"fileExtension='.ai',mimeType='application/postscript'\", \"fileExtension='.aif',mimeType='audio/x-aiff'\", \"fileExtension='.aifc',mimeType='audio/aiff'\", \"fileExtension='.aiff',mimeType='audio/aiff'\", \"fileExtension='.application',mimeType='application/x-ms-application'\", \"fileExtension='.art',mimeType='image/x-jg'\", \"fileExtension='.asd',mimeType='application/octet-stream'\", \"fileExtension='.asf',mimeType='video/x-ms-asf'\", \"fileExtension='.asi',mimeType='application/octet-stream'\", \"fileExtension='.asm',mimeType='text/plain'\", \"fileExtension='.asr',mimeType='video/x-ms-asf'\", \"fileExtension='.asx',mimeType='video/x-ms-asf'\", \"fileExtension='.atom',mimeType='application/atom+xml'\", \"fileExtension='.au',mimeType='audio/basic'\", \"fileExtension='.avi',mimeType='video/avi'\", \"fileExtension='.axs',mimeType='application/olescript'\", \"fileExtension='.bas',mimeType='text/plain'\", \"fileExtension='.bcpio',mimeType='application/x-bcpio'\", \"fileExtension='.bin',mimeType='application/octet-stream'\", \"fileExtension='.bmp',mimeType='image/bmp'\", \"fileExtension='.c',mimeType='text/plain'\", \"fileExtension='.cab',mimeType='application/vnd.ms-cab-compressed'\", \"fileExtension='.calx',mimeType='application/vnd.ms-office.calx'\", \"fileExtension='.cat',mimeType='application/vnd.ms-pki.seccat'\", \"fileExtension='.cdf',mimeType='application/x-cdf'\", \"fileExtension='.chm',mimeType='application/octet-stream'\", \"fileExtension='.class',mimeType='application/x-java-applet'\", \"fileExtension='.clp',mimeType='application/x-msclip'\", \"fileExtension='.cmx',mimeType='image/x-cmx'\", \"fileExtension='.cnf',mimeType='text/plain'\", \"fileExtension='.cod',mimeType='image/cis-cod'\", \"fileExtension='.cpio',mimeType='application/x-cpio'\", \"fileExtension='.cpp',mimeType='text/plain'\", \"fileExtension='.crd',mimeType='application/x-mscardfile'\", \"fileExtension='.crl',mimeType='application/pkix-crl'\", \"fileExtension='.crt',mimeType='application/x-x509-ca-cert'\", \"fileExtension='.csh',mimeType='application/x-csh'\", \"fileExtension='.css',mimeType='text/css'\", \"fileExtension='.csv',mimeType='application/octet-stream'\", \"fileExtension='.cur',mimeType='application/octet-stream'\", \"fileExtension='.dcr',mimeType='application/x-director'\", \"fileExtension='.deploy',mimeType='application/octet-stream'\", \"fileExtension='.der',mimeType='application/x-x509-ca-cert'\", \"fileExtension='.dib',mimeType='image/bmp'\", \"fileExtension='.dir',mimeType='application/x-director'\", \"fileExtension='.disco',mimeType='text/xml'\", \"fileExtension='.dll',mimeType='application/x-msdownload'\", \"fileExtension='.dll.config',mimeType='text/xml'\", \"fileExtension='.dlm',mimeType='text/dlm'\", \"fileExtension='.doc',mimeType='application/msword'\", \"fileExtension='.docm',mimeType='application/vnd.ms-word.document.macroEnabled.12'\", \"fileExtension='.docx',mimeType='application/vnd.openxmlformats-officedocument.wordprocessingml.document'\", \"fileExtension='.dot',mimeType='application/msword'\", \"fileExtension='.dotm',mimeType='application/vnd.ms-word.template.macroEnabled.12'\", \"fileExtension='.dotx',mimeType='application/vnd.openxmlformats-officedocument.wordprocessingml.template'\", \"fileExtension='.dsp',mimeType='application/octet-stream'\", \"fileExtension='.dtd',mimeType='text/xml'\", \"fileExtension='.dvi',mimeType='application/x-dvi'\", \"fileExtension='.dvr-ms',mimeType='video/x-ms-dvr'\", \"fileExtension='.dwf',mimeType='drawing/x-dwf'\", \"fileExtension='.dwp',mimeType='application/octet-stream'\", \"fileExtension='.dxr',mimeType='application/x-director'\", \"fileExtension='.eml',mimeType='message/rfc822'\", \"fileExtension='.emz',mimeType='application/octet-stream'\", \"fileExtension='.eot',mimeType='application/vnd.ms-fontobject'\", \"fileExtension='.eps',mimeType='application/postscript'\", \"fileExtension='.etx',mimeType='text/x-setext'\", \"fileExtension='.evy',mimeType='application/envoy'\", \"fileExtension='.exe',mimeType='application/octet-stream'\", \"fileExtension='.exe.config',mimeType='text/xml'\", \"fileExtension='.fdf',mimeType='application/vnd.fdf'\", \"fileExtension='.fif',mimeType='application/fractals'\", \"fileExtension='.fla',mimeType='application/octet-stream'\", \"fileExtension='.flr',mimeType='x-world/x-vrml'\", \"fileExtension='.flv',mimeType='video/x-flv'\", \"fileExtension='.gif',mimeType='image/gif'\", \"fileExtension='.gtar',mimeType='application/x-gtar'\", \"fileExtension='.gz',mimeType='application/x-gzip'\", \"fileExtension='.h',mimeType='text/plain'\", \"fileExtension='.hdf',mimeType='application/x-hdf'\", \"fileExtension='.hdml',mimeType='text/x-hdml'\", \"fileExtension='.hhc',mimeType='application/x-oleobject'\", \"fileExtension='.hhk',mimeType='application/octet-stream'\", \"fileExtension='.hhp',mimeType='application/octet-stream'\", \"fileExtension='.hlp',mimeType='application/winhlp'\", \"fileExtension='.hqx',mimeType='application/mac-binhex40'\", \"fileExtension='.hta',mimeType='application/hta'\", \"fileExtension='.htc',mimeType='text/x-component'\", \"fileExtension='.htm',mimeType='text/html'\", \"fileExtension='.html',mimeType='text/html'\", \"fileExtension='.htt',mimeType='text/webviewhtml'\", \"fileExtension='.hxt',mimeType='text/html'\", \"fileExtension='.ico',mimeType='image/x-icon'\", \"fileExtension='.ics',mimeType='text/calendar'\", \"fileExtension='.ief',mimeType='image/ief'\", \"fileExtension='.iii',mimeType='application/x-iphone'\", \"fileExtension='.inf',mimeType='application/octet-stream'\", \"fileExtension='.ins',mimeType='application/x-internet-signup'\", \"fileExtension='.isp',mimeType='application/x-internet-signup'\", \"fileExtension='.IVF',mimeType='video/x-ivf'\", \"fileExtension='.jar',mimeType='application/java-archive'\", \"fileExtension='.java',mimeType='application/octet-stream'\", \"fileExtension='.jck',mimeType='application/liquidmotion'\", \"fileExtension='.jcz',mimeType='application/liquidmotion'\", \"fileExtension='.jfif',mimeType='image/pjpeg'\", \"fileExtension='.jpb',mimeType='application/octet-stream'\", \"fileExtension='.jpe',mimeType='image/jpeg'\", \"fileExtension='.jpeg',mimeType='image/jpeg'\", \"fileExtension='.jpg',mimeType='image/jpeg'\", \"fileExtension='.js',mimeType='application/javascript'\", \"fileExtension='.json',mimeType='application/json'\", \"fileExtension='.jsx',mimeType='text/jscript'\", \"fileExtension='.latex',mimeType='application/x-latex'\", \"fileExtension='.lit',mimeType='application/x-ms-reader'\", \"fileExtension='.lpk',mimeType='application/octet-stream'\", \"fileExtension='.lsf',mimeType='video/x-la-asf'\", \"fileExtension='.lsx',mimeType='video/x-la-asf'\", \"fileExtension='.lzh',mimeType='application/octet-stream'\", \"fileExtension='.m13',mimeType='application/x-msmediaview'\", \"fileExtension='.m14',mimeType='application/x-msmediaview'\", \"fileExtension='.m1v',mimeType='video/mpeg'\", \"fileExtension='.m2ts',mimeType='video/vnd.dlna.mpeg-tts'\", \"fileExtension='.m3u',mimeType='audio/x-mpegurl'\", \"fileExtension='.m4a',mimeType='audio/mp4'\", \"fileExtension='.m4v',mimeType='video/mp4'\", \"fileExtension='.man',mimeType='application/x-troff-man'\", \"fileExtension='.manifest',mimeType='application/x-ms-manifest'\", \"fileExtension='.map',mimeType='text/plain'\", \"fileExtension='.mdb',mimeType='application/x-msaccess'\", \"fileExtension='.mdp',mimeType='application/octet-stream'\", \"fileExtension='.me',mimeType='application/x-troff-me'\", \"fileExtension='.mht',mimeType='message/rfc822'\", \"fileExtension='.mhtml',mimeType='message/rfc822'\", \"fileExtension='.mid',mimeType='audio/mid'\", \"fileExtension='.midi',mimeType='audio/mid'\", \"fileExtension='.mix',mimeType='application/octet-stream'\", \"fileExtension='.mmf',mimeType='application/x-smaf'\", \"fileExtension='.mno',mimeType='text/xml'\", \"fileExtension='.mny',mimeType='application/x-msmoney'\", \"fileExtension='.mov',mimeType='video/quicktime'\", \"fileExtension='.movie',mimeType='video/x-sgi-movie'\", \"fileExtension='.mp2',mimeType='video/mpeg'\", \"fileExtension='.mp3',mimeType='audio/mpeg'\", \"fileExtension='.mp4',mimeType='video/mp4'\", \"fileExtension='.mp4v',mimeType='video/mp4'\", \"fileExtension='.mpa',mimeType='video/mpeg'\", \"fileExtension='.mpe',mimeType='video/mpeg'\", \"fileExtension='.mpeg',mimeType='video/mpeg'\", \"fileExtension='.mpg',mimeType='video/mpeg'\", \"fileExtension='.mpp',mimeType='application/vnd.ms-project'\", \"fileExtension='.mpv2',mimeType='video/mpeg'\", \"fileExtension='.ms',mimeType='application/x-troff-ms'\", \"fileExtension='.msi',mimeType='application/octet-stream'\", \"fileExtension='.mso',mimeType='application/octet-stream'\", \"fileExtension='.mvb',mimeType='application/x-msmediaview'\", \"fileExtension='.mvc',mimeType='application/x-miva-compiled'\", \"fileExtension='.nc',mimeType='application/x-netcdf'\", \"fileExtension='.nsc',mimeType='video/x-ms-asf'\", \"fileExtension='.nws',mimeType='message/rfc822'\", \"fileExtension='.ocx',mimeType='application/octet-stream'\", \"fileExtension='.oda',mimeType='application/oda'\", \"fileExtension='.odc',mimeType='text/x-ms-odc'\", \"fileExtension='.ods',mimeType='application/oleobject'\", \"fileExtension='.oga',mimeType='audio/ogg'\", \"fileExtension='.ogg',mimeType='video/ogg'\", \"fileExtension='.ogv',mimeType='video/ogg'\", \"fileExtension='.one',mimeType='application/onenote'\", \"fileExtension='.onea',mimeType='application/onenote'\", \"fileExtension='.onetoc',mimeType='application/onenote'\", \"fileExtension='.onetoc2',mimeType='application/onenote'\", \"fileExtension='.onetmp',mimeType='application/onenote'\", \"fileExtension='.onepkg',mimeType='application/onenote'\", \"fileExtension='.osdx',mimeType='application/opensearchdescription+xml'\", \"fileExtension='.otf',mimeType='font/otf'\", \"fileExtension='.p10',mimeType='application/pkcs10'\", \"fileExtension='.p12',mimeType='application/x-pkcs12'\", \"fileExtension='.p7b',mimeType='application/x-pkcs7-certificates'\", \"fileExtension='.p7c',mimeType='application/pkcs7-mime'\", \"fileExtension='.p7m',mimeType='application/pkcs7-mime'\", \"fileExtension='.p7r',mimeType='application/x-pkcs7-certreqresp'\", \"fileExtension='.p7s',mimeType='application/pkcs7-signature'\", \"fileExtension='.pbm',mimeType='image/x-portable-bitmap'\", \"fileExtension='.pcx',mimeType='application/octet-stream'\", \"fileExtension='.pcz',mimeType='application/octet-stream'\", \"fileExtension='.pdf',mimeType='application/pdf'\", \"fileExtension='.pfb',mimeType='application/octet-stream'\", \"fileExtension='.pfm',mimeType='application/octet-stream'\", \"fileExtension='.pfx',mimeType='application/x-pkcs12'\", \"fileExtension='.pgm',mimeType='image/x-portable-graymap'\", \"fileExtension='.pko',mimeType='application/vnd.ms-pki.pko'\", \"fileExtension='.pma',mimeType='application/x-perfmon'\", \"fileExtension='.pmc',mimeType='application/x-perfmon'\", \"fileExtension='.pml',mimeType='application/x-perfmon'\", \"fileExtension='.pmr',mimeType='application/x-perfmon'\", \"fileExtension='.pmw',mimeType='application/x-perfmon'\", \"fileExtension='.png',mimeType='image/png'\", \"fileExtension='.pnm',mimeType='image/x-portable-anymap'\", \"fileExtension='.pnz',mimeType='image/png'\", \"fileExtension='.pot',mimeType='application/vnd.ms-powerpoint'\", \"fileExtension='.potm',mimeType='application/vnd.ms-powerpoint.template.macroEnabled.12'\", \"fileExtension='.potx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.template'\", \"fileExtension='.ppam',mimeType='application/vnd.ms-powerpoint.addin.macroEnabled.12'\", \"fileExtension='.ppm',mimeType='image/x-portable-pixmap'\", \"fileExtension='.pps',mimeType='application/vnd.ms-powerpoint'\", \"fileExtension='.ppsm',mimeType='application/vnd.ms-powerpoint.slideshow.macroEnabled.12'\", \"fileExtension='.ppsx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.slideshow'\", \"fileExtension='.ppt',mimeType='application/vnd.ms-powerpoint'\", \"fileExtension='.pptm',mimeType='application/vnd.ms-powerpoint.presentation.macroEnabled.12'\", \"fileExtension='.pptx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.presentation'\", \"fileExtension='.prf',mimeType='application/pics-rules'\", \"fileExtension='.prm',mimeType='application/octet-stream'\", \"fileExtension='.prx',mimeType='application/octet-stream'\", \"fileExtension='.ps',mimeType='application/postscript'\", \"fileExtension='.psd',mimeType='application/octet-stream'\", \"fileExtension='.psm',mimeType='application/octet-stream'\", \"fileExtension='.psp',mimeType='application/octet-stream'\", \"fileExtension='.pub',mimeType='application/x-mspublisher'\", \"fileExtension='.qt',mimeType='video/quicktime'\", \"fileExtension='.qtl',mimeType='application/x-quicktimeplayer'\", \"fileExtension='.qxd',mimeType='application/octet-stream'\", \"fileExtension='.ra',mimeType='audio/x-pn-realaudio'\", \"fileExtension='.ram',mimeType='audio/x-pn-realaudio'\", \"fileExtension='.rar',mimeType='application/octet-stream'\", \"fileExtension='.ras',mimeType='image/x-cmu-raster'\", \"fileExtension='.rf',mimeType='image/vnd.rn-realflash'\", \"fileExtension='.rgb',mimeType='image/x-rgb'\", \"fileExtension='.rm',mimeType='application/vnd.rn-realmedia'\", \"fileExtension='.rmi',mimeType='audio/mid'\", \"fileExtension='.roff',mimeType='application/x-troff'\", \"fileExtension='.rpm',mimeType='audio/x-pn-realaudio-plugin'\", \"fileExtension='.rtf',mimeType='application/rtf'\", \"fileExtension='.rtx',mimeType='text/richtext'\", \"fileExtension='.scd',mimeType='application/x-msschedule'\", \"fileExtension='.sct',mimeType='text/scriptlet'\", \"fileExtension='.sea',mimeType='application/octet-stream'\", \"fileExtension='.setpay',mimeType='application/set-payment-initiation'\", \"fileExtension='.setreg',mimeType='application/set-registration-initiation'\", \"fileExtension='.sgml',mimeType='text/sgml'\", \"fileExtension='.sh',mimeType='application/x-sh'\", \"fileExtension='.shar',mimeType='application/x-shar'\", \"fileExtension='.sit',mimeType='application/x-stuffit'\", \"fileExtension='.sldm',mimeType='application/vnd.ms-powerpoint.slide.macroEnabled.12'\", \"fileExtension='.sldx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.slide'\", \"fileExtension='.smd',mimeType='audio/x-smd'\", \"fileExtension='.smi',mimeType='application/octet-stream'\", \"fileExtension='.smx',mimeType='audio/x-smd'\", \"fileExtension='.smz',mimeType='audio/x-smd'\", \"fileExtension='.snd',mimeType='audio/basic'\", \"fileExtension='.snp',mimeType='application/octet-stream'\", \"fileExtension='.spc',mimeType='application/x-pkcs7-certificates'\", \"fileExtension='.spl',mimeType='application/futuresplash'\", \"fileExtension='.spx',mimeType='audio/ogg'\", \"fileExtension='.src',mimeType='application/x-wais-source'\", \"fileExtension='.ssm',mimeType='application/streamingmedia'\", \"fileExtension='.sst',mimeType='application/vnd.ms-pki.certstore'\", \"fileExtension='.stl',mimeType='application/vnd.ms-pki.stl'\", \"fileExtension='.sv4cpio',mimeType='application/x-sv4cpio'\", \"fileExtension='.sv4crc',mimeType='application/x-sv4crc'\", \"fileExtension='.svg',mimeType='image/svg+xml'\", \"fileExtension='.svgz',mimeType='image/svg+xml'\", \"fileExtension='.swf',mimeType='application/x-shockwave-flash'\", \"fileExtension='.t',mimeType='application/x-troff'\", \"fileExtension='.tar',mimeType='application/x-tar'\", \"fileExtension='.tcl',mimeType='application/x-tcl'\", \"fileExtension='.tex',mimeType='application/x-tex'\", \"fileExtension='.texi',mimeType='application/x-texinfo'\", \"fileExtension='.texinfo',mimeType='application/x-texinfo'\", \"fileExtension='.tgz',mimeType='application/x-compressed'\", \"fileExtension='.thmx',mimeType='application/vnd.ms-officetheme'\", \"fileExtension='.thn',mimeType='application/octet-stream'\", \"fileExtension='.tif',mimeType='image/tiff'\", \"fileExtension='.tiff',mimeType='image/tiff'\", \"fileExtension='.toc',mimeType='application/octet-stream'\", \"fileExtension='.tr',mimeType='application/x-troff'\", \"fileExtension='.trm',mimeType='application/x-msterminal'\", \"fileExtension='.ts',mimeType='video/vnd.dlna.mpeg-tts'\", \"fileExtension='.tsv',mimeType='text/tab-separated-values'\", \"fileExtension='.ttf',mimeType='application/octet-stream'\", \"fileExtension='.tts',mimeType='video/vnd.dlna.mpeg-tts'\", \"fileExtension='.txt',mimeType='text/plain'\", \"fileExtension='.u32',mimeType='application/octet-stream'\", \"fileExtension='.uls',mimeType='text/iuls'\", \"fileExtension='.ustar',mimeType='application/x-ustar'\", \"fileExtension='.vbs',mimeType='text/vbscript'\", \"fileExtension='.vcf',mimeType='text/x-vcard'\", \"fileExtension='.vcs',mimeType='text/plain'\", \"fileExtension='.vdx',mimeType='application/vnd.ms-visio.viewer'\", \"fileExtension='.vml',mimeType='text/xml'\", \"fileExtension='.vsd',mimeType='application/vnd.visio'\", \"fileExtension='.vss',mimeType='application/vnd.visio'\", \"fileExtension='.vst',mimeType='application/vnd.visio'\", \"fileExtension='.vsto',mimeType='application/x-ms-vsto'\", \"fileExtension='.vsw',mimeType='application/vnd.visio'\", \"fileExtension='.vsx',mimeType='application/vnd.visio'\", \"fileExtension='.vtx',mimeType='application/vnd.visio'\", \"fileExtension='.wav',mimeType='audio/wav'\", \"fileExtension='.wax',mimeType='audio/x-ms-wax'\", \"fileExtension='.wbmp',mimeType='image/vnd.wap.wbmp'\", \"fileExtension='.wcm',mimeType='application/vnd.ms-works'\", \"fileExtension='.wdb',mimeType='application/vnd.ms-works'\", \"fileExtension='.webm',mimeType='video/webm'\", \"fileExtension='.wks',mimeType='application/vnd.ms-works'\", \"fileExtension='.wm',mimeType='video/x-ms-wm'\", \"fileExtension='.wma',mimeType='audio/x-ms-wma'\", \"fileExtension='.wmd',mimeType='application/x-ms-wmd'\", \"fileExtension='.wmf',mimeType='application/x-msmetafile'\", \"fileExtension='.wml',mimeType='text/vnd.wap.wml'\", \"fileExtension='.wmlc',mimeType='application/vnd.wap.wmlc'\", \"fileExtension='.wmls',mimeType='text/vnd.wap.wmlscript'\", \"fileExtension='.wmlsc',mimeType='application/vnd.wap.wmlscriptc'\", \"fileExtension='.wmp',mimeType='video/x-ms-wmp'\", \"fileExtension='.wmv',mimeType='video/x-ms-wmv'\", \"fileExtension='.wmx',mimeType='video/x-ms-wmx'\", \"fileExtension='.wmz',mimeType='application/x-ms-wmz'\", \"fileExtension='.woff',mimeType='font/x-woff'\", \"fileExtension='.wps',mimeType='application/vnd.ms-works'\", \"fileExtension='.wri',mimeType='application/x-mswrite'\", \"fileExtension='.wrl',mimeType='x-world/x-vrml'\", \"fileExtension='.wrz',mimeType='x-world/x-vrml'\", \"fileExtension='.wsdl',mimeType='text/xml'\", \"fileExtension='.wtv',mimeType='video/x-ms-wtv'\", \"fileExtension='.wvx',mimeType='video/x-ms-wvx'\", \"fileExtension='.x',mimeType='application/directx'\", \"fileExtension='.xaf',mimeType='x-world/x-vrml'\", \"fileExtension='.xaml',mimeType='application/xaml+xml'\", \"fileExtension='.xap',mimeType='application/x-silverlight-app'\", \"fileExtension='.xbap',mimeType='application/x-ms-xbap'\", \"fileExtension='.xbm',mimeType='image/x-xbitmap'\", \"fileExtension='.xdr',mimeType='text/plain'\", \"fileExtension='.xht',mimeType='application/xhtml+xml'\", \"fileExtension='.xhtml',mimeType='application/xhtml+xml'\", \"fileExtension='.xla',mimeType='application/vnd.ms-excel'\", \"fileExtension='.xlam',mimeType='application/vnd.ms-excel.addin.macroEnabled.12'\", \"fileExtension='.xlc',mimeType='application/vnd.ms-excel'\", \"fileExtension='.xlm',mimeType='application/vnd.ms-excel'\", \"fileExtension='.xls',mimeType='application/vnd.ms-excel'\", \"fileExtension='.xlsb',mimeType='application/vnd.ms-excel.sheet.binary.macroEnabled.12'\", \"fileExtension='.xlsm',mimeType='application/vnd.ms-excel.sheet.macroEnabled.12'\", \"fileExtension='.xlsx',mimeType='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'\", \"fileExtension='.xlt',mimeType='application/vnd.ms-excel'\", \"fileExtension='.xltm',mimeType='application/vnd.ms-excel.template.macroEnabled.12'\", \"fileExtension='.xltx',mimeType='application/vnd.openxmlformats-officedocument.spreadsheetml.template'\", \"fileExtension='.xlw',mimeType='application/vnd.ms-excel'\", \"fileExtension='.xml',mimeType='text/xml'\", \"fileExtension='.xof',mimeType='x-world/x-vrml'\", \"fileExtension='.xpm',mimeType='image/x-xpixmap'\", \"fileExtension='.xps',mimeType='application/vnd.ms-xpsdocument'\", \"fileExtension='.xsd',mimeType='text/xml'\", \"fileExtension='.xsf',mimeType='text/xml'\", \"fileExtension='.xsl',mimeType='text/xml'\", \"fileExtension='.xslt',mimeType='text/xml'\", \"fileExtension='.xsn',mimeType='application/octet-stream'\", \"fileExtension='.xtp',mimeType='application/octet-stream'\", \"fileExtension='.xwd',mimeType='image/x-xwindowdump'\", \"fileExtension='.z',mimeType='application/x-compress'\", \"fileExtension='.zip',mimeType='application/x-zip-compressed'\"]\n```\n- `add_default_documents` - The items you want to add to the default document collection, only used during `:add`. Array of strings, default: `[]`\n- `add_mime_maps` - The items you want to add to the mime-map/mime-type collection, only used during `:add`. Array of strings, default: `[]`\n- `delete_default_documents` - The items you want to delete from the default document collection, only used during `:delete`. Array of strings, default: `[]`\n- `delete_mime_maps` - The items you want to delete from the mime-map/mime-type collection, only used during `:delete`. Array of strings, default: `[]`\n\n### Examples\n\n```ruby\n# Add foo.html to default documents, and add '.dmg' as mime type extension at root level\niis_root 'add stuff' do\n add_default_documents ['foo.html']\n add_mime_maps [\"fileExtension='.dmg',mimeType='application/octet-stream'\"]\n action :add\nend\n```\n```ruby\n# Remove index.html from default document and .323 as a mime type at root level\niis_root 'delete stuff' do\n delete_default_documents ['index.html']\n delete_mime_maps [\"fileExtension='.323',mimeType='text/h323'\"]\n action :delete\nend\n```\niis_site\n---------\n\nAllows for easy management of IIS virtual sites (ie vhosts).\n\n### Actions\n\n- `:add` - add a new virtual site\n- `:config` - apply configuration to an existing virtual site\n- `:delete` - delete an existing virtual site\n- `:start` - start a virtual site\n- `:stop` - stop a virtual site\n- `:restart` - restart a virtual site\n\n### Attribute Parameters\n\n- `site_name` - name attribute.\n- `site_id` - if not given IIS generates a unique ID for the site\n- `path` - IIS will create a root application and a root virtual directory mapped to this specified local path\n- `protocol` - http protocol type the site should respond to. valid values are :http, :https. default is :http\n- `port` - port site will listen on. default is 80\n- `host_header` - host header (also known as domains or host names) the site should map to. default is all host headers\n- `options` - additional options to configure the site\n- `bindings` - Advanced options to configure the information required for requests to communicate with a Web site. See http://www.iis.net/configreference/system.applicationhost/sites/site/bindings/binding for parameter format. When binding is used, port protocol and host_header should not be used.\n- `application_pool` - set the application pool of the site\n- `options` - support for additional options -logDir, -limits, -ftpServer, etc...\n- `log_directory` - specifies the logging directory, where the log file and logging-related support files are stored.\n- `log_period` - specifies how often iis creates a new log file\n- `log_truncsize` - specifies the maximum size of the log file (in bytes) after which to create a new log file.\n\n### Examples\n\n```ruby\n# stop and delete the default site\niis_site 'Default Web Site' do\n action [:stop, :delete]\nend\n```\n\n```ruby\n# create and start a new site that maps to\n# the physical location C:\\inetpub\\wwwroot\\testfu\n# first the physical location must exist\ndirectory \"#{node['iis']['docroot']}/testfu\" do\n action :create\nend\n\n# now create and start the site (note this will use the default application pool which must exist)\niis_site 'Testfu Site' do\n protocol :http\n port 80\n path \"#{node['iis']['docroot']}/testfu\"\n action [:add,:start]\nend\n```\n\n```ruby\n# do the same but map to testfu.chef.io domain\n# first the physical location must exist\ndirectory \"#{node['iis']['docroot']}/testfu\" do\n action :create\nend\n\n# now create and start the site (note this will use the default application pool which must exist)\niis_site 'Testfu Site' do\n protocol :http\n port 80\n path \"#{node['iis']['docroot']}/testfu\"\n host_header \"testfu.chef.io\"\n action [:add,:start]\nend\n```\n\n```ruby\n# create and start a new site that maps to\n# the physical C:\\inetpub\\wwwroot\\testfu\n# first the physical location must exist\ndirectory \"#{node['iis']['docroot']}/testfu\" do\n action :create\nend\n\n# also adds bindings to http and https\n# binding http to the ip address 10.12.0.136,\n# the port 80, and the host header www.domain.com\n# also binding https to any ip address,\n# the port 443, and the host header www.domain.com\n# now create and start the site (note this will use the default application pool which must exist)\niis_site 'FooBar Site' do\n bindings \"http/10.12.0.136:80:www.domain.com,https/*:443:www.domain.com\n path \"#{node['iis']['docroot']}/testfu\"\n action [:add,:start]\nend\n```\n\niis_config\n-----------\nRuns a config command on your IIS instance.\n\n### Actions\n\n- `:set` - Edit configuration section (appcmd set config)\n- `:clear` - Clear the section configuration (appcmd clear config)\n- `:config` - [ DEPRECATED ] use `:set` instead\n\n### Attribute Parameters\n\n- `cfg_cmd` - name attribute. What ever command you would pass in after \"appcmd.exe set config\"\n\n### Example\n\n```ruby\n# Sets up logging\niis_config \"/section:system.applicationHost/sites /siteDefaults.logfile.directory:\\\"D:\\\\logs\\\"\" do\n action :set\nend\n```\n\n```ruby\n# Increase file upload size for 'MySite'\niis_config \"\\\"MySite\\\" /section:requestfiltering /requestlimits.maxallowedcontentlength:50000000\" do\n action :set\nend\n```\n\n```ruby\n# Set IUSR username and password authentication\niis_config \"\\\"MyWebsite/aSite\\\" -section:system.webServer/security/authentication/anonymousAuthentication /enabled:\\\"True\\\" /userName:\\\"IUSR_foobar\\\" /password:\\\"p@assword\\\" /commit:apphost\" do\n action :set\nend\n```\n\n```ruby\n# Authenticate with application pool\niis_config \"\\\"MyWebsite/aSite\\\" -section:system.webServer/security/authentication/anonymousAuthentication /enabled:\\\"True\\\" /userName:\\\"\\\" /commit:apphost\" do\n action :set\nend\n\n```\n\n```ruby\n# Loads an array of commands from the node\ncfg_cmds = node['iis']['cfg_cmd']\ncfg_cmds.each do |cmd|\n iis_config \"#{cmd}\" do\n action :set\n end\nend\n```\n\n```ruby\n# Add static machine key at site level\niis_config \"MySite /commit:site /section:machineKey /validation:AES /validationKey:AAAAAA /decryptionKey:ZZZZZ\" do\n action :set\nend\n```\n\n```ruby\n# Remove machine key\niis_config \"MySite /commit:site /section:machineKey\"\n action :clear\nend\n```\n\n\niis_pool\n---------\nCreates an application pool in IIS.\n\n### Actions\n\n- `:add` - add a new application pool\n- `:config` - apply configuration to an existing application pool\n- `:delete` - delete an existing application pool\n- `:start` - start a application pool\n- `:stop` - stop a application pool\n- `:restart` - restart a application pool\n- `:recycle` - recycle an application pool\n\n### Attribute Parameters\n\n#### Root Items\n- `pool_name` - name attribute. Specifies the name of the pool to create.\n- `runtime_version` - specifies what .NET version of the runtime to use.\n- `pipeline_mode` - specifies what pipeline mode to create the pool with, valid values are :Integrated or :Classic, the default is :Integrated\n- `no_managed_code` - allow Unmanaged Code in setting up IIS app pools is shutting down. - default is true - optional\n\n#### Add Items\n- `start_mode` - Specifies the startup type for the application pool - default :OnDemand (:OnDemand, :AlwaysRunning) - optional\n- `auto_start` - When true, indicates to the World Wide Web Publishing Service (W3SVC) that the application pool should be automatically started when it is created or when IIS is started. - boolean: default true - optional\n- `queue_length` - Indicates to HTTP.sys how many requests to queue for an application pool before rejecting future requests. - default is 1000 - optional\n- `thirty_two_bit` - set the pool to run in 32 bit mode, valid values are true or false, default is false - optional\n\n#### Process Model Items\n- `max_proc` - specifies the number of worker processes associated with the pool.\n- `load_user_profile` - This property is used only when a service starts in a named user account. - Default is false - optional\n- `pool_identity` - the account identity that they app pool will run as, valid values are :SpecificUser, :NetworkService, :LocalService, :LocalSystem, :ApplicationPoolIdentity\n- `pool_username` - username for the identity for the application pool\n- `pool_password` password for the identity for the application pool is started. Default is true - optional\n- `logon_type` - Specifies the logon type for the process identity. (For additional information about [logon types](http://msdn.microsoft.com/en-us/library/aa378184%28VS.85%29.aspx), see the LogonUser Function topic on Microsoft's MSDN Web site.) - Available [:LogonBatch, :LogonService] - default is :LogonBatch - optional\n- `manual_group_membership` - Specifies whether the IIS_IUSRS group Security Identifier (SID) is added to the worker process token. When false, IIS automatically uses an application pool identity as though it were a member of the built-in IIS_IUSRS group, which has access to necessary file and system resources. When true, an application pool identity must be explicitly added to all resources that a worker process requires at runtime. - default is false - optional\n- `idle_timeout` - Specifies how long (in minutes) a worker process should run idle if no new requests are received and the worker process is not processing requests. After the allocated time passes, the worker process should request that it be shut down by the WWW service. - default is '00:20:00' - optional\n- `idle_timeout_action` - Specifies the option of suspending an idle worker process rather than terminating it. Valid values are :Terminate and :Suspend - optional\n- `shutdown_time_limit` - Specifies the time that the W3SVC service waits after it initiated a recycle. If the worker process does not shut down within the shutdownTimeLimit, it will be terminated by the W3SVC service. - default is '00:01:30' - optional\n- `startup_time_limit` - Specifies the time that IIS waits for an application pool to start. If the application pool does not startup within the startupTimeLimit, the worker process is terminated and the rapid-fail protection count is incremented. - default is '00:01:30' - optional\n- `pinging_enabled` - Specifies whether pinging is enabled for the worker process. - default is true - optional\n- `ping_interval` - Specifies the time between health-monitoring pings that the WWW service sends to a worker process - default is '00:00:30' - optional\n- `ping_response_time` - Specifies the time that a worker process is given to respond to a health-monitoring ping. After the time limit is exceeded, the WWW service terminates the worker process - default is '00:01:30' - optional\n\n#### Recycling Items\n- `disallow_rotation_on_config_change` - The DisallowRotationOnConfigChange property specifies whether or not the World Wide Web Publishing Service (WWW Service) should rotate worker processes in an application pool when the configuration has changed. - Default is false - optional\n- `disallow_overlapping_rotation` - Specifies whether the WWW Service should start another worker process to replace the existing worker process while that process\n- `recycle_after_time` - specifies a pool to recycle at regular time intervals, d.hh:mm:ss, d optional\n- `recycle_at_time` - schedule a pool to recycle at a specific time, d.hh:mm:ss, d optional\n- `private_mem` - specifies the amount of private memory (in kilobytes) after which you want the pool to recycle\n\n#### Failure Items\n- `load_balancer_capabilities` - Specifies behavior when a worker process cannot be started, such as when the request queue is full or an application pool is in rapid-fail protection. - default is :HttpLevel - optional\n- `orphan_worker_process` - Specifies whether to assign a worker process to an orphan state instead of terminating it when an application pool fails. - default is false - optional\n- `orphan_action_exe` - Specifies an executable to run when the WWW service orphans a worker process (if the orphanWorkerProcess attribute is set to true). You can use the orphanActionParams attribute to send parameters to the executable. - optional\n- `orphan_action_params` - Indicates command-line parameters for the executable named by the orphanActionExe attribute. To specify the process ID of the orphaned process, use %1%. - optional\n- `rapid_fail_protection` - Setting to true instructs the WWW service to remove from service all applications that are in an application pool - default is true - optional\n- `rapid_fail_protection_interval` - Specifies the number of minutes before the failure count for a process is reset. - default is '00:05:00' - optional\n- `rapid_fail_protection_max_crashes` - Specifies the maximum number of failures that are allowed within the number of minutes specified by the rapidFailProtectionInterval attribute. - default is 5 - optional\n- `auto_shutdown_exe` - Specifies an executable to run when the WWW service shuts down an application pool. - optional\n- `auto_shutdown_params` - Specifies command-line parameters for the executable that is specified in the autoShutdownExe attribute. - optional\n\n#### CPU Items\n- `cpu_action` - Configures the action that IIS takes when a worker process exceeds its configured CPU limit. The action attribute is configured on a per-application pool basis. - Available options [:NoAction, :KillW3wp, :Throttle, :ThrottleUnderLoad] - default is :NoAction - optional\n- `cpu_limit` - Configures the maximum percentage of CPU time (in 1/1000ths of one percent) that the worker processes in an application pool are allowed to consume over a period of time as indicated by the resetInterval attribute. If the limit set by the limit attribute is exceeded, an event is written to the event log and an optional set of events can be triggered. These optional events are determined by the action attribute. - default is 0 - optional\n- `cpu_reset_interval` - Specifies the reset period (in minutes) for CPU monitoring and throttling limits on an application pool. When the number of minutes elapsed since the last process accounting reset equals the number specified by this property, IIS resets the CPU timers for both the logging and limit intervals. - default is '00:05:00' - optional\n- `cpu_smp_affinitized` - Specifies whether a particular worker process assigned to an application pool should also be assigned to a given CPU. - default is false - optional\n- `smp_processor_affinity_mask` - Specifies the hexadecimal processor mask for multi-processor computers, which indicates to which CPU the worker processes in an application pool should be bound. Before this property takes effect, the smpAffinitized attribute must be set to true for the application pool. - default is 4294967295 - optional\n- `smp_processor_affinity_mask_2` - Specifies the high-order DWORD hexadecimal processor mask for 64-bit multi-processor computers, which indicates to which CPU the worker processes in an application pool should be bound. Before this property takes effect, the smpAffinitized attribute must be set to true for the application pool. - default is 4294967295 - optional\n\n### Example\n\n```ruby\n# creates a new app pool\niis_pool 'myAppPool_v1_1' do\n runtime_version \"2.0\"\n pipeline_mode :Classic\n action :add\nend\n```\n\niis_app\n--------\n\nCreates an application in IIS.\n\n### Actions\n\n- `:add` - add a new application pool\n- `:delete` - delete an existing application pool\n- `:config` - configures an existing application pool\n\n### Attribute Parameters\n\n- `site_name` - name attribute. The name of the site to add this app to\n- `path` -The virtual path for this application\n- `application_pool` - The pool this application belongs to\n- `physical_path` - The physical path where this app resides.\n- `enabled_protocols` - The enabled protocols that this app provides (http, https, net.pipe, net.tcp, etc)\n\n### Example\n\n```ruby\n# creates a new app\niis_app \"myApp\" do\n path \"/v1_1\"\n application_pool \"myAppPool_v1_1\"\n physical_path \"#{node['iis']['docroot']}/testfu/v1_1\"\n enabled_protocols \"http,net.pipe\"\n action :add\nend\n```\n\niis_vdir\n---------\n\nAllows easy management of IIS virtual directories (i.e. vdirs).\n\n### Actions\n\n- :add: - add a new virtual directory\n- :delete: - delete an existing virtual directory\n- :config: - configure a virtual directory\n\n### Attribute Parameters\n\n- `application_name`: name attribute. Specifies the name of the application attribute. This is the name of the website or application you are adding it to.\n- `path`: The virtual directory path on the site.\n- `physical_path`: The physical path of the virtual directory on the disk.\n- `username`: (optional) The username required to logon to the physical_path. If set to \"\" will clear username and password.\n- `password`: (optional) The password required to logon to the physical_path\n- `logon_method`: (optional, default: :ClearText) The method used to logon (:Interactive, :Batch, :Network, :ClearText). For more information on these types, see \"LogonUser Function\", Read more at [MSDN](http://msdn2.microsoft.com/en-us/library/aa378184.aspx)\n- `allow_sub_dir_config`: (optional, default: true) Boolean that specifies whether or not the Web server will look for configuration files located in the subdirectories of this virtual directory. Setting this to false can improve performance on servers with very large numbers of web.config files, but doing so prevents IIS configuration from being read in subdirectories.\n\n### Examples\n\n```ruby\n# add a virtual directory to default application\niis_vdir 'Default Web Site/' do\n action :add\n path '/Content/Test'\n physical_path 'C:\\wwwroot\\shared\\test'\nend\n```\n\n```ruby\n# add a virtual directory to an application under a site\niis_vdir 'Default Web Site/my application' do\n action :add\n path '/Content/Test'\n physical_path 'C:\\wwwroot\\shared\\test'\nend\n```\n\n```ruby\n# adds a virtual directory to default application which points to a smb share. (Remember to escape the \"\\\"'s)\niis_vdir 'Default Web Site/' do\n action :add\n path '/Content/Test'\n physical_path '\\\\\\\\sharename\\\\sharefolder\\\\1'\nend\n```\n\n```ruby\n# configure a virtual directory to have a username and password\niis_vdir 'Default Web Site/' do\n action :config\n path '/Content/Test'\n username 'domain\\myspecialuser'\n password 'myspecialpassword'\nend\n```\n\n```ruby\n# delete a virtual directory from the default application\niis_vdir 'Default Web Site/' do\n action :delete\n path '/Content/Test'\nend\n```\n\niis_section\n---------\n\nAllows for the locking/unlocking of sections ([listed here](http://www.iis.net/configreference) or via the command `appcmd list config \\\"\\\" /config:* /xml`)\n\nThis is valuable to allow the `web.config` of an individual application/website control it's own settings.\n\n### Actions\n\n- `:lock`: - locks the `section` passed\n- `:unlock`: - unlocks the `section` passed\n\n### Attribute Parameters\n\n- `section`: The name of the section to lock.\n- `returns`: The result of the `shell_out` command.\n\n### Examples\n\n```ruby\n# Sets the IIS global windows authentication to be locked globally\niis_section 'locks global configuration of windows auth' do\n section 'system.webServer/security/authentication/windowsAuthentication'\n action :lock\nend\n```\n\n```ruby\n# Sets the IIS global Basic authentication to be locked globally\niis_section 'locks global configuration of Basic auth' do\n section 'system.webServer/security/authentication/basicAuthentication'\n action :lock\nend\n```\n\n```ruby\n# Sets the IIS global windows authentication to be unlocked globally\niis_section 'unlocked web.config globally for windows auth' do\n action :unlock\n section 'system.webServer/security/authentication/windowsAuthentication'\nend\n```\n\n```ruby\n# Sets the IIS global Basic authentication to be unlocked globally\niis_section 'unlocked web.config globally for Basic auth' do\n action :unlock\n section 'system.webServer/security/authentication/basicAuthentication'\nend\n```\n\niis_module\n--------\n\nManages modules globally or on a per site basis.\n\n### Actions\n\n- `:add` - add a new module\n- `:delete` - delete a module\n- `:install` - install a native module from the filesystem (.dll)\n- `:uninstall` - uninstall a native module\n\n### Attribute Parameters\n\n- `module_name` - The name of the module to add or delete\n- `type` - The type of module\n- `precondition` - precondition for module\n- `application` - The application or site to add the module to\n- `add` - Whether the module you install has to be globally added\n- `image` - Location of the DLL of the module to install\n\n### Example\n\n```ruby\n# Adds a module called \"My 3rd Party Module\" to mySite/\niis_module \"My 3rd Party Module\" do\n application \"mySite/\"\n precondition \"bitness64\"\n action :add\nend\n```\n\n```ruby\n# Adds a module called \"MyModule\" to all IIS sites on the server\niis_module \"MyModule\"\n```\n\n\nUsage\n=====\n\ndefault\n-------\n\nInstalls and configures IIS 7.0/7.5/8.0 using the default configuration.\n\nmod_*\n-----\n\nThis cookbook also contains recipes for installing individual IIS modules (extensions). These recipes can be included in a node's run_list to build the minimal desired custom IIS installation.\n\n* `mod_aspnet` - installs ASP.NET runtime components\n* `mod_aspnet45` - installs ASP.NET 4.5 runtime components\n* `mod_auth_basic` - installs Basic Authentication support\n* `mod_auth_windows` - installs Windows Authentication (authenticate clients by using NTLM or Kerberos) support\n* `mod_compress_dynamic` - installs dynamic content compression support. *PLEASE NOTE* - enabling dynamic compression always gives you more efficient use of bandwidth, but if your server's processor utilization is already very high, the CPU load imposed by dynamic compression might make your site perform more slowly.\n* `mod_compress_static` - installs static content compression support\n* `mod_iis6_metabase_compat` - installs IIS 6 Metabase Compatibility component.\n* `mod_isapi` - installs ISAPI (Internet Server Application Programming Interface) extension and filter support.\n* `mod_logging` - installs and enables HTTP Logging (logging of Web site activity), Logging Tools (logging tools and scripts) and Custom Logging (log any of the HTTP request/response headers, IIS server variables, and client-side fields with simple configuration) support\n* `mod_management` - installs Web server Management Console which supports management of local and remote Web servers\n* `mod_security` - installs URL Authorization (Authorizes client access to the URLs that comprise a Web application), Request Filtering (configures rules to block selected client requests) and IP Security (allows or denies content access based on IP address or domain name) support.\n* `mod_tracing` - installs support for tracing ASP.NET applications and failed requests.\n\nNote: Not every possible IIS module has a corresponding recipe. The foregoing recipes are included for convenience, but users may also place additional IIS modules that are installable as Windows features into the ``node['iis']['components']`` array.\n\nAlternatives\n=====\n* [Powershell based IIS Cookbook (Pre-DSC)](https://github.com/ebsco/iisposh)\n* DSC Based- [CWebAdministration](https://github.com/PowerShellOrg/cWebAdministration) / [XWebadministration](https://github.com/PowerShell/xWebAdministration) Powershell Module(s)\n\nLicense and Author\n==================\n\n* Author:: Seth Chisamore ()\n* Author:: Julian Dunn ()\n* Author:: Justin Schuhmann ()\n\nCopyright:: 2011-2015, Chef Software, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{"windows":">= 0.0.0"},"dependencies":{"windows":">= 1.34.6"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{}} \ No newline at end of file +{"name":"iis","version":"5.0.8","description":"Installs/Configures Microsoft Internet Information Services","long_description":"# iis Cookbook\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/iis.svg?branch=master)](https://travis-ci.org/chef-cookbooks/iis) [![Cookbook Version](https://img.shields.io/cookbook/v/iis.svg)](https://supermarket.chef.io/cookbooks/iis)\n\nInstalls and configures Microsoft Internet Information Services (IIS) 7.0 and later\n\n## Contents\n\n- [Attributes](#attributes)\n- [Resource/Provider](#resourceprovider)\n\n - [iis_root](#iis_root) Allows for easy management of the IIS Root Machine settings\n - [iis_site](#iis_site) Allows for easy management of IIS virtual sites (ie vhosts).\n - [iis_config](#iis_config) Runs a config command on your IIS instance.\n - [iis_pool](#iis_pool) Creates an application pool in IIS.\n - [iis_app](#iis_app) Creates an application in IIS.\n - [iis_vdir](#iis_vdir) Allows easy management of IIS virtual directories (i.e. vdirs).\n - [iis_section](#iis_section) Allows for the locking/unlocking of application web.config sections.\n - [iis_module](#iis_module) Manages modules globally or on a per site basis.\n\n- [Usage](#usage)\n\n - [default](#default) Default recipe\n - [mod_*](#mod_) Recipes for installing individual IIS modules (extensions).\n\n- [Alternatives](#alternative-cookbooks)\n\n- [License and Author](#license-and-author)\n\n## Requirements\n\n### Platforms\n\n- Windows Vista\n- Windows 7\n- Windows 8, 8.1\n- Windows Server 2008 (R1, R2)\n- Windows Server 2012 (R1, R2)\n\nWindows 2003R2 is _not_ supported because it lacks Add/Remove Features.\n\n### Chef\n\n- Chef 12.1+\n\n### Cookbooks\n\n- windows\n\n## Attributes\n\n- `node['iis']['home']` - IIS main home directory. default is `%WINDIR%\\System32\\inetsrv`\n- `node['iis']['conf_dir']` - location where main IIS configs lives. default is `%WINDIR%\\System32\\inetsrv\\config`\n- `node['iis']['pubroot']` - . default is `%SYSTEMDRIVE%\\inetpub`\n- `node['iis']['docroot']` - IIS web site home directory. default is `%SYSTEMDRIVE%\\inetpub\\wwwroot`\n- `node['iis']['log_dir']` - location of IIS logs. default is `%SYSTEMDRIVE%\\inetpub\\logs\\LogFiles`\n- `node['iis']['cache_dir']` - location of cached data. default is `%SYSTEMDRIVE%\\inetpub\\temp`\n\n## Resource/Provider\n\n### iis_root\n\nAllows for easy management of the IIS Root Machine settings\n\n#### Actions\n\n`default` = `:config`\n\n- `:add` - only does addition operations will not delete anything to an Array object\n- `:delete` - only does deletion operations will not add anything to an Array object\n- `:config` - does both addition and deletion make sure your Array objects contain everything you want\n\n#### Properties\n\n- `default_documents_enabled` - Enables or disables default_documents for the root machine, Valid Values: true, false default: `true`\n- `default_documents` - The items you want to set as the default document collection, only used during `:config`. Array of strings, default: `['Default.htm', 'Default.asp', 'index.htm', 'index.html', 'iisstart.htm', 'default.aspx']`\n- `mime_maps` - The items you want to set as the mime-maps or mime-types collection, only used during `:config`. Array of strings, default:\n\n ```ruby\n [\"fileExtension='.323',mimeType='text/h323'\", \"fileExtension='.3g2',mimeType='video/3gpp2'\", \"fileExtension='.3gp2',mimeType='video/3gpp2'\", \"fileExtension='.3gp',mimeType='video/3gpp'\", \"fileExtension='.3gpp',mimeType='video/3gpp'\", \"fileExtension='.aaf',mimeType='application/octet-stream'\", \"fileExtension='.aac',mimeType='audio/aac'\", \"fileExtension='.aca',mimeType='application/octet-stream'\", \"fileExtension='.accdb',mimeType='application/msaccess'\", \"fileExtension='.accde',mimeType='application/msaccess'\", \"fileExtension='.accdt',mimeType='application/msaccess'\", \"fileExtension='.acx',mimeType='application/internet-property-stream'\", \"fileExtension='.adt',mimeType='audio/vnd.dlna.adts'\", \"fileExtension='.adts',mimeType='audio/vnd.dlna.adts'\", \"fileExtension='.afm',mimeType='application/octet-stream'\", \"fileExtension='.ai',mimeType='application/postscript'\", \"fileExtension='.aif',mimeType='audio/x-aiff'\", \"fileExtension='.aifc',mimeType='audio/aiff'\", \"fileExtension='.aiff',mimeType='audio/aiff'\", \"fileExtension='.application',mimeType='application/x-ms-application'\", \"fileExtension='.art',mimeType='image/x-jg'\", \"fileExtension='.asd',mimeType='application/octet-stream'\", \"fileExtension='.asf',mimeType='video/x-ms-asf'\", \"fileExtension='.asi',mimeType='application/octet-stream'\", \"fileExtension='.asm',mimeType='text/plain'\", \"fileExtension='.asr',mimeType='video/x-ms-asf'\", \"fileExtension='.asx',mimeType='video/x-ms-asf'\", \"fileExtension='.atom',mimeType='application/atom+xml'\", \"fileExtension='.au',mimeType='audio/basic'\", \"fileExtension='.avi',mimeType='video/avi'\", \"fileExtension='.axs',mimeType='application/olescript'\", \"fileExtension='.bas',mimeType='text/plain'\", \"fileExtension='.bcpio',mimeType='application/x-bcpio'\", \"fileExtension='.bin',mimeType='application/octet-stream'\", \"fileExtension='.bmp',mimeType='image/bmp'\", \"fileExtension='.c',mimeType='text/plain'\", \"fileExtension='.cab',mimeType='application/vnd.ms-cab-compressed'\", \"fileExtension='.calx',mimeType='application/vnd.ms-office.calx'\", \"fileExtension='.cat',mimeType='application/vnd.ms-pki.seccat'\", \"fileExtension='.cdf',mimeType='application/x-cdf'\", \"fileExtension='.chm',mimeType='application/octet-stream'\", \"fileExtension='.class',mimeType='application/x-java-applet'\", \"fileExtension='.clp',mimeType='application/x-msclip'\", \"fileExtension='.cmx',mimeType='image/x-cmx'\", \"fileExtension='.cnf',mimeType='text/plain'\", \"fileExtension='.cod',mimeType='image/cis-cod'\", \"fileExtension='.cpio',mimeType='application/x-cpio'\", \"fileExtension='.cpp',mimeType='text/plain'\", \"fileExtension='.crd',mimeType='application/x-mscardfile'\", \"fileExtension='.crl',mimeType='application/pkix-crl'\", \"fileExtension='.crt',mimeType='application/x-x509-ca-cert'\", \"fileExtension='.csh',mimeType='application/x-csh'\", \"fileExtension='.css',mimeType='text/css'\", \"fileExtension='.csv',mimeType='application/octet-stream'\", \"fileExtension='.cur',mimeType='application/octet-stream'\", \"fileExtension='.dcr',mimeType='application/x-director'\", \"fileExtension='.deploy',mimeType='application/octet-stream'\", \"fileExtension='.der',mimeType='application/x-x509-ca-cert'\", \"fileExtension='.dib',mimeType='image/bmp'\", \"fileExtension='.dir',mimeType='application/x-director'\", \"fileExtension='.disco',mimeType='text/xml'\", \"fileExtension='.dll',mimeType='application/x-msdownload'\", \"fileExtension='.dll.config',mimeType='text/xml'\", \"fileExtension='.dlm',mimeType='text/dlm'\", \"fileExtension='.doc',mimeType='application/msword'\", \"fileExtension='.docm',mimeType='application/vnd.ms-word.document.macroEnabled.12'\", \"fileExtension='.docx',mimeType='application/vnd.openxmlformats-officedocument.wordprocessingml.document'\", \"fileExtension='.dot',mimeType='application/msword'\", \"fileExtension='.dotm',mimeType='application/vnd.ms-word.template.macroEnabled.12'\", \"fileExtension='.dotx',mimeType='application/vnd.openxmlformats-officedocument.wordprocessingml.template'\", \"fileExtension='.dsp',mimeType='application/octet-stream'\", \"fileExtension='.dtd',mimeType='text/xml'\", \"fileExtension='.dvi',mimeType='application/x-dvi'\", \"fileExtension='.dvr-ms',mimeType='video/x-ms-dvr'\", \"fileExtension='.dwf',mimeType='drawing/x-dwf'\", \"fileExtension='.dwp',mimeType='application/octet-stream'\", \"fileExtension='.dxr',mimeType='application/x-director'\", \"fileExtension='.eml',mimeType='message/rfc822'\", \"fileExtension='.emz',mimeType='application/octet-stream'\", \"fileExtension='.eot',mimeType='application/vnd.ms-fontobject'\", \"fileExtension='.eps',mimeType='application/postscript'\", \"fileExtension='.etx',mimeType='text/x-setext'\", \"fileExtension='.evy',mimeType='application/envoy'\", \"fileExtension='.exe',mimeType='application/octet-stream'\", \"fileExtension='.exe.config',mimeType='text/xml'\", \"fileExtension='.fdf',mimeType='application/vnd.fdf'\", \"fileExtension='.fif',mimeType='application/fractals'\", \"fileExtension='.fla',mimeType='application/octet-stream'\", \"fileExtension='.flr',mimeType='x-world/x-vrml'\", \"fileExtension='.flv',mimeType='video/x-flv'\", \"fileExtension='.gif',mimeType='image/gif'\", \"fileExtension='.gtar',mimeType='application/x-gtar'\", \"fileExtension='.gz',mimeType='application/x-gzip'\", \"fileExtension='.h',mimeType='text/plain'\", \"fileExtension='.hdf',mimeType='application/x-hdf'\", \"fileExtension='.hdml',mimeType='text/x-hdml'\", \"fileExtension='.hhc',mimeType='application/x-oleobject'\", \"fileExtension='.hhk',mimeType='application/octet-stream'\", \"fileExtension='.hhp',mimeType='application/octet-stream'\", \"fileExtension='.hlp',mimeType='application/winhlp'\", \"fileExtension='.hqx',mimeType='application/mac-binhex40'\", \"fileExtension='.hta',mimeType='application/hta'\", \"fileExtension='.htc',mimeType='text/x-component'\", \"fileExtension='.htm',mimeType='text/html'\", \"fileExtension='.html',mimeType='text/html'\", \"fileExtension='.htt',mimeType='text/webviewhtml'\", \"fileExtension='.hxt',mimeType='text/html'\", \"fileExtension='.ico',mimeType='image/x-icon'\", \"fileExtension='.ics',mimeType='text/calendar'\", \"fileExtension='.ief',mimeType='image/ief'\", \"fileExtension='.iii',mimeType='application/x-iphone'\", \"fileExtension='.inf',mimeType='application/octet-stream'\", \"fileExtension='.ins',mimeType='application/x-internet-signup'\", \"fileExtension='.isp',mimeType='application/x-internet-signup'\", \"fileExtension='.IVF',mimeType='video/x-ivf'\", \"fileExtension='.jar',mimeType='application/java-archive'\", \"fileExtension='.java',mimeType='application/octet-stream'\", \"fileExtension='.jck',mimeType='application/liquidmotion'\", \"fileExtension='.jcz',mimeType='application/liquidmotion'\", \"fileExtension='.jfif',mimeType='image/pjpeg'\", \"fileExtension='.jpb',mimeType='application/octet-stream'\", \"fileExtension='.jpe',mimeType='image/jpeg'\", \"fileExtension='.jpeg',mimeType='image/jpeg'\", \"fileExtension='.jpg',mimeType='image/jpeg'\", \"fileExtension='.js',mimeType='application/javascript'\", \"fileExtension='.json',mimeType='application/json'\", \"fileExtension='.jsx',mimeType='text/jscript'\", \"fileExtension='.latex',mimeType='application/x-latex'\", \"fileExtension='.lit',mimeType='application/x-ms-reader'\", \"fileExtension='.lpk',mimeType='application/octet-stream'\", \"fileExtension='.lsf',mimeType='video/x-la-asf'\", \"fileExtension='.lsx',mimeType='video/x-la-asf'\", \"fileExtension='.lzh',mimeType='application/octet-stream'\", \"fileExtension='.m13',mimeType='application/x-msmediaview'\", \"fileExtension='.m14',mimeType='application/x-msmediaview'\", \"fileExtension='.m1v',mimeType='video/mpeg'\", \"fileExtension='.m2ts',mimeType='video/vnd.dlna.mpeg-tts'\", \"fileExtension='.m3u',mimeType='audio/x-mpegurl'\", \"fileExtension='.m4a',mimeType='audio/mp4'\", \"fileExtension='.m4v',mimeType='video/mp4'\", \"fileExtension='.man',mimeType='application/x-troff-man'\", \"fileExtension='.manifest',mimeType='application/x-ms-manifest'\", \"fileExtension='.map',mimeType='text/plain'\", \"fileExtension='.mdb',mimeType='application/x-msaccess'\", \"fileExtension='.mdp',mimeType='application/octet-stream'\", \"fileExtension='.me',mimeType='application/x-troff-me'\", \"fileExtension='.mht',mimeType='message/rfc822'\", \"fileExtension='.mhtml',mimeType='message/rfc822'\", \"fileExtension='.mid',mimeType='audio/mid'\", \"fileExtension='.midi',mimeType='audio/mid'\", \"fileExtension='.mix',mimeType='application/octet-stream'\", \"fileExtension='.mmf',mimeType='application/x-smaf'\", \"fileExtension='.mno',mimeType='text/xml'\", \"fileExtension='.mny',mimeType='application/x-msmoney'\", \"fileExtension='.mov',mimeType='video/quicktime'\", \"fileExtension='.movie',mimeType='video/x-sgi-movie'\", \"fileExtension='.mp2',mimeType='video/mpeg'\", \"fileExtension='.mp3',mimeType='audio/mpeg'\", \"fileExtension='.mp4',mimeType='video/mp4'\", \"fileExtension='.mp4v',mimeType='video/mp4'\", \"fileExtension='.mpa',mimeType='video/mpeg'\", \"fileExtension='.mpe',mimeType='video/mpeg'\", \"fileExtension='.mpeg',mimeType='video/mpeg'\", \"fileExtension='.mpg',mimeType='video/mpeg'\", \"fileExtension='.mpp',mimeType='application/vnd.ms-project'\", \"fileExtension='.mpv2',mimeType='video/mpeg'\", \"fileExtension='.ms',mimeType='application/x-troff-ms'\", \"fileExtension='.msi',mimeType='application/octet-stream'\", \"fileExtension='.mso',mimeType='application/octet-stream'\", \"fileExtension='.mvb',mimeType='application/x-msmediaview'\", \"fileExtension='.mvc',mimeType='application/x-miva-compiled'\", \"fileExtension='.nc',mimeType='application/x-netcdf'\", \"fileExtension='.nsc',mimeType='video/x-ms-asf'\", \"fileExtension='.nws',mimeType='message/rfc822'\", \"fileExtension='.ocx',mimeType='application/octet-stream'\", \"fileExtension='.oda',mimeType='application/oda'\", \"fileExtension='.odc',mimeType='text/x-ms-odc'\", \"fileExtension='.ods',mimeType='application/oleobject'\", \"fileExtension='.oga',mimeType='audio/ogg'\", \"fileExtension='.ogg',mimeType='video/ogg'\", \"fileExtension='.ogv',mimeType='video/ogg'\", \"fileExtension='.one',mimeType='application/onenote'\", \"fileExtension='.onea',mimeType='application/onenote'\", \"fileExtension='.onetoc',mimeType='application/onenote'\", \"fileExtension='.onetoc2',mimeType='application/onenote'\", \"fileExtension='.onetmp',mimeType='application/onenote'\", \"fileExtension='.onepkg',mimeType='application/onenote'\", \"fileExtension='.osdx',mimeType='application/opensearchdescription+xml'\", \"fileExtension='.otf',mimeType='font/otf'\", \"fileExtension='.p10',mimeType='application/pkcs10'\", \"fileExtension='.p12',mimeType='application/x-pkcs12'\", \"fileExtension='.p7b',mimeType='application/x-pkcs7-certificates'\", \"fileExtension='.p7c',mimeType='application/pkcs7-mime'\", \"fileExtension='.p7m',mimeType='application/pkcs7-mime'\", \"fileExtension='.p7r',mimeType='application/x-pkcs7-certreqresp'\", \"fileExtension='.p7s',mimeType='application/pkcs7-signature'\", \"fileExtension='.pbm',mimeType='image/x-portable-bitmap'\", \"fileExtension='.pcx',mimeType='application/octet-stream'\", \"fileExtension='.pcz',mimeType='application/octet-stream'\", \"fileExtension='.pdf',mimeType='application/pdf'\", \"fileExtension='.pfb',mimeType='application/octet-stream'\", \"fileExtension='.pfm',mimeType='application/octet-stream'\", \"fileExtension='.pfx',mimeType='application/x-pkcs12'\", \"fileExtension='.pgm',mimeType='image/x-portable-graymap'\", \"fileExtension='.pko',mimeType='application/vnd.ms-pki.pko'\", \"fileExtension='.pma',mimeType='application/x-perfmon'\", \"fileExtension='.pmc',mimeType='application/x-perfmon'\", \"fileExtension='.pml',mimeType='application/x-perfmon'\", \"fileExtension='.pmr',mimeType='application/x-perfmon'\", \"fileExtension='.pmw',mimeType='application/x-perfmon'\", \"fileExtension='.png',mimeType='image/png'\", \"fileExtension='.pnm',mimeType='image/x-portable-anymap'\", \"fileExtension='.pnz',mimeType='image/png'\", \"fileExtension='.pot',mimeType='application/vnd.ms-powerpoint'\", \"fileExtension='.potm',mimeType='application/vnd.ms-powerpoint.template.macroEnabled.12'\", \"fileExtension='.potx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.template'\", \"fileExtension='.ppam',mimeType='application/vnd.ms-powerpoint.addin.macroEnabled.12'\", \"fileExtension='.ppm',mimeType='image/x-portable-pixmap'\", \"fileExtension='.pps',mimeType='application/vnd.ms-powerpoint'\", \"fileExtension='.ppsm',mimeType='application/vnd.ms-powerpoint.slideshow.macroEnabled.12'\", \"fileExtension='.ppsx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.slideshow'\", \"fileExtension='.ppt',mimeType='application/vnd.ms-powerpoint'\", \"fileExtension='.pptm',mimeType='application/vnd.ms-powerpoint.presentation.macroEnabled.12'\", \"fileExtension='.pptx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.presentation'\", \"fileExtension='.prf',mimeType='application/pics-rules'\", \"fileExtension='.prm',mimeType='application/octet-stream'\", \"fileExtension='.prx',mimeType='application/octet-stream'\", \"fileExtension='.ps',mimeType='application/postscript'\", \"fileExtension='.psd',mimeType='application/octet-stream'\", \"fileExtension='.psm',mimeType='application/octet-stream'\", \"fileExtension='.psp',mimeType='application/octet-stream'\", \"fileExtension='.pub',mimeType='application/x-mspublisher'\", \"fileExtension='.qt',mimeType='video/quicktime'\", \"fileExtension='.qtl',mimeType='application/x-quicktimeplayer'\", \"fileExtension='.qxd',mimeType='application/octet-stream'\", \"fileExtension='.ra',mimeType='audio/x-pn-realaudio'\", \"fileExtension='.ram',mimeType='audio/x-pn-realaudio'\", \"fileExtension='.rar',mimeType='application/octet-stream'\", \"fileExtension='.ras',mimeType='image/x-cmu-raster'\", \"fileExtension='.rf',mimeType='image/vnd.rn-realflash'\", \"fileExtension='.rgb',mimeType='image/x-rgb'\", \"fileExtension='.rm',mimeType='application/vnd.rn-realmedia'\", \"fileExtension='.rmi',mimeType='audio/mid'\", \"fileExtension='.roff',mimeType='application/x-troff'\", \"fileExtension='.rpm',mimeType='audio/x-pn-realaudio-plugin'\", \"fileExtension='.rtf',mimeType='application/rtf'\", \"fileExtension='.rtx',mimeType='text/richtext'\", \"fileExtension='.scd',mimeType='application/x-msschedule'\", \"fileExtension='.sct',mimeType='text/scriptlet'\", \"fileExtension='.sea',mimeType='application/octet-stream'\", \"fileExtension='.setpay',mimeType='application/set-payment-initiation'\", \"fileExtension='.setreg',mimeType='application/set-registration-initiation'\", \"fileExtension='.sgml',mimeType='text/sgml'\", \"fileExtension='.sh',mimeType='application/x-sh'\", \"fileExtension='.shar',mimeType='application/x-shar'\", \"fileExtension='.sit',mimeType='application/x-stuffit'\", \"fileExtension='.sldm',mimeType='application/vnd.ms-powerpoint.slide.macroEnabled.12'\", \"fileExtension='.sldx',mimeType='application/vnd.openxmlformats-officedocument.presentationml.slide'\", \"fileExtension='.smd',mimeType='audio/x-smd'\", \"fileExtension='.smi',mimeType='application/octet-stream'\", \"fileExtension='.smx',mimeType='audio/x-smd'\", \"fileExtension='.smz',mimeType='audio/x-smd'\", \"fileExtension='.snd',mimeType='audio/basic'\", \"fileExtension='.snp',mimeType='application/octet-stream'\", \"fileExtension='.spc',mimeType='application/x-pkcs7-certificates'\", \"fileExtension='.spl',mimeType='application/futuresplash'\", \"fileExtension='.spx',mimeType='audio/ogg'\", \"fileExtension='.src',mimeType='application/x-wais-source'\", \"fileExtension='.ssm',mimeType='application/streamingmedia'\", \"fileExtension='.sst',mimeType='application/vnd.ms-pki.certstore'\", \"fileExtension='.stl',mimeType='application/vnd.ms-pki.stl'\", \"fileExtension='.sv4cpio',mimeType='application/x-sv4cpio'\", \"fileExtension='.sv4crc',mimeType='application/x-sv4crc'\", \"fileExtension='.svg',mimeType='image/svg+xml'\", \"fileExtension='.svgz',mimeType='image/svg+xml'\", \"fileExtension='.swf',mimeType='application/x-shockwave-flash'\", \"fileExtension='.t',mimeType='application/x-troff'\", \"fileExtension='.tar',mimeType='application/x-tar'\", \"fileExtension='.tcl',mimeType='application/x-tcl'\", \"fileExtension='.tex',mimeType='application/x-tex'\", \"fileExtension='.texi',mimeType='application/x-texinfo'\", \"fileExtension='.texinfo',mimeType='application/x-texinfo'\", \"fileExtension='.tgz',mimeType='application/x-compressed'\", \"fileExtension='.thmx',mimeType='application/vnd.ms-officetheme'\", \"fileExtension='.thn',mimeType='application/octet-stream'\", \"fileExtension='.tif',mimeType='image/tiff'\", \"fileExtension='.tiff',mimeType='image/tiff'\", \"fileExtension='.toc',mimeType='application/octet-stream'\", \"fileExtension='.tr',mimeType='application/x-troff'\", \"fileExtension='.trm',mimeType='application/x-msterminal'\", \"fileExtension='.ts',mimeType='video/vnd.dlna.mpeg-tts'\", \"fileExtension='.tsv',mimeType='text/tab-separated-values'\", \"fileExtension='.ttf',mimeType='application/octet-stream'\", \"fileExtension='.tts',mimeType='video/vnd.dlna.mpeg-tts'\", \"fileExtension='.txt',mimeType='text/plain'\", \"fileExtension='.u32',mimeType='application/octet-stream'\", \"fileExtension='.uls',mimeType='text/iuls'\", \"fileExtension='.ustar',mimeType='application/x-ustar'\", \"fileExtension='.vbs',mimeType='text/vbscript'\", \"fileExtension='.vcf',mimeType='text/x-vcard'\", \"fileExtension='.vcs',mimeType='text/plain'\", \"fileExtension='.vdx',mimeType='application/vnd.ms-visio.viewer'\", \"fileExtension='.vml',mimeType='text/xml'\", \"fileExtension='.vsd',mimeType='application/vnd.visio'\", \"fileExtension='.vss',mimeType='application/vnd.visio'\", \"fileExtension='.vst',mimeType='application/vnd.visio'\", \"fileExtension='.vsto',mimeType='application/x-ms-vsto'\", \"fileExtension='.vsw',mimeType='application/vnd.visio'\", \"fileExtension='.vsx',mimeType='application/vnd.visio'\", \"fileExtension='.vtx',mimeType='application/vnd.visio'\", \"fileExtension='.wav',mimeType='audio/wav'\", \"fileExtension='.wax',mimeType='audio/x-ms-wax'\", \"fileExtension='.wbmp',mimeType='image/vnd.wap.wbmp'\", \"fileExtension='.wcm',mimeType='application/vnd.ms-works'\", \"fileExtension='.wdb',mimeType='application/vnd.ms-works'\", \"fileExtension='.webm',mimeType='video/webm'\", \"fileExtension='.wks',mimeType='application/vnd.ms-works'\", \"fileExtension='.wm',mimeType='video/x-ms-wm'\", \"fileExtension='.wma',mimeType='audio/x-ms-wma'\", \"fileExtension='.wmd',mimeType='application/x-ms-wmd'\", \"fileExtension='.wmf',mimeType='application/x-msmetafile'\", \"fileExtension='.wml',mimeType='text/vnd.wap.wml'\", \"fileExtension='.wmlc',mimeType='application/vnd.wap.wmlc'\", \"fileExtension='.wmls',mimeType='text/vnd.wap.wmlscript'\", \"fileExtension='.wmlsc',mimeType='application/vnd.wap.wmlscriptc'\", \"fileExtension='.wmp',mimeType='video/x-ms-wmp'\", \"fileExtension='.wmv',mimeType='video/x-ms-wmv'\", \"fileExtension='.wmx',mimeType='video/x-ms-wmx'\", \"fileExtension='.wmz',mimeType='application/x-ms-wmz'\", \"fileExtension='.woff',mimeType='font/x-woff'\", \"fileExtension='.wps',mimeType='application/vnd.ms-works'\", \"fileExtension='.wri',mimeType='application/x-mswrite'\", \"fileExtension='.wrl',mimeType='x-world/x-vrml'\", \"fileExtension='.wrz',mimeType='x-world/x-vrml'\", \"fileExtension='.wsdl',mimeType='text/xml'\", \"fileExtension='.wtv',mimeType='video/x-ms-wtv'\", \"fileExtension='.wvx',mimeType='video/x-ms-wvx'\", \"fileExtension='.x',mimeType='application/directx'\", \"fileExtension='.xaf',mimeType='x-world/x-vrml'\", \"fileExtension='.xaml',mimeType='application/xaml+xml'\", \"fileExtension='.xap',mimeType='application/x-silverlight-app'\", \"fileExtension='.xbap',mimeType='application/x-ms-xbap'\", \"fileExtension='.xbm',mimeType='image/x-xbitmap'\", \"fileExtension='.xdr',mimeType='text/plain'\", \"fileExtension='.xht',mimeType='application/xhtml+xml'\", \"fileExtension='.xhtml',mimeType='application/xhtml+xml'\", \"fileExtension='.xla',mimeType='application/vnd.ms-excel'\", \"fileExtension='.xlam',mimeType='application/vnd.ms-excel.addin.macroEnabled.12'\", \"fileExtension='.xlc',mimeType='application/vnd.ms-excel'\", \"fileExtension='.xlm',mimeType='application/vnd.ms-excel'\", \"fileExtension='.xls',mimeType='application/vnd.ms-excel'\", \"fileExtension='.xlsb',mimeType='application/vnd.ms-excel.sheet.binary.macroEnabled.12'\", \"fileExtension='.xlsm',mimeType='application/vnd.ms-excel.sheet.macroEnabled.12'\", \"fileExtension='.xlsx',mimeType='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'\", \"fileExtension='.xlt',mimeType='application/vnd.ms-excel'\", \"fileExtension='.xltm',mimeType='application/vnd.ms-excel.template.macroEnabled.12'\", \"fileExtension='.xltx',mimeType='application/vnd.openxmlformats-officedocument.spreadsheetml.template'\", \"fileExtension='.xlw',mimeType='application/vnd.ms-excel'\", \"fileExtension='.xml',mimeType='text/xml'\", \"fileExtension='.xof',mimeType='x-world/x-vrml'\", \"fileExtension='.xpm',mimeType='image/x-xpixmap'\", \"fileExtension='.xps',mimeType='application/vnd.ms-xpsdocument'\", \"fileExtension='.xsd',mimeType='text/xml'\", \"fileExtension='.xsf',mimeType='text/xml'\", \"fileExtension='.xsl',mimeType='text/xml'\", \"fileExtension='.xslt',mimeType='text/xml'\", \"fileExtension='.xsn',mimeType='application/octet-stream'\", \"fileExtension='.xtp',mimeType='application/octet-stream'\", \"fileExtension='.xwd',mimeType='image/x-xwindowdump'\", \"fileExtension='.z',mimeType='application/x-compress'\", \"fileExtension='.zip',mimeType='application/x-zip-compressed'\"]\n ```\n\n- `add_default_documents` - The items you want to add to the default document collection, only used during `:add`. Array of strings, default: `[]`\n\n- `add_mime_maps` - The items you want to add to the mime-map/mime-type collection, only used during `:add`. Array of strings, default: `[]`\n\n- `delete_default_documents` - The items you want to delete from the default document collection, only used during `:delete`. Array of strings, default: `[]`\n\n- `delete_mime_maps` - The items you want to delete from the mime-map/mime-type collection, only used during `:delete`. Array of strings, default: `[]`\n\n#### Examples\n\n```ruby\n# Add foo.html to default documents, and add '.dmg' as mime type extension at root level\niis_root 'add stuff' do\n add_default_documents ['foo.html']\n add_mime_maps [\"fileExtension='.dmg',mimeType='application/octet-stream'\"]\n action :add\nend\n```\n\n```ruby\n# Remove index.html from default document and .323 as a mime type at root level\niis_root 'delete stuff' do\n delete_default_documents ['index.html']\n delete_mime_maps [\"fileExtension='.323',mimeType='text/h323'\"]\n action :delete\nend\n```\n\n### iis_site\n\nAllows for easy management of IIS virtual sites (ie vhosts).\n\n#### Actions\n\n- `:add` - add a new virtual site\n- `:config` - apply configuration to an existing virtual site\n- `:delete` - delete an existing virtual site\n- `:start` - start a virtual site\n- `:stop` - stop a virtual site\n- `:restart` - restart a virtual site\n\n#### Properties\n\n- `site_name` - name attribute.\n- `site_id` - if not given IIS generates a unique ID for the site\n- `path` - IIS will create a root application and a root virtual directory mapped to this specified local path\n- `protocol` - http protocol type the site should respond to. valid values are :http, :https. default is :http\n- `port` - port site will listen on. default is 80\n- `host_header` - host header (also known as domains or host names) the site should map to. default is all host headers\n- `options` - additional options to configure the site\n- `bindings` - Advanced options to configure the information required for requests to communicate with a Web site. See for parameter format. When binding is used, port protocol and host_header should not be used.\n- `application_pool` - set the application pool of the site\n- `options` - support for additional options -logDir, -limits, -ftpServer, etc...\n- `log_directory` - specifies the logging directory, where the log file and logging-related support files are stored.\n- `log_period` - specifies how often iis creates a new log file\n- `log_truncsize` - specifies the maximum size of the log file (in bytes) after which to create a new log file.\n\n#### Examples\n\n```ruby\n# stop and delete the default site\niis_site 'Default Web Site' do\n action [:stop, :delete]\nend\n```\n\n```ruby\n# create and start a new site that maps to\n# the physical location C:\\inetpub\\wwwroot\\testfu\n# first the physical location must exist\ndirectory \"#{node['iis']['docroot']}/testfu\" do\n action :create\nend\n\n# now create and start the site (note this will use the default application pool which must exist)\niis_site 'Testfu Site' do\n protocol :http\n port 80\n path \"#{node['iis']['docroot']}/testfu\"\n action [:add,:start]\nend\n```\n\n```ruby\n# do the same but map to testfu.chef.io domain\n# first the physical location must exist\ndirectory \"#{node['iis']['docroot']}/testfu\" do\n action :create\nend\n\n# now create and start the site (note this will use the default application pool which must exist)\niis_site 'Testfu Site' do\n protocol :http\n port 80\n path \"#{node['iis']['docroot']}/testfu\"\n host_header \"testfu.chef.io\"\n action [:add,:start]\nend\n```\n\n```ruby\n# create and start a new site that maps to\n# the physical C:\\inetpub\\wwwroot\\testfu\n# first the physical location must exist\ndirectory \"#{node['iis']['docroot']}/testfu\" do\n action :create\nend\n\n# also adds bindings to http and https\n# binding http to the ip address 10.12.0.136,\n# the port 80, and the host header www.domain.com\n# also binding https to any ip address,\n# the port 443, and the host header www.domain.com\n# now create and start the site (note this will use the default application pool which must exist)\niis_site 'FooBar Site' do\n bindings \"http/10.12.0.136:80:www.domain.com,https/*:443:www.domain.com\n path \"#{node['iis']['docroot']}/testfu\"\n action [:add,:start]\nend\n```\n\n### iis_config\n\nRuns a config command on your IIS instance.\n\n#### Actions\n\n- `:set` - Edit configuration section (appcmd set config)\n- `:clear` - Clear the section configuration (appcmd clear config)\n- `:config` - [ DEPRECATED ] use `:set` instead\n\n#### Properties\n\n- `cfg_cmd` - name attribute. What ever command you would pass in after \"appcmd.exe set config\"\n\n#### Example\n\n```ruby\n# Sets up logging\niis_config \"/section:system.applicationHost/sites /siteDefaults.logfile.directory:\\\"D:\\\\logs\\\"\" do\n action :set\nend\n```\n\n```ruby\n# Increase file upload size for 'MySite'\niis_config \"\\\"MySite\\\" /section:requestfiltering /requestlimits.maxallowedcontentlength:50000000\" do\n action :set\nend\n```\n\n```ruby\n# Set IUSR username and password authentication\niis_config \"\\\"MyWebsite/aSite\\\" -section:system.webServer/security/authentication/anonymousAuthentication /enabled:\\\"True\\\" /userName:\\\"IUSR_foobar\\\" /password:\\\"p@assword\\\" /commit:apphost\" do\n action :set\nend\n```\n\n```ruby\n# Authenticate with application pool\niis_config \"\\\"MyWebsite/aSite\\\" -section:system.webServer/security/authentication/anonymousAuthentication /enabled:\\\"True\\\" /userName:\\\"\\\" /commit:apphost\" do\n action :set\nend\n```\n\n```ruby\n# Loads an array of commands from the node\ncfg_cmds = node['iis']['cfg_cmd']\ncfg_cmds.each do |cmd|\n iis_config \"#{cmd}\" do\n action :set\n end\nend\n```\n\n```ruby\n# Add static machine key at site level\niis_config \"MySite /commit:site /section:machineKey /validation:AES /validationKey:AAAAAA /decryptionKey:ZZZZZ\" do\n action :set\nend\n```\n\n```ruby\n# Remove machine key\niis_config \"MySite /commit:site /section:machineKey\" do\n action :clear\nend\n```\n\n### iis_pool\n\nCreates an application pool in IIS.\n\n#### Actions\n\n- `:add` - add a new application pool\n- `:config` - apply configuration to an existing application pool\n- `:delete` - delete an existing application pool\n- `:start` - start a application pool\n- `:stop` - stop a application pool\n- `:restart` - restart a application pool\n- `:recycle` - recycle an application pool\n\n#### Properties\n\n##### Root Items\n\n- `pool_name` - name attribute. Specifies the name of the pool to create.\n- `runtime_version` - specifies what .NET version of the runtime to use.\n- `pipeline_mode` - specifies what pipeline mode to create the pool with, valid values are :Integrated or :Classic, the default is :Integrated\n- `no_managed_code` - allow Unmanaged Code in setting up IIS app pools is shutting down. - default is true - optional\n\n##### Add Items\n\n- `start_mode` - Specifies the startup type for the application pool - default :OnDemand (:OnDemand, :AlwaysRunning) - optional\n- `auto_start` - When true, indicates to the World Wide Web Publishing Service (W3SVC) that the application pool should be automatically started when it is created or when IIS is started. - boolean: default true - optional\n- `queue_length` - Indicates to HTTP.sys how many requests to queue for an application pool before rejecting future requests. - default is 1000 - optional\n- `thirty_two_bit` - set the pool to run in 32 bit mode, valid values are true or false, default is false - optional\n\n##### Process Model Items\n\n- `max_proc` - specifies the number of worker processes associated with the pool.\n- `load_user_profile` - This property is used only when a service starts in a named user account. - Default is false - optional\n- `pool_identity` - the account identity that they app pool will run as, valid values are :SpecificUser, :NetworkService, :LocalService, :LocalSystem, :ApplicationPoolIdentity\n- `pool_username` - username for the identity for the application pool\n- `pool_password` password for the identity for the application pool is started. Default is true - optional\n- `logon_type` - Specifies the logon type for the process identity. (For additional information about [logon types](http://msdn.microsoft.com/en-us/library/aa378184%28VS.85%29.aspx), see the LogonUser Function topic on Microsoft's MSDN Web site.) - Available [:LogonBatch, :LogonService] - default is :LogonBatch - optional\n- `manual_group_membership` - Specifies whether the IIS_IUSRS group Security Identifier (SID) is added to the worker process token. When false, IIS automatically uses an application pool identity as though it were a member of the built-in IIS_IUSRS group, which has access to necessary file and system resources. When true, an application pool identity must be explicitly added to all resources that a worker process requires at runtime. - default is false - optional\n- `idle_timeout` - Specifies how long (in minutes) a worker process should run idle if no new requests are received and the worker process is not processing requests. After the allocated time passes, the worker process should request that it be shut down by the WWW service. - default is '00:20:00' - optional\n- `idle_timeout_action` - Specifies the option of suspending an idle worker process rather than terminating it. Valid values are :Terminate and :Suspend - optional\n- `shutdown_time_limit` - Specifies the time that the W3SVC service waits after it initiated a recycle. If the worker process does not shut down within the shutdownTimeLimit, it will be terminated by the W3SVC service. - default is '00:01:30' - optional\n- `startup_time_limit` - Specifies the time that IIS waits for an application pool to start. If the application pool does not startup within the startupTimeLimit, the worker process is terminated and the rapid-fail protection count is incremented. - default is '00:01:30' - optional\n- `pinging_enabled` - Specifies whether pinging is enabled for the worker process. - default is true - optional\n- `ping_interval` - Specifies the time between health-monitoring pings that the WWW service sends to a worker process - default is '00:00:30' - optional\n- `ping_response_time` - Specifies the time that a worker process is given to respond to a health-monitoring ping. After the time limit is exceeded, the WWW service terminates the worker process - default is '00:01:30' - optional\n\n##### Recycling Items\n\n- `disallow_rotation_on_config_change` - The DisallowRotationOnConfigChange property specifies whether or not the World Wide Web Publishing Service (WWW Service) should rotate worker processes in an application pool when the configuration has changed. - Default is false - optional\n- `disallow_overlapping_rotation` - Specifies whether the WWW Service should start another worker process to replace the existing worker process while that process\n- `log_event_on_recycle` - configure IIS to log an event when one or more of the following configured events cause an application pool to recycle (for additional information about [logging events] (https://technet.microsoft.com/en-us/library/cc771318%28v=ws.10%29.aspx). - default is 'Time, Requests, Schedule, Memory, IsapiUnhealthy, OnDemand, ConfigChange, PrivateMemory' - optional\n- `recycle_schedule_clear` - specifies a pool to clear all scheduled recycle times, [true,false] Default is false - optional\n- `recycle_after_time` - specifies a pool to recycle at regular time intervals, d.hh:mm:ss, d optional\n- `recycle_at_time` - schedule a pool to recycle at a specific time, d.hh:mm:ss, d optional\n- `private_mem` - specifies the amount of private memory (in kilobytes) after which you want the pool to recycle\n- `virtual_mem` - specifies the amount of virtual memory (in kilobytes) after which you want the pool to recycle\n\n#### Failure Items\n\n- `load_balancer_capabilities` - Specifies behavior when a worker process cannot be started, such as when the request queue is full or an application pool is in rapid-fail protection. - default is :HttpLevel - optional\n- `orphan_worker_process` - Specifies whether to assign a worker process to an orphan state instead of terminating it when an application pool fails. - default is false - optional\n- `orphan_action_exe` - Specifies an executable to run when the WWW service orphans a worker process (if the orphanWorkerProcess attribute is set to true). You can use the orphanActionParams attribute to send parameters to the executable. - optional\n- `orphan_action_params` - Indicates command-line parameters for the executable named by the orphanActionExe attribute. To specify the process ID of the orphaned process, use %1%. - optional\n- `rapid_fail_protection` - Setting to true instructs the WWW service to remove from service all applications that are in an application pool - default is true - optional\n- `rapid_fail_protection_interval` - Specifies the number of minutes before the failure count for a process is reset. - default is '00:05:00' - optional\n- `rapid_fail_protection_max_crashes` - Specifies the maximum number of failures that are allowed within the number of minutes specified by the rapidFailProtectionInterval attribute. - default is 5 - optional\n- `auto_shutdown_exe` - Specifies an executable to run when the WWW service shuts down an application pool. - optional\n- `auto_shutdown_params` - Specifies command-line parameters for the executable that is specified in the autoShutdownExe attribute. - optional\n\n##### CPU Items\n\n- `cpu_action` - Configures the action that IIS takes when a worker process exceeds its configured CPU limit. The action attribute is configured on a per-application pool basis. - Available options [:NoAction, :KillW3wp, :Throttle, :ThrottleUnderLoad] - default is :NoAction - optional\n- `cpu_limit` - Configures the maximum percentage of CPU time (in 1/1000ths of one percent) that the worker processes in an application pool are allowed to consume over a period of time as indicated by the resetInterval attribute. If the limit set by the limit attribute is exceeded, an event is written to the event log and an optional set of events can be triggered. These optional events are determined by the action attribute. - default is 0 - optional\n- `cpu_reset_interval` - Specifies the reset period (in minutes) for CPU monitoring and throttling limits on an application pool. When the number of minutes elapsed since the last process accounting reset equals the number specified by this property, IIS resets the CPU timers for both the logging and limit intervals. - default is '00:05:00' - optional\n- `cpu_smp_affinitized` - Specifies whether a particular worker process assigned to an application pool should also be assigned to a given CPU. - default is false - optional\n- `smp_processor_affinity_mask` - Specifies the hexadecimal processor mask for multi-processor computers, which indicates to which CPU the worker processes in an application pool should be bound. Before this property takes effect, the smpAffinitized attribute must be set to true for the application pool. - default is 4294967295 - optional\n- `smp_processor_affinity_mask_2` - Specifies the high-order DWORD hexadecimal processor mask for 64-bit multi-processor computers, which indicates to which CPU the worker processes in an application pool should be bound. Before this property takes effect, the smpAffinitized attribute must be set to true for the application pool. - default is 4294967295 - optional\n\n#### Example\n\n```ruby\n# creates a new app pool\niis_pool 'myAppPool_v1_1' do\n runtime_version \"2.0\"\n pipeline_mode :Classic\n action :add\nend\n```\n\n### iis_app\n\nCreates an application in IIS.\n\n#### Actions\n\n- `:add` - add a new application pool\n- `:delete` - delete an existing application pool\n- `:config` - configures an existing application pool\n\n#### Properties\n\n- `site_name` - name attribute. The name of the site to add this app to\n- `path` -The virtual path for this application\n- `application_pool` - The pool this application belongs to\n- `physical_path` - The physical path where this app resides.\n- `enabled_protocols` - The enabled protocols that this app provides (http, https, net.pipe, net.tcp, etc)\n\n#### Example\n\n```ruby\n# creates a new app\niis_app \"myApp\" do\n path \"/v1_1\"\n application_pool \"myAppPool_v1_1\"\n physical_path \"#{node['iis']['docroot']}/testfu/v1_1\"\n enabled_protocols \"http,net.pipe\"\n action :add\nend\n```\n\n### iis_vdir\n\nAllows easy management of IIS virtual directories (i.e. vdirs).\n\n#### Actions\n\n- :add: - add a new virtual directory\n- :delete: - delete an existing virtual directory\n- :config: - configure a virtual directory\n\n#### Attribute Parameters\n\n- `application_name`: name attribute. Specifies the name of the application attribute. This is the name of the website or application you are adding it to.\n- `path`: The virtual directory path on the site.\n- `physical_path`: The physical path of the virtual directory on the disk.\n- `username`: (optional) The username required to logon to the physical_path. If set to \"\" will clear username and password.\n- `password`: (optional) The password required to logon to the physical_path\n- `logon_method`: (optional, default: :ClearText) The method used to logon (:Interactive, :Batch, :Network, :ClearText). For more information on these types, see \"LogonUser Function\", Read more at [MSDN](http://msdn2.microsoft.com/en-us/library/aa378184.aspx)\n- `allow_sub_dir_config`: (optional, default: true) Boolean that specifies whether or not the Web server will look for configuration files located in the subdirectories of this virtual directory. Setting this to false can improve performance on servers with very large numbers of web.config files, but doing so prevents IIS configuration from being read in subdirectories.\n\n#### Examples\n\n```ruby\n# add a virtual directory to default application\niis_vdir 'Default Web Site/' do\n action :add\n path '/Content/Test'\n physical_path 'C:\\wwwroot\\shared\\test'\nend\n```\n\n```ruby\n# add a virtual directory to an application under a site\niis_vdir 'Default Web Site/my application' do\n action :add\n path '/Content/Test'\n physical_path 'C:\\wwwroot\\shared\\test'\nend\n```\n\n```ruby\n# adds a virtual directory to default application which points to a smb share. (Remember to escape the \"\\\"'s)\niis_vdir 'Default Web Site/' do\n action :add\n path '/Content/Test'\n physical_path '\\\\\\\\sharename\\\\sharefolder\\\\1'\nend\n```\n\n```ruby\n# configure a virtual directory to have a username and password\niis_vdir 'Default Web Site/' do\n action :config\n path '/Content/Test'\n username 'domain\\myspecialuser'\n password 'myspecialpassword'\nend\n```\n\n```ruby\n# delete a virtual directory from the default application\niis_vdir 'Default Web Site/' do\n action :delete\n path '/Content/Test'\nend\n```\n\n### iis_section\n\nAllows for the locking/unlocking of sections ([listed here](http://www.iis.net/configreference) or via the command `appcmd list config \\\"\\\" /config:* /xml`)\n\nThis is valuable to allow the `web.config` of an individual application/website control it's own settings.\n\n#### Actions\n\n- `:lock`: - locks the `section` passed\n- `:unlock`: - unlocks the `section` passed\n\n#### Attribute Parameters\n\n- `section`: The name of the section to lock.\n- `returns`: The result of the `shell_out` command.\n\n#### Examples\n\n```ruby\n# Sets the IIS global windows authentication to be locked globally\niis_section 'locks global configuration of windows auth' do\n section 'system.webServer/security/authentication/windowsAuthentication'\n action :lock\nend\n```\n\n```ruby\n# Sets the IIS global Basic authentication to be locked globally\niis_section 'locks global configuration of Basic auth' do\n section 'system.webServer/security/authentication/basicAuthentication'\n action :lock\nend\n```\n\n```ruby\n# Sets the IIS global windows authentication to be unlocked globally\niis_section 'unlocked web.config globally for windows auth' do\n action :unlock\n section 'system.webServer/security/authentication/windowsAuthentication'\nend\n```\n\n```ruby\n# Sets the IIS global Basic authentication to be unlocked globally\niis_section 'unlocked web.config globally for Basic auth' do\n action :unlock\n section 'system.webServer/security/authentication/basicAuthentication'\nend\n```\n\n### iis_module\n\nManages modules globally or on a per site basis.\n\n#### Actions\n\n- `:add` - add a new module\n- `:delete` - delete a module\n- `:install` - install a native module from the filesystem (.dll)\n- `:uninstall` - uninstall a native module\n\n#### Attribute Parameters\n\n- `module_name` - The name of the module to add or delete\n- `type` - The type of module\n- `precondition` - precondition for module\n- `application` - The application or site to add the module to\n- `add` - Whether the module you install has to be globally added\n- `image` - Location of the DLL of the module to install\n\n#### Example\n\n```ruby\n# Adds a module called \"My 3rd Party Module\" to mySite/\niis_module \"My 3rd Party Module\" do\n application \"mySite/\"\n precondition \"bitness64\"\n action :add\nend\n```\n\n```ruby\n# Adds a module called \"MyModule\" to all IIS sites on the server\niis_module \"MyModule\"\n```\n\n## Usage\n\n### default recipe\n\nInstalls and configures IIS 7.0/7.5/8.0 using the default configuration.\n\n### mod_* recipes\n\nThis cookbook also contains recipes for installing individual IIS modules (extensions). These recipes can be included in a node's run_list to build the minimal desired custom IIS installation.\n\n- `mod_aspnet` - installs ASP.NET runtime components\n- `mod_aspnet45` - installs ASP.NET 4.5 runtime components\n- `mod_auth_basic` - installs Basic Authentication support\n- `mod_auth_windows` - installs Windows Authentication (authenticate clients by using NTLM or Kerberos) support\n- `mod_compress_dynamic` - installs dynamic content compression support. _PLEASE NOTE_ - enabling dynamic compression always gives you more efficient use of bandwidth, but if your server's processor utilization is already very high, the CPU load imposed by dynamic compression might make your site perform more slowly.\n- `mod_compress_static` - installs static content compression support\n- `mod_iis6_metabase_compat` - installs IIS 6 Metabase Compatibility component.\n- `mod_isapi` - installs ISAPI (Internet Server Application Programming Interface) extension and filter support.\n- `mod_logging` - installs and enables HTTP Logging (logging of Web site activity), Logging Tools (logging tools and scripts) and Custom Logging (log any of the HTTP request/response headers, IIS server variables, and client-side fields with simple configuration) support\n- `mod_management` - installs Web server Management Console which supports management of local and remote Web servers\n- `mod_security` - installs URL Authorization (Authorizes client access to the URLs that comprise a Web application), Request Filtering (configures rules to block selected client requests) and IP Security (allows or denies content access based on IP address or domain name) support.\n- `mod_tracing` - installs support for tracing ASP.NET applications and failed requests.\n\nNote: Not every possible IIS module has a corresponding recipe. The foregoing recipes are included for convenience, but users may also place additional IIS modules that are installable as Windows features into the `node['iis']['components']` array.\n\n## Alternative Cookbooks\n\n- [Powershell based IIS Cookbook (Pre-DSC)](https://github.com/ebsco/iisposh)\n- DSC Based- [CWebAdministration](https://github.com/PowerShellOrg/cWebAdministration) / [XWebadministration](https://github.com/PowerShell/xWebAdministration) Powershell Module(s)\n\n## License and Author\n\n- Author:: Seth Chisamore ([schisamo@chef.io](mailto:schisamo@chef.io))\n- Author:: Julian Dunn ([jdunn@chef.io](mailto:jdunn@chef.io))\n- Author:: Justin Schuhmann ([jmschu02@gmail.com](mailto:jmschu02@gmail.com))\n\n```text\nCopyright 2011-2016, Chef Software, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{"windows":">= 0.0.0"},"dependencies":{"windows":">= 1.34.6"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{}} \ No newline at end of file diff --git a/cookbooks/iis/providers/app.rb b/cookbooks/iis/providers/app.rb index 0c3d1f5..ca2f5d8 100644 --- a/cookbooks/iis/providers/app.rb +++ b/cookbooks/iis/providers/app.rb @@ -1,10 +1,10 @@ # # Author:: Kendrick Martin (kendrick.martin@webtrends.com) # Contributor:: Adam Wayne (awayne@waynedigital.com) -# Cookbook Name:: iis +# Cookbook:: iis # Provider:: app # -# Copyright:: 2011, Webtrends Inc. +# Copyright:: 2011-2016, Webtrends Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -34,7 +34,7 @@ action :add do cmd << " /applicationPool:\"#{new_resource.application_pool}\"" if new_resource.application_pool cmd << " /physicalPath:\"#{windows_cleanpath(new_resource.physical_path)}\"" if new_resource.physical_path cmd << " /enabledProtocols:\"#{new_resource.enabled_protocols}\"" if new_resource.enabled_protocols - cmd << " /commit:\"MACHINE/WEBROOT/APPHOST\"" + cmd << ' /commit:\"MACHINE/WEBROOT/APPHOST\"' Chef::Log.debug(cmd) shell_out!(cmd) new_resource.updated_by_last_action(true) @@ -124,11 +124,7 @@ def load_current_resource if cmd.stderr.empty? result = cmd.stdout.match(regex) Chef::Log.debug("#{new_resource} current_resource match output:#{result}") - if result - @current_resource.exists = true - else - @current_resource.exists = false - end + @current_resource.exists = result else log "Failed to run iis_app action :load_current_resource, #{cmd_current_values.stderr}" do level :warn diff --git a/cookbooks/iis/providers/config.rb b/cookbooks/iis/providers/config.rb index c278979..8f4bd34 100644 --- a/cookbooks/iis/providers/config.rb +++ b/cookbooks/iis/providers/config.rb @@ -1,10 +1,10 @@ # # Author:: Kendrick Martin (kendrick.martin@webtrends.com) # Contributor:: David Dvorak (david.dvorak@webtrends.com) -# Cookbook Name:: iis +# Cookbook:: iis # Resource:: config # -# Copyright:: 2011, Webtrends Inc. +# Copyright:: 2011-2016, Webtrends Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -27,15 +27,19 @@ include Opscode::IIS::Processors # :config deprecated, use :set instead action :config do - config + Chef::Log.warn <<-eos + Use of action `:config` in resource `iis_config` is now deprecated and will be removed in a future release (v4.2.0). + `:set` should be used instead. + eos + new_resource.updated_by_last_action(true) if config end action :set do - config + new_resource.updated_by_last_action(true) if config end action :clear do - config(:clear) + new_resource.updated_by_last_action(true) if config(:clear) end def config(action = :set) diff --git a/cookbooks/iis/providers/module.rb b/cookbooks/iis/providers/module.rb index 9906dc1..1ab764d 100644 --- a/cookbooks/iis/providers/module.rb +++ b/cookbooks/iis/providers/module.rb @@ -1,9 +1,9 @@ # # Author:: Jon DeCamp () -# Cookbook Name:: iis +# Cookbook:: iis # Provider:: site # -# Copyright:: 2013, Nordstrom, Inc. +# Copyright:: 2013-2016, Nordstrom, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -79,6 +79,7 @@ action :install do cmd = "#{appcmd(node)} install module /name:\"#{new_resource.module_name}\"" cmd << " /add:\"#{new_resource.add}\"" unless new_resource.add.nil? cmd << " /image:\"#{new_resource.image}\"" if new_resource.image + cmd << " /preCondition:\"#{new_resource.precondition}\"" if new_resource.precondition shell_out!(cmd, returns: [0, 42]) @@ -108,19 +109,15 @@ end def load_current_resource @current_resource = Chef::Resource::IisModule.new(new_resource.name) @current_resource.module_name(new_resource.module_name) - if new_resource.application - cmd = shell_out("#{appcmd(node)} list module /module.name:\"#{new_resource.module_name}\" /app.name:\"#{new_resource.application}\"") - else - cmd = shell_out("#{appcmd(node)} list module /module.name:\"#{new_resource.module_name}\"") - end + cmd = if new_resource.application + shell_out("#{appcmd(node)} list module /module.name:\"#{new_resource.module_name}\" /app.name:\"#{new_resource.application}\"") + else + shell_out("#{appcmd(node)} list module /module.name:\"#{new_resource.module_name}\"") + end # 'MODULE "Module Name" ( type:module.type, preCondition:condition )' # 'MODULE "Module Name" ( native, preCondition:condition )' Chef::Log.debug("#{new_resource} list module command output: #{cmd.stdout}") - if cmd.stdout.empty? - @current_resource.exists = false - else - @current_resource.exists = true - end + @current_resource.exists = !cmd.stdout.empty? end diff --git a/cookbooks/iis/providers/pool.rb b/cookbooks/iis/providers/pool.rb index 8c45e07..6f7e996 100644 --- a/cookbooks/iis/providers/pool.rb +++ b/cookbooks/iis/providers/pool.rb @@ -1,10 +1,10 @@ # # Author:: Kendrick Martin (kendrick.martin@webtrends.com) # Contributor:: David Dvorak (david.dvorak@webtrends.com) -# Cookbook Name:: iis +# Cookbook:: iis # Provider:: pool # -# Copyright:: 2011, Webtrends Inc. +# Copyright:: 2011-2016, Webtrends Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -32,11 +32,11 @@ action :add do cmd = "#{appcmd(node)} add apppool /name:\"#{new_resource.pool_name}\"" if new_resource.no_managed_code cmd << ' /managedRuntimeVersion:' - else - cmd << " /managedRuntimeVersion:v#{new_resource.runtime_version}" if new_resource.runtime_version + elsif new_resource.runtime_version + cmd << " /managedRuntimeVersion:v#{new_resource.runtime_version}" end cmd << " /managedPipelineMode:#{new_resource.pipeline_mode.capitalize}" if new_resource.pipeline_mode - cmd << " /commit:\"MACHINE/WEBROOT/APPHOST\"" + cmd << ' /commit:\"MACHINE/WEBROOT/APPHOST\"' Chef::Log.debug(cmd) shell_out!(cmd) configure @@ -107,7 +107,7 @@ def load_current_resource Chef::Log.debug("#{new_resource} current_resource match output: #{result}") if result @current_resource.exists = true - @current_resource.running = (result[4] =~ /Started/) ? true : false + @current_resource.running = result[4] =~ /Started/ ? true : false else @current_resource.exists = false @current_resource.running = false @@ -135,15 +135,20 @@ def configure doc = Document.new(xml) # root items - is_new_managed_runtime_version = new_value?(doc.root, 'APPPOOL/@RuntimeVersion', "v#{new_resource.runtime_version}") + is_new_managed_runtime_version = + if new_resource.no_managed_code + new_value?(doc.root, 'APPPOOL/@RuntimeVersion', '') + else + new_value?(doc.root, 'APPPOOL/@RuntimeVersion', "v#{new_resource.runtime_version}") + end is_new_pipeline_mode = new_value?(doc.root, 'APPPOOL/@PipelineMode', new_resource.pipeline_mode) # add items - if iis_version >= '7.0' + if iis_version >= 7.0 is_new_auto_start = new_value?(doc.root, 'APPPOOL/add/@autoStart', new_resource.auto_start.to_s) end - if iis_version > '7.0' + if iis_version > 7.0 is_new_start_mode = new_value?(doc.root, 'APPPOOL/add/@startMode', new_resource.start_mode.to_s) end @@ -153,17 +158,17 @@ def configure # processModel items is_new_max_processes = new_or_empty_value?(doc.root, 'APPPOOL/add/processModel/@maxProcesses', new_resource.max_proc.to_s) is_new_load_user_profile = new_value?(doc.root, 'APPPOOL/add/processModel/@loadUserProfile', new_resource.load_user_profile.to_s) - if iis_version > '7.0' + if iis_version > 7.0 is_new_identity_type = new_value?(doc.root, 'APPPOOL/add/processModel/@identityType', new_resource.pool_identity.to_s) end is_new_user_name = new_or_empty_value?(doc.root, 'APPPOOL/add/processModel/@userName', new_resource.pool_username.to_s) is_new_password = new_or_empty_value?(doc.root, 'APPPOOL/add/processModel/@password', new_resource.pool_password.to_s) - if iis_version > '7.0' + if iis_version > 7.0 is_new_logon_type = new_value?(doc.root, 'APPPOOL/add/processModel/@logonType', new_resource.logon_type.to_s) end is_new_manual_group_membership = new_value?(doc.root, 'APPPOOL/add/processModel/@manualGroupMembership', new_resource.manual_group_membership.to_s) is_new_idle_timeout = new_value?(doc.root, 'APPPOOL/add/processModel/@idleTimeout', new_resource.idle_timeout.to_s) - if iis_version >= '8.5' + if iis_version >= 8.5 is_new_idle_timeout_action = new_value?(doc.root, 'APPPOOL/add/processModel/@idleTimeoutAction', new_resource.idle_timeout_action) end is_new_shutdown_time_limit = new_value?(doc.root, 'APPPOOL/add/processModel/@shutdownTimeLimit', new_resource.shutdown_time_limit.to_s) @@ -189,25 +194,26 @@ def configure is_new_recycle_after_time = new_or_empty_value?(doc.root, 'APPPOOL/add/recycling/periodicRestart/@time', new_resource.recycle_after_time.to_s) is_new_recycle_at_time = new_or_empty_value?(doc.root, "APPPOOL/add/recycling/periodicRestart/schedule/add[@value='#{new_resource.recycle_at_time}']/@value", new_resource.recycle_at_time.to_s) is_new_private_memory = new_or_empty_value?(doc.root, 'APPPOOL/add/recycling/periodicRestart/@privateMemory', new_resource.private_mem.to_s) - is_new_log_event_on_recycle = new_value?(doc.root, 'APPPOOL/add/recycling/@logEventOnRecycle', 'Time, Requests, Schedule, Memory, IsapiUnhealthy, OnDemand, ConfigChange, PrivateMemory') + is_new_virtual_memory = new_or_empty_value?(doc.root, 'APPPOOL/add/recycling/periodicRestart/@memory', new_resource.virtual_mem.to_s) + is_new_log_event_on_recycle = new_or_empty_value?(doc.root, 'APPPOOL/add/recycling/@logEventOnRecycle', new_resource.log_event_on_recycle.to_s) # cpu items is_new_cpu_action = new_value?(doc.root, 'APPPOOL/add/cpu/@action', new_resource.cpu_action.to_s) is_new_cpu_limit = new_value?(doc.root, 'APPPOOL/add/cpu/@limit', new_resource.cpu_limit.to_s) is_new_cpu_smp_affinitized = new_value?(doc.root, 'APPPOOL/add/cpu/@smpAffinitized', new_resource.cpu_smp_affinitized.to_s) is_new_cpu_reset_interval = new_value?(doc.root, 'APPPOOL/add/cpu/@resetInterval', new_resource.cpu_reset_interval.to_s) - is_new_smp_processor_affinity_mask = new_value?(doc.root, 'APPPOOL/add/cpu/@smpProcessorAffinityMask', new_resource.smp_processor_affinity_mask.to_s) - is_new_smp_processor_affinity_mask_2 = new_value?(doc.root, 'APPPOOL/add/cpu/@smpProcessorAffinityMask2', new_resource.smp_processor_affinity_mask_2.to_s) + is_new_smp_processor_affinity_mask = new_value?(doc.root, 'APPPOOL/add/cpu/@smpProcessorAffinityMask', new_resource.smp_processor_affinity_mask.floor) + is_new_smp_processor_affinity_mask_2 = new_value?(doc.root, 'APPPOOL/add/cpu/@smpProcessorAffinityMask2', new_resource.smp_processor_affinity_mask_2.floor) # Application Pool Config @cmd = "#{appcmd(node)} set config /section:applicationPools" # root items - if iis_version >= '7.0' + if iis_version >= 7.0 configure_application_pool(is_new_auto_start, "autoStart:#{new_resource.auto_start}") end - if iis_version >= '7.5' + if iis_version >= 7.5 configure_application_pool(is_new_start_mode, "startMode:#{new_resource.start_mode}") end @@ -217,7 +223,7 @@ def configure configure_application_pool(new_resource.runtime_version && is_new_managed_runtime_version, "managedRuntimeVersion:v#{new_resource.runtime_version}") end configure_application_pool(new_resource.pipeline_mode && is_new_pipeline_mode, "managedPipelineMode:#{new_resource.pipeline_mode}") - configure_application_pool(new_resource.thirty_two_bit && is_new_enable_32_bit_app_on_win_64, "enable32BitAppOnWin64:#{new_resource.thirty_two_bit}") + configure_application_pool(is_new_enable_32_bit_app_on_win_64, "enable32BitAppOnWin64:#{new_resource.thirty_two_bit}") configure_application_pool(new_resource.queue_length && is_new_queue_length, "queueLength:#{new_resource.queue_length}") # processModel items @@ -226,7 +232,7 @@ def configure configure_application_pool(is_new_logon_type, "processModel.logonType:#{new_resource.logon_type}") configure_application_pool(is_new_manual_group_membership, "processModel.manualGroupMembership:#{new_resource.manual_group_membership}") configure_application_pool(is_new_idle_timeout, "processModel.idleTimeout:#{new_resource.idle_timeout}") - if iis_version >= '8.5' + if iis_version >= 8.5 configure_application_pool(is_new_idle_timeout_action, "processModel.idleTimeoutAction:#{new_resource.idle_timeout_action}") end configure_application_pool(is_new_shutdown_time_limit, "processModel.shutdownTimeLimit:#{new_resource.shutdown_time_limit}") @@ -236,7 +242,7 @@ def configure configure_application_pool(is_new_ping_response_time, "processModel.pingResponseTime:#{new_resource.ping_response_time}") node_array = XPath.match(doc.root, 'APPPOOL/add/recycling/periodicRestart/schedule/add') - should_clear_apppool_schedules = (new_resource.recycle_at_time && is_new_recycle_at_time) || node_array.length > 1 + should_clear_apppool_schedules = ((new_resource.recycle_at_time && is_new_recycle_at_time) && !node_array.empty?) || (new_resource.recycle_schedule_clear && !node_array.empty?) # recycling items ## Special case this collection removal for now. @@ -250,8 +256,9 @@ def configure configure_application_pool(new_resource.recycle_after_time && is_new_recycle_after_time, "recycling.periodicRestart.time:#{new_resource.recycle_after_time}") configure_application_pool(new_resource.recycle_at_time && is_new_recycle_at_time, "recycling.periodicRestart.schedule.[value='#{new_resource.recycle_at_time}']", '+') - configure_application_pool(is_new_log_event_on_recycle, 'recycling.logEventOnRecycle:PrivateMemory,Memory,Schedule,Requests,Time,ConfigChange,OnDemand,IsapiUnhealthy') + configure_application_pool(new_resource.log_event_on_recycle && is_new_log_event_on_recycle, "recycling.logEventOnRecycle:#{new_resource.log_event_on_recycle}") configure_application_pool(new_resource.private_mem && is_new_private_memory, "recycling.periodicRestart.privateMemory:#{new_resource.private_mem}") + configure_application_pool(new_resource.virtual_mem && is_new_virtual_memory, "recycling.periodicRestart.memory:#{new_resource.virtual_mem}") configure_application_pool(is_new_disallow_rotation_on_config_change, "recycling.disallowRotationOnConfigChange:#{new_resource.disallow_rotation_on_config_change}") configure_application_pool(is_new_disallow_overlapping_rotation, "recycling.disallowOverlappingRotation:#{new_resource.disallow_overlapping_rotation}") @@ -271,10 +278,10 @@ def configure configure_application_pool(is_new_cpu_limit, "cpu.limit:#{new_resource.cpu_limit}") configure_application_pool(is_new_cpu_reset_interval, "cpu.resetInterval:#{new_resource.cpu_reset_interval}") configure_application_pool(is_new_cpu_smp_affinitized, "cpu.smpAffinitized:#{new_resource.cpu_smp_affinitized}") - configure_application_pool(is_new_smp_processor_affinity_mask, "cpu.smpProcessorAffinityMask:#{new_resource.smp_processor_affinity_mask}") - configure_application_pool(is_new_smp_processor_affinity_mask_2, "cpu.smpProcessorAffinityMask2:#{new_resource.smp_processor_affinity_mask_2}") + configure_application_pool(is_new_smp_processor_affinity_mask, "cpu.smpProcessorAffinityMask:#{new_resource.smp_processor_affinity_mask.floor}") + configure_application_pool(is_new_smp_processor_affinity_mask_2, "cpu.smpProcessorAffinityMask2:#{new_resource.smp_processor_affinity_mask_2.floor}") - if (@cmd != "#{appcmd(node)} set config /section:applicationPools") + if @cmd != "#{appcmd(node)} set config /section:applicationPools" Chef::Log.debug(@cmd) shell_out!(@cmd) end diff --git a/cookbooks/iis/providers/root.rb b/cookbooks/iis/providers/root.rb index 1538b58..3358017 100644 --- a/cookbooks/iis/providers/root.rb +++ b/cookbooks/iis/providers/root.rb @@ -1,9 +1,9 @@ # # Author:: Justin Schuhmann () -# Cookbook Name:: iis +# Cookbook:: iis # Provider:: root # -# Copyright:: Justin Schuhmann +# Copyright:: 2016, Justin Schuhmann # # 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/cookbooks/iis/providers/section.rb b/cookbooks/iis/providers/section.rb index 398f3c3..173ac28 100644 --- a/cookbooks/iis/providers/section.rb +++ b/cookbooks/iis/providers/section.rb @@ -1,9 +1,9 @@ # # Author:: Justin Schuhmann -# Cookbook Name:: iis +# Cookbook:: iis # Resource:: lock # -# Copyright:: Justin Schuhmann +# Copyright:: 2016, Justin Schuhmann # # 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/cookbooks/iis/providers/site.rb b/cookbooks/iis/providers/site.rb index aa2b9e3..5c8ebbf 100644 --- a/cookbooks/iis/providers/site.rb +++ b/cookbooks/iis/providers/site.rb @@ -1,9 +1,9 @@ # # Author:: Seth Chisamore () -# Cookbook Name:: iis +# Cookbook:: iis # Provider:: site # -# Copyright:: 2011, Chef Software, Inc. +# Copyright:: 2011-2016, 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. @@ -46,7 +46,7 @@ action :add do configure if new_resource.application_pool - shell_out!("#{appcmd(node)} set app \"#{new_resource.site_name}/\" /applicationPool:\"#{new_resource.application_pool}\"", returns: [0, 42]) + shell_out!("#{appcmd(node)} set site /site.name:\"#{new_resource.site_name}\" /[path='/'].applicationPool:\"#{new_resource.application_pool}\"", returns: [0, 42]) end new_resource.updated_by_last_action(true) Chef::Log.info("#{new_resource} added new site '#{new_resource.site_name}'") @@ -114,7 +114,7 @@ def load_current_resource @current_resource.site_id(result[2].to_i) @current_resource.exists = true @current_resource.bindings(result[3]) - @current_resource.running = (result[4] =~ /Started/) ? true : false + @current_resource.running = result[4] =~ /Started/ ? true : false else @current_resource.exists = false @current_resource.running = false @@ -140,9 +140,9 @@ def configure is_new_physical_path = new_or_empty_value?(doc.root, 'SITE/site/application/virtualDirectory/@physicalPath', new_resource.path.to_s) is_new_port_host_provided = !"#{XPath.first(doc.root, 'SITE/@bindings')},".include?("#{new_resource.protocol}/*:#{new_resource.port}:#{new_resource.host_header},") is_new_site_id = new_value?(doc.root, 'SITE/site/@id', new_resource.site_id.to_s) - is_new_log_directory = new_or_empty_value?(doc.root, 'SITE/logFiles/@directory', new_resource.log_directory.to_s) - is_new_log_period = new_or_empty_value?(doc.root, 'SITE/logFile/@period', new_resource.log_period.to_s) - is_new_log_trunc = new_or_empty_value?(doc.root, 'SITE/logFiles/@truncateSize', new_resource.log_truncsize.to_s) + is_new_log_directory = new_or_empty_value?(doc.root, 'SITE/site/logFile/@directory', new_resource.log_directory.to_s) + is_new_log_period = new_or_empty_value?(doc.root, 'SITE/site/logFile/@period', new_resource.log_period.to_s) + is_new_log_trunc = new_or_empty_value?(doc.root, 'SITE/site/logFile/@truncateSize', new_resource.log_truncsize.to_s) is_new_application_pool = new_value?(doc.root, 'SITE/site/application/@applicationPool', new_resource.application_pool) if new_resource.bindings && is_new_bindings diff --git a/cookbooks/iis/providers/vdir.rb b/cookbooks/iis/providers/vdir.rb index 908b543..bcb24f1 100644 --- a/cookbooks/iis/providers/vdir.rb +++ b/cookbooks/iis/providers/vdir.rb @@ -1,9 +1,9 @@ # # Author:: Justin Schuhmann () -# Cookbook Name:: iis +# Cookbook:: iis # Provider:: site # -# Copyright:: Justin Schuhmann +# Copyright:: 2016, Justin Schuhmann # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -35,7 +35,7 @@ action :add do cmd << " /password:\"#{new_resource.password}\"" if new_resource.password cmd << " /logonMethod:#{new_resource.logon_method}" if new_resource.logon_method cmd << " /allowSubDirConfig:#{new_resource.allow_sub_dir_config}" if new_resource.allow_sub_dir_config - cmd << " /commit:\"MACHINE/WEBROOT/APPHOST\"" + cmd << ' /commit:\"MACHINE/WEBROOT/APPHOST\"' Chef::Log.info(cmd) shell_out!(cmd, returns: [0, 42, 183]) @@ -130,11 +130,7 @@ def load_current_resource # VDIR "Testfu Site/Content/Test" result = cmd.stdout.match(/^VDIR\s\"#{Regexp.escape(application_identifier)}\"/) Chef::Log.debug("#{new_resource} current_resource match output: #{result}") - if result - @current_resource.exists = true - else - @current_resource.exists = false - end + @current_resource.exists = result else log "Failed to run iis_vdir action :load_current_resource, #{cmd_current_values.stderr}" do level :warn @@ -153,5 +149,7 @@ def application_name_check new_resource.application_name("#{new_resource.application_name}/") elsif new_resource.application_name.chomp('/').include?('/') && new_resource.application_name.end_with?('/') new_resource.application_name(new_resource.application_name.chomp('/')) + else + new_resource.application_name end end diff --git a/cookbooks/iis/recipes/default.rb b/cookbooks/iis/recipes/default.rb index 710f05a..839f8c5 100644 --- a/cookbooks/iis/recipes/default.rb +++ b/cookbooks/iis/recipes/default.rb @@ -1,9 +1,9 @@ # # Author:: Seth Chisamore () -# Cookbook Name:: iis +# Cookbook:: iis # Recipe:: default # -# Copyright 2011, Chef Software, Inc. +# Copyright:: 2011-2016, 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. @@ -21,7 +21,7 @@ # Always add this, so that we don't require this to be added if we want to add other components default = Opscode::IIS::Helper.older_than_windows2008r2? ? 'Web-Server' : 'IIS-WebServerRole' -(node['iis']['components'] + [default]).each do |feature| +([default] + node['iis']['components']).each do |feature| windows_feature feature do action :install all !Opscode::IIS::Helper.older_than_windows2012? diff --git a/cookbooks/iis/recipes/mod_application_initialization.rb b/cookbooks/iis/recipes/mod_application_initialization.rb index b9c05cb..24b392e 100644 --- a/cookbooks/iis/recipes/mod_application_initialization.rb +++ b/cookbooks/iis/recipes/mod_application_initialization.rb @@ -1,9 +1,9 @@ # # Author:: Seth Chisamore () -# Cookbook Name:: iis +# Cookbook:: iis # Recipe:: mod_application_initialization # -# Copyright 2011, Chef Software, Inc. +# Copyright:: 2011-2016, 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/cookbooks/iis/recipes/mod_aspnet.rb b/cookbooks/iis/recipes/mod_aspnet.rb index 403a16f..06fa308 100644 --- a/cookbooks/iis/recipes/mod_aspnet.rb +++ b/cookbooks/iis/recipes/mod_aspnet.rb @@ -1,9 +1,9 @@ # # Author:: Seth Chisamore () -# Cookbook Name:: iis +# Cookbook:: iis # Recipe:: mod_aspnet # -# Copyright 2011, Chef Software, Inc. +# Copyright:: 2011-2016, 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. @@ -21,14 +21,16 @@ include_recipe 'iis' include_recipe 'iis::mod_isapi' -if Opscode::IIS::Helper.older_than_windows2008r2? - features = %w(NET-Framework) -else - features = %w(IIS-NetFxExtensibility IIS-ASPNET) -end +features = if Opscode::IIS::Helper.older_than_windows2008r2? + %w(NET-Framework) + else + %w(IIS-NetFxExtensibility IIS-ASPNET) + end features.each do |feature| windows_feature feature do action :install + all !Opscode::IIS::Helper.older_than_windows2012? + source node['iis']['source'] unless node['iis']['source'].nil? end end diff --git a/cookbooks/iis/recipes/mod_aspnet45.rb b/cookbooks/iis/recipes/mod_aspnet45.rb index 92c0f0d..b12bd77 100644 --- a/cookbooks/iis/recipes/mod_aspnet45.rb +++ b/cookbooks/iis/recipes/mod_aspnet45.rb @@ -1,9 +1,9 @@ # # Author:: Blair Hamilton () -# Cookbook Name:: iis +# Cookbook:: iis # Recipe:: mod_aspnet45 # -# Copyright 2011, Chef Software, Inc. +# Copyright:: 2011-2016, 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. @@ -21,11 +21,11 @@ include_recipe 'iis' include_recipe 'iis::mod_isapi' -if Opscode::IIS::Helper.older_than_windows2008r2? - features = %w(NET-Framework) -else - features = %w(NetFx4Extended-ASPNET45 IIS-NetFxExtensibility45 IIS-ASPNET45) -end +features = if Opscode::IIS::Helper.older_than_windows2008r2? + %w(NET-Framework) + else + %w(NetFx4Extended-ASPNET45 IIS-NetFxExtensibility45 IIS-ASPNET45) + end features.each do |feature| windows_feature feature do diff --git a/cookbooks/iis/recipes/mod_auth_anonymous.rb b/cookbooks/iis/recipes/mod_auth_anonymous.rb index cc909c9..55c6657 100644 --- a/cookbooks/iis/recipes/mod_auth_anonymous.rb +++ b/cookbooks/iis/recipes/mod_auth_anonymous.rb @@ -1,9 +1,9 @@ # # Author:: Justin Schuhmann -# Cookbook Name:: iis +# Cookbook:: iis # Recipe:: mod_auth_basic # -# Copyright:: Justin Schuhmann +# Copyright:: 2016, Justin Schuhmann # # 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/cookbooks/iis/recipes/mod_auth_basic.rb b/cookbooks/iis/recipes/mod_auth_basic.rb index 68bf16a..41bb4b8 100644 --- a/cookbooks/iis/recipes/mod_auth_basic.rb +++ b/cookbooks/iis/recipes/mod_auth_basic.rb @@ -1,9 +1,9 @@ # # Author:: Seth Chisamore () -# Cookbook Name:: iis +# Cookbook:: iis # Recipe:: mod_auth_basic # -# Copyright:: Copyright (c) 2011 Chef Software, Inc. +# Copyright:: 2011-2016, 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. @@ -20,11 +20,11 @@ include_recipe 'iis' -if Opscode::IIS::Helper.older_than_windows2008r2? - feature = 'Web-Basic-Auth' -else - feature = 'IIS-BasicAuthentication' -end +feature = if Opscode::IIS::Helper.older_than_windows2008r2? + 'Web-Basic-Auth' + else + 'IIS-BasicAuthentication' + end windows_feature feature do action :install diff --git a/cookbooks/iis/recipes/mod_auth_digest.rb b/cookbooks/iis/recipes/mod_auth_digest.rb index e7ce189..53e06b5 100644 --- a/cookbooks/iis/recipes/mod_auth_digest.rb +++ b/cookbooks/iis/recipes/mod_auth_digest.rb @@ -1,9 +1,9 @@ # # Author:: Justin Schuhmann -# Cookbook Name:: iis +# Cookbook:: iis # Recipe:: mod_auth_basic # -# Copyright:: Justin Schuhmann +# Copyright:: 2016, Justin Schuhmann # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -20,11 +20,11 @@ include_recipe 'iis' -if Opscode::IIS::Helper.older_than_windows2008r2? - feature = 'Web-Digest-Auth' -else - feature = 'IIS-DigestAuthentication' -end +feature = if Opscode::IIS::Helper.older_than_windows2008r2? + 'Web-Digest-Auth' + else + 'IIS-DigestAuthentication' + end windows_feature feature do action :install diff --git a/cookbooks/iis/recipes/mod_auth_windows.rb b/cookbooks/iis/recipes/mod_auth_windows.rb index bb89d79..2f58008 100644 --- a/cookbooks/iis/recipes/mod_auth_windows.rb +++ b/cookbooks/iis/recipes/mod_auth_windows.rb @@ -1,9 +1,9 @@ # # Author:: Seth Chisamore () -# Cookbook Name:: iis +# Cookbook:: iis # Recipe:: mod_auth_windows # -# Copyright 2011, Chef Software, Inc. +# Copyright:: 2011-2016, 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. @@ -20,11 +20,11 @@ include_recipe 'iis' -if Opscode::IIS::Helper.older_than_windows2008r2? - feature = 'Web-Windows-Auth' -else - feature = 'IIS-WindowsAuthentication' -end +feature = if Opscode::IIS::Helper.older_than_windows2008r2? + 'Web-Windows-Auth' + else + 'IIS-WindowsAuthentication' + end windows_feature feature do action :install diff --git a/cookbooks/iis/recipes/mod_cgi.rb b/cookbooks/iis/recipes/mod_cgi.rb index f10f300..54d884f 100644 --- a/cookbooks/iis/recipes/mod_cgi.rb +++ b/cookbooks/iis/recipes/mod_cgi.rb @@ -1,9 +1,9 @@ # # Author:: Richard Downer () -# Cookbook Name:: iis +# Cookbook:: iis # Recipe:: mod_cgi # -# Copyright 2013, Cloudsoft Corporation +# Copyright:: 2013-2016, Cloudsoft Corporation # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -20,11 +20,11 @@ include_recipe 'iis' -if Opscode::IIS::Helper.older_than_windows2008r2? - feature = 'Web-CGI' -else - feature = 'IIS-CGI' -end +feature = if Opscode::IIS::Helper.older_than_windows2008r2? + 'Web-CGI' + else + 'IIS-CGI' + end windows_feature feature do action :install diff --git a/cookbooks/iis/recipes/mod_compress_dynamic.rb b/cookbooks/iis/recipes/mod_compress_dynamic.rb index 4603b79..09d41c3 100644 --- a/cookbooks/iis/recipes/mod_compress_dynamic.rb +++ b/cookbooks/iis/recipes/mod_compress_dynamic.rb @@ -1,9 +1,9 @@ # # Author:: Seth Chisamore () -# Cookbook Name:: iis +# Cookbook:: iis # Recipe:: mod_compress_dynamic # -# Copyright 2011, Chef Software, Inc. +# Copyright:: 2011-2016, 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. @@ -20,11 +20,11 @@ include_recipe 'iis' -if Opscode::IIS::Helper.older_than_windows2008r2? - feature = 'Web-Dyn-Compression' -else - feature = 'IIS-HttpCompressionDynamic' -end +feature = if Opscode::IIS::Helper.older_than_windows2008r2? + 'Web-Dyn-Compression' + else + 'IIS-HttpCompressionDynamic' + end windows_feature feature do action :install diff --git a/cookbooks/iis/recipes/mod_compress_static.rb b/cookbooks/iis/recipes/mod_compress_static.rb index a5a99a2..dc02885 100644 --- a/cookbooks/iis/recipes/mod_compress_static.rb +++ b/cookbooks/iis/recipes/mod_compress_static.rb @@ -1,9 +1,9 @@ # # Author:: Seth Chisamore () -# Cookbook Name:: iis +# Cookbook:: iis # Recipe:: mod_compress_static # -# Copyright 2011, Chef Software, Inc. +# Copyright:: 2011-2016, 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. @@ -20,11 +20,11 @@ include_recipe 'iis' -if Opscode::IIS::Helper.older_than_windows2008r2? - feature = 'Web-Stat-Compression' -else - feature = 'IIS-HttpCompressionStatic' -end +feature = if Opscode::IIS::Helper.older_than_windows2008r2? + 'Web-Stat-Compression' + else + 'IIS-HttpCompressionStatic' + end windows_feature feature do action :install diff --git a/cookbooks/iis/recipes/mod_ftp.rb b/cookbooks/iis/recipes/mod_ftp.rb index aa176c8..de88989 100644 --- a/cookbooks/iis/recipes/mod_ftp.rb +++ b/cookbooks/iis/recipes/mod_ftp.rb @@ -1,9 +1,9 @@ # # Author:: Kevin Rivers () -# Cookbook Name:: iis +# Cookbook:: iis # Recipe:: mod_ftp # -# Copyright 2014, Kevin Rivers +# Copyright:: 2014-2016, Kevin Rivers # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -20,11 +20,11 @@ include_recipe 'iis' -if Opscode::IIS::Helper.older_than_windows2008r2? - features = %w(Web-Ftp-Server Web-Ftp-Service Web-Ftp-Ext) -else - features = %w(IIS-FTPServer IIS-FTPSvc IIS-FTPExtensibility) -end +features = if Opscode::IIS::Helper.older_than_windows2008r2? + %w(Web-Ftp-Server Web-Ftp-Service Web-Ftp-Ext) + else + %w(IIS-FTPServer IIS-FTPSvc IIS-FTPExtensibility) + end features.each do |f| windows_feature f do diff --git a/cookbooks/iis/recipes/mod_iis6_metabase_compat.rb b/cookbooks/iis/recipes/mod_iis6_metabase_compat.rb index 698fe8b..459fbe5 100644 --- a/cookbooks/iis/recipes/mod_iis6_metabase_compat.rb +++ b/cookbooks/iis/recipes/mod_iis6_metabase_compat.rb @@ -1,9 +1,9 @@ # # Author:: Kristian Vlaardingerbroek () -# Cookbook Name:: iis +# Cookbook:: iis # Recipe:: mod_iis6_metabase_compat # -# Copyright 2013, Schuberg Philis B.V. +# Copyright:: 2013-2016, Schuberg Philis B.V. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -20,11 +20,11 @@ include_recipe 'iis' -if Opscode::IIS::Helper.older_than_windows2008r2? - features = %w(Web-Mgmt-Compat Web-Metabase) -else - features = %w(IIS-IIS6ManagementCompatibility IIS-Metabase) -end +features = if Opscode::IIS::Helper.older_than_windows2008r2? + %w(Web-Mgmt-Compat Web-Metabase) + else + %w(IIS-IIS6ManagementCompatibility IIS-Metabase) + end features.each do |f| windows_feature f do diff --git a/cookbooks/iis/recipes/mod_isapi.rb b/cookbooks/iis/recipes/mod_isapi.rb index 9bb2249..e95edad 100644 --- a/cookbooks/iis/recipes/mod_isapi.rb +++ b/cookbooks/iis/recipes/mod_isapi.rb @@ -1,9 +1,9 @@ # # Author:: Seth Chisamore () -# Cookbook Name:: iis +# Cookbook:: iis # Recipe:: mod_isapi # -# Copyright 2011, Chef Software, Inc. +# Copyright:: 2011-2016, 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. @@ -20,11 +20,11 @@ include_recipe 'iis' -if Opscode::IIS::Helper.older_than_windows2008r2? - features = %w(Web-ISAPI-Filter Web-ISAPI-Ext) -else - features = %w(IIS-ISAPIFilter IIS-ISAPIExtensions) -end +features = if Opscode::IIS::Helper.older_than_windows2008r2? + %w(Web-ISAPI-Filter Web-ISAPI-Ext) + else + %w(IIS-ISAPIFilter IIS-ISAPIExtensions) + end features.each do |feature| windows_feature feature do diff --git a/cookbooks/iis/recipes/mod_logging.rb b/cookbooks/iis/recipes/mod_logging.rb index 21a1b92..a2cacf7 100644 --- a/cookbooks/iis/recipes/mod_logging.rb +++ b/cookbooks/iis/recipes/mod_logging.rb @@ -1,9 +1,9 @@ # # Author:: Seth Chisamore () -# Cookbook Name:: iis +# Cookbook:: iis # Recipe:: mod_logging # -# Copyright 2011, Chef Software, Inc. +# Copyright:: 2011-2016, 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. @@ -20,11 +20,11 @@ include_recipe 'iis' -if Opscode::IIS::Helper.older_than_windows2008r2? - feature = 'Web-Http-Logging' -else - feature = 'IIS-CustomLogging' -end +feature = if Opscode::IIS::Helper.older_than_windows2008r2? + 'Web-Http-Logging' + else + 'IIS-CustomLogging' + end windows_feature feature do action :install diff --git a/cookbooks/iis/recipes/mod_management.rb b/cookbooks/iis/recipes/mod_management.rb index ee98a87..659eda9 100644 --- a/cookbooks/iis/recipes/mod_management.rb +++ b/cookbooks/iis/recipes/mod_management.rb @@ -1,9 +1,9 @@ # # Author:: Seth Chisamore () -# Cookbook Name:: iis +# Cookbook:: iis # Recipe:: mod_management # -# Copyright 2011, Chef Software, Inc. +# Copyright:: 2011-2016, 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. @@ -20,14 +20,15 @@ include_recipe 'iis' -if Opscode::IIS::Helper.older_than_windows2008r2? - features = %w(Web-Mgmt-Console Web-Mgmt-Service) -else - features = %w(IIS-ManagementConsole IIS-ManagementService) -end +features = if Opscode::IIS::Helper.older_than_windows2008r2? + %w(Web-Mgmt-Console Web-Mgmt-Service) + else + %w(IIS-ManagementConsole IIS-ManagementService) + end features.each do |feature| windows_feature feature do action :install + all !Opscode::IIS::Helper.older_than_windows2012? end end diff --git a/cookbooks/iis/recipes/mod_security.rb b/cookbooks/iis/recipes/mod_security.rb index 37d7b40..8ed8695 100644 --- a/cookbooks/iis/recipes/mod_security.rb +++ b/cookbooks/iis/recipes/mod_security.rb @@ -1,9 +1,9 @@ # # Author:: Seth Chisamore () -# Cookbook Name:: iis +# Cookbook:: iis # Recipe:: mod_security # -# Copyright 2011, Chef Software, Inc. +# Copyright:: 2011-2016, 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. @@ -20,11 +20,11 @@ include_recipe 'iis' -if Opscode::IIS::Helper.older_than_windows2008r2? - features = %w(Web-Url-Auth Web-Filtering Web-IP-Security) -else - features = %w(IIS-URLAuthorization IIS-RequestFiltering IIS-IPSecurity) -end +features = if Opscode::IIS::Helper.older_than_windows2008r2? + %w(Web-Url-Auth Web-Filtering Web-IP-Security) + else + %w(IIS-URLAuthorization IIS-RequestFiltering IIS-IPSecurity) + end features.each do |feature| windows_feature feature do diff --git a/cookbooks/iis/recipes/mod_tracing.rb b/cookbooks/iis/recipes/mod_tracing.rb index 54a7168..594c492 100644 --- a/cookbooks/iis/recipes/mod_tracing.rb +++ b/cookbooks/iis/recipes/mod_tracing.rb @@ -1,9 +1,9 @@ # # Author:: Seth Chisamore () -# Cookbook Name:: iis +# Cookbook:: iis # Recipe:: mod_diagnostics # -# Copyright 2011, Chef Software, Inc. +# Copyright:: 2011-2016, 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. @@ -20,11 +20,11 @@ include_recipe 'iis' -if Opscode::IIS::Helper.older_than_windows2008r2? - feature = 'Web-Http-Tracing' -else - feature = 'IIS-HTTPTracing' -end +feature = if Opscode::IIS::Helper.older_than_windows2008r2? + 'Web-Http-Tracing' + else + 'IIS-HTTPTracing' + end windows_feature feature do action :install diff --git a/cookbooks/iis/recipes/remove_default_site.rb b/cookbooks/iis/recipes/remove_default_site.rb index 606f057..ed8aada 100644 --- a/cookbooks/iis/recipes/remove_default_site.rb +++ b/cookbooks/iis/recipes/remove_default_site.rb @@ -1,9 +1,9 @@ # # Author:: Kendrick Martin () -# Cookbook Name:: iis +# Cookbook:: iis # Recipe:: remove_default_site # -# Copyright 2012, Webtrends, Inc. +# Copyright:: 2012-2016, Webtrends, 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/cookbooks/iis/resources/app.rb b/cookbooks/iis/resources/app.rb index c51a85f..4382662 100644 --- a/cookbooks/iis/resources/app.rb +++ b/cookbooks/iis/resources/app.rb @@ -1,9 +1,9 @@ # # Author:: Kendrick Martin (kendrick.martin@webtrends.com>) -# Cookbook Name:: iis +# Cookbook:: iis # Resource:: app # -# Copyright:: 2011, Webtrends Inc. +# Copyright:: 2011-2016, Webtrends 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/cookbooks/iis/resources/config.rb b/cookbooks/iis/resources/config.rb index 6351f3b..d7a3e65 100644 --- a/cookbooks/iis/resources/config.rb +++ b/cookbooks/iis/resources/config.rb @@ -1,9 +1,9 @@ # # Author:: Kendrick Martin (kendrick.martin@webtrends.com) -# Cookbook Name:: iis +# Cookbook:: iis # Resource:: config # -# Copyright:: 2011, Webtrends Inc. +# Copyright:: 2011-2016, Webtrends 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/cookbooks/iis/resources/module.rb b/cookbooks/iis/resources/module.rb index b5b26f5..2d5c5d5 100644 --- a/cookbooks/iis/resources/module.rb +++ b/cookbooks/iis/resources/module.rb @@ -1,9 +1,9 @@ # # Author:: Jon DeCamp () -# Cookbook Name:: iis +# Cookbook:: iis # Resource:: module # -# Copyright:: 2012, Nordstrom, Inc. +# Copyright:: 2012-2016, Nordstrom, 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/cookbooks/iis/resources/pool.rb b/cookbooks/iis/resources/pool.rb index 9c02161..d2ed780 100644 --- a/cookbooks/iis/resources/pool.rb +++ b/cookbooks/iis/resources/pool.rb @@ -1,10 +1,10 @@ # # Author:: Kendrick Martin (kendrick.martin@webtrends.com>) # Contributor:: David Dvorak (david.dvorak@webtrends.com) -# Cookbook Name:: iis +# Cookbook:: iis # Resource:: pool # -# Copyright:: 2011, Webtrends Inc. +# Copyright:: 2011-2016, Webtrends Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -53,9 +53,12 @@ attribute :ping_response_time, kind_of: String, default: '00:01:30' # recycling items attribute :disallow_rotation_on_config_change, kind_of: [TrueClass, FalseClass], default: false attribute :disallow_overlapping_rotation, kind_of: [TrueClass, FalseClass], default: false +attribute :recycle_schedule_clear, kind_of: [TrueClass, FalseClass], default: false +attribute :log_event_on_recycle, kind_of: String, default: node['iis']['recycle']['log_events'] attribute :recycle_after_time, kind_of: String attribute :recycle_at_time, kind_of: String attribute :private_mem, kind_of: Integer +attribute :virtual_mem, kind_of: Integer # failure items attribute :load_balancer_capabilities, kind_of: Symbol, equal_to: [:HttpLevel, :TcpLevel], default: :HttpLevel @@ -73,7 +76,7 @@ attribute :cpu_action, kind_of: Symbol, equal_to: [:NoAction, :KillW3wp, :Thrott attribute :cpu_limit, kind_of: Integer, default: 0 attribute :cpu_reset_interval, kind_of: String, default: '00:05:00' attribute :cpu_smp_affinitized, kind_of: [TrueClass, FalseClass], default: false -attribute :smp_processor_affinity_mask, kind_of: Bignum, default: 4_294_967_295 -attribute :smp_processor_affinity_mask_2, kind_of: Bignum, default: 4_294_967_295 +attribute :smp_processor_affinity_mask, kind_of: Float, default: 4_294_967_295.0 +attribute :smp_processor_affinity_mask_2, kind_of: Float, default: 4_294_967_295.0 attr_accessor :exists, :running diff --git a/cookbooks/iis/resources/root.rb b/cookbooks/iis/resources/root.rb index 0ca1ce9..9fe4fc0 100644 --- a/cookbooks/iis/resources/root.rb +++ b/cookbooks/iis/resources/root.rb @@ -1,9 +1,9 @@ # # Author:: Justin Schuhmann () -# Cookbook Name:: iis +# Cookbook:: iis # Resource:: root # -# Copyright:: Justin Schuhmann +# Copyright:: 2016, Justin Schuhmann # # 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/cookbooks/iis/resources/section.rb b/cookbooks/iis/resources/section.rb index 7d57614..e7e6a03 100644 --- a/cookbooks/iis/resources/section.rb +++ b/cookbooks/iis/resources/section.rb @@ -1,9 +1,9 @@ # # Author:: Justin Schuhmann -# Cookbook Name:: iis +# Cookbook:: iis # Resource:: lock # -# Copyright:: Justin Schuhmann +# Copyright:: 2016, Justin Schuhmann # # 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/cookbooks/iis/resources/site.rb b/cookbooks/iis/resources/site.rb index 4353063..69a8914 100644 --- a/cookbooks/iis/resources/site.rb +++ b/cookbooks/iis/resources/site.rb @@ -1,9 +1,9 @@ # # Author:: Seth Chisamore () -# Cookbook Name:: iis +# Cookbook:: iis # Resource:: site # -# Copyright:: 2011, Chef Software, Inc. +# Copyright:: 2011-2016, 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/cookbooks/iis/resources/vdir.rb b/cookbooks/iis/resources/vdir.rb index 980f55d..913d16b 100644 --- a/cookbooks/iis/resources/vdir.rb +++ b/cookbooks/iis/resources/vdir.rb @@ -1,9 +1,9 @@ # # Author:: Justin Schuhmann () -# Cookbook Name:: iis +# Cookbook:: iis # Resource:: site # -# Copyright:: Justin Schuhmann +# Copyright:: 2016, Justin Schuhmann # # 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/cookbooks/mingw/.foodcritic b/cookbooks/mingw/.foodcritic new file mode 100644 index 0000000..b9f8767 --- /dev/null +++ b/cookbooks/mingw/.foodcritic @@ -0,0 +1 @@ +~FC016 diff --git a/cookbooks/mingw/CHANGELOG.md b/cookbooks/mingw/CHANGELOG.md new file mode 100644 index 0000000..dd81178 --- /dev/null +++ b/cookbooks/mingw/CHANGELOG.md @@ -0,0 +1,44 @@ +# mingw Cookbook CHANGELOG + +This file is used to list changes made in each version of the mingw cookbook. + +## 2.0.0 (2017-02-27) + +- Require Chef 12.5 and remove compat_resource dependency + +## 1.2.5 (2017-01-18) + +- Require a working compat_resource + +## v1.2.4 (2016-07-26) + +- New msys2 shells do not inherit PATH from windows. Provide a way for + clients to do this. + +## v1.2.3 (2016-07-25) + +- If PKG_CONFIG_PATH is already defined, honor it in the msys2 shell. + +## v1.2.2 (2016-06-24) + +- Download msys2 from the primary download url (instead of a specific mirror). + +## v1.2.1 (2016-06-23) + +- Fix msys2 initial install/upgrade steps that dependended on file modification time. +- Make msys2_package :install idempotent - it should not reinstall packages. +- Do not allow bash.exe to be called if MSYSTEM is undefined. + +## v1.2.0 (2016-06-03) +- Updating to fix the issue where msys2 bash does not inherit the cwd correctly + +## v1.1.0 (2016-06-03) +- Add msys2 based compiler support using the new msys2_package resource + +## v1.0.0 (2016-05-11) + +- Remove unnecessary default_action from the resources +- Depend on compat_resource cookbook to add Chef 12.1 - 12.4 compatbility +- Add this changelog file +- Fix license metadata in metadata.rb +- Disable FC016 check diff --git a/cookbooks/mingw/CONTRIBUTING.md b/cookbooks/mingw/CONTRIBUTING.md new file mode 100644 index 0000000..ef2f2b8 --- /dev/null +++ b/cookbooks/mingw/CONTRIBUTING.md @@ -0,0 +1,2 @@ +Please refer to +https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD diff --git a/cookbooks/mingw/MAINTAINERS.md b/cookbooks/mingw/MAINTAINERS.md new file mode 100644 index 0000000..873629f --- /dev/null +++ b/cookbooks/mingw/MAINTAINERS.md @@ -0,0 +1,17 @@ + + +# Maintainers +This file lists how this cookbook project is maintained. When making changes to the system, this +file tells you who needs to review your patch - you need a simple majority of maintainers +for the relevant subsystems to provide a :+1: on your pull request. Additionally, you need +to not receive a veto from a Lieutenant or the Project Lead. + +Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) +for details on the process and how to become a maintainer or the project lead. + +# Project Maintainer +* [Kartik Null Cating-Subramanian](https://github.com/ksubrama) + +# Maintainers +* [Kartik Null Cating-Subramanian](https://github.com/ksubrama) +* [Seth Chisamore](https://github.com/schisamo) diff --git a/cookbooks/mingw/README.md b/cookbooks/mingw/README.md new file mode 100644 index 0000000..e111adc --- /dev/null +++ b/cookbooks/mingw/README.md @@ -0,0 +1,133 @@ +# mingw Cookbook + +[![Cookbook Version](http://img.shields.io/cookbook/v/mingw.svg)][cookbook] [![Build Status](http://img.shields.io/travis/chef-cookbooks/mingw.svg?branch=master)][travis] + +Installs a mingw/msys based compiler tools chain on windows. This is required for compiling C software from source. + +## Requirements + +### Platforms + +- Windows + +### Chef + +- Chef 12.5+ + +### Cookbooks + +- seven_zip + +## Usage + +Add this cookbook as a dependency to your cookbook in its `metadata.rb` and include the default recipe in one of your recipes. + +```ruby +# metadata.rb +depends 'mingw' +``` + +```ruby +# your recipe.rb +include_recipe 'mingw::default' +``` + +Use the `msys2_package` resource in any recipe to fetch msys2 based packages. Use the `mingw_get` resource in any recipe to fetch mingw packages. Use the `mingw_tdm_gcc` resource to fetch a version of the TDM GCC compiler. + +By default, you should prefer the msys2 packages as they are newer and better supported. C/C++ compilers on windows use various different exception formats and you need to pick the right one for your task. In the 32-bit world, you have SJLJ (set-jump/long-jump) based exception handling and DWARF-2 (shortened to DW2) based exception handling. SJLJ produces code that can happily throw exceptions across stack frames of code compiled by MSVC. DW2 involves more extensive metadata but produces code that cannot unwind MSVC generated stack-frames - hence you need to ensure that you don't have any code that throws across a "system call". Certain languages and runtimes have specific requirements as to the exception format supported. As an example, if you are building code for Rust, you will probably need a modern gcc from msys2 with DW2 support as that's what the panic/exception formatter in Rust depends on. In a 64-bit world, you may still use SJLJ but compilers all commonly support SEH (structured exception handling). + +Of course, to further complicate matters, different versions of different compilers support different exception handling. The default compilers that come with mingw_get are 32-bit only compilers and support DW2\. The TDM compilers come in 3 flavors: a 32-bit only version with SJLJ support, a 32-bit only version with DW2 support and a "multilib" compiler which supports only SJLJ in 32-bit mode but can produce 64-bit SEH code. The standard library support varies drastically between these various compiler flavors (even within the same version). In msys2, you can install a mingw-w64 based compilers for either 32-bit DW2 support or 64-bit SEH support. If all this hurts your brain, I can only apologize. + +## Resources + +### msys2_package + +- ':install' - Installs an msys2 package using pacman. +- ':remove' - Uninstalls any existing msys2 package. +- ':upgrade' - Upgrades the specified package using pacman. + +All options also automatically attempt to install a 64-bit based msys2 base file system at the root path specified. Note that you probably won't need a "32-bit" msys2 unless you are actually on a 32-bit only platform. You can still install both 32 and 64-bit compilers and libraries in a 64-bit msys2 base file system. + +#### Parameters + +- `package` - An msys2 pacman package (or meta-package) to fetch and install. You may use a legal package wild-card pattern here if you are installing. This is the name attribute. +- `root` - The root directory where msys2 tools will be installed. This directory must not contain any spaces in order to pacify old posix tools and most Makefiles. + +#### Examples + +To get the core msys2 developer tools in `C:\msys2` + +```ruby +msys2_package 'base-devel' do + root 'C:\msys2' +end +``` + +### mingw_get + +#### Actions + +- `:install` - Installs a mingw package from sourceforge using mingw-get.exe. +- `:remove` - Uninstalls a mingw package. +- `:upgrade` - Upgrades a mingw package (even to a lower version). + +#### Parameters + +- `package` - A mingw-get package (or meta-package) to fetch and install. You may use a legal package wild-card pattern here if you are installing. This is the name attribute. +- `root` - The root directory where msys and mingw tools will be installed. This directory must not contain any spaces in order to pacify old posix tools and most Makefiles. + +#### Examples + +To get the core msys developer tools in `C:\mingw32` + +```ruby +mingw_get 'msys-base=2013072300-msys-bin.meta' do + root 'C:\mingw32' +end +``` + +### mingw_tdm_gcc + +#### Actions + +- `:install` - Installs the TDM compiler toolchain at the given path. This only gives you a compiler. If you need any support tooling such as make/grep/awk/bash etc., see `mingw_get`. + +#### Parameters + +- `flavor` - Either `:sjlj_32` or `:seh_sjlj_64`. TDM-64 is a 32/64-bit multi-lib "cross-compiler" toolchain that builds 64-bit by default. It uses structured exception handling (SEH) in 64-bit code and setjump-longjump exception handling (SJLJ) in 32-bit code. TDM-32 only builds 32-bit binaries and uses SJLJ. +- `root` - The root directory where compiler tools and runtime will be installed. This directory must not contain any spaces in order to pacify old posix tools and most Makefiles. +- `version` - The version of the compiler to fetch and install. This is the name attribute. Currently, '5.1.0' is supported. + +#### Examples + +To get the 32-bit TDM GCC compiler in `C:\mingw32` + +```ruby +mingw_tdm_gcc '5.1.0' do + flavor :sjlj_32 + root 'C:\mingw32' +end +``` + +## License & Authors + +**Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io)) + +**Copyright:** 2009-2016, 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. +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. +``` + +[cookbook]: https://supermarket.chef.io/cookbooks/mingw +[travis]: http://travis-ci.org/chef-cookbooks/mingw diff --git a/cookbooks/mingw/files/default/bash.bat b/cookbooks/mingw/files/default/bash.bat new file mode 100644 index 0000000..97a7f99 --- /dev/null +++ b/cookbooks/mingw/files/default/bash.bat @@ -0,0 +1,17 @@ +@echo off +set HOME=/home/%USERNAME% + +IF "%MSYSTEM%"=="" ( + echo MSYSTEM is NOT defined + exit +) + +rem Ask MSYS to initialize with a minimal path by default. +rem This will put only the windows system paths into the msys path. +set MSYS2_PATH_TYPE=minimal + +rem See /etc/profile - it should invoke post-install step 05-home-dir.post +rem which uses this environment variable to change directories. +set CHERE_INVOKING=1 + +%~dp0..\usr\bin\bash.exe -l %* diff --git a/cookbooks/mingw/files/default/custom-upgrade.sh b/cookbooks/mingw/files/default/custom-upgrade.sh new file mode 100644 index 0000000..db729eb --- /dev/null +++ b/cookbooks/mingw/files/default/custom-upgrade.sh @@ -0,0 +1,23 @@ +declare -r CRITICAL_PACKAGES="bash pacman msys2-runtime" +declare -r OPTIONAL_PACKAGES="msys2-runtime-devel" + +# set pacman command if not already defined +PACMAN=${PACMAN:-pacman} +# save full path to command as PATH may change when sourcing /etc/profile +PACMAN_PATH=$(type -P $PACMAN) + +run_pacman() { + local cmd + cmd=("$PACMAN_PATH" "$@") + "${cmd[@]}" +} + +if ! run_pacman -Sy; then + exit 1 +fi + +run_pacman -Qu ${CRITICAL_PACKAGES} + +if ! run_pacman -S --noconfirm --needed ${CRITICAL_PACKAGES} ${OPTIONAL_PACKAGES}; then + exit 1 +fi diff --git a/cookbooks/mingw/files/default/custom_prefix.sh b/cookbooks/mingw/files/default/custom_prefix.sh new file mode 100644 index 0000000..85a1e2e --- /dev/null +++ b/cookbooks/mingw/files/default/custom_prefix.sh @@ -0,0 +1,13 @@ +# Prepend values from the parent environment to msys2 environment variables. + +export PKG_CONFIG_PATH="${PREMSYS2_PKG_CONFIG_PATH:+${PREMSYS2_PKG_CONFIG_PATH}:}${PKG_CONFIG_PATH}" + +# Instead of placing our entire windows path into msys2, we can selectively +# prepend just the important parts that we need. This also ensures that +# we don't accidentally add other unnecessary chef or git msys2 library +# files in the path. +export PATH="${PREMSYS2_PATH:+${PREMSYS2_PATH}:}${PATH}" + +# TODO: If there are other variabled we want to control like MANPATH or ACLOCALPATH, +# add those here. + diff --git a/cookbooks/mingw/files/default/pthread.h b/cookbooks/mingw/files/default/pthread.h new file mode 100644 index 0000000..ac8fb37 --- /dev/null +++ b/cookbooks/mingw/files/default/pthread.h @@ -0,0 +1,719 @@ +/* + Copyright (c) 2011-2013 mingw-w64 project + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/* + * Parts of this library are derived by: + * + * Posix Threads library for Microsoft Windows + * + * Use at own risk, there is no implied warranty to this code. + * It uses undocumented features of Microsoft Windows that can change + * at any time in the future. + * + * (C) 2010 Lockless Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Lockless Inc. nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AN + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef WIN_PTHREADS_H +#define WIN_PTHREADS_H + +#include +#include +#include + +#include +#include +#include + +#include + +#include "pthread_compat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define __WINPTHREADS_VERSION_MAJOR 0 +#define __WINPTHREADS_VERSION_MINOR 5 +#define __WINPTHREADS_VERSION_PATCHLEVEL 0 + +/* MSB 8-bit major version, 8-bit minor version, 16-bit patch level. */ +#define __WINPTHREADS_VERSION 0x00050000 + +#if defined DLL_EXPORT && !defined WINPTHREAD_STATIC +#ifdef IN_WINPTHREAD +#define WINPTHREAD_API __declspec(dllexport) +#else +#define WINPTHREAD_API __declspec(dllimport) +#endif +#else +#define WINPTHREAD_API +#endif + +/* #define WINPTHREAD_DBG 1 */ + +/* Compatibility stuff: */ +#define RWLS_PER_THREAD 8 + +/* Error-codes. */ +#ifndef ETIMEDOUT +#define ETIMEDOUT 138 +#endif +#ifndef ENOTSUP +#define ENOTSUP 129 +#endif +#ifndef EWOULDBLOCK +#define EWOULDBLOCK 140 +#endif + +/* pthread specific defines. */ + +#define PTHREAD_CANCEL_DISABLE 0 +#define PTHREAD_CANCEL_ENABLE 0x01 + +#define PTHREAD_CANCEL_DEFERRED 0 +#define PTHREAD_CANCEL_ASYNCHRONOUS 0x02 + +#define PTHREAD_CREATE_JOINABLE 0 +#define PTHREAD_CREATE_DETACHED 0x04 + +#define PTHREAD_EXPLICIT_SCHED 0 +#define PTHREAD_INHERIT_SCHED 0x08 + +#define PTHREAD_SCOPE_PROCESS 0 +#define PTHREAD_SCOPE_SYSTEM 0x10 + +#define PTHREAD_DEFAULT_ATTR (PTHREAD_CANCEL_ENABLE) + +#define PTHREAD_CANCELED ((void *) (intptr_t) 0xDEADBEEF) + +#define _PTHREAD_NULL_THREAD ((pthread_t) 0) + +#define PTHREAD_ONCE_INIT 0 + +#define PTHREAD_DESTRUCTOR_ITERATIONS 256 +#define PTHREAD_KEYS_MAX (1<<20) + +#define PTHREAD_MUTEX_NORMAL 0 +#define PTHREAD_MUTEX_ERRORCHECK 1 +#define PTHREAD_MUTEX_RECURSIVE 2 +#define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL + +#define PTHREAD_MUTEX_SHARED 1 +#define PTHREAD_MUTEX_PRIVATE 0 + +#define PTHREAD_PRIO_NONE 0 +#define PTHREAD_PRIO_INHERIT 8 +#define PTHREAD_PRIO_PROTECT 16 +#define PTHREAD_PRIO_MULT 32 +#define PTHREAD_PROCESS_SHARED 1 +#define PTHREAD_PROCESS_PRIVATE 0 + +#define PTHREAD_MUTEX_FAST_NP PTHREAD_MUTEX_NORMAL +#define PTHREAD_MUTEX_TIMED_NP PTHREAD_MUTEX_FAST_NP +#define PTHREAD_MUTEX_ADAPTIVE_NP PTHREAD_MUTEX_FAST_NP +#define PTHREAD_MUTEX_ERRORCHECK_NP PTHREAD_MUTEX_ERRORCHECK +#define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE + +void * WINPTHREAD_API pthread_timechange_handler_np(void * dummy); +/* int WINPTHREAD_API pthread_delay_np (const struct timespec *interval); */ +int WINPTHREAD_API pthread_num_processors_np(void); +int WINPTHREAD_API pthread_set_num_processors_np(int n); + +#define PTHREAD_BARRIER_SERIAL_THREAD 1 + +/* maximum number of times a read lock may be obtained */ +#define MAX_READ_LOCKS (INT_MAX - 1) + +/* No fork() in windows - so ignore this */ +#define pthread_atfork(F1,F2,F3) 0 + +/* unsupported stuff: */ +#define pthread_mutex_getprioceiling(M, P) ENOTSUP +#define pthread_mutex_setprioceiling(M, P) ENOTSUP +#define pthread_getcpuclockid(T, C) ENOTSUP +#define pthread_attr_getguardsize(A, S) ENOTSUP +#define pthread_attr_setgaurdsize(A, S) ENOTSUP + +typedef long pthread_once_t; +typedef unsigned pthread_mutexattr_t; +typedef unsigned pthread_key_t; +typedef void *pthread_barrierattr_t; +typedef int pthread_condattr_t; +typedef int pthread_rwlockattr_t; + +/* +struct _pthread_v; + +typedef struct pthread_t { + struct _pthread_v *p; + int x; +} pthread_t; +*/ + +typedef uintptr_t pthread_t; + +typedef struct _pthread_cleanup _pthread_cleanup; +struct _pthread_cleanup +{ + void (*func)(void *); + void *arg; + _pthread_cleanup *next; +}; + +#define pthread_cleanup_push(F, A)\ +{\ + const _pthread_cleanup _pthread_cup = {(F), (A), *pthread_getclean()};\ + __sync_synchronize();\ + *pthread_getclean() = (_pthread_cleanup *) &_pthread_cup;\ + __sync_synchronize() + +/* Note that if async cancelling is used, then there is a race here */ +#define pthread_cleanup_pop(E)\ + (*pthread_getclean() = _pthread_cup.next, (E?_pthread_cup.func((pthread_once_t *)_pthread_cup.arg):0));} + +/* ------------------------------------------------------------------- + * CHEF PATCHES + * + * PREVENT REDECLERATION OF timespec + * + * The original header here assumed that struct timespec was not + * available on windows under mingw. So it redeclared timespec itself. + * + * This currently generates and error. With recent binutils, timespec + * is declared in time.h but in a slightly different manner from the + * traditional posix definition (it involves unions) to account for + * MSVC related issues. + * + * They need to go through a lot of hoops to declare the exact size + * and layout of timespec because MSVC uses a slightly more loltastic + * definition of time_t than everyone else in the universe. + * Traditionally, time_t was an integral quantity that represents the + * number of seconds since the unix epoch and it's 32-bits wide. + * This leads to the Y2038 problem where the timestamp will overflow. + * MSVC "solves" this by changing the definition of time_t to 64-bit + * on 64-bit platforms which wreaks havoc on a large number of + * structs that need to deal with the new layout (including timespec). + * Thankfully, we are using a compiler that sticks to the older + * definition of time_t - so as long as we don't attempt to link it + * to any MSVC generated libraries, we should be ok. The winpthreads + * compatibility layer that ships with TDM GCC was patched and + * compiled under these assumptions. + * + * Since we are assuming that we aren't going to generally be mixing + * MSVC generated and mingw generated dlls and TDM GCC provides us with + * good old-fashioned system libraries and dlls, we can simply delete + * the declaration of timespec here and use parts/time.h from mingwrt + * instead. + */ + +#define __need_time_t +#define __need_struct_timespec +#define _FAKE_TIME_H_SOURCED 1 +#include + +/* END OF CHEF PATCHES + * ------------------------------------------------------------------- + */ + +#ifndef SCHED_OTHER +/* Some POSIX realtime extensions, mostly stubbed */ +#define SCHED_OTHER 0 +#define SCHED_FIFO 1 +#define SCHED_RR 2 +#define SCHED_MIN SCHED_OTHER +#define SCHED_MAX SCHED_RR + +struct sched_param { + int sched_priority; +}; + +int WINPTHREAD_API sched_yield(void); +int WINPTHREAD_API sched_get_priority_min(int pol); +int WINPTHREAD_API sched_get_priority_max(int pol); +int WINPTHREAD_API sched_getscheduler(pid_t pid); +int WINPTHREAD_API sched_setscheduler(pid_t pid, int pol, const struct sched_param *param); + +#endif + +typedef struct pthread_attr_t pthread_attr_t; +struct pthread_attr_t +{ + unsigned p_state; + void *stack; + size_t s_size; + struct sched_param param; +}; + +int WINPTHREAD_API pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param); +int WINPTHREAD_API pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param); +int WINPTHREAD_API pthread_getschedparam(pthread_t thread, int *pol, struct sched_param *param); +int WINPTHREAD_API pthread_setschedparam(pthread_t thread, int pol, const struct sched_param *param); +int WINPTHREAD_API pthread_attr_setschedpolicy (pthread_attr_t *attr, int pol); +int WINPTHREAD_API pthread_attr_getschedpolicy (pthread_attr_t *attr, int *pol); + +/* synchronization objects */ +typedef void *pthread_spinlock_t; +typedef void *pthread_mutex_t; +typedef void *pthread_cond_t; +typedef void *pthread_rwlock_t; +typedef void *pthread_barrier_t; + +#define PTHREAD_MUTEX_NORMAL 0 +#define PTHREAD_MUTEX_ERRORCHECK 1 +#define PTHREAD_MUTEX_RECURSIVE 2 + +#define GENERIC_INITIALIZER ((void *) (size_t) -1) +#define GENERIC_ERRORCHECK_INITIALIZER ((void *) (size_t) -2) +#define GENERIC_RECURSIVE_INITIALIZER ((void *) (size_t) -3) +#define GENERIC_NORMAL_INITIALIZER ((void *) (size_t) -1) +#define PTHREAD_MUTEX_INITIALIZER (pthread_mutex_t)GENERIC_INITIALIZER +#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER (pthread_mutex_t)GENERIC_RECURSIVE_INITIALIZER +#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER (pthread_mutex_t)GENERIC_ERRORCHECK_INITIALIZER +#define PTHREAD_NORMAL_MUTEX_INITIALIZER (pthread_mutex_t)GENERIC_NORMAL_INITIALIZER +#define PTHREAD_DEFAULT_MUTEX_INITIALIZER PTHREAD_NORMAL_MUTEX_INITIALIZER +#define PTHREAD_COND_INITIALIZER (pthread_cond_t)GENERIC_INITIALIZER +#define PTHREAD_RWLOCK_INITIALIZER (pthread_rwlock_t)GENERIC_INITIALIZER +#define PTHREAD_SPINLOCK_INITIALIZER (pthread_spinlock_t)GENERIC_INITIALIZER + +extern void WINPTHREAD_API (**_pthread_key_dest)(void *); +int WINPTHREAD_API pthread_key_create(pthread_key_t *key, void (* dest)(void *)); +int WINPTHREAD_API pthread_key_delete(pthread_key_t key); +void * WINPTHREAD_API pthread_getspecific(pthread_key_t key); +int WINPTHREAD_API pthread_setspecific(pthread_key_t key, const void *value); + +pthread_t WINPTHREAD_API pthread_self(void); +int WINPTHREAD_API pthread_once(pthread_once_t *o, void (*func)(void)); +void WINPTHREAD_API pthread_testcancel(void); +int WINPTHREAD_API pthread_equal(pthread_t t1, pthread_t t2); +void WINPTHREAD_API pthread_tls_init(void); +void WINPTHREAD_API _pthread_cleanup_dest(pthread_t t); +int WINPTHREAD_API pthread_get_concurrency(int *val); +int WINPTHREAD_API pthread_set_concurrency(int val); +void WINPTHREAD_API pthread_exit(void *res); +void WINPTHREAD_API _pthread_invoke_cancel(void); +int WINPTHREAD_API pthread_cancel(pthread_t t); +int WINPTHREAD_API pthread_kill(pthread_t t, int sig); +unsigned WINPTHREAD_API _pthread_get_state(const pthread_attr_t *attr, unsigned flag); +int WINPTHREAD_API _pthread_set_state(pthread_attr_t *attr, unsigned flag, unsigned val); +int WINPTHREAD_API pthread_setcancelstate(int state, int *oldstate); +int WINPTHREAD_API pthread_setcanceltype(int type, int *oldtype); +int WINPTHREAD_API pthread_create_wrapper(void *args); +int WINPTHREAD_API pthread_create(pthread_t *th, const pthread_attr_t *attr, void *(* func)(void *), void *arg); +int WINPTHREAD_API pthread_join(pthread_t t, void **res); +int WINPTHREAD_API pthread_detach(pthread_t t); + +int WINPTHREAD_API pthread_rwlock_init(pthread_rwlock_t *rwlock_, const pthread_rwlockattr_t *attr); +int WINPTHREAD_API pthread_rwlock_wrlock(pthread_rwlock_t *l); +int WINPTHREAD_API pthread_rwlock_timedwrlock(pthread_rwlock_t *rwlock, const struct timespec *ts); +int WINPTHREAD_API pthread_rwlock_rdlock(pthread_rwlock_t *l); +int WINPTHREAD_API pthread_rwlock_timedrdlock(pthread_rwlock_t *l, const struct timespec *ts); +int WINPTHREAD_API pthread_rwlock_unlock(pthread_rwlock_t *l); +int WINPTHREAD_API pthread_rwlock_tryrdlock(pthread_rwlock_t *l); +int WINPTHREAD_API pthread_rwlock_trywrlock(pthread_rwlock_t *l); +int WINPTHREAD_API pthread_rwlock_destroy (pthread_rwlock_t *l); + +int WINPTHREAD_API pthread_cond_init(pthread_cond_t *cv, const pthread_condattr_t *a); +int WINPTHREAD_API pthread_cond_destroy(pthread_cond_t *cv); +int WINPTHREAD_API pthread_cond_signal (pthread_cond_t *cv); +int WINPTHREAD_API pthread_cond_broadcast (pthread_cond_t *cv); +int WINPTHREAD_API pthread_cond_wait (pthread_cond_t *cv, pthread_mutex_t *external_mutex); +int WINPTHREAD_API pthread_cond_timedwait(pthread_cond_t *cv, pthread_mutex_t *external_mutex, const struct timespec *t); +int WINPTHREAD_API pthread_cond_timedwait_relative_np(pthread_cond_t *cv, pthread_mutex_t *external_mutex, const struct timespec *t); + +int WINPTHREAD_API pthread_mutex_lock(pthread_mutex_t *m); +int WINPTHREAD_API pthread_mutex_timedlock(pthread_mutex_t *m, const struct timespec *ts); +int WINPTHREAD_API pthread_mutex_unlock(pthread_mutex_t *m); +int WINPTHREAD_API pthread_mutex_trylock(pthread_mutex_t *m); +int WINPTHREAD_API pthread_mutex_init(pthread_mutex_t *m, const pthread_mutexattr_t *a); +int WINPTHREAD_API pthread_mutex_destroy(pthread_mutex_t *m); + +int WINPTHREAD_API pthread_barrier_destroy(pthread_barrier_t *b); +int WINPTHREAD_API pthread_barrier_init(pthread_barrier_t *b, const void *attr, unsigned int count); +int WINPTHREAD_API pthread_barrier_wait(pthread_barrier_t *b); + +int WINPTHREAD_API pthread_spin_init(pthread_spinlock_t *l, int pshared); +int WINPTHREAD_API pthread_spin_destroy(pthread_spinlock_t *l); +/* No-fair spinlock due to lack of knowledge of thread number. */ +int WINPTHREAD_API pthread_spin_lock(pthread_spinlock_t *l); +int WINPTHREAD_API pthread_spin_trylock(pthread_spinlock_t *l); +int WINPTHREAD_API pthread_spin_unlock(pthread_spinlock_t *l); + +int WINPTHREAD_API pthread_attr_init(pthread_attr_t *attr); +int WINPTHREAD_API pthread_attr_destroy(pthread_attr_t *attr); +int WINPTHREAD_API pthread_attr_setdetachstate(pthread_attr_t *a, int flag); +int WINPTHREAD_API pthread_attr_getdetachstate(const pthread_attr_t *a, int *flag); +int WINPTHREAD_API pthread_attr_setinheritsched(pthread_attr_t *a, int flag); +int WINPTHREAD_API pthread_attr_getinheritsched(const pthread_attr_t *a, int *flag); +int WINPTHREAD_API pthread_attr_setscope(pthread_attr_t *a, int flag); +int WINPTHREAD_API pthread_attr_getscope(const pthread_attr_t *a, int *flag); +int WINPTHREAD_API pthread_attr_getstackaddr(pthread_attr_t *attr, void **stack); +int WINPTHREAD_API pthread_attr_setstackaddr(pthread_attr_t *attr, void *stack); +int WINPTHREAD_API pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *size); +int WINPTHREAD_API pthread_attr_setstacksize(pthread_attr_t *attr, size_t size); + +int WINPTHREAD_API pthread_mutexattr_init(pthread_mutexattr_t *a); +int WINPTHREAD_API pthread_mutexattr_destroy(pthread_mutexattr_t *a); +int WINPTHREAD_API pthread_mutexattr_gettype(const pthread_mutexattr_t *a, int *type); +int WINPTHREAD_API pthread_mutexattr_settype(pthread_mutexattr_t *a, int type); +int WINPTHREAD_API pthread_mutexattr_getpshared(const pthread_mutexattr_t *a, int *type); +int WINPTHREAD_API pthread_mutexattr_setpshared(pthread_mutexattr_t * a, int type); +int WINPTHREAD_API pthread_mutexattr_getprotocol(const pthread_mutexattr_t *a, int *type); +int WINPTHREAD_API pthread_mutexattr_setprotocol(pthread_mutexattr_t *a, int type); +int WINPTHREAD_API pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *a, int * prio); +int WINPTHREAD_API pthread_mutexattr_setprioceiling(pthread_mutexattr_t *a, int prio); +int WINPTHREAD_API pthread_getconcurrency(void); +int WINPTHREAD_API pthread_setconcurrency(int new_level); + +int WINPTHREAD_API pthread_condattr_destroy(pthread_condattr_t *a); +int WINPTHREAD_API pthread_condattr_init(pthread_condattr_t *a); +int WINPTHREAD_API pthread_condattr_getpshared(const pthread_condattr_t *a, int *s); +int WINPTHREAD_API pthread_condattr_setpshared(pthread_condattr_t *a, int s); + +#ifndef __clockid_t_defined +typedef int clockid_t; +#define __clockid_t_defined 1 +#endif /* __clockid_t_defined */ + +int WINPTHREAD_API pthread_condattr_getclock (const pthread_condattr_t *attr, + clockid_t *clock_id); +int WINPTHREAD_API pthread_condattr_setclock(pthread_condattr_t *attr, + clockid_t clock_id); +int WINPTHREAD_API __pthread_clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp, struct timespec *rmtp); + +int WINPTHREAD_API pthread_barrierattr_init(void **attr); +int WINPTHREAD_API pthread_barrierattr_destroy(void **attr); +int WINPTHREAD_API pthread_barrierattr_setpshared(void **attr, int s); +int WINPTHREAD_API pthread_barrierattr_getpshared(void **attr, int *s); + +/* Private extensions for analysis and internal use. */ +struct _pthread_cleanup ** WINPTHREAD_API pthread_getclean (void); +void * WINPTHREAD_API pthread_gethandle (pthread_t t); +void * WINPTHREAD_API pthread_getevent (); + +unsigned long long WINPTHREAD_API _pthread_rel_time_in_ms(const struct timespec *ts); +unsigned long long WINPTHREAD_API _pthread_time_in_ms(void); +unsigned long long WINPTHREAD_API _pthread_time_in_ms_from_timespec(const struct timespec *ts); +int WINPTHREAD_API _pthread_tryjoin (pthread_t t, void **res); +int WINPTHREAD_API pthread_rwlockattr_destroy(pthread_rwlockattr_t *a); +int WINPTHREAD_API pthread_rwlockattr_getpshared(pthread_rwlockattr_t *a, int *s); +int WINPTHREAD_API pthread_rwlockattr_init(pthread_rwlockattr_t *a); +int WINPTHREAD_API pthread_rwlockattr_setpshared(pthread_rwlockattr_t *a, int s); + +#ifndef SIG_BLOCK +#define SIG_BLOCK 0 +#endif +#ifndef SIG_UNBLOCK +#define SIG_UNBLOCK 1 +#endif +#ifndef SIG_SETMASK +#define SIG_SETMASK 2 +#endif + +#include + +#undef _POSIX_THREAD_DESTRUCTOR_ITERATIONS +#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS PTHREAD_DESTRUCTOR_ITERATIONS + +#undef _POSIX_THREAD_KEYS_MAX +#define _POSIX_THREAD_KEYS_MAX PTHREAD_KEYS_MAX + +#undef PTHREAD_THREADS_MAX +#define PTHREAD_THREADS_MAX 2019 + +#undef _POSIX_SEM_NSEMS_MAX +#define _POSIX_SEM_NSEMS_MAX 256 + +#undef SEM_NSEMS_MAX +#define SEM_NSEMS_MAX 1024 + +/* Wrap cancellation points. */ +#ifdef __WINPTRHEAD_ENABLE_WRAP_API +#define accept(...) (pthread_testcancel(), accept(__VA_ARGS__)) +#define aio_suspend(...) (pthread_testcancel(), aio_suspend(__VA_ARGS__)) +#define clock_nanosleep(...) (pthread_testcancel(), clock_nanosleep(__VA_ARGS__)) +#define close(...) (pthread_testcancel(), close(__VA_ARGS__)) +#define connect(...) (pthread_testcancel(), connect(__VA_ARGS__)) +#define creat(...) (pthread_testcancel(), creat(__VA_ARGS__)) +#define fcntl(...) (pthread_testcancel(), fcntl(__VA_ARGS__)) +#define fdatasync(...) (pthread_testcancel(), fdatasync(__VA_ARGS__)) +#define fsync(...) (pthread_testcancel(), fsync(__VA_ARGS__)) +#define getmsg(...) (pthread_testcancel(), getmsg(__VA_ARGS__)) +#define getpmsg(...) (pthread_testcancel(), getpmsg(__VA_ARGS__)) +#define lockf(...) (pthread_testcancel(), lockf(__VA_ARGS__)) +#define mg_receive(...) (pthread_testcancel(), mg_receive(__VA_ARGS__)) +#define mg_send(...) (pthread_testcancel(), mg_send(__VA_ARGS__)) +#define mg_timedreceive(...) (pthread_testcancel(), mg_timedreceive(__VA_ARGS__)) +#define mg_timessend(...) (pthread_testcancel(), mg_timedsend(__VA_ARGS__)) +#define msgrcv(...) (pthread_testcancel(), msgrecv(__VA_ARGS__)) +#define msgsnd(...) (pthread_testcancel(), msgsnd(__VA_ARGS__)) +#define msync(...) (pthread_testcancel(), msync(__VA_ARGS__)) +#define nanosleep(...) (pthread_testcancel(), nanosleep(__VA_ARGS__)) +#define open(...) (pthread_testcancel(), open(__VA_ARGS__)) +#define pause(...) (pthread_testcancel(), pause(__VA_ARGS__)) +#define poll(...) (pthread_testcancel(), poll(__VA_ARGS__)) +#define pread(...) (pthread_testcancel(), pread(__VA_ARGS__)) +#define pselect(...) (pthread_testcancel(), pselect(__VA_ARGS__)) +#define putmsg(...) (pthread_testcancel(), putmsg(__VA_ARGS__)) +#define putpmsg(...) (pthread_testcancel(), putpmsg(__VA_ARGS__)) +#define pwrite(...) (pthread_testcancel(), pwrite(__VA_ARGS__)) +#define read(...) (pthread_testcancel(), read(__VA_ARGS__)) +#define readv(...) (pthread_testcancel(), readv(__VA_ARGS__)) +#define recv(...) (pthread_testcancel(), recv(__VA_ARGS__)) +#define recvfrom(...) (pthread_testcancel(), recvfrom(__VA_ARGS__)) +#define recvmsg(...) (pthread_testcancel(), recvmsg(__VA_ARGS__)) +#define select(...) (pthread_testcancel(), select(__VA_ARGS__)) +#define sem_timedwait(...) (pthread_testcancel(), sem_timedwait(__VA_ARGS__)) +#define sem_wait(...) (pthread_testcancel(), sem_wait(__VA_ARGS__)) +#define send(...) (pthread_testcancel(), send(__VA_ARGS__)) +#define sendmsg(...) (pthread_testcancel(), sendmsg(__VA_ARGS__)) +#define sendto(...) (pthread_testcancel(), sendto(__VA_ARGS__)) +#define sigpause(...) (pthread_testcancel(), sigpause(__VA_ARGS__)) +#define sigsuspend(...) (pthread_testcancel(), sigsuspend(__VA_ARGS__)) +#define sigwait(...) (pthread_testcancel(), sigwait(__VA_ARGS__)) +#define sigwaitinfo(...) (pthread_testcancel(), sigwaitinfo(__VA_ARGS__)) +#define sleep(...) (pthread_testcancel(), sleep(__VA_ARGS__)) +//#define Sleep(...) (pthread_testcancel(), Sleep(__VA_ARGS__)) +#define system(...) (pthread_testcancel(), system(__VA_ARGS__)) +#define access(...) (pthread_testcancel(), access(__VA_ARGS__)) +#define asctime(...) (pthread_testcancel(), asctime(__VA_ARGS__)) +#define catclose(...) (pthread_testcancel(), catclose(__VA_ARGS__)) +#define catgets(...) (pthread_testcancel(), catgets(__VA_ARGS__)) +#define catopen(...) (pthread_testcancel(), catopen(__VA_ARGS__)) +#define closedir(...) (pthread_testcancel(), closedir(__VA_ARGS__)) +#define closelog(...) (pthread_testcancel(), closelog(__VA_ARGS__)) +#define ctermid(...) (pthread_testcancel(), ctermid(__VA_ARGS__)) +#define ctime(...) (pthread_testcancel(), ctime(__VA_ARGS__)) +#define dbm_close(...) (pthread_testcancel(), dbm_close(__VA_ARGS__)) +#define dbm_delete(...) (pthread_testcancel(), dbm_delete(__VA_ARGS__)) +#define dbm_fetch(...) (pthread_testcancel(), dbm_fetch(__VA_ARGS__)) +#define dbm_nextkey(...) (pthread_testcancel(), dbm_nextkey(__VA_ARGS__)) +#define dbm_open(...) (pthread_testcancel(), dbm_open(__VA_ARGS__)) +#define dbm_store(...) (pthread_testcancel(), dbm_store(__VA_ARGS__)) +#define dlclose(...) (pthread_testcancel(), dlclose(__VA_ARGS__)) +#define dlopen(...) (pthread_testcancel(), dlopen(__VA_ARGS__)) +#define endgrent(...) (pthread_testcancel(), endgrent(__VA_ARGS__)) +#define endhostent(...) (pthread_testcancel(), endhostent(__VA_ARGS__)) +#define endnetent(...) (pthread_testcancel(), endnetent(__VA_ARGS__)) +#define endprotoent(...) (pthread_testcancel(), endprotoend(__VA_ARGS__)) +#define endpwent(...) (pthread_testcancel(), endpwent(__VA_ARGS__)) +#define endservent(...) (pthread_testcancel(), endservent(__VA_ARGS__)) +#define endutxent(...) (pthread_testcancel(), endutxent(__VA_ARGS__)) +#define fclose(...) (pthread_testcancel(), fclose(__VA_ARGS__)) +#define fflush(...) (pthread_testcancel(), fflush(__VA_ARGS__)) +#define fgetc(...) (pthread_testcancel(), fgetc(__VA_ARGS__)) +#define fgetpos(...) (pthread_testcancel(), fgetpos(__VA_ARGS__)) +#define fgets(...) (pthread_testcancel(), fgets(__VA_ARGS__)) +#define fgetwc(...) (pthread_testcancel(), fgetwc(__VA_ARGS__)) +#define fgetws(...) (pthread_testcancel(), fgetws(__VA_ARGS__)) +#define fmtmsg(...) (pthread_testcancel(), fmtmsg(__VA_ARGS__)) +#define fopen(...) (pthread_testcancel(), fopen(__VA_ARGS__)) +#define fpathconf(...) (pthread_testcancel(), fpathconf(__VA_ARGS__)) +#define fprintf(...) (pthread_testcancel(), fprintf(__VA_ARGS__)) +#define fputc(...) (pthread_testcancel(), fputc(__VA_ARGS__)) +#define fputs(...) (pthread_testcancel(), fputs(__VA_ARGS__)) +#define fputwc(...) (pthread_testcancel(), fputwc(__VA_ARGS__)) +#define fputws(...) (pthread_testcancel(), fputws(__VA_ARGS__)) +#define fread(...) (pthread_testcancel(), fread(__VA_ARGS__)) +#define freopen(...) (pthread_testcancel(), freopen(__VA_ARGS__)) +#define fscanf(...) (pthread_testcancel(), fscanf(__VA_ARGS__)) +#define fseek(...) (pthread_testcancel(), fseek(__VA_ARGS__)) +#define fseeko(...) (pthread_testcancel(), fseeko(__VA_ARGS__)) +#define fsetpos(...) (pthread_testcancel(), fsetpos(__VA_ARGS__)) +#define fstat(...) (pthread_testcancel(), fstat(__VA_ARGS__)) +#define ftell(...) (pthread_testcancel(), ftell(__VA_ARGS__)) +#define ftello(...) (pthread_testcancel(), ftello(__VA_ARGS__)) +#define ftw(...) (pthread_testcancel(), ftw(__VA_ARGS__)) +#define fwprintf(...) (pthread_testcancel(), fwprintf(__VA_ARGS__)) +#define fwrite(...) (pthread_testcancel(), fwrite(__VA_ARGS__)) +#define fwscanf(...) (pthread_testcancel(), fwscanf(__VA_ARGS__)) +#define getaddrinfo(...) (pthread_testcancel(), getaddrinfo(__VA_ARGS__)) +#define getc(...) (pthread_testcancel(), getc(__VA_ARGS__)) +#define getc_unlocked(...) (pthread_testcancel(), getc_unlocked(__VA_ARGS__)) +#define getchar(...) (pthread_testcancel(), getchar(__VA_ARGS__)) +#define getchar_unlocked(...) (pthread_testcancel(), getchar_unlocked(__VA_ARGS__)) +#define getcwd(...) (pthread_testcancel(), getcwd(__VA_ARGS__)) +#define getdate(...) (pthread_testcancel(), getdate(__VA_ARGS__)) +#define getgrent(...) (pthread_testcancel(), getgrent(__VA_ARGS__)) +#define getgrgid(...) (pthread_testcancel(), getgrgid(__VA_ARGS__)) +#define getgrgid_r(...) (pthread_testcancel(), getgrgid_r(__VA_ARGS__)) +#define gergrnam(...) (pthread_testcancel(), getgrnam(__VA_ARGS__)) +#define getgrnam_r(...) (pthread_testcancel(), getgrnam_r(__VA_ARGS__)) +#define gethostbyaddr(...) (pthread_testcancel(), gethostbyaddr(__VA_ARGS__)) +#define gethostbyname(...) (pthread_testcancel(), gethostbyname(__VA_ARGS__)) +#define gethostent(...) (pthread_testcancel(), gethostent(__VA_ARGS__)) +#define gethostid(...) (pthread_testcancel(), gethostid(__VA_ARGS__)) +#define gethostname(...) (pthread_testcancel(), gethostname(__VA_ARGS__)) +#define getlogin(...) (pthread_testcancel(), getlogin(__VA_ARGS__)) +#define getlogin_r(...) (pthread_testcancel(), getlogin_r(__VA_ARGS__)) +#define getnameinfo(...) (pthread_testcancel(), getnameinfo(__VA_ARGS__)) +#define getnetbyaddr(...) (pthread_testcancel(), getnetbyaddr(__VA_ARGS__)) +#define getnetbyname(...) (pthread_testcancel(), getnetbyname(__VA_ARGS__)) +#define getnetent(...) (pthread_testcancel(), getnetent(__VA_ARGS__)) +#define getopt(...) (pthread_testcancel(), getopt(__VA_ARGS__)) +#define getprotobyname(...) (pthread_testcancel(), getprotobyname(__VA_ARGS__)) +#define getprotobynumber(...) (pthread_testcancel(), getprotobynumber(__VA_ARGS__)) +#define getprotoent(...) (pthread_testcancel(), getprotoent(__VA_ARGS__)) +#define getpwent(...) (pthread_testcancel(), getpwent(__VA_ARGS__)) +#define getpwnam(...) (pthread_testcancel(), getpwnam(__VA_ARGS__)) +#define getpwnam_r(...) (pthread_testcancel(), getpwnam_r(__VA_ARGS__)) +#define getpwuid(...) (pthread_testcancel(), getpwuid(__VA_ARGS__)) +#define getpwuid_r(...) (pthread_testcancel(), getpwuid_r(__VA_ARGS__)) +#define gets(...) (pthread_testcancel(), gets(__VA_ARGS__)) +#define getservbyname(...) (pthread_testcancel(), getservbyname(__VA_ARGS__)) +#define getservbyport(...) (pthread_testcancel(), getservbyport(__VA_ARGS__)) +#define getservent(...) (pthread_testcancel(), getservent(__VA_ARGS__)) +#define getutxent(...) (pthread_testcancel(), getutxent(__VA_ARGS__)) +#define getutxid(...) (pthread_testcancel(), getutxid(__VA_ARGS__)) +#define getutxline(...) (pthread_testcancel(), getutxline(__VA_ARGS__)) +#undef getwc +#define getwc(...) (pthread_testcancel(), getwc(__VA_ARGS__)) +#undef getwchar +#define getwchar(...) (pthread_testcancel(), getwchar(__VA_ARGS__)) +#define getwd(...) (pthread_testcancel(), getwd(__VA_ARGS__)) +#define glob(...) (pthread_testcancel(), glob(__VA_ARGS__)) +#define iconv_close(...) (pthread_testcancel(), iconv_close(__VA_ARGS__)) +#define iconv_open(...) (pthread_testcancel(), iconv_open(__VA_ARGS__)) +#define ioctl(...) (pthread_testcancel(), ioctl(__VA_ARGS__)) +#define link(...) (pthread_testcancel(), link(__VA_ARGS__)) +#define localtime(...) (pthread_testcancel(), localtime(__VA_ARGS__)) +#define lseek(...) (pthread_testcancel(), lseek(__VA_ARGS__)) +#define lstat(...) (pthread_testcancel(), lstat(__VA_ARGS__)) +#define mkstemp(...) (pthread_testcancel(), mkstemp(__VA_ARGS__)) +#define nftw(...) (pthread_testcancel(), nftw(__VA_ARGS__)) +#define opendir(...) (pthread_testcancel(), opendir(__VA_ARGS__)) +#define openlog(...) (pthread_testcancel(), openlog(__VA_ARGS__)) +#define pathconf(...) (pthread_testcancel(), pathconf(__VA_ARGS__)) +#define pclose(...) (pthread_testcancel(), pclose(__VA_ARGS__)) +#define perror(...) (pthread_testcancel(), perror(__VA_ARGS__)) +#define popen(...) (pthread_testcancel(), popen(__VA_ARGS__)) +#define posix_fadvise(...) (pthread_testcancel(), posix_fadvise(__VA_ARGS__)) +#define posix_fallocate(...) (pthread_testcancel(), posix_fallocate(__VA_ARGS__)) +#define posix_madvise(...) (pthread_testcancel(), posix_madvise(__VA_ARGS__)) +#define posix_openpt(...) (pthread_testcancel(), posix_openpt(__VA_ARGS__)) +#define posix_spawn(...) (pthread_testcancel(), posix_spawn(__VA_ARGS__)) +#define posix_spawnp(...) (pthread_testcancel(), posix_spawnp(__VA_ARGS__)) +#define posix_trace_clear(...) (pthread_testcancel(), posix_trace_clear(__VA_ARGS__)) +#define posix_trace_close(...) (pthread_testcancel(), posix_trace_close(__VA_ARGS__)) +#define posix_trace_create(...) (pthread_testcancel(), posix_trace_create(__VA_ARGS__)) +#define posix_trace_create_withlog(...) (pthread_testcancel(), posix_trace_create_withlog(__VA_ARGS__)) +#define posix_trace_eventtypelist_getne(...) (pthread_testcancel(), posix_trace_eventtypelist_getne(__VA_ARGS__)) +#define posix_trace_eventtypelist_rewin(...) (pthread_testcancel(), posix_trace_eventtypelist_rewin(__VA_ARGS__)) +#define posix_trace_flush(...) (pthread_testcancel(), posix_trace_flush(__VA_ARGS__)) +#define posix_trace_get_attr(...) (pthread_testcancel(), posix_trace_get_attr(__VA_ARGS__)) +#define posix_trace_get_filter(...) (pthread_testcancel(), posix_trace_get_filter(__VA_ARGS__)) +#define posix_trace_get_status(...) (pthread_testcancel(), posix_trace_get_status(__VA_ARGS__)) +#define posix_trace_getnext_event(...) (pthread_testcancel(), posix_trace_getnext_event(__VA_ARGS__)) +#define posix_trace_open(...) (pthread_testcancel(), posix_trace_open(__VA_ARGS__)) +#define posix_trace_rewind(...) (pthread_testcancel(), posix_trace_rewind(__VA_ARGS__)) +#define posix_trace_setfilter(...) (pthread_testcancel(), posix_trace_setfilter(__VA_ARGS__)) +#define posix_trace_shutdown(...) (pthread_testcancel(), posix_trace_shutdown(__VA_ARGS__)) +#define posix_trace_timedgetnext_event(...) (pthread_testcancel(), posix_trace_timedgetnext_event(__VA_ARGS__)) +#define posix_typed_mem_open(...) (pthread_testcancel(), posix_typed_mem_open(__VA_ARGS__)) +#define printf(...) (pthread_testcancel(), printf(__VA_ARGS__)) +#define putc(...) (pthread_testcancel(), putc(__VA_ARGS__)) +#define putc_unlocked(...) (pthread_testcancel(), putc_unlocked(__VA_ARGS__)) +#define putchar(...) (pthread_testcancel(), putchar(__VA_ARGS__)) +#define putchar_unlocked(...) (pthread_testcancel(), putchar_unlocked(__VA_ARGS__)) +#define puts(...) (pthread_testcancel(), puts(__VA_ARGS__)) +#define pututxline(...) (pthread_testcancel(), pututxline(__VA_ARGS__)) +#undef putwc +#define putwc(...) (pthread_testcancel(), putwc(__VA_ARGS__)) +#undef putwchar +#define putwchar(...) (pthread_testcancel(), putwchar(__VA_ARGS__)) +#define readdir(...) (pthread_testcancel(), readdir(__VA_ARSG__)) +#define readdir_r(...) (pthread_testcancel(), readdir_r(__VA_ARGS__)) +#define remove(...) (pthread_testcancel(), remove(__VA_ARGS__)) +#define rename(...) (pthread_testcancel(), rename(__VA_ARGS__)) +#define rewind(...) (pthread_testcancel(), rewind(__VA_ARGS__)) +#define rewinddir(...) (pthread_testcancel(), rewinddir(__VA_ARGS__)) +#define scanf(...) (pthread_testcancel(), scanf(__VA_ARGS__)) +#define seekdir(...) (pthread_testcancel(), seekdir(__VA_ARGS__)) +#define semop(...) (pthread_testcancel(), semop(__VA_ARGS__)) +#define setgrent(...) (pthread_testcancel(), setgrent(__VA_ARGS__)) +#define sethostent(...) (pthread_testcancel(), sethostemt(__VA_ARGS__)) +#define setnetent(...) (pthread_testcancel(), setnetent(__VA_ARGS__)) +#define setprotoent(...) (pthread_testcancel(), setprotoent(__VA_ARGS__)) +#define setpwent(...) (pthread_testcancel(), setpwent(__VA_ARGS__)) +#define setservent(...) (pthread_testcancel(), setservent(__VA_ARGS__)) +#define setutxent(...) (pthread_testcancel(), setutxent(__VA_ARGS__)) +#define stat(...) (pthread_testcancel(), stat(__VA_ARGS__)) +#define strerror(...) (pthread_testcancel(), strerror(__VA_ARGS__)) +#define strerror_r(...) (pthread_testcancel(), strerror_r(__VA_ARGS__)) +#define strftime(...) (pthread_testcancel(), strftime(__VA_ARGS__)) +#define symlink(...) (pthread_testcancel(), symlink(__VA_ARGS__)) +#define sync(...) (pthread_testcancel(), sync(__VA_ARGS__)) +#define syslog(...) (pthread_testcancel(), syslog(__VA_ARGS__)) +#define tmpfile(...) (pthread_testcancel(), tmpfile(__VA_ARGS__)) +#define tmpnam(...) (pthread_testcancel(), tmpnam(__VA_ARGS__)) +#define ttyname(...) (pthread_testcancel(), ttyname(__VA_ARGS__)) +#define ttyname_r(...) (pthread_testcancel(), ttyname_r(__VA_ARGS__)) +#define tzset(...) (pthread_testcancel(), tzset(__VA_ARGS__)) +#define ungetc(...) (pthread_testcancel(), ungetc(__VA_ARGS__)) +#define ungetwc(...) (pthread_testcancel(), ungetwc(__VA_ARGS__)) +#define unlink(...) (pthread_testcancel(), unlink(__VA_ARGS__)) +#define vfprintf(...) (pthread_testcancel(), vfprintf(__VA_ARGS__)) +#define vfwprintf(...) (pthread_testcancel(), vfwprintf(__VA_ARGS__)) +#define vprintf(...) (pthread_testcancel(), vprintf(__VA_ARGS__)) +#define vwprintf(...) (pthread_testcancel(), vwprintf(__VA_ARGS__)) +#define wcsftime(...) (pthread_testcancel(), wcsftime(__VA_ARGS__)) +#define wordexp(...) (pthread_testcancel(), wordexp(__VA_ARGS__)) +#define wprintf(...) (pthread_testcancel(), wprintf(__VA_ARGS__)) +#define wscanf(...) (pthread_testcancel(), wscanf(__VA_ARGS__)) +#endif + +/* We deal here with a gcc issue for posix threading on Windows. + We would need to change here gcc's gthr-posix.h header, but this + got rejected. So we deal it within this header. */ +#ifdef _GTHREAD_USE_MUTEX_INIT_FUNC +#undef _GTHREAD_USE_MUTEX_INIT_FUNC +#endif +#define _GTHREAD_USE_MUTEX_INIT_FUNC 1 + +#ifdef __cplusplus +} +#endif + +#endif /* WIN_PTHREADS_H */ diff --git a/cookbooks/mingw/files/default/time.h b/cookbooks/mingw/files/default/time.h new file mode 100644 index 0000000..1800b43 --- /dev/null +++ b/cookbooks/mingw/files/default/time.h @@ -0,0 +1,297 @@ +/* + * time.h + * + * Type definitions and function declarations relating to date and time. + * + * $Id: time.h,v ffe8d63c87e3 2015/05/18 12:49:39 keithmarshall $ + * + * Written by Rob Savoye + * Copyright (C) 1997-2007, 2011, 2015, MinGW.org Project. + * + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice, this permission notice, and the following + * disclaimer shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +#ifndef _TIME_H +#define _TIME_H + +/* All the headers include this file. */ +#include <_mingw.h> + +/* Number of clock ticks per second. A clock tick is the unit by which + * processor time is measured and is returned by 'clock'. + */ +#define CLOCKS_PER_SEC ((clock_t)(1000)) +#define CLK_TCK CLOCKS_PER_SEC + +#ifndef RC_INVOKED +/* + * Some elements declared in time.h may also be required by other + * header files, without necessarily including time.h itself; such + * elements are declared in the local parts/time.h system header file. + * Declarations for such elements must be selected prior to inclusion: + */ +#define __need_time_t +#define __need_struct_timespec +#include + +/* time.h is also required to duplicate the following type definitions, + * which are nominally defined in stddef.h + */ +#define __need_NULL +#define __need_wchar_t +#define __need_size_t +#include + +/* A type for measuring processor time in clock ticks; (no need to + * guard this, since it isn't defined elsewhere). + */ +typedef long clock_t; + +#ifndef _TM_DEFINED +/* + * A structure for storing all kinds of useful information about the + * current (or another) time. + */ +struct tm +{ + int tm_sec; /* Seconds: 0-59 (K&R says 0-61?) */ + int tm_min; /* Minutes: 0-59 */ + int tm_hour; /* Hours since midnight: 0-23 */ + int tm_mday; /* Day of the month: 1-31 */ + int tm_mon; /* Months *since* january: 0-11 */ + int tm_year; /* Years since 1900 */ + int tm_wday; /* Days since Sunday (0-6) */ + int tm_yday; /* Days since Jan. 1: 0-365 */ + int tm_isdst; /* +1 Daylight Savings Time, 0 No DST, + * -1 don't know */ +}; +#define _TM_DEFINED +#endif + +_BEGIN_C_DECLS + +_CRTIMP clock_t __cdecl __MINGW_NOTHROW clock (void); +#if __MSVCRT_VERSION__ < 0x0800 +_CRTIMP time_t __cdecl __MINGW_NOTHROW time (time_t*); +_CRTIMP double __cdecl __MINGW_NOTHROW difftime (time_t, time_t); +_CRTIMP time_t __cdecl __MINGW_NOTHROW mktime (struct tm*); +#endif + +/* + * These functions write to and return pointers to static buffers that may + * be overwritten by other function calls. Yikes! + * + * NOTE: localtime, and perhaps the others of the four functions grouped + * below may return NULL if their argument is not 'acceptable'. Also note + * that calling asctime with a NULL pointer will produce an Invalid Page + * Fault and crap out your program. Guess how I know. Hint: stat called on + * a directory gives 'invalid' times in st_atime etc... + */ +_CRTIMP char* __cdecl __MINGW_NOTHROW asctime (const struct tm*); +#if __MSVCRT_VERSION__ < 0x0800 +_CRTIMP char* __cdecl __MINGW_NOTHROW ctime (const time_t*); +_CRTIMP struct tm* __cdecl __MINGW_NOTHROW gmtime (const time_t*); +_CRTIMP struct tm* __cdecl __MINGW_NOTHROW localtime (const time_t*); +#endif + +_CRTIMP size_t __cdecl __MINGW_NOTHROW strftime (char*, size_t, const char*, const struct tm*); + +#ifndef __STRICT_ANSI__ + +extern _CRTIMP void __cdecl __MINGW_NOTHROW _tzset (void); + +#ifndef _NO_OLDNAMES +extern _CRTIMP void __cdecl __MINGW_NOTHROW tzset (void); +#endif + +_CRTIMP char* __cdecl __MINGW_NOTHROW _strdate(char*); +_CRTIMP char* __cdecl __MINGW_NOTHROW _strtime(char*); + +/* These require newer versions of msvcrt.dll (6.10 or higher). */ +#if __MSVCRT_VERSION__ >= 0x0601 +_CRTIMP __time64_t __cdecl __MINGW_NOTHROW _time64( __time64_t*); +_CRTIMP __time64_t __cdecl __MINGW_NOTHROW _mktime64 (struct tm*); +_CRTIMP char* __cdecl __MINGW_NOTHROW _ctime64 (const __time64_t*); +_CRTIMP struct tm* __cdecl __MINGW_NOTHROW _gmtime64 (const __time64_t*); +_CRTIMP struct tm* __cdecl __MINGW_NOTHROW _localtime64 (const __time64_t*); +#endif /* __MSVCRT_VERSION__ >= 0x0601 */ + +/* These require newer versions of msvcrt.dll (8.00 or higher). */ +#if __MSVCRT_VERSION__ >= 0x0800 +_CRTIMP __time32_t __cdecl __MINGW_NOTHROW _time32 (__time32_t*); +_CRTIMP double __cdecl __MINGW_NOTHROW _difftime32 (__time32_t, __time32_t); +_CRTIMP double __cdecl __MINGW_NOTHROW _difftime64 (__time64_t, __time64_t); +_CRTIMP __time32_t __cdecl __MINGW_NOTHROW _mktime32 (struct tm*); +_CRTIMP __time32_t __cdecl __MINGW_NOTHROW _mkgmtime32 (struct tm*); +_CRTIMP __time64_t __cdecl __MINGW_NOTHROW _mkgmtime64 (struct tm*); +_CRTIMP char* __cdecl __MINGW_NOTHROW _ctime32 (const __time32_t*); +_CRTIMP struct tm* __cdecl __MINGW_NOTHROW _gmtime32 (const __time32_t*); +_CRTIMP struct tm* __cdecl __MINGW_NOTHROW _localtime32 (const __time32_t*); +#ifndef _USE_32BIT_TIME_T +_CRTALIAS time_t __cdecl __MINGW_NOTHROW time (time_t* _v) { return(_time64 (_v)); } +_CRTALIAS double __cdecl __MINGW_NOTHROW difftime (time_t _v1, time_t _v2) { return(_difftime64 (_v1,_v2)); } +_CRTALIAS time_t __cdecl __MINGW_NOTHROW mktime (struct tm* _v) { return(_mktime64 (_v)); } +_CRTALIAS time_t __cdecl __MINGW_NOTHROW _mkgmtime (struct tm* _v) { return(_mkgmtime64 (_v)); } +_CRTALIAS char* __cdecl __MINGW_NOTHROW ctime (const time_t* _v) { return(_ctime64 (_v)); } +_CRTALIAS struct tm* __cdecl __MINGW_NOTHROW gmtime (const time_t* _v) { return(_gmtime64 (_v)); } +_CRTALIAS struct tm* __cdecl __MINGW_NOTHROW localtime (const time_t* _v) { return(_localtime64 (_v)); } +#else +_CRTALIAS time_t __cdecl __MINGW_NOTHROW time (time_t* _v) { return(_time32 (_v)); } +_CRTALIAS double __cdecl __MINGW_NOTHROW difftime (time_t _v1, time_t _v2) { return(_difftime32 (_v1,_v2)); } +_CRTALIAS time_t __cdecl __MINGW_NOTHROW mktime (struct tm* _v) { return(_mktime32 (_v)); } +_CRTALIAS time_t __cdecl __MINGW_NOTHROW _mkgmtime (struct tm* _v) { return(_mkgmtime32 (_v)); } +_CRTALIAS char* __cdecl __MINGW_NOTHROW ctime (const time_t* _v) { return(_ctime32 (_v)); } +_CRTALIAS struct tm* __cdecl __MINGW_NOTHROW gmtime (const time_t* _v) { return(_gmtime32 (_v)); } +_CRTALIAS struct tm* __cdecl __MINGW_NOTHROW localtime (const time_t* _v) { return(_localtime32 (_v)); } +#endif /* !_USE_32BIT_TIME_T */ +#endif /* __MSVCRT_VERSION__ >= 0x0800 */ + +/* _daylight: non zero if daylight savings time is used. + * _timezone: difference in seconds between GMT and local time. + * _tzname: standard/daylight savings time zone names (an array with two + * elements). + */ +#ifdef __MSVCRT__ + +/* These are for compatibility with pre-VC 5.0 suppied MSVCRT. */ +extern _CRTIMP int* __cdecl __MINGW_NOTHROW __p__daylight (void); +extern _CRTIMP long* __cdecl __MINGW_NOTHROW __p__timezone (void); +extern _CRTIMP char** __cdecl __MINGW_NOTHROW __p__tzname (void); + +__MINGW_IMPORT int _daylight; +__MINGW_IMPORT long _timezone; +__MINGW_IMPORT char *_tzname[2]; + +#else /* not __MSVCRT (ie. crtdll) */ + +#ifndef __DECLSPEC_SUPPORTED + +extern int* _imp___daylight_dll; +extern long* _imp___timezone_dll; +extern char** _imp___tzname; + +#define _daylight (*_imp___daylight_dll) +#define _timezone (*_imp___timezone_dll) +#define _tzname (*_imp___tzname) + +#else /* __DECLSPEC_SUPPORTED */ + +__MINGW_IMPORT int _daylight_dll; +__MINGW_IMPORT long _timezone_dll; +__MINGW_IMPORT char* _tzname[2]; + +#define _daylight _daylight_dll +#define _timezone _timezone_dll + +#endif /* __DECLSPEC_SUPPORTED */ +#endif /* ! __MSVCRT__ */ +#endif /* ! __STRICT_ANSI__ */ + +#ifndef _NO_OLDNAMES +#ifdef __MSVCRT__ + +/* These go in the oldnames import library for MSVCRT. + */ +__MINGW_IMPORT int daylight; +__MINGW_IMPORT long timezone; +__MINGW_IMPORT char *tzname[2]; + +#else /* ! __MSVCRT__ */ +/* + * CRTDLL is royally messed up when it comes to these macros. + * TODO: import and alias these via oldnames import library instead + * of macros. + */ +#define daylight _daylight +/* + * NOTE: timezone not defined as a macro because it would conflict with + * struct timezone in sys/time.h. Also, tzname used to a be macro, but + * now it's in moldname. + */ +__MINGW_IMPORT char *tzname[2]; + +#endif /* ! __MSVCRT__ */ +#endif /* ! _NO_OLDNAMES */ + +#ifndef _WTIME_DEFINED +/* wide function prototypes, also declared in wchar.h */ +#ifndef __STRICT_ANSI__ +#ifdef __MSVCRT__ +_CRTIMP wchar_t* __cdecl __MINGW_NOTHROW _wasctime(const struct tm*); +#if __MSVCRT_VERSION__ < 0x0800 +_CRTIMP wchar_t* __cdecl __MINGW_NOTHROW _wctime(const time_t*); +#endif +_CRTIMP wchar_t* __cdecl __MINGW_NOTHROW _wstrdate(wchar_t*); +_CRTIMP wchar_t* __cdecl __MINGW_NOTHROW _wstrtime(wchar_t*); +#if __MSVCRT_VERSION__ >= 0x0601 +_CRTIMP wchar_t* __cdecl __MINGW_NOTHROW _wctime64 (const __time64_t*); +#endif +#if __MSVCRT_VERSION__ >= 0x0800 +_CRTIMP wchar_t* __cdecl __MINGW_NOTHROW _wctime32 (const __time32_t*); +#ifndef _USE_32BIT_TIME_T +_CRTALIAS wchar_t* __cdecl __MINGW_NOTHROW _wctime (const time_t* _v) { return(_wctime64 (_v)); } +#else +_CRTALIAS wchar_t* __cdecl __MINGW_NOTHROW _wctime (const time_t* _v) { return(_wctime32 (_v)); } +#endif +#endif /* __MSVCRT_VERSION__ >= 0x0800 */ +#endif /* __MSVCRT__ */ +#endif /* __STRICT_ANSI__ */ +_CRTIMP size_t __cdecl __MINGW_NOTHROW wcsftime (wchar_t*, size_t, const wchar_t*, const struct tm*); +#define _WTIME_DEFINED +#endif /* _WTIME_DEFINED */ + +_END_C_DECLS + +/* ------------------------------------------------------------------- + * CHEF PATCHES + * + * PROVIDE clock_gettime ETC. IN time.h FOR POSIX COMPLIANCE. + * + * This code was copied from the 64-bit TDM gcc compiler headers. It + * is here to allow certain libraries (like libxslt) to compile + * because they assume that they are only going to be built on a POSIX + * system. The C99 standards do not require that these functions be + * available but most POSIX systems provide them unless strict x-play + * compatibility is requested. + * + * On windows, configure could possibly identify that these functions + * are unavailable but since it tests for function availability to + * attempting to link a binary with said functions, these tests + * succeed with our TDM mingw runtime (because we indeed support these + * posix compatibility methods). Hence we pretend like we are a POSIX + * compliant system and export these methods. + */ + +/* POSIX 2008 says clock_gettime and timespec are defined in time.h header, + but other systems - like Linux, Solaris, etc - tend to declare such + recent extensions only if the following guards are met. */ +#if !defined(IN_WINPTHREAD) && \ + ((!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX)) || \ + (_POSIX_C_SOURCE > 2) || defined(__EXTENSIONS__)) +#include +#endif + +/* END OF CHEF PATCHES + * ------------------------------------------------------------------- + */ + +#endif /* ! RC_INVOKED */ +#endif /* ! _TIME_H: $RCSfile: time.h,v $: end of file */ diff --git a/cookbooks/yum/providers/globalconfig.rb b/cookbooks/mingw/libraries/_helper.rb similarity index 52% rename from cookbooks/yum/providers/globalconfig.rb rename to cookbooks/mingw/libraries/_helper.rb index 867d1c2..4a90fa4 100644 --- a/cookbooks/yum/providers/globalconfig.rb +++ b/cookbooks/mingw/libraries/_helper.rb @@ -1,9 +1,8 @@ # -# Cookbook Name:: yum -# Provider:: repository +# Cookbook:: mingw +# Library:: _helper # -# Author:: Sean OMeara -# Copyright 2013, Chef +# Copyright:: 2016, 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. @@ -18,24 +17,22 @@ # limitations under the License. # -# Allow for Chef 10 support -use_inline_resources if defined?(use_inline_resources) +module Mingw + module Helper + def win_friendly_path(path) + path.gsub(::File::SEPARATOR, ::File::ALT_SEPARATOR || '\\') if path + end -def whyrun_supported? - true -end + def archive_name(source) + url = ::URI.parse(source) + ::File.basename(::URI.unescape(url.path)) + end -action :create do - template new_resource.path do - source 'main.erb' - cookbook 'yum' - mode '0644' - variables(config: new_resource) + def tar_name(source) + aname = archive_name(source) + ::File.basename(aname, ::File.extname(aname)) + end end end -action :delete do - file new_resource.path do - action :delete - end -end +Chef::Resource.send(:include, Mingw::Helper) diff --git a/cookbooks/mingw/metadata.json b/cookbooks/mingw/metadata.json new file mode 100644 index 0000000..594f4fa --- /dev/null +++ b/cookbooks/mingw/metadata.json @@ -0,0 +1 @@ +{"name":"mingw","version":"2.0.0","description":"Installs a mingw/msys based toolchain on windows","long_description":"# mingw Cookbook\n\n[![Cookbook Version](http://img.shields.io/cookbook/v/mingw.svg)][cookbook] [![Build Status](http://img.shields.io/travis/chef-cookbooks/mingw.svg?branch=master)][travis]\n\nInstalls a mingw/msys based compiler tools chain on windows. This is required for compiling C software from source.\n\n## Requirements\n\n### Platforms\n\n- Windows\n\n### Chef\n\n- Chef 12.5+\n\n### Cookbooks\n\n- seven_zip\n\n## Usage\n\nAdd this cookbook as a dependency to your cookbook in its `metadata.rb` and include the default recipe in one of your recipes.\n\n```ruby\n# metadata.rb\ndepends 'mingw'\n```\n\n```ruby\n# your recipe.rb\ninclude_recipe 'mingw::default'\n```\n\nUse the `msys2_package` resource in any recipe to fetch msys2 based packages. Use the `mingw_get` resource in any recipe to fetch mingw packages. Use the `mingw_tdm_gcc` resource to fetch a version of the TDM GCC compiler.\n\nBy default, you should prefer the msys2 packages as they are newer and better supported. C/C++ compilers on windows use various different exception formats and you need to pick the right one for your task. In the 32-bit world, you have SJLJ (set-jump/long-jump) based exception handling and DWARF-2 (shortened to DW2) based exception handling. SJLJ produces code that can happily throw exceptions across stack frames of code compiled by MSVC. DW2 involves more extensive metadata but produces code that cannot unwind MSVC generated stack-frames - hence you need to ensure that you don't have any code that throws across a \"system call\". Certain languages and runtimes have specific requirements as to the exception format supported. As an example, if you are building code for Rust, you will probably need a modern gcc from msys2 with DW2 support as that's what the panic/exception formatter in Rust depends on. In a 64-bit world, you may still use SJLJ but compilers all commonly support SEH (structured exception handling).\n\nOf course, to further complicate matters, different versions of different compilers support different exception handling. The default compilers that come with mingw_get are 32-bit only compilers and support DW2\\. The TDM compilers come in 3 flavors: a 32-bit only version with SJLJ support, a 32-bit only version with DW2 support and a \"multilib\" compiler which supports only SJLJ in 32-bit mode but can produce 64-bit SEH code. The standard library support varies drastically between these various compiler flavors (even within the same version). In msys2, you can install a mingw-w64 based compilers for either 32-bit DW2 support or 64-bit SEH support. If all this hurts your brain, I can only apologize.\n\n## Resources\n\n### msys2_package\n\n- ':install' - Installs an msys2 package using pacman.\n- ':remove' - Uninstalls any existing msys2 package.\n- ':upgrade' - Upgrades the specified package using pacman.\n\nAll options also automatically attempt to install a 64-bit based msys2 base file system at the root path specified. Note that you probably won't need a \"32-bit\" msys2 unless you are actually on a 32-bit only platform. You can still install both 32 and 64-bit compilers and libraries in a 64-bit msys2 base file system.\n\n#### Parameters\n\n- `package` - An msys2 pacman package (or meta-package) to fetch and install. You may use a legal package wild-card pattern here if you are installing. This is the name attribute.\n- `root` - The root directory where msys2 tools will be installed. This directory must not contain any spaces in order to pacify old posix tools and most Makefiles.\n\n#### Examples\n\nTo get the core msys2 developer tools in `C:\\msys2`\n\n```ruby\nmsys2_package 'base-devel' do\n root 'C:\\msys2'\nend\n```\n\n### mingw_get\n\n#### Actions\n\n- `:install` - Installs a mingw package from sourceforge using mingw-get.exe.\n- `:remove` - Uninstalls a mingw package.\n- `:upgrade` - Upgrades a mingw package (even to a lower version).\n\n#### Parameters\n\n- `package` - A mingw-get package (or meta-package) to fetch and install. You may use a legal package wild-card pattern here if you are installing. This is the name attribute.\n- `root` - The root directory where msys and mingw tools will be installed. This directory must not contain any spaces in order to pacify old posix tools and most Makefiles.\n\n#### Examples\n\nTo get the core msys developer tools in `C:\\mingw32`\n\n```ruby\nmingw_get 'msys-base=2013072300-msys-bin.meta' do\n root 'C:\\mingw32'\nend\n```\n\n### mingw_tdm_gcc\n\n#### Actions\n\n- `:install` - Installs the TDM compiler toolchain at the given path. This only gives you a compiler. If you need any support tooling such as make/grep/awk/bash etc., see `mingw_get`.\n\n#### Parameters\n\n- `flavor` - Either `:sjlj_32` or `:seh_sjlj_64`. TDM-64 is a 32/64-bit multi-lib \"cross-compiler\" toolchain that builds 64-bit by default. It uses structured exception handling (SEH) in 64-bit code and setjump-longjump exception handling (SJLJ) in 32-bit code. TDM-32 only builds 32-bit binaries and uses SJLJ.\n- `root` - The root directory where compiler tools and runtime will be installed. This directory must not contain any spaces in order to pacify old posix tools and most Makefiles.\n- `version` - The version of the compiler to fetch and install. This is the name attribute. Currently, '5.1.0' is supported.\n\n#### Examples\n\nTo get the 32-bit TDM GCC compiler in `C:\\mingw32`\n\n```ruby\nmingw_tdm_gcc '5.1.0' do\n flavor :sjlj_32\n root 'C:\\mingw32'\nend\n```\n\n## License & Authors\n\n**Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io))\n\n**Copyright:** 2009-2016, Chef Software, Inc.\n\n```\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n\n[cookbook]: https://supermarket.chef.io/cookbooks/mingw\n[travis]: http://travis-ci.org/chef-cookbooks/mingw\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{"windows":">= 0.0.0"},"dependencies":{"seven_zip":">= 0.0.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{}} \ No newline at end of file diff --git a/cookbooks/postfix/files/default/tests/minitest/support/helpers.rb b/cookbooks/mingw/recipes/default.rb similarity index 69% rename from cookbooks/postfix/files/default/tests/minitest/support/helpers.rb rename to cookbooks/mingw/recipes/default.rb index f306f2e..33426f0 100644 --- a/cookbooks/postfix/files/default/tests/minitest/support/helpers.rb +++ b/cookbooks/mingw/recipes/default.rb @@ -1,5 +1,8 @@ -# encoding: utf-8 -# Copyright 2012-2014, Chef Software, Inc. +# +# Cookbook:: mingw +# Recipe:: default +# +# Copyright:: 2016, 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. @@ -12,14 +15,5 @@ # 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. -# -# helpers -module Helpers - # postfix - module Postfix - include MiniTest::Chef::Assertions - include MiniTest::Chef::Context - include MiniTest::Chef::Resources - end -end +include_recipe 'seven_zip::default' diff --git a/cookbooks/mingw/resources/get.rb b/cookbooks/mingw/resources/get.rb new file mode 100644 index 0000000..22cc9d2 --- /dev/null +++ b/cookbooks/mingw/resources/get.rb @@ -0,0 +1,56 @@ +# +# Cookbook:: mingw +# Resource:: get +# +# Copyright:: 2016, 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. +# 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. +# + +# Installs the core msys utilities needed for mingw/git/any other posix +# based toolchain at a desired location using mingw-get.exe. + +property :package, kind_of: String, name_property: true +property :root, kind_of: String, required: true + +resource_name :mingw_get + +action_class do + def mingw_do_action(action_cmd) + seven_zip_archive "fetching mingw-get to #{win_friendly_path(root)}" do + source 'http://iweb.dl.sourceforge.net/project/mingw/Installer/mingw-get/mingw-get-0.6.2-beta-20131004-1/mingw-get-0.6.2-mingw32-beta-20131004-1-bin.zip' + path root + checksum '2e0e9688d42adc68c5611759947e064156e169ff871816cae52d33ee0655826d' + not_if do + ::File.exist?(::File.join(root, 'bin/mingw-get.exe')) + end + end + + execute "performing #{action_cmd} for #{package}" do + command ".\\bin\\mingw-get.exe -v #{action_cmd} #{package}" + cwd root + end + end +end + +action :install do + mingw_do_action('install') +end + +action :upgrade do + mingw_do_action('upgrade') +end + +action :remove do + mingw_do_action('remove') +end diff --git a/cookbooks/mingw/resources/msys2_package.rb b/cookbooks/mingw/resources/msys2_package.rb new file mode 100644 index 0000000..a3594dd --- /dev/null +++ b/cookbooks/mingw/resources/msys2_package.rb @@ -0,0 +1,139 @@ +# +# Cookbook:: mingw +# Resource:: msys2_package +# +# Copyright:: 2016, 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. +# 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. +# + +# Installs msys2 base system and installs/upgrades packages within in. +# +# Where's the version flag? Where's idempotence you say? Well f*** you +# for trying to version your product. This is arch. They live on the edge. +# You never get anything but the latest version. And if that's broken... +# well that's your problem isn't it? And they don't believe in preserving +# older versions. Good luck! + +property :package, kind_of: String, name_property: true +property :root, kind_of: String, required: true + +resource_name :msys2_package + +action_class do + # + # Runs a command through a bash login shell made by our shim .bat file. + # The bash.bat file defaults %HOME% to #{root}/home/%USERNAME% and requests + # that the command be run in the current working directory. + # + def msys2_exec(comment, cmd) + f_root = win_friendly_path(root) + execute comment do + command ".\\bin\\bash.bat -c '#{cmd}'" + cwd f_root + live_stream true + environment('MSYSTEM' => 'MSYS') + end + end + + def msys2_init + cache_dir = ::File.join(root, '.cache') + f_cache_dir = win_friendly_path(cache_dir) + base_url = 'http://downloads.sourceforge.net/project/msys2/Base/x86_64/msys2-base-x86_64-20160205.tar.xz' + base_checksum = '7e97e2af042e1b6f62cf0298fe84839014ef3d4a3e7825cffc6931c66cc0fc20' + + unless ::File.exist?(::File.join(root, 'msys2.exe')) + seven_zip_archive "cache msys2 base to #{f_cache_dir}" do + source base_url + path f_cache_dir + checksum base_checksum + overwrite true + end + + seven_zip_archive "extract msys2 base archive to #{f_cache_dir}" do + source "#{f_cache_dir}\\#{tar_name(base_url)}" + path f_cache_dir + overwrite true + end + + ruby_block 'copy msys2 base files to root' do + block do + # Oh my god msys2 and pacman are picky as hell when it comes to + # updating core files. They use the mtime on certain files to + # determine if they need to updated or not and simply skip various + # steps otherwise. + ::FileUtils.cp_r(::Dir.glob("#{cache_dir}/msys64/*"), root, preserve: true) + end + end + end + + pacman_key_dir = ::File.join(root, 'etc/pacman.d/gnupg') + bin_dir = ::File.join(root, 'bin') + + directory win_friendly_path(bin_dir) + + cookbook_file win_friendly_path("#{bin_dir}/bash.bat") do + source 'bash.bat' + cookbook 'mingw' + end + + cookbook_file win_friendly_path(::File.join(root, 'custom-upgrade.sh')) do + source 'custom-upgrade.sh' + cookbook 'mingw' + end + + cookbook_file win_friendly_path(::File.join(root, 'etc/profile.d/custom_prefix.sh')) do + source 'custom_prefix.sh' + cookbook 'mingw' + end + + # $HOME is using files from /etc/skel. The home-directory creation step + # will automatically be performed if other users log in - so if you wish + # to globally modify user first time setup, edit /etc/skel or add + # "post-setup" steps to /etc/post-install/ + # The first-time init shell must be restarted and cannot be reused. + msys2_exec('msys2 first time init', 'exit') unless ::File.exist?(pacman_key_dir) + + # Update pacman and msys base packages. + if ::File.exist?(::File.join(root, 'usr/bin/update-core')) || !::File.exist?(::File.join(root, 'custom-upgrade.sh')) + msys2_exec('upgrade msys2 core', '/custom-upgrade.sh') + msys2_exec('upgrade msys2 core: part 2', 'pacman -Suu --noconfirm') + # Now we can actually upgrade everything ever. + msys2_exec('upgrade entire msys2 system: 1', 'pacman -Syuu --noconfirm') + # Might need to do it once more to pick up a few stragglers. + msys2_exec('upgrade entire msys2 system: 2', 'pacman -Syuu --noconfirm') + end + end + + def msys2_do_action(comment, action_cmd) + msys2_init + msys2_exec(comment, action_cmd) + end +end + +action :install do + msys2_do_action("installing #{package}", "pacman -S --needed --noconfirm #{package}") +end + +# Package name is ignored. This is arch. Why would you ever upgrade a single +# package and its deps? That'll just break everything else that ever depended +# on a different version of that dep. Because arch is wonderful like that. +# So you only get the choice to move everything to latest or not... it's the +# most agile development possible! +action :upgrade do + msys2_do_action("upgrading #{package}", "pacman -Syu --noconfirm #{package}") +end + +action :remove do + msys2_do_action("removing #{package}", "pacman -R --noconfirm #{package}") +end diff --git a/cookbooks/mingw/resources/tdm_gcc.rb b/cookbooks/mingw/resources/tdm_gcc.rb new file mode 100644 index 0000000..5c8d63c --- /dev/null +++ b/cookbooks/mingw/resources/tdm_gcc.rb @@ -0,0 +1,114 @@ +# +# Cookbook:: mingw +# Resource:: tdm_gcc +# +# Copyright:: 2016, 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. +# 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. +# + +# Installs a gcc based C/C++ compiler and runtime from TDM GCC. + +property :flavor, kind_of: Symbol, is: [:sjlj_32, :seh_sjlj_64], default: :seh_sjlj_64 +property :root, kind_of: String, required: true +property :version, kind_of: String, is: ['5.1.0'], name_property: true + +resource_name :mingw_tdm_gcc + +tdm_gcc_64 = { + 'http://iweb.dl.sourceforge.net/project/tdm-gcc/TDM-GCC%205%20series/5.1.0-tdm64-1/gcc-5.1.0-tdm64-1-core.tar.lzma' => + '29393aac890847089ad1e93f81a28f6744b1609c00b25afca818f3903e42e4bd', + 'http://iweb.dl.sourceforge.net/project/tdm-gcc/MinGW-w64%20runtime/GCC%205%20series/mingw64runtime-v4-git20150618-gcc5-tdm64-1.tar.lzma' => + '29186e0bb36824b10026d78bdcf238d631d8fc1d90718d2ebbd9ec239b6f94dd', + 'http://iweb.dl.sourceforge.net/project/tdm-gcc/GNU%20binutils/binutils-2.25-tdm64-1.tar.lzma' => + '4722bb7b4d46cef714234109e25e5d1cfd29f4e53365b6d615c8a00735f60e40', + 'http://iweb.dl.sourceforge.net/project/tdm-gcc/TDM-GCC%205%20series/5.1.0-tdm64-1/gcc-5.1.0-tdm64-1-c%2B%2B.tar.lzma' => + '17fd497318d1ac187a113e8665330d746ad9607a0406ab2374db0d8e6f4094d1', +} + +tdm_gcc_32 = { + 'http://iweb.dl.sourceforge.net/project/tdm-gcc/TDM-GCC%205%20series/5.1.0-tdm-1%20SJLJ/gcc-5.1.0-tdm-1-core.tar.lzma' => + '9199e6ecbce956ff4704b52098beb38e313176ace610285fb93758a08752870e', + 'http://iweb.dl.sourceforge.net/project/tdm-gcc/TDM-GCC%205%20series/5.1.0-tdm-1%20SJLJ/gcc-5.1.0-tdm-1-c%2B%2B.tar.lzma' => + '19fe46819ce43531d066b438479300027bbf06da57e8a10be5100466f80c28fc', +} + +action :install do + cache_dir = ::File.join(root, '.cache') + f_root = win_friendly_path(root) + + if flavor == :sjlj_32 + [ + 'binutils-bin=2.25.1', + 'libintl-dll=0.18.3.2', + 'mingwrt-dll=3.21.1', + 'mingwrt-dev=3.21.1', + 'w32api-dev=3.17', + ].each do |package_fragment| + mingw_get "install #{package_fragment} at #{f_root}" do + package "mingw32-#{package_fragment}-*" + root new_resource.root + end + end + end + + to_fetch = + case flavor + when :sjlj_32 + tdm_gcc_32 + when :seh_sjlj_64 + tdm_gcc_64 + else + raise "Unknown flavor: #{flavor}" + end + + to_fetch.each do |url, hash| + seven_zip_archive "cache #{archive_name(url)} to #{win_friendly_path(cache_dir)}" do + source url + path cache_dir + checksum hash + overwrite true + end + + seven_zip_archive "extract #{tar_name(url)} to #{f_root}" do + source ::File.join(cache_dir, tar_name(url)) + path root + overwrite true + end + end + + # Patch time.h headers for compatibility with winpthreads. + # These patches were made for binutils 2.25.1 for 32-bit TDM GCC only. + if flavor == :sjlj_32 + include_dir = win_friendly_path(::File.join(root, 'include')) + cookbook_file "#{include_dir}\\pthread.h" do + cookbook 'mingw' + source 'pthread.h' + end + + cookbook_file "#{include_dir}\\time.h" do + cookbook 'mingw' + source 'time.h' + end + end +end + +def archive_name(source) + url = ::URI.parse(source) + ::File.basename(::URI.unescape(url.path)) +end + +def tar_name(source) + aname = archive_name(source) + ::File.basename(aname, ::File.extname(aname)) +end diff --git a/cookbooks/omnibus_updater/CHANGELOG.md b/cookbooks/omnibus_updater/CHANGELOG.md index 826e85d..c0d5196 100644 --- a/cookbooks/omnibus_updater/CHANGELOG.md +++ b/cookbooks/omnibus_updater/CHANGELOG.md @@ -1,94 +1,149 @@ -v1.0.6 -====== -* Get rid of warnings about defined constant -* update Chef download url -* Updates supported versions -* require chef/rest -* use Chef::Mash explicitly -* Define the Chef::Mash constant if not provided by chef -* add test suites for ubuntu 14.04 and centos 7 +# omnibus_updater Cookbook CHANGELOG -v1.0.4 -====== -* file_cache_path path to store chef-client -* Avoid deleting chef-server packages if using the same cache dir -* Only backup the last old chef client file -* make sure directory exists before trying to write to it +This file is used to list changes made in each version of the omnibus_updater cookbook. -v1.0.2 -====== -* Maintenance updates -* Support for Fedora -* omnitrucker solaris update -* bug fixes +## 3.0.2 (2017-03-07) -v1.0.0 -====== -* Breaking change: `:always_download` is now defaulted to false -* Add solaris package install support (#37 thanks @jtimberman) -* Update notifies/subscribes usage to support older Chefs (#38 thanks @spheromak) +- Fix version detection for macOS systems +- Test with Local Delivery instead of Rake -v0.2.8 -====== -* Always download the package (thanks @miketheman for swiftly pointing out the issue!) +## 3.0.1 (2017-01-05) -v0.2.6 -====== -* Work with amazon linux (thanks @thommay) -* Disable updates on debian 5 (thanks @ianand0204) -* Only use major version on debian systems (thanks @kvs) -* Allow prevention of downgrades (thanks @buysse) -* Add support for restarting chef service after upgrade (thanks @andrewfraley) +- Remove the remaining system gem reference -v0.2.4 -====== -* Only download omnibus package if version difference detected (#20 #22 #23) -* Provide attribute for always downloading package even if version matches +## 3.0.0 (2017-01-05) -v0.2.3 -====== -* Use chef internals for interactions with omnitruck to provide proper proxy support (#19) +- Added support for the new upgrade exit code (213) introduced with RFC062 and first shipped in chef 12.15.19 +- Fix support for upgrading Windows client 12.6 and later by first moving the install directory +- Remove the recipe to cleanup system ruby chef installs. We should assume everyone is on Omnibus installs at this point and this same functionality can be easily implemented in your own recipes +- Added suse, opensuse, and opensuseleap to the metadata -v0.2.0 -====== -* Use omnitruck client for url generation for package fetching -* Use `prerelease` in favor of `allow_release_clients` +## 2.0.0 (2016-08-19) -v0.1.2 -====== -* Fix regression on debian package path construction (thanks [ashmere](https://github.com/ashmere)) +- Hard fail on unsupported platforms now +- Add suse support +- Add additional chefspec tests -v0.1.1 -====== -* Search for proper version suffix if not provided (removes default '-1') -* Do not allow release clients by default when version search is enabled -* Push omnibus package installation to the end of run (reduces issue described in #10) -* Allow updater to be disabled via attribute (thanks [Teemu Matilainen](https://github.com/tmatilai)) +## 1.2.1 (2016-08-19) -v0.1.0 -====== -* Fix redhat related versioning issues -* Remove requirement for '-1' suffix on versions -* Initial support for automatic latest version install +- Use the improved rakefile +- Fix github URLs in the metadata +- Add testing on additional platforms to kitchen config +- fix 1.2.0 no implicit conversion of nil to string. fixes #123 -v0.0.5 -====== -* Add support for Ubuntu 12.10 -* Path fixes for non-64 bit packages (thanks [ashmere](https://github.com/ashmere)) +## 1.2.0 (2016-08-18) -v0.0.4 -====== -* Use new aws bucket by default -* Update file key building +- Add OS X DMG Support and fix Mac OS X Version Determination +- Add a potential Restart Fix +- Add chef_version metadata to the metadata.rb file +- Change maintainership to Chef and add standard Chef contributing, test, and maintainer docs +- Renamed the test recipe for consistency and removed the use of minitest +- Swapped Librarian for Berkshelf +- Added testing in Travis CI using ChefDK +- Resolved Foodcritic FC001/FC043 warnings +- Resolved all Cookstyle warnings +- Identify Fedora to be EL7 not EL6 +- Avoid a node.set deprecation warning +- No need to warn on Debian 5\. No one should be on this now. +- Add a test for the standard flows -v0.0.3 -====== -* Path fix for debian omnibus packages (thanks [ashmere](https://github.com/ashmere)) +# v1.1.0 -v0.0.2 -====== -* Add robust check when uninstalling chef gem to prevent removal from omnibus +- Add Windows support (only Chef client versions 12.5.1 and below). +- Improve upgrade behavior on Amazon Linux +- Explicitly require windows testing gems in order to support test-kitchen 1.6.x. -v0.0.1 -====== -* Initial release +# v1.0.6 + +- Get rid of warnings about defined constant +- update Chef download url +- Updates supported versions +- require chef/rest +- use Chef::Mash explicitly +- Define the Chef::Mash constant if not provided by chef +- add test suites for ubuntu 14.04 and centos 7 + +# v1.0.4 + +- file_cache_path path to store chef-client +- Avoid deleting chef-server packages if using the same cache dir +- Only backup the last old chef client file +- make sure directory exists before trying to write to it + +# v1.0.2 + +- Maintenance updates +- Support for Fedora +- omnitrucker solaris update +- bug fixes + +# v1.0.0 + +- Breaking change: `:always_download` is now defaulted to false +- Add solaris package install support (#37 thanks @jtimberman) +- Update notifies/subscribes usage to support older Chefs (#38 thanks @spheromak) + +# v0.2.8 + +- Always download the package (thanks @miketheman for swiftly pointing out the issue!) + +# v0.2.6 + +- Work with amazon linux (thanks @thommay) +- Disable updates on debian 5 (thanks @ianand0204) +- Only use major version on debian systems (thanks @kvs) +- Allow prevention of downgrades (thanks @buysse) +- Add support for restarting chef service after upgrade (thanks @andrewfraley) + +# v0.2.4 + +- Only download omnibus package if version difference detected (#20 #22 #23) +- Provide attribute for always downloading package even if version matches + +# v0.2.3 + +- Use chef internals for interactions with omnitruck to provide proper proxy support (#19) + +# v0.2.0 + +- Use omnitruck client for url generation for package fetching +- Use `prerelease` in favor of `allow_release_clients` + +# v0.1.2 + +- Fix regression on debian package path construction (thanks [ashmere](https://github.com/ashmere)) + +# v0.1.1 + +- Search for proper version suffix if not provided (removes default '-1') +- Do not allow release clients by default when version search is enabled +- Push omnibus package installation to the end of run (reduces issue described in #10) +- Allow updater to be disabled via attribute (thanks [Teemu Matilainen](https://github.com/tmatilai)) + +# v0.1.0 + +- Fix redhat related versioning issues +- Remove requirement for '-1' suffix on versions +- Initial support for automatic latest version install + +# v0.0.5 + +- Add support for Ubuntu 12.10 +- Path fixes for non-64 bit packages (thanks [ashmere](https://github.com/ashmere)) + +# v0.0.4 + +- Use new aws bucket by default +- Update file key building + +# v0.0.3 + +- Path fix for debian omnibus packages (thanks [ashmere](https://github.com/ashmere)) + +# v0.0.2 + +- Add robust check when uninstalling chef gem to prevent removal from omnibus + +# v0.0.1 + +- Initial release diff --git a/cookbooks/omnibus_updater/CONTRIBUTING.md b/cookbooks/omnibus_updater/CONTRIBUTING.md new file mode 100644 index 0000000..cd21578 --- /dev/null +++ b/cookbooks/omnibus_updater/CONTRIBUTING.md @@ -0,0 +1 @@ +Please refer to diff --git a/cookbooks/omnibus_updater/MAINTAINERS.md b/cookbooks/omnibus_updater/MAINTAINERS.md new file mode 100644 index 0000000..645ed14 --- /dev/null +++ b/cookbooks/omnibus_updater/MAINTAINERS.md @@ -0,0 +1,15 @@ + + +# Maintainers + +This file lists how this cookbook project is maintained. When making changes to the system, this file tells you who needs to review your patch - you need a review from an existing maintainer for the cookbook to provide a :+1: on your pull request. Additionally, you need to not receive a veto from a Lieutenant or the Project Lead. + +Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) for details on the process and how to become a maintainer or the project lead. + +# Project Maintainer +* [Tim Smith](https://github.com/tas50) + +# Maintainers +* [Jennifer Davis](https://github.com/sigje) +* [Tim Smith](https://github.com/tas50) +* [Thom May](https://github.com/thommay) diff --git a/cookbooks/omnibus_updater/README.md b/cookbooks/omnibus_updater/README.md index b4c8454..5c08a6d 100644 --- a/cookbooks/omnibus_updater/README.md +++ b/cookbooks/omnibus_updater/README.md @@ -1,36 +1,37 @@ -OmnibusUpdater -============== +# omnibus_updater cookbook -Update your omnibus! This cookbook can install the omnibus -Chef package into your system if you are currently running -via gem install, and it can keep your omnibus install up -to date. +[![Build Status](https://travis-ci.org/chef-cookbooks/omnibus_updater.svg?branch=master)](http://travis-ci.org/chef-cookbooks/omnibus_updater) [![Cookbook Version](https://img.shields.io/cookbook/v/omnibus_updater.svg)](https://supermarket.chef.io/cookbooks/omnibus_updater) -Supports -======== +This cookbook allows you to upgrade the omnibus based Chef install package via Chef. You can run either latest or pin to specific version. -- redhat -- centos -- amazon -- scientific -- oracle -- debian -- ubuntu -- mac_os_x -- solaris +## Requirements -Usage -===== +### Platforms -Add the recipe to your run list and specify what version should -be installed on the node: +- Debian / Ubuntu +- Mac OS X +- RHEL (redhat, centos, amazon, scientific, oracle) +- Solaris +- SLES / openSUSE +- Windows + +### Chef + +- Chef 11+ + +### Cookbooks + +- none + +## Usage + +Add the recipe to your run list and specify what version should be installed on the node: `knife node run_list add recipe[omnibus_updater]` -In your role you'll likely want to set the version. It defaults -to nothing, and will install the latest.. +In your role you'll likely want to set the version. It defaults to nothing, and will install the latest.. -``` +```ruby override_attributes( :omnibus_updater => { :version => '11.4.0' @@ -38,64 +39,63 @@ override_attributes( ) ``` -It can also uninstall Chef from the system Ruby installation -if you tell it to: +## Features -``` -override_attributes( - :omnibus_updater => { - :remove_chef_system_gem => true - } -) +### Latest Version + +Force installation of the latest version regardless of value stored in version attribute by setting the `force_latest` attribute. + +### Chef Killing + +By default the omnibus updater will kill the chef instance by raising an exception. You can turn this off using the `kill_chef_on_upgrade` attribute. It is not recommended to turn this off. Internal chef libraries may change, move, or no longer exist. The currently running instance can encounter unexpected states because of this. To prevent this, the updater will attempt to kill the Chef instance so that it can be restarted in a normal state. + +When `kill_chef_on_upgrade` is true Test-kitchen's converge stage will fail. To avoid this and attempt a second converge after the initial converge aborts, you can configure `.kitchen.yml` to retry a converge given a specific exit code from `node['omnibus_updater']['kill_chef_on_upgrade_exit_code']`. The second converge should pick up the new chef-client version and exit without error. The following is how to accomplish this: + +```yaml +provisioner: + retry_on_exit_code: + - 213 + max_retries: 1 + wait_for_retry: 1 + client_rb: + exit_status: :enabled + client_fork: false ``` -Features -======== +Exit code 213 is a special designation for Chef Client Upgrade and only exists in Chef Client >= 12.15.19\. If using an older client, you can replace exit code 213 (Chef upgrade) with 3 (SIGTERM recvd) as a workaround. Exit codes are documented here: -Latest Version --------------- - -Force installation of the latest version regardless of value stored in version -attribute by setting the `force_latest` attribute. - -Chef Killing ------------- - -By default the omnibus updater will kill the chef instance by raising an exception. -You can turn this off using the `kill_chef_on_upgrade` attribute. It is not -recommended to turn this off. Internal chef libraries may change, move, or no -longer exist. The currently running instance can encounter unexpected states because -of this. To prevent this, the updater will attempt to kill the Chef instance so -that it can be restarted in a normal state. - -Restart chef-client Service ---------------------------- +## Restart chef-client Service Use the `restart_chef_service` attribute to restart chef-client if you have it running as a service. -Prerelease --------- +### Prerelease Prereleases can be installed via the auto-installation using `prerelease` attribute. -Disable -------- +### Disable -If you want to disable the updater you can set the `disabled` -attribute to true. This might be useful if the cookbook is added -to a role but should then be skipped for example on a Chef server. +If you want to disable the updater you can set the `disabled` attribute to true. This might be useful if the cookbook is added to a role but should then be skipped for example on a Chef server. -Prevent Downgrade ------------------ +### Prevent Downgrade -If you want to prevent the updater from downgrading chef on a node, you -can set the `prevent_downgrade` attribute to true. This can be useful -for testing new versions manually. Note that the `always_download` -attribute takes precedence if set. +If you want to prevent the updater from downgrading chef on a node, you can set the `prevent_downgrade` attribute to true. This can be useful for testing new versions manually. Note that the `always_download` attribute takes precedence if set. -Infos -===== +## License & Authors -* Repo: https://github.com/hw-cookbooks/omnibus_updater -* IRC: Freenode @ #heavywater -* Cookbook: http://ckbk.it/omnibus_updater +- Author: Chris Roberts ([chrisroberts.code@gmail.com](mailto:chrisroberts.code@gmail.com)) + +```text +Copyright:: 2010-2016, 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. +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. +``` diff --git a/cookbooks/omnibus_updater/attributes/default.rb b/cookbooks/omnibus_updater/attributes/default.rb index f41a1bd..2d1ebc4 100644 --- a/cookbooks/omnibus_updater/attributes/default.rb +++ b/cookbooks/omnibus_updater/attributes/default.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: omnibus_updater +# Cookbook:: omnibus_updater # Attributes:: default # -# Copyright 2014, Heavy Water Ops, LLC +# Copyright:: 2014-2017, Heavy Water Ops, LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,15 +17,16 @@ # limitations under the License. # -default[:omnibus_updater][:version] = nil -default[:omnibus_updater][:force_latest] = false -default[:omnibus_updater][:cache_dir] = "#{Chef::Config[:file_cache_path]}/omnibus_updater" -default[:omnibus_updater][:cache_omnibus_installer] = false -default[:omnibus_updater][:remove_chef_system_gem] = false -default[:omnibus_updater][:prerelease] = false -default[:omnibus_updater][:disabled] = false -default[:omnibus_updater][:kill_chef_on_upgrade] = true -default[:omnibus_updater][:always_download] = false -default[:omnibus_updater][:prevent_downgrade] = false -default[:omnibus_updater][:restart_chef_service] = false -default[:omnibus_updater][:checksum] = nil +default['omnibus_updater']['version'] = nil +default['omnibus_updater']['force_latest'] = false +default['omnibus_updater']['cache_dir'] = "#{Chef::Config[:file_cache_path]}/omnibus_updater" +default['omnibus_updater']['cache_omnibus_installer'] = false +default['omnibus_updater']['prerelease'] = false +default['omnibus_updater']['disabled'] = false +default['omnibus_updater']['kill_chef_on_upgrade'] = true +default['omnibus_updater']['kill_chef_on_upgrade_exit_code'] = 213 +default['omnibus_updater']['always_download'] = false +default['omnibus_updater']['prevent_downgrade'] = false +default['omnibus_updater']['restart_chef_service'] = false +default['omnibus_updater']['checksum'] = nil +default['omnibus_updater']['addlocal'] = 'ChefClientFeature,ChefServiceFeature' # Recommend adding ChefPSModuleFeature for clients 12.4.0 and up on windows platform. diff --git a/cookbooks/omnibus_updater/libraries/omnibus_checker.rb b/cookbooks/omnibus_updater/libraries/omnibus_checker.rb index 445cc07..23cf860 100644 --- a/cookbooks/omnibus_updater/libraries/omnibus_checker.rb +++ b/cookbooks/omnibus_updater/libraries/omnibus_checker.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: omnibus_updater +# Cookbook:: omnibus_updater # Library:: omnibuschecker # -# Copyright 2014, Heavy Water Ops, LLC +# Copyright:: 2014-2017, Heavy Water Ops, LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -25,6 +25,6 @@ end OmnibusChecker.send(:extend, OmnibusChecker) -unless(Chef::Recipe.instance_methods.include?(:is_omnibus?)) +unless Chef::Recipe.instance_methods.include?(:is_omnibus?) Chef::Recipe.send(:include, OmnibusChecker) end diff --git a/cookbooks/omnibus_updater/libraries/omnitrucker.rb b/cookbooks/omnibus_updater/libraries/omnitrucker.rb index 0179dd3..e8d9247 100644 --- a/cookbooks/omnibus_updater/libraries/omnitrucker.rb +++ b/cookbooks/omnibus_updater/libraries/omnitrucker.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: omnibus_updater +# Cookbook:: omnibus_updater # Library:: omnitrucker # -# Copyright 2014, Heavy Water Ops, LLC +# Copyright:: 2014-2017, Heavy Water Ops, LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,37 +17,33 @@ # limitations under the License. # -require "chef/rest" -require "chef/mash" -require "net/http" +require 'chef/rest' +require 'chef/mash' +require 'net/http' -unless(Chef.constants.include?(:Mash)) - Chef::Mash = Mash -end +Chef::Mash = Mash unless Chef.constants.include?(:Mash) module OmnibusTrucker class << self URL_MAP = { - :p => :platform, :pv => :platform_version, :m => :machine, - :v => :version, :prerelease => :prerelease, - :nightlies => :nightlies - } unless defined?(URL_MAP) + p: :platform, pv: :platform_version, m: :machine, + v: :version, prerelease: :prerelease, + nightlies: :nightlies + }.freeze unless defined?(URL_MAP) def build_url(*opts) args = node = nil opts.each do |o| - if(o.kind_of?(Hash)) + if o.is_a?(Hash) args = o - elsif(o.kind_of?(Chef::Node)) + elsif o.is_a?(Chef::Node) node = o else raise ArgumentError.new "Provided argument is not allowed: #{o.class}" end end args ||= {} - if(node) - args = collect_attributes(node).merge(args) - end + args = collect_attributes(node).merge(args) if node url = args[:url] || "http://www.chef.io/chef/download#{'-server' if args[:server]}" u_args = URL_MAP.map do |u_k, a_k| "#{u_k}=#{args[a_k]}" unless args[a_k].nil? @@ -55,46 +51,52 @@ module OmnibusTrucker "#{url}?#{u_args.join('&')}" end - def collect_attributes(node, args={}) + def collect_attributes(node, args = {}) set = Chef::Mash[ - [:platform_family, :platform, :platform_version].map do |k| + %w(platform_family platform platform_version).map do |k| [k, args[k] || node[k]] end ] - unless(@attrs) - if(set[:platform] == 'amazon') - @attrs = {:platform => 'el', :platform_version => 6} - elsif(set[:platform_family] == 'fedora') - @attrs = {:platform => 'el', :platform_version => 6} - elsif(set[:platform_family] == 'rhel') - @attrs = {:platform => 'el', :platform_version => set[:platform_version].to_i} - elsif(set[:platform] == 'debian') - @attrs = {:platform => set[:platform], :platform_version => set[:platform_version].to_i} - elsif(set[:platform_family] == 'mac_os_x') - @attrs = {:platform => set[:platform_family], :platform_version => [set[:platform_version].to_f, 10.7].min} + unless @attrs + if set['platform'] == 'amazon' + @attrs = { platform: 'el', platform_version: 6 } + elsif set['platform_family'] == 'fedora' + @attrs = { platform: 'el', platform_version: 7 } + elsif set['platform_family'] == 'rhel' + @attrs = { platform: 'el', platform_version: set['platform_version'].to_i } + elsif set['platform'] == 'debian' + @attrs = { platform: set['platform'], platform_version: set['platform_version'].to_i } + elsif set['platform'] =~ /opensuse/ + @attrs = { platform: 'suse', platform_version: 13 } + elsif set['platform_family'] == 'suse' + @attrs = { platform: 'sles', platform_version: 12 } + elsif set['platform_family'] == 'mac_os_x' + major, minor, _patch = set['platform_version'].split('.').map { |v| String(v) } + minor = [minor.to_i, 11].min # this is somewhat of a hack, we need to prevent this recipe to construct links for 10.12 for which there is no download yet... + @attrs = { platform: set['platform_family'], platform_version: [[major, minor].join('.'), '10.7'].max { |x, y| Gem::Version.new(x) <=> Gem::Version.new(y) } } + elsif set['platform_family'] == 'windows' + @attrs = { platform: set['platform'], platform_version: '2008r2' } else - @attrs = {:platform => set[:platform], :platform_version => set[:platform_version]} + @attrs = { platform: set['platform'], platform_version: set['platform_version'] } end - @attrs[:machine] = args[:machine] || node[:kernel][:machine] - @attrs[:machine] = "i386" if(set[:platform_family] == 'solaris2' && @attrs[:machine] == "i86pc") + @attrs[:machine] = args[:machine] || node['kernel']['machine'] + @attrs[:machine] = 'i386' if set['platform_family'] == 'solaris2' && @attrs[:machine] == 'i86pc' end @attrs end def url(url_or_node, node = nil) - if(url_or_node.is_a?(Chef::Node)) + if url_or_node.is_a?(Chef::Node) url = build_url(url_or_node) node = url_or_node else url = url_or_node - raise "Node instance is required for Omnitruck.url!" unless node + raise 'Node instance is required for Omnitruck.url!' unless node end + Chef::Log.info("Using URL '#{url}' for chef-download") unless url.nil? request = Chef::REST::RESTRequest.new(:head, URI.parse(url), nil) result = request.call - if(result.kind_of?(Net::HTTPRedirection)) - result['location'] - end + result['location'] if result.is_a?(Net::HTTPRedirection) end - end end diff --git a/cookbooks/omnibus_updater/metadata.json b/cookbooks/omnibus_updater/metadata.json index ff2316d..2455d5e 100644 --- a/cookbooks/omnibus_updater/metadata.json +++ b/cookbooks/omnibus_updater/metadata.json @@ -1,56 +1 @@ -{ - "name": "omnibus_updater", - "description": "Chef omnibus package updater and installer", - "long_description": "OmnibusUpdater\n==============\n\nUpdate your omnibus! This cookbook can install the omnibus\nChef package into your system if you are currently running\nvia gem install, and it can keep your omnibus install up\nto date.\n\nSupports\n========\n\n- redhat\n- centos\n- amazon\n- scientific\n- oracle\n- debian\n- ubuntu\n- mac_os_x\n- solaris\n\nUsage\n=====\n\nAdd the recipe to your run list and specify what version should\nbe installed on the node:\n\n`knife node run_list add recipe[omnibus_updater]`\n\nIn your role you'll likely want to set the version. It defaults\nto nothing, and will install the latest..\n\n```\noverride_attributes(\n :omnibus_updater => {\n :version => '11.4.0'\n }\n)\n```\n\nIt can also uninstall Chef from the system Ruby installation\nif you tell it to:\n\n```\noverride_attributes(\n :omnibus_updater => {\n :remove_chef_system_gem => true\n }\n)\n```\n\nFeatures\n========\n\nLatest Version\n--------------\n\nForce installation of the latest version regardless of value stored in version\nattribute by setting the `force_latest` attribute.\n\nChef Killing\n------------\n\nBy default the omnibus updater will kill the chef instance by raising an exception.\nYou can turn this off using the `kill_chef_on_upgrade` attribute. It is not\nrecommended to turn this off. Internal chef libraries may change, move, or no\nlonger exist. The currently running instance can encounter unexpected states because\nof this. To prevent this, the updater will attempt to kill the Chef instance so\nthat it can be restarted in a normal state.\n\nRestart chef-client Service\n---------------------------\n\nUse the `restart_chef_service` attribute to restart chef-client if you have it running as a service.\n\nPrerelease\n--------\n\nPrereleases can be installed via the auto-installation using `prerelease` attribute.\n\nDisable\n-------\n\nIf you want to disable the updater you can set the `disabled`\nattribute to true. This might be useful if the cookbook is added\nto a role but should then be skipped for example on a Chef server.\n\nPrevent Downgrade\n-----------------\n\nIf you want to prevent the updater from downgrading chef on a node, you \ncan set the `prevent_downgrade` attribute to true. This can be useful\nfor testing new versions manually. Note that the `always_download` \nattribute takes precedence if set.\n\nInfos\n=====\n\n* Repo: https://github.com/hw-cookbooks/omnibus_updater\n* IRC: Freenode @ #heavywater\n* Cookbook: http://ckbk.it/omnibus_updater\n", - "maintainer": "Chris Roberts", - "maintainer_email": "chrisroberts.code@gmail.com", - "license": "Apache 2.0", - "platforms": { - "redhat": ">= 0.0.0", - "centos": ">= 0.0.0", - "amazon": ">= 0.0.0", - "scientific": ">= 0.0.0", - "oracle": ">= 0.0.0", - "debian": ">= 0.0.0", - "ubuntu": ">= 0.0.0", - "mac_os_x": ">= 0.0.0", - "solaris": ">= 0.0.0" - }, - "dependencies": { - - }, - "recommendations": { - - }, - "suggestions": { - - }, - "conflicting": { - - }, - "providing": { - - }, - "replacing": { - - }, - "attributes": { - - }, - "groupings": { - - }, - "recipes": { - - }, - "version": "1.0.6", - "source_url": "", - "issues_url": "", - "privacy": false, - "chef_versions": [ - - ], - "ohai_versions": [ - - ] -} +{"name":"omnibus_updater","version":"3.0.2","description":"Chef omnibus package updater and installer","long_description":"# omnibus_updater cookbook\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/omnibus_updater.svg?branch=master)](http://travis-ci.org/chef-cookbooks/omnibus_updater) [![Cookbook Version](https://img.shields.io/cookbook/v/omnibus_updater.svg)](https://supermarket.chef.io/cookbooks/omnibus_updater)\n\nThis cookbook allows you to upgrade the omnibus based Chef install package via Chef. You can run either latest or pin to specific version.\n\n## Requirements\n\n### Platforms\n\n- Debian / Ubuntu\n- Mac OS X\n- RHEL (redhat, centos, amazon, scientific, oracle)\n- Solaris\n- SLES / openSUSE\n- Windows\n\n### Chef\n\n- Chef 11+\n\n### Cookbooks\n\n- none\n\n## Usage\n\nAdd the recipe to your run list and specify what version should be installed on the node:\n\n`knife node run_list add recipe[omnibus_updater]`\n\nIn your role you'll likely want to set the version. It defaults to nothing, and will install the latest..\n\n```ruby\noverride_attributes(\n :omnibus_updater => {\n :version => '11.4.0'\n }\n)\n```\n\n## Features\n\n### Latest Version\n\nForce installation of the latest version regardless of value stored in version attribute by setting the `force_latest` attribute.\n\n### Chef Killing\n\nBy default the omnibus updater will kill the chef instance by raising an exception. You can turn this off using the `kill_chef_on_upgrade` attribute. It is not recommended to turn this off. Internal chef libraries may change, move, or no longer exist. The currently running instance can encounter unexpected states because of this. To prevent this, the updater will attempt to kill the Chef instance so that it can be restarted in a normal state.\n\nWhen `kill_chef_on_upgrade` is true Test-kitchen's converge stage will fail. To avoid this and attempt a second converge after the initial converge aborts, you can configure `.kitchen.yml` to retry a converge given a specific exit code from `node['omnibus_updater']['kill_chef_on_upgrade_exit_code']`. The second converge should pick up the new chef-client version and exit without error. The following is how to accomplish this:\n\n```yaml\nprovisioner:\n retry_on_exit_code:\n - 213\n max_retries: 1\n wait_for_retry: 1\n client_rb:\n exit_status: :enabled\n client_fork: false\n```\n\nExit code 213 is a special designation for Chef Client Upgrade and only exists in Chef Client >= 12.15.19\\. If using an older client, you can replace exit code 213 (Chef upgrade) with 3 (SIGTERM recvd) as a workaround. Exit codes are documented here: \n\n## Restart chef-client Service\n\nUse the `restart_chef_service` attribute to restart chef-client if you have it running as a service.\n\n### Prerelease\n\nPrereleases can be installed via the auto-installation using `prerelease` attribute.\n\n### Disable\n\nIf you want to disable the updater you can set the `disabled` attribute to true. This might be useful if the cookbook is added to a role but should then be skipped for example on a Chef server.\n\n### Prevent Downgrade\n\nIf you want to prevent the updater from downgrading chef on a node, you can set the `prevent_downgrade` attribute to true. This can be useful for testing new versions manually. Note that the `always_download` attribute takes precedence if set.\n\n## License & Authors\n\n- Author: Chris Roberts ([chrisroberts.code@gmail.com](mailto:chrisroberts.code@gmail.com))\n\n```text\nCopyright:: 2010-2016, Chef Software, Inc\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{"amazon":">= 0.0.0","centos":">= 0.0.0","debian":">= 0.0.0","mac_os_x":">= 0.0.0","opensuse":">= 0.0.0","opensuseleap":">= 0.0.0","oracle":">= 0.0.0","redhat":">= 0.0.0","scientific":">= 0.0.0","solaris":">= 0.0.0","suse":">= 0.0.0","ubuntu":">= 0.0.0","windows":">= 0.0.0"},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{}} \ No newline at end of file diff --git a/cookbooks/omnibus_updater/metadata.rb b/cookbooks/omnibus_updater/metadata.rb deleted file mode 100644 index f8c32fe..0000000 --- a/cookbooks/omnibus_updater/metadata.rb +++ /dev/null @@ -1,11 +0,0 @@ -name "omnibus_updater" -maintainer "Chris Roberts" -maintainer_email "chrisroberts.code@gmail.com" -license "Apache 2.0" -description "Chef omnibus package updater and installer" -long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -version "1.0.6" - -%w(redhat centos amazon scientific oracle debian ubuntu mac_os_x solaris).each do |plat| - supports plat -end diff --git a/cookbooks/omnibus_updater/recipes/default.rb b/cookbooks/omnibus_updater/recipes/default.rb index e6f646d..96b13cd 100644 --- a/cookbooks/omnibus_updater/recipes/default.rb +++ b/cookbooks/omnibus_updater/recipes/default.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: omnibus_updater +# Cookbook:: omnibus_updater # Recipe:: default # -# Copyright 2014, Heavy Water Ops, LLC +# Copyright:: 2014-2017, Heavy Water Ops, LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,17 +17,15 @@ # limitations under the License. # -if(node[:omnibus_updater][:disabled]) +# fail hard if we're on an unsupported platform +# feel free to open PRs to add additional platforms +unless platform_family?('debian', 'fedora', 'mac_os_x', 'rhel', 'solaris2', 'windows', 'suse') + Chef::Application.fatal! "Omnibus updater does not support the #{node['platform']} platform" +end + +if node['omnibus_updater']['disabled'] Chef::Log.warn 'Omnibus updater disabled via `disabled` attribute' -elsif(node[:platform] == 'debian' && Gem::Version.new(node[:platform_version]) < Gem::Version.new('6.0.0')) - Chef::Log.warn 'Omnibus updater does not support Debian 5' -elsif(node[:platform] == 'raspbian') - Chef::Log.warn 'Omnibus updater does not support Raspbian' else include_recipe 'omnibus_updater::downloader' include_recipe 'omnibus_updater::installer' end - -if(node[:omnibus_updater][:remove_chef_system_gem]) - include_recipe 'omnibus_updater::remove_chef_system_gem' -end diff --git a/cookbooks/omnibus_updater/recipes/downloader.rb b/cookbooks/omnibus_updater/recipes/downloader.rb index 5b3d2b8..8645dc8 100644 --- a/cookbooks/omnibus_updater/recipes/downloader.rb +++ b/cookbooks/omnibus_updater/recipes/downloader.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: omnibus_updater +# Cookbook:: omnibus_updater # Recipe:: downloader # -# Copyright 2014, Heavy Water Ops, LLC +# Copyright:: 2014-2017, Heavy Water Ops, LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -20,42 +20,48 @@ # NOTE: This recipe is here for others that just want the # package, not the actual installation (lxc for example) -if(node[:omnibus_updater][:direct_url]) - remote_path = node[:omnibus_updater][:direct_url] +if node['omnibus_updater']['direct_url'] + remote_path = node['omnibus_updater']['direct_url'] else - version = node[:omnibus_updater][:version] || '' + version = node['omnibus_updater']['version'] || '' remote_path = OmnibusTrucker.url( OmnibusTrucker.build_url(node, - :version => node[:omnibus_updater][:force_latest] ? nil : version.sub(/\-.+$/, ''), - :prerelease => node[:omnibus_updater][:preview] - ), node + version: node['omnibus_updater']['force_latest'] ? nil : version.sub(/\-.+$/, ''), + prerelease: node['omnibus_updater']['preview'] + ), node ) + raise 'Could not construct URL for chef-download' if remote_path.nil? end -if(remote_path) - node.set[:omnibus_updater][:full_url] = remote_path +if remote_path + node.normal['omnibus_updater']['full_url'] = remote_path - directory node[:omnibus_updater][:cache_dir] do + directory node['omnibus_updater']['cache_dir'] do recursive true end remote_file "omnibus_remote[#{File.basename(remote_path)}]" do - path File.join(node[:omnibus_updater][:cache_dir], File.basename(remote_path)) + path File.join(node['omnibus_updater']['cache_dir'], File.basename(remote_path)) source remote_path backup false - checksum node[:omnibus_updater][:checksum] if node[:omnibus_updater][:checksum] + checksum node['omnibus_updater']['checksum'] if node['omnibus_updater']['checksum'] action :create_if_missing only_if do - unless(version = node[:omnibus_updater][:version]) - version = node[:omnibus_updater][:full_url].scan(%r{chef[_-](\d+\.\d+.\d+)}).flatten.first + unless (version = node['omnibus_updater']['version']) + version = case node['platform_family'] + when 'windows' + node['omnibus_updater']['full_url'].scan(/chef-windows|client-(\d+\.\d+.\d+)/).flatten.first + else + node['omnibus_updater']['full_url'].scan(/chef[_-](\d+\.\d+.\d+)/).flatten.first + end end - if(node[:omnibus_updater][:always_download]) + if node['omnibus_updater']['always_download'] # warn if there may be unexpected behavior - node[:omnibus_updater][:prevent_downgrade] && - Chef::Log.warn("omnibus_updater: prevent_downgrade is ignored when always_download is true") + node['omnibus_updater']['prevent_downgrade'] && + Chef::Log.warn('omnibus_updater: prevent_downgrade is ignored when always_download is true') Chef::Log.debug "Omnibus Updater remote path: #{remote_path}" true - elsif(node[:omnibus_updater][:prevent_downgrade]) + elsif node['omnibus_updater']['prevent_downgrade'] # Return true if the found/specified version is newer Gem::Version.new(version.to_s.sub(/\-.+$/, '')) > Gem::Version.new(Chef::VERSION) else diff --git a/cookbooks/omnibus_updater/recipes/installer.rb b/cookbooks/omnibus_updater/recipes/installer.rb index bfea578..d509d91 100644 --- a/cookbooks/omnibus_updater/recipes/installer.rb +++ b/cookbooks/omnibus_updater/recipes/installer.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: omnibus_updater +# Cookbook:: omnibus_updater # Recipe:: installer # -# Copyright 2014, Heavy Water Ops, LLC +# Copyright:: 2014-2017, Heavy Water Ops, LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,53 +18,107 @@ # include_recipe 'omnibus_updater' -remote_path = node[:omnibus_updater][:full_url].to_s +remote_path = node['omnibus_updater']['full_url'] -file '/tmp/nocheck' do - content 'conflict=nocheck\naction=nocheck' - only_if { node['os'] =~ /^solaris/ } -end - -service 'chef-client' do +service 'chef-client-omnibus' do + service_name 'chef-client' + supports status: true, restart: true action :nothing end -ruby_block 'omnibus chef killer' do - block do - raise 'New omnibus chef version installed. Killing Chef run!' - end - action :nothing - only_if do - node[:omnibus_updater][:kill_chef_on_upgrade] - end -end +if platform?('windows') + version = node['omnibus_updater']['version'] || remote_path.scan(/chef-windows|client-(\d+\.\d+.\d+)/).flatten.first + Chef::Recipe.send(:include, Chef::Mixin::ShellOut) + chef_version = shell_out('chef-client -v') + chef_version = chef_version.stdout -execute "omnibus_install[#{File.basename(remote_path)}]" do - case File.extname(remote_path) - when '.deb' - command "dpkg -i #{File.join(node[:omnibus_updater][:cache_dir], File.basename(remote_path))}" - when '.rpm' - command "rpm -Uvh --oldpackage #{File.join(node[:omnibus_updater][:cache_dir], File.basename(remote_path))}" - when '.sh' - command "/bin/sh #{File.join(node[:omnibus_updater][:cache_dir], File.basename(remote_path))}" - when '.solaris' - command "pkgadd -n -d #{File.join(node[:omnibus_updater][:cache_dir], File.basename(remote_path))} -a /tmp/nocheck chef" - else - raise "Unknown package type encountered for install: #{File.extname(remote_path)}" + # clean up previous upgrades + directory 'c:/opscode/chef.upgrade' do + action :delete + recursive true end - action :nothing - if(node[:omnibus_updater][:restart_chef_service]) - notifies :restart, resources(:service => 'chef-client'), :immediately - end - notifies :create, resources(:ruby_block => 'omnibus chef killer'), :immediately -end -ruby_block 'Omnibus Chef install notifier' do - block{ true } - action :nothing - subscribes :create, resources(:remote_file => "omnibus_remote[#{File.basename(remote_path)}]"), :immediately - notifies :run, resources(:execute => "omnibus_install[#{File.basename(remote_path)}]"), :delayed - only_if { node['chef_packages']['chef']['version'] != node['omnibus_updater']['version'] } + if node['chef_packages']['chef']['version'] != node['omnibus_updater']['version'] + execute 'chef-move' do + command 'move c:/opscode/chef c:/opscode/chef.upgrade' + action :nothing + end + execute 'chef-uninstall' do + command 'wmic product where "name like \'Chef Client%% %%\'" call uninstall /nointeractive' + action :nothing + end + execute 'chef-install' do + command "msiexec.exe /qn /i #{File.basename(remote_path)} ADDLOCAL=\"#{node['omnibus_updater']['addlocal']}\"" + cwd node['omnibus_updater']['cache_dir'] + action :nothing + end + execute 'chef-service-kill' do + command 'taskkill /F /FI "SERVICES eq chef-client"' + action :nothing + end + + ruby_block 'Omnibus Chef Update' do + block { true } + notifies :run, 'execute[chef-service-kill]', :immediately + notifies :run, 'execute[chef-move]', :immediately + notifies :run, 'execute[chef-uninstall]', :immediately + notifies :run, 'execute[chef-install]', :immediately + notifies :start, 'service[chef-client-omnibus]', :immediately if node['omnibus_updater']['restart_chef_service'] + not_if { chef_version == "Chef: #{version}\r\n" } + end + end +else + file '/tmp/nocheck' do + content 'conflict=nocheck\naction=nocheck' + only_if { node['os'] =~ /^solaris/ } + end + + ruby_block 'omnibus chef killer' do + block do + Chef::Application.fatal!('New omnibus chef version installed. Killing Chef run!', node['omnibus_updater']['kill_chef_on_upgrade_exit_code']) + end + action :nothing + only_if { node['omnibus_updater']['kill_chef_on_upgrade'] } + end + + execute "omnibus_install[#{File.basename(remote_path)}]" do # ~FC009 + case File.extname(remote_path) + when '.deb' + command "dpkg -i #{File.join(node['omnibus_updater']['cache_dir'], File.basename(remote_path))}" + when '.rpm' + if node['platform'] == 'amazon' + command "rpm -e chef && rpm -Uvh --oldpackage #{File.join(node['omnibus_updater']['cache_dir'], File.basename(remote_path))}" + else + command "rpm -Uvh --oldpackage #{File.join(node['omnibus_updater']['cache_dir'], File.basename(remote_path))}" + end + when '.sh' + command "/bin/sh #{File.join(node['omnibus_updater']['cache_dir'], File.basename(remote_path))}" + when '.solaris' + command "pkgadd -n -d #{File.join(node['omnibus_updater']['cache_dir'], File.basename(remote_path))} -a /tmp/nocheck chef" + when '.dmg' + command <<-EOF + hdiutil detach "/Volumes/chef_software" >/dev/null 2>&1 || true + hdiutil attach "#{File.join(node['omnibus_updater']['cache_dir'], File.basename(remote_path))}" -mountpoint "/Volumes/chef_software" + cd / && /usr/sbin/installer -pkg `find "/Volumes/chef_software" -name \*.pkg` -target / + hdiutil detach "/Volumes/chef_software" + EOF + else + raise "Unknown package type encountered for install: #{File.extname(remote_path)}" + end + action :nothing + if node['omnibus_updater']['restart_chef_service'] + notifies :restart, 'service[chef-client-omnibus]', :immediately + end + notifies :create, 'ruby_block[omnibus chef killer]', :immediately + end + + ruby_block 'Omnibus Chef install notifier' do + block { true } + action :nothing + subscribes :create, "remote_file[omnibus_remote[#{File.basename(remote_path)}]]", :immediately + notifies :run, "execute[omnibus_install[#{File.basename(remote_path)}]]", :delayed + only_if { node['chef_packages']['chef']['version'] != node['omnibus_updater']['version'] } + end end include_recipe 'omnibus_updater::old_package_cleaner' diff --git a/cookbooks/omnibus_updater/recipes/old_package_cleaner.rb b/cookbooks/omnibus_updater/recipes/old_package_cleaner.rb index 0cfd111..8c7ed04 100644 --- a/cookbooks/omnibus_updater/recipes/old_package_cleaner.rb +++ b/cookbooks/omnibus_updater/recipes/old_package_cleaner.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: omnibus_updater +# Cookbook:: omnibus_updater # Recipe:: old_package_cleaner # -# Copyright 2014, Heavy Water Ops, LLC +# Copyright:: 2014-2017, Heavy Water Ops, LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,9 +18,9 @@ # old_pkgs = - if(::File.exist?(node[:omnibus_updater][:cache_dir])) - Dir.glob(File.join(node[:omnibus_updater][:cache_dir], 'chef_*')).find_all do |file| - !file.include?(node[:omnibus_updater][:version].to_s) && !file.scan(/\.(rpm|deb)$/).empty? + if ::File.exist?(node['omnibus_updater']['cache_dir']) + Dir.glob(File.join(node['omnibus_updater']['cache_dir'], 'chef*')).find_all do |file| + !file.include?(node['omnibus_updater']['version'].to_s) && !file.scan(/\.(rpm|deb|msi|dmg)$/).empty? end else [] diff --git a/cookbooks/omnibus_updater/recipes/remove_chef_system_gem.rb b/cookbooks/omnibus_updater/recipes/remove_chef_system_gem.rb deleted file mode 100644 index 576b379..0000000 --- a/cookbooks/omnibus_updater/recipes/remove_chef_system_gem.rb +++ /dev/null @@ -1,29 +0,0 @@ -# -# Cookbook Name:: omnibus_updater -# Recipe:: remove_chef_system_gem -# -# Copyright 2014, Heavy Water Ops, LLC -# -# 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. -# - -gem_package 'chef' do - action :purge - only_if do - Chef::Provider::Package::Rubygems.new( - Chef::Resource::GemPackage.new('dummy_package') - ).gem_env.gem_paths.detect{|path| - path.start_with?('/opt/omnibus') || path.start_with?('/opt/chef') - }.nil? && node[:omnibus_updater][:remove_chef_system_gem] - end -end diff --git a/cookbooks/partial_search/CHANGELOG.md b/cookbooks/partial_search/CHANGELOG.md deleted file mode 100644 index 92503bf..0000000 --- a/cookbooks/partial_search/CHANGELOG.md +++ /dev/null @@ -1,47 +0,0 @@ -partial_search Cookbook CHANGELOG -================================= -This file is used to list changes made in each version of the partial_search cookbook. - -v1.0.9 (2015-10-21) -------------------- -------------------- -* Updated description to clarify that this cookbook is no longer needed for chef-client 12.0 -* Updated .gitignore file -* Added .foodcritic file to exclude rules that don't apply -* Added Test Kitchen config -* Added Chef standard Rubocop config -* Added Travis CI testing to use Chef DK -* Added Berksfile -* Added Gemfile with the latest development dependencies -* Updated contributing and testing docs -* Added maintainers.md and maintainers.toml files -* Added Travis and cookbook version badges to the readme -* Updated Opscode -> Chef Software -* Added a Rakefile for simplified testing -* Added a Chefignore file -* Resolved Rubocop warnings -* Added source_url and issues_url to the metadata -* Added basic convergence Chefspec test - -v1.0.8 (2014-02-25) -------------------- -- [COOK-4260] Update compatibility in README.md - -v1.0.6 ------- -- **Hotfix** - Revert client-side caching bug - -v1.0.4 ------- -### New Feature -- **[COOK-2584](https://tickets.chef.io/browse/COOK-2584)** - Add client-side result cache - -v1.0.2 ------- -### Bug -- [COOK-3164]: `partial_search` should use - `Chef::Config[:chef_server_url]` instead of `search_url` - -v1.0.0 ------- -- Initial release diff --git a/cookbooks/partial_search/README.md b/cookbooks/partial_search/README.md deleted file mode 100644 index 0d9a90f..0000000 --- a/cookbooks/partial_search/README.md +++ /dev/null @@ -1,84 +0,0 @@ -Partial Search Cookbook -======================= -[![Build Status](https://travis-ci.org/chef-cookbooks/partial_search.svg?branch=master)](http://travis-ci.org/chef-cookbooks/partial_search) -[![Cookbook Version](https://img.shields.io/cookbook/v/partial_search.svg)](https://supermarket.chef.io/cookbooks/partial_search) - -[Partial Search](http://docs.chef.io/essentials_search.html#partial-search) -is a search API available on Chef Server. (see Notes below for version compatibility) -It can be used to reduce the network bandwidth and the memory used by -chef-client to process search results. - -This cookbook provides an experimental interface to the partial search -API by providing a `partial_search` method that can be used instead of -the `search` method in your recipes. - -The `partial_search` method allows you to retrieve just the attributes -of interest. For example, you can execute a search to return just the -name and IP addresses of the nodes in your infrastructure rather than -receiving an array of complete node objects and post-processing them. - -NOTE: Since Chef Client 12.0 the partial_search capability has been built-in -so it does not require this cookbook. - -Install -------- -Upload this cookbook and include it in the dependencies of any -cookbook where you would like to use `partial_search`. - - -Usage ------ -When you call `partial_search`, you need to specify the key paths of the -attributes you want returned. Key paths are specified as an array -of strings. Each key path is mapped to a short name of your -choosing. Consider the following example: - -```ruby -partial_search(:node, 'role:web', - :keys => { 'name' => [ 'name' ], - 'ip' => [ 'ipaddress' ], - 'kernel_version' => [ 'kernel', 'version' ] - } -).each do |result| - puts result['name'] - puts result['ip'] - puts result['kernel_version'] -end -``` - -In the example above, two attributes will be extracted (on the -server) from the nodes that match the search query. The result will -be a simple hash with keys 'name' and 'ip'. - - -Notes ------ -* We would like your feedback on this feature and the interface - provided by this cookbook. Please send comments to the chef-dev - mailing list. - -* The partial search API is available in the Open Source Chef Server since 11.0.4 - -* The partial search API is available in Enterprise Chef Server since 1.2.2 - - -License & Authors ------------------ -- Author:: Adam Jacob () -- Author:: John Keiser () - -```text -Copyright:: 2012-2015, 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. -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. -``` diff --git a/cookbooks/partial_search/libraries/partial_search.rb b/cookbooks/partial_search/libraries/partial_search.rb deleted file mode 100644 index 5a29368..0000000 --- a/cookbooks/partial_search/libraries/partial_search.rb +++ /dev/null @@ -1,147 +0,0 @@ -# -# Author:: Adam Jacob () -# Author:: John Keiser () -# Copyright:: Copyright (c) 2012 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/config' -require 'uri' -require 'chef/rest' -# These are needed so that JSON can inflate search results -require 'chef/node' -require 'chef/role' -require 'chef/environment' -require 'chef/data_bag' -require 'chef/data_bag_item' - -class Chef - class PartialSearch - attr_accessor :rest - - def initialize(url = nil) - @rest = ::Chef::REST.new(url || ::Chef::Config[:chef_server_url]) - end - - # Search Solr for objects of a given type, for a given query. If you give - # it a block, it will handle the paging for you dynamically. - def search(type, query = '*:*', args = {}, &block) - fail ArgumentError, 'Type must be a string or a symbol!' unless type.is_a?(String) || type.is_a?(Symbol) - - sort = args.include?(:sort) ? args[:sort] : 'X_CHEF_id_CHEF_X asc' - start = args.include?(:start) ? args[:start] : 0 - rows = args.include?(:rows) ? args[:rows] : 1000 - query_string = "search/#{type}?q=#{escape(query)}&sort=#{escape(sort)}&start=#{escape(start)}&rows=#{escape(rows)}" - if args[:keys] - response = @rest.post_rest(query_string, args[:keys]) - response_rows = response['rows'].map { |row| row['data'] } - else - response = @rest.get_rest(query_string) - response_rows = response['rows'] - end - if block - response_rows.each { |o| block.call(o) unless o.nil? } - unless (response['start'] + response_rows.length) >= response['total'] - nstart = response['start'] + rows - args_hash = { - keys: args[:keys], - sort: sort, - start: nstart, - rows: rows - } - search(type, query, args_hash, &block) - end - true - else - [response_rows, response['start'], response['total']] - end - end - - def list_indexes - @rest.get_rest('search') - end - - private - - def escape(s) - s && URI.escape(s.to_s) - end - end -end - -# partial_search(type, query, options, &block) -# -# Searches for nodes, roles, etc. and returns the results. This method may -# perform more than one search request, if there are a large number of results. -# -# ==== Parameters -# * +type+: index type (:role, :node, :client, :environment, data bag name) -# * +query+: SOLR query. "*:*", "role:blah", "not role:blah", etc. Defaults to '*:*' -# * +options+: hash with options: -# ** +:start+: First row to return (:start => 50, :rows => 100 means "return the -# 50th through 150th result") -# ** +:rows+: Number of rows to return. Defaults to 1000. -# ** +:sort+: a SOLR sort specification. Defaults to 'X_CHEF_id_CHEF_X asc'. -# ** +:keys+: partial search keys. If this is not specified, the search will -# not be partial. -# -# ==== Returns -# -# This method returns an array of search results. Partial search results will -# be JSON hashes with the structure specified in the +keys+ option. Other -# results include +Chef::Node+, +Chef::Role+, +Chef::Client+, +Chef::Environment+, -# +Chef::DataBag+ and +Chef::DataBagItem+ objects, depending on the search type. -# -# If a block is specified, the block will be called with each result instead of -# returning an array. This method will not block if it returns -# -# If start or row is specified, and no block is given, the result will be a -# triple containing the list, the start and total: -# -# [ [ row1, row2, ... ], start, total ] -# -# ==== Example -# -# partial_search(:node, 'role:webserver', -# keys: { -# name: [ 'name' ], -# ip: [ 'amazon', 'ip', 'public' ] -# } -# ).each do |node| -# puts "#{node[:name]}: #{node[:ip]}" -# end -# -def partial_search(type, query = '*:*', *args, &block) - # Support both the old (positional args) and new (hash args) styles of calling - if args.length == 1 && args[0].is_a?(Hash) - args_hash = args[0] - else - args_hash = {} - args_hash[:sort] = args[0] if args.length >= 1 - args_hash[:start] = args[1] if args.length >= 2 - args_hash[:rows] = args[2] if args.length >= 3 - end - # If you pass a block, or have the start or rows arguments, do raw result parsing - if Kernel.block_given? || args_hash[:start] || args_hash[:rows] - Chef::PartialSearch.new.search(type, query, args_hash, &block) - # Otherwise, do the iteration for the end user - else - results = [] - Chef::PartialSearch.new.search(type, query, args_hash) do |o| - results << o - end - results - end -end diff --git a/cookbooks/partial_search/metadata.json b/cookbooks/partial_search/metadata.json deleted file mode 100644 index f1aa073..0000000 --- a/cookbooks/partial_search/metadata.json +++ /dev/null @@ -1 +0,0 @@ -{"name":"partial_search","version":"1.0.9","description":"Provides experimental interface to partial search API in Chef Software Hosted Chef for Chef-Client pre-12.0","long_description":"Partial Search Cookbook\n=======================\n[![Build Status](https://travis-ci.org/chef-cookbooks/partial_search.svg?branch=master)](http://travis-ci.org/chef-cookbooks/partial_search)\n[![Cookbook Version](https://img.shields.io/cookbook/v/partial_search.svg)](https://supermarket.chef.io/cookbooks/partial_search)\n\n[Partial Search](http://docs.chef.io/essentials_search.html#partial-search)\nis a search API available on Chef Server. (see Notes below for version compatibility)\nIt can be used to reduce the network bandwidth and the memory used by\nchef-client to process search results.\n\nThis cookbook provides an experimental interface to the partial search\nAPI by providing a `partial_search` method that can be used instead of\nthe `search` method in your recipes.\n\nThe `partial_search` method allows you to retrieve just the attributes\nof interest. For example, you can execute a search to return just the\nname and IP addresses of the nodes in your infrastructure rather than\nreceiving an array of complete node objects and post-processing them.\n\nNOTE: Since Chef Client 12.0 the partial_search capability has been built-in\nso it does not require this cookbook.\n\nInstall\n-------\nUpload this cookbook and include it in the dependencies of any\ncookbook where you would like to use `partial_search`.\n\n\nUsage\n-----\nWhen you call `partial_search`, you need to specify the key paths of the\nattributes you want returned. Key paths are specified as an array\nof strings. Each key path is mapped to a short name of your\nchoosing. Consider the following example:\n\n```ruby\npartial_search(:node, 'role:web',\n :keys => { 'name' => [ 'name' ],\n 'ip' => [ 'ipaddress' ],\n 'kernel_version' => [ 'kernel', 'version' ]\n }\n).each do |result|\n puts result['name']\n puts result['ip']\n puts result['kernel_version']\nend\n```\n\nIn the example above, two attributes will be extracted (on the\nserver) from the nodes that match the search query. The result will\nbe a simple hash with keys 'name' and 'ip'.\n\n\nNotes\n-----\n* We would like your feedback on this feature and the interface\n provided by this cookbook. Please send comments to the chef-dev\n mailing list.\n\n* The partial search API is available in the Open Source Chef Server since 11.0.4\n\n* The partial search API is available in Enterprise Chef Server since 1.2.2\n\n\nLicense & Authors\n-----------------\n- Author:: Adam Jacob ()\n- Author:: John Keiser ()\n\n```text\nCopyright:: 2012-2015, Chef Software, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{}} \ No newline at end of file diff --git a/cookbooks/partial_search/recipes/default.rb b/cookbooks/partial_search/recipes/default.rb deleted file mode 100644 index 792d600..0000000 --- a/cookbooks/partial_search/recipes/default.rb +++ /dev/null @@ -1 +0,0 @@ -# diff --git a/cookbooks/postfix/CHANGELOG.md b/cookbooks/postfix/CHANGELOG.md index b2f7f2e..a827d23 100644 --- a/cookbooks/postfix/CHANGELOG.md +++ b/cookbooks/postfix/CHANGELOG.md @@ -1,172 +1,215 @@ -postfix Cookbook CHANGELOG -========================== +# postfix Cookbook CHANGELOG + This file is used to list changes made in each version of the postfix cookbook. -v3.7.0 (2015-04-30) -------------------- +## 5.0.1 (2017-03-03) + +- Fix documentation error on inet-interfaces +- Test with Local Delivery instead of Rake +- Fix master.cf attributes types on README + +## 5.0.0 (2017-01-17) + +- Manage any hash: tables for postfix with hash_maps recipe +- Fully customizable master.cf file +- Support for any kind of postfix lookup tables +- Remove old minitest files +- Update chef requirement in the readme +- Update tests for new config comment blocks +- fixing /etc/aliases syntax for full-mailaddresses + +## 4.0.0 (2016-09-07) + +- Update supported platforms in metadata +- Remove node name from config file +- Testing updates +- Use node.normal vs. node.set to avoid deprecation warnings +- Require Chef 12+ + +## v3.8.0 (2016-04-01) + +- Updated attributes to use node.default_unless instead of node.default to be more wrapper friendly +- Added integration and unit testing in Travis CI +- Added rubocop config and resolved rubocop warnings +- Added Gemfile with all necessary test deps +- Added standard gitignore and chefignore files +- Added updated contributing and testing docs +- Removed the Kitchen Digital Ocean files and dependencies +- Added additional platforms to the Test Kitchen config +- Added a Rakefile for simplified testing +- Fixed a typo in the use_relay_restrictions_maps attribute that prevented the default from being set +- Added fedora and oracle as supported platforms in the metadata +- Removed the attributes from the metadata. +- Added long_description to the metadata +- Added Chef 11 compatibility checks to issues_url and source_url in metadata.rb +- Added maintainers.md and maintainers.toml files + +## v3.7.0 (2015-04-30) + - Adding support for relay restrictions - Update chefspec and serverspec tests -v3.6.2 (2014-10-31) -------------------- +## v3.6.2 (2014-10-31) + - Fix FreeBSDisms -v3.6.1 (2014-10-28) -------------------- +## v3.6.1 (2014-10-28) + - Fix documentation around node['postfix']['main']['relayhost'] attribute - Fix logic around include_recipe 'postfix::virtual_aliases_domains' -v3.6.0 (2014-08-25) -------------------- +## v3.6.0 (2014-08-25) + - restart postfix after updating virtual alias templates #86 - fixing typo for alias_db location in omnios - moving conditional attributes to a recipe so they can be modified - via other cookbook attributes +- via other cookbook attributes + +## v3.5.0 (2014-08-25) -v3.5.0 (2014-08-25) -------------------- Adding virtual_domains functionality -v3.4.1 (2014-08-20) -------------------- +## v3.4.1 (2014-08-20) + Removing unused parameters from main.cf -v3.4.0 (2014-07-25) -------------------- +## v3.4.0 (2014-07-25) + Refactoring to fix some logic issues -v3.3.1 (2014-06-11) -------------------- +## v3.3.1 (2014-06-11) + Reverting #37 - [COOK-3418] Virtual Domain Support PR - duplicate of #55 +## v3.3.0 (2014-06-11) -v3.3.0 (2014-06-11) -------------------- -- #37 - [COOK-3418] - Virtual Domain Support -- #44 - Fix minor formatting issue in attributes -- #55 - Add support for virtual aliases -- #57 - Fixing attributes bug in README -- #64 - add smtp_generic maps configuration option -- #66 - [COOK-3652] Add support for transport mappings -- #67 - [COOK-4662] Added support for access control -- #68 - Properly handle binding to loopback on mixed IPV4/IPV6 systems +- 37 - [COOK-3418] - Virtual Domain Support +- 44 - Fix minor formatting issue in attributes +- 55 - Add support for virtual aliases +- 57 - Fixing attributes bug in README +- 64 - add smtp_generic maps configuration option +- 66 - [COOK-3652] Add support for transport mappings +- 67 - [COOK-4662] Added support for access control +- 68 - Properly handle binding to loopback on mixed IPV4/IPV6 systems +## v3.2.0 (2014-05-09) -v3.2.0 (2014-05-09) -------------------- - [COOK-4619] - no way to unset recipient_delimiter +## v3.1.8 (2014-03-27) -v3.1.8 (2014-03-27) -------------------- - [COOK-4410] - Fix sender_canonical configuration by adding template - and postmap execution +- and postmap execution +## v3.1.6 (2014-03-19) -v3.1.6 (2014-03-19) -------------------- - [COOK-4423] - use platform_family, find cert.pem on rhel +## v3.1.4 (2014-02-27) -v3.1.4 (2014-02-27) -------------------- [COOK-4329] Migrate minitest PITs to latest test-kitchen + serverspec +## v3.1.2 (2014-02-19) -v3.1.2 (2014-02-19) -------------------- ### Bug + - **[COOK-4357](https://tickets.chef.io/browse/COOK-4357)** - postfix::sasl_auth recipe fails to converge +## v3.1.0 (2014-02-19) -v3.1.0 (2014-02-19) -------------------- ### Bug + - **[COOK-4322](https://tickets.chef.io/browse/COOK-4322)** - Postfix cookbook has incorrect default path for sasl_passwd ### New Feature + - **[COOK-4086](https://tickets.chef.io/browse/COOK-4086)** - use conf_dir attribute for sasl recipe, and add omnios support - **[COOK-2551](https://tickets.chef.io/browse/COOK-2551)** - Support creating the sender_canonical map file +## v3.0.4 -v3.0.4 ------- ### Bug + - **[COOK-3824](https://tickets.chef.io/browse/COOK-3824)** - main.cf.erb mishandles lists ### Improvement + - **[COOK-3822](https://tickets.chef.io/browse/COOK-3822)** - postfix cookbook readme has an incorrect example - Got rubocop errors down to 32 ### New Feature + - **[COOK-2551](https://tickets.chef.io/browse/COOK-2551)** - Support creating the sender_canonical map file +## v3.0.2 -v3.0.2 ------- ### Bug + - **[COOK-3617](https://tickets.chef.io/browse/COOK-3617)** - Fix error when no there is no FQDN - **[COOK-3530](https://tickets.chef.io/browse/COOK-3530)** - Update `client.rb` after 3.0.0 refactor - **[COOK-2499](https://tickets.chef.io/browse/COOK-2499)** - Do not use resource cloning ### Improvement + - **[COOK-3116](https://tickets.chef.io/browse/COOK-3116)** - Add SmartOS support +## v3.0.0 -v3.0.0 ------- ### Improvement + - **[COOK-3328](https://tickets.chef.io/browse/COOK-3328)** - Postfix main/master and attributes refactor **Breaking changes**: + - Attributes are namespaced as `node['postfix']`, `node['postfix']['main']`, and `node['postfix']['master']`. -v2.1.6 ------- +## v2.1.6 + ### Bug + - [COOK-2501]: Reference to `['postfix']['domain']` should be `['postfix']['mydomain']` - [COOK-2715]: master.cf uses old name for `smtp_fallback_relay` (`fallback_relay`) parameter in master.cf -v2.1.4 ------- +## v2.1.4 + - [COOK-2281] - postfix aliases uses require_recipe statement -v2.1.2 ------- +## v2.1.2 + - [COOK-2010] - postfix sasl_auth does not include the sasl plain package -v2.1.0 ------- +## v2.1.0 + - [COOK-1233] - optional configuration for canonical maps - [COOK-1660] - allow comma separated arrays in aliases - [COOK-1662] - allow inet_interfaces configuration via attribute -v2.0.0 ------- +## v2.0.0 + This version uses platform_family attribute, making the cookbook incompatible with older versions of Chef/Ohai, hence the major version bump. - [COOK-1535] - `smtpd_cache` should be in `data_directory`, not `queue_directory` - [COOK-1790] - /etc/aliases template is only in ubuntu directory - [COOK-1792] - add minitest-chef tests to postfix cookbook -v1.2.2 ------- +## v1.2.2 + - [COOK-1442] - Missing ['postfix']['domain'] Attribute causes initial installation failure - [COOK-1520] - Add support for procmail delivery - [COOK-1528] - Make aliasses template less specific - [COOK-1538] - Add iptables_rule template - [COOK-1540] - Add smtpd_milters and non_smtpd_milters parameters to main.cf -v1.2.0 ------- +## v1.2.0 + - [COOK-880] - add client/server roles for search-based discovery of relayhost -v1.0.0 ------- +## v1.0.0 + - [COOK-668] - RHEL/CentOS/Scientific/Amazon platform support - [COOK-733] - postfix::aliases recipe to manage /etc/aliases - [COOK-821] - add README.md :) -v0.8.4 ------- +## v0.8.4 + - Current public release. diff --git a/cookbooks/postfix/CONTRIBUTING.md b/cookbooks/postfix/CONTRIBUTING.md new file mode 100644 index 0000000..cd21578 --- /dev/null +++ b/cookbooks/postfix/CONTRIBUTING.md @@ -0,0 +1 @@ +Please refer to diff --git a/cookbooks/postfix/MAINTAINERS.md b/cookbooks/postfix/MAINTAINERS.md new file mode 100644 index 0000000..645ed14 --- /dev/null +++ b/cookbooks/postfix/MAINTAINERS.md @@ -0,0 +1,15 @@ + + +# Maintainers + +This file lists how this cookbook project is maintained. When making changes to the system, this file tells you who needs to review your patch - you need a review from an existing maintainer for the cookbook to provide a :+1: on your pull request. Additionally, you need to not receive a veto from a Lieutenant or the Project Lead. + +Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) for details on the process and how to become a maintainer or the project lead. + +# Project Maintainer +* [Tim Smith](https://github.com/tas50) + +# Maintainers +* [Jennifer Davis](https://github.com/sigje) +* [Tim Smith](https://github.com/tas50) +* [Thom May](https://github.com/thommay) diff --git a/cookbooks/postfix/README.md b/cookbooks/postfix/README.md index 586881a..3531da4 100644 --- a/cookbooks/postfix/README.md +++ b/cookbooks/postfix/README.md @@ -1,73 +1,84 @@ -postfix Cookbook -================ +# postfix Cookbook + +[![Build Status](https://travis-ci.org/chef-cookbooks/postfix.svg?branch=master)](https://travis-ci.org/chef-cookbooks/postfix) [![Cookbook Version](https://img.shields.io/cookbook/v/postfix.svg)](https://supermarket.chef.io/cookbooks/postfix) + Installs and configures postfix for client or outbound relayhost, or to do SASL authentication. On RHEL-family systems, sendmail will be replaced with postfix. +## Requirements -Requirements ------------- ### Platforms -- Ubuntu 10.04+ -- Debian 6.0+ + +- Ubuntu 12.04+ +- Debian 7.0+ - RHEL/CentOS/Scientific 5.7+, 6.2+ - Amazon Linux (as of AMIs created after 4/9/2012) May work on other platforms with or without modification. +### Chef + +- Chef 12.1+ + +### Cookbooks + +- none + +## Attributes -Attributes ----------- See `attributes/default.rb` for default values. ### Generic cookbook attributes -* `node['postfix']['mail_type']` - Sets the kind of mail configuration. `master` will set up a server (relayhost). -* `node['postfix']['relayhost_role']` - name of a role used for search in the client recipe. -* `node['postfix']['multi_environment_relay']` - set to true if nodes should not constrain search for the relayhost in their own environment. -* `node['postfix']['use_procmail']` - set to true if nodes should use procmail as the delivery agent. -* `node['postfix']['use_alias_maps']` - set to true if you want the cookbook to use/configure alias maps -* `node['postfix']['use_transport_maps']` - set to true if you want the cookbook to use/configure transport maps -* `node['postfix']['use_access_maps']` - set to true if you want the cookbook to use/configure access maps -* `node['postfix']['use_virtual_aliases']` - set to true if you want the cookbook to use/configure virtual alias maps -* `node['postfix']['use_relay_restrictions_maps']` - set to true if you want the cookbook to use/configure a list of domains to which postfix will allow relay -* `node['postfix']['aliases']` - hash of aliases to create with `recipe[postfix::aliases]`, see below under __Recipes__ for more information. -* `node['postfix']['transports']` - hash of transports to create with `recipe[postfix::transports]`, see below under __Recipes__ for more information. -* `node['postfix']['access']` - hash of access to create with `recipe[postfix::access]`, see below under __Recipes__ for more information. -* `node['postfix']['virtual_aliases']` - hash of virtual_aliases to create with `recipe[postfix::virtual_aliases]`, see below under __Recipes__ for more information. -* `node['postfix']['main_template_source']` - Cookbook source for main.cf template. Default 'postfix' -* `node['postfix']['master_template_source']` - Cookbook source for master.cf template. Default 'postfix' -### main.cf and sasl\_passwd template attributes -The main.cf template has been simplified to include any attributes in the `node['postfix']['main']` data structure. The following attributes are still included with this cookbook to maintain some semblance of backwards compatibility. +- `node['postfix']['mail_type']` - Sets the kind of mail configuration. `master` will set up a server (relayhost). +- `node['postfix']['relayhost_role']` - name of a role used for search in the client recipe. +- `node['postfix']['multi_environment_relay']` - set to true if nodes should not constrain search for the relayhost in their own environment. +- `node['postfix']['use_procmail']` - set to true if nodes should use procmail as the delivery agent. +- `node['postfix']['use_alias_maps']` - set to true if you want the cookbook to use/configure alias maps +- `node['postfix']['use_transport_maps']` - set to true if you want the cookbook to use/configure transport maps +- `node['postfix']['use_access_maps']` - set to true if you want the cookbook to use/configure access maps +- `node['postfix']['use_virtual_aliases']` - set to true if you want the cookbook to use/configure virtual alias maps +- `node['postfix']['use_relay_restrictions_maps']` - set to true if you want the cookbook to use/configure a list of domains to which postfix will allow relay +- `node['postfix']['aliases']` - hash of aliases to create with `recipe[postfix::aliases]`, see below under **Recipes** for more information. +- `node['postfix']['transports']` - hash of transports to create with `recipe[postfix::transports]`, see below under **Recipes** for more information. +- `node['postfix']['access']` - hash of access to create with `recipe[postfix::access]`, see below under **Recipes** for more information. +- `node['postfix']['virtual_aliases']` - hash of virtual_aliases to create with `recipe[postfix::virtual_aliases]`, see below under __Recipes__ for more information. +- `node['postfix']['main_template_source']` - Cookbook source for main.cf template. Default 'postfix' +- `node['postfix']['master_template_source']` - Cookbook source for master.cf template. Default 'postfix' -This change in namespace to `node['postfix']['main']` should allow for greater flexibility, given the large number of configuration variables for the postfix daemon. All of these cookbook attributes correspond to the option of the same name in `/etc/postfix/main.cf`. +### main.cf and sasl_passwd template attributes -* `node['postfix']['main']['biff']` - (yes/no); default no -* `node['postfix']['main']['append_dot_mydomain']` - (yes/no); default no -* `node['postfix']['main']['myhostname']` - defaults to fqdn from Ohai -* `node['postfix']['main']['mydomain']` - defaults to domain from Ohai -* `node['postfix']['main']['myorigin']` - defaults to $myhostname -* `node['postfix']['main']['mynetworks']` - default is nil, which forces Postfix to default to loopback addresses. -* `node['postfix']['main']['inet_interfaces']` - set to `loopback-only`, or `all` for server recipe -* `node['postfix']['main']['alias_maps']` - set to `hash:/etc/aliases` -* `node['postfix']['main']['mailbox_size_limit']` - set to `0` (disabled) -* `node['postfix']['main']['mydestination']` - default fqdn, hostname, localhost.localdomain, localhost -* `node['postfix']['main']['smtpd_use_tls']` - (yes/no); default yes. See conditional cert/key attributes. - - `node['postfix']['main']['smtpd_tls_cert_file']` - conditional attribute, set to full path of server's x509 certificate. - - `node['postfix']['main']['smtpd_tls_key_file']` - conditional attribute, set to full path of server's private key - - `node['postfix']['main']['smtpd_tls_CAfile']` - set to platform specific CA bundle - - `node['postfix']['main']['smtpd_tls_session_cache_database']` - set to `btree:${data_directory}/smtpd_scache` -* `node['postfix']['main']['smtp_use_tls']` - (yes/no); default yes. See following conditional attributes. - - `node['postfix']['main']['smtp_tls_CAfile']` - set to platform specific CA bundle - - `node['postfix']['main']['smtp_tls_session_cache_database']` - set to `btree:${data_directory}/smtpd_scache` -* `node['postfix']['main']['smtp_sasl_auth_enable']` - (yes/no); default no. If enabled, see following conditional attributes. - - `node['postfix']['main']['smtp_sasl_password_maps']` - Set to `hash:/etc/postfix/sasl_passwd` template file - - `node['postfix']['main']['smtp_sasl_security_options']` - Set to noanonymous - - `node['postfix']['main']['relayhost']` - Set to empty string - - `node['postfix']['sasl']['smtp_sasl_user_name']` - SASL user to authenticate as. Default empty - - `node['postfix']['sasl']['smtp_sasl_passwd']` - SASL password to use. Default empty. -* `node['postfix']['sender_canonical_map_entries']` - (hash with key value pairs); default not configured. Setup generic canonical maps. See `man 5 canonical`. If has at least one value, then will be enabled in config. -* `node['postfix']['smtp_generic_map_entries']` - (hash with key value pairs); default not configured. Setup generic postfix maps. See `man 5 generic`. If has at least one value, then will be enabled in config. +The main.cf template has been simplified to include any attributes in the `node['postfix']['main']` data structure. The following attributes are still included with this cookbook to maintain some semblance of backwards compatibility. + +This change in namespace to `node['postfix']['main']` should allow for greater flexibility, given the large number of configuration variables for the postfix daemon. All of these cookbook attributes correspond to the option of the same name in `/etc/postfix/main.cf`. + +- `node['postfix']['main']['biff']` - (yes/no); default no +- `node['postfix']['main']['append_dot_mydomain']` - (yes/no); default no +- `node['postfix']['main']['myhostname']` - defaults to fqdn from Ohai +- `node['postfix']['main']['mydomain']` - defaults to domain from Ohai +- `node['postfix']['main']['myorigin']` - defaults to $myhostname +- `node['postfix']['main']['mynetworks']` - default is nil, which forces Postfix to default to loopback addresses. +- `node['postfix']['main']['inet_interfaces']` - set to `loopback-only`, or `all` for server recipe +- `node['postfix']['main']['alias_maps']` - set to `hash:/etc/aliases` +- `node['postfix']['main']['mailbox_size_limit']` - set to `0` (disabled) +- `node['postfix']['main']['mydestination']` - default fqdn, hostname, localhost.localdomain, localhost +- `node['postfix']['main']['smtpd_use_tls']` - (yes/no); default yes. See conditional cert/key attributes. +- `node['postfix']['main']['smtpd_tls_cert_file']` - conditional attribute, set to full path of server's x509 certificate. +- `node['postfix']['main']['smtpd_tls_key_file']` - conditional attribute, set to full path of server's private key +- `node['postfix']['main']['smtpd_tls_CAfile']` - set to platform specific CA bundle +- `node['postfix']['main']['smtpd_tls_session_cache_database']` - set to `btree:${data_directory}/smtpd_scache` +- `node['postfix']['main']['smtp_use_tls']` - (yes/no); default yes. See following conditional attributes. +- `node['postfix']['main']['smtp_tls_CAfile']` - set to platform specific CA bundle +- `node['postfix']['main']['smtp_tls_session_cache_database']` - set to `btree:${data_directory}/smtpd_scache` +- `node['postfix']['main']['smtp_sasl_auth_enable']` - (yes/no); default no. If enabled, see following conditional attributes. +- `node['postfix']['main']['smtp_sasl_password_maps']` - Set to `hash:/etc/postfix/sasl_passwd` template file +- `node['postfix']['main']['smtp_sasl_security_options']` - Set to noanonymous +- `node['postfix']['main']['relayhost']` - Set to empty string +- `node['postfix']['sasl']['smtp_sasl_user_name']` - SASL user to authenticate as. Default empty +- `node['postfix']['sasl']['smtp_sasl_passwd']` - SASL password to use. Default empty. +- `node['postfix']['sender_canonical_map_entries']` - (hash with key value pairs); default not configured. Setup generic canonical maps. See `man 5 canonical`. If has at least one value, then will be enabled in config. +- `node['postfix']['smtp_generic_map_entries']` - (hash with key value pairs); default not configured. Setup generic postfix maps. See `man 5 generic`. If has at least one value, then will be enabled in config. Example of json role config, for setup *_map_entries: @@ -80,68 +91,193 @@ Example of json role config, for setup *_map_entries: `}` ### master.cf template attributes -* `node['postfix']['master']['submission'] - Whether to use submission (TCP 587) daemon. (true/false); default false +The master.cf template has been changed to allow full customization of the file content. For purpose of backwards compatibility default attributes generate the same master.cf. But via `node['postfix']['master']` data structure in your role for instance it can be completelly rewritten. + +Examples of json role config, for customize master.cf: + +`postfix : {` + +`...` + +turn some services off or on: + +```json + "master" : { + "smtps": { + "active": true + }, + "old-cyrus": { + "active": false + }, + "cyrus": { + "active": false + }, + "uucp": { + "active": false + }, + "ifmail": { + "active": false + }, +``` + +`...` define you own service: + +```json + "spamfilter": { + "comment": "My own spamfilter", + "active": true, + "order": 590, + "type": "unix", + "unpriv": false, + "chroot": false, + "command": "pipe", + "args": ["flags=Rq user=spamd argv=/usr/bin/spamfilter.sh -oi -f ${sender} ${recipient}"] + } +``` + +`...` + +`}` `}` + +The possible service hash fields and their meanings: hash key - have to be unique, unless you wish to override default definition. + +Field | Mandatory | Description +------- | --------- | -------------------------------------------------------------------- +active | Yes | Boolean. Defines whether or not the service needs to be in master.cf +comment | No | String. If you would like to add a comment line before service line +order | Yes | Integer. Number to define the order of lines in the file +type | Yes | String. Type of the service (inet, unix, fifo) +private | No | Boolean. If present replaced by `y` or `n`, otherwise by `-` +unpriv | No | Boolean. If present replaced by `y` or `n`, otherwise by `-` +chroot | No | Boolean. If present replaced by `y` or `n`, otherwise by `-` +wakeup | No | String. If present value placed in file, otherwise replaced by `-` +maxproc | No | String. If present value placed in file, otherwise replaced by `-` +command | Yes | String. The command to be executed. +args | Yes | Array of Strings. Arguments passed to command. + +For more information about meaning of the fields consult `master (5)` manual: + +## Recipes -Recipes -------- ### default -Installs the postfix package and manages the service and the main configuration files (`/etc/postfix/main.cf` and `/etc/postfix/master.cf`). See __Usage__ and __Examples__ to see how to affect behavior of this recipe through configuration. Depending on the `node['postfix']['use_alias_maps']`, `node['postfix']['use_transport_maps']`, `node['postfix']['use_access_maps']` and `node['postfix']['use_virtual_aliases']` attributes the default recipe can call additional recipes to manage additional postfix configuration files + +Installs the postfix package and manages the service and the main configuration files (`/etc/postfix/main.cf` and `/etc/postfix/master.cf`). See **Usage** and **Examples** to see how to affect behavior of this recipe through configuration. Depending on the `node['postfix']['use_alias_maps']`, `node['postfix']['use_transport_maps']`, `node['postfix']['use_access_maps']` and `node['postfix']['use_virtual_aliases']` attributes the default recipe can call additional recipes to manage additional postfix configuration files For a more dynamic approach to discovery for the relayhost, see the `client` and `server` recipes below. ### client + Use this recipe to have nodes automatically search for the mail relay based which node has the `node['postfix']['relayhost_role']` role. Sets the `node['postfix']['main']['relayhost']` attribute to the first result from the search. Includes the default recipe to install, configure and start postfix. Does not work with `chef-solo`. -### sasl\_auth +### sasl_auth + Sets up the system to authenticate with a remote mail relay using SASL authentication. ### server + To use Chef Server search to automatically detect a node that is the relayhost, use this recipe in a role that will be relayhost. By default, the role should be "relayhost" but you can change the attribute `node['postfix']['relayhost_role']` to modify this. **Note** This recipe will set the `node['postfix']['mail_type']` to "master" with an override attribute. +### maps + +General recipe to manage any number of any type postfix lookup tables. You can replace with it recipes like `transport` or `virtual_aliases`, but what is more important - you can create any kinds of maps, which has no own recipe, including database lookup maps configuration. `maps` is a hash keys of which is a lookup table type and value is another hash with filenames as the keys and hash with file content as the value. File content is an any number of key/value pairs which meaning depends on lookup table type. Examlle: + +```json + "override_attributes": { + "postfix": { + "maps": { + "hash": { + "/etc/postfix/vmailbox": { + "john@example.com": "ok", + "john@example.net": "ok", + }, + "/etc/postfix/virtual": { + "postmaster@example.com": "john@example.com", + "postmaster@example.net": "john@example.net", + "root@mail.example.net": "john@example.net" + }, + "/etc/postfix/envelope_senders": { + "@example.com": "john@example.com", + "@example.net": "john@example.net" + }, + "/etc/postfix/relay_recipients": { + "john@example.net": "ok", + "john@example.com": "ok", + "admin@example.com": "ok", + } + }, + "pgsql": { + "/etc/postfix/pgtest": { + "hosts": "db.local:2345", + "user": "postfix", + "password": "test", + "dbname": "postdb", + "query": "SELECT replacement FROM aliases WHERE mailbox = '%s'" + } + } + } + } +``` + +To use these files in your configuration reference them in `node['postfix']['main']`, for instance: + +```json + "postfix": { + "main": { + "smtpd_sender_login_maps": "hash:/etc/postfix/envelope_senders", + "relay_recipient_maps": "hash:/etc/postfix/relay_recipients", + "virtual_mailbox_maps": "hash:/etc/postfix/vmailbox", + "virtual_alias_maps": "hash:/etc/postfix/virtual", + } + } +``` + ### aliases + Manage `/etc/aliases` with this recipe. Currently only Ubuntu 10.04 platform has a template for the aliases file. Add your aliases template to the `templates/default` or to the appropriate platform+version directory per the File Specificity rules for templates. Then specify a hash of aliases for the `node['postfix']['aliases']` attribute. Arrays are supported as alias values, since postfix supports comma separated values per alias, simply specify your alias as an array to use this handy feature. ### aliases + Manage `/etc/aliases` with this recipe. ### transports + Manage `/etc/postfix/transport` with this recipe. ### access + Manage `/etc/postfix/access` with this recipe. ### virtual_aliases + Manage `/etc/postfix/virtual` with this recipe. ### relay_restrictions -Manage `/etc/postfix/relay_restriction` with this recipe -The postfix option smtpd_relay_restrictions in main.cf will point to this hash map db. +Manage `/etc/postfix/relay_restriction` with this recipe The postfix option smtpd_relay_restrictions in main.cf will point to this hash map db. -http://wiki.chef.io/display/chef/Templates#Templates-TemplateLocationSpecificity + +## Usage -Usage ------ On systems that should simply send mail directly to a relay, or out to the internet, use `recipe[postfix]` and modify the `node['postfix']['main']['relayhost']` attribute via a role. -On systems that should be the MX for a domain, set the attributes accordingly and make sure the `node['postfix']['mail_type']` attribute is `master`. See __Examples__ for information on how to use `recipe[postfix::server]` to do this automatically. +On systems that should be the MX for a domain, set the attributes accordingly and make sure the `node['postfix']['mail_type']` attribute is `master`. See **Examples** for information on how to use `recipe[postfix::server]` to do this automatically. If you need to use SASL authentication to send mail through your ISP (such as on a home network), use `postfix::sasl_auth` and set the appropriate attributes. -For each of these implementations, see __Examples__ for role usage. - +For each of these implementations, see **Examples** for role usage. ### Examples + The example roles below only have the relevant postfix usage. You may have other contents depending on what you're configuring on your systems. The `base` role is applied to all nodes in the environment. @@ -172,7 +308,7 @@ override_attributes( "mail_type" => "master", "main" => { "mynetworks" => [ "10.3.3.0/24", "127.0.0.0/8" ], - "inet-interfaces" => "all", + "inet_interfaces" => "all", "mydomain" => "example.com", "myorigin" => "example.com" } @@ -204,9 +340,10 @@ override_attributes( For an example of using encrypted data bags to encrypt the SASL password, see the following blog post: -* http://jtimberman.github.com/blog/2011/08/06/encrypted-data-bag-for-postfix-sasl-authentication/ +- #### Examples using the client & server recipes + If you'd like to use the more dynamic search based approach for discovery, use the server and client recipes. First, create a relayhost role. ```ruby @@ -288,13 +425,13 @@ override_attributes( ) ``` -License & Authors ------------------ -- Author:: Joshua Timberman +## License & Authors -```text -Copyright:: 2009-2014, Chef Software, Inc +**Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io)) +**Copyright:** 2009-2016, 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. You may obtain a copy of the License at diff --git a/cookbooks/postfix/attributes/default.rb b/cookbooks/postfix/attributes/default.rb index f14a4cf..a261125 100644 --- a/cookbooks/postfix/attributes/default.rb +++ b/cookbooks/postfix/attributes/default.rb @@ -1,6 +1,5 @@ -# encoding: utf-8 # Author:: Joshua Timberman -# Copyright:: Copyright 2009-2014, Chef Software, Inc. +# Copyright:: 2009-2016, Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,7 +15,7 @@ # limitations under the License. # Generic cookbook attributes -default['postfix']['mail_type'] = 'client' +default['postfix']['mail_type'] = 'client' default['postfix']['relayhost_role'] = 'relayhost' default['postfix']['multi_environment_relay'] = false default['postfix']['use_procmail'] = false @@ -25,7 +24,7 @@ default['postfix']['use_transport_maps'] = false default['postfix']['use_access_maps'] = false default['postfix']['use_virtual_aliases'] = false default['postfix']['use_virtual_aliases_domains'] = false -default['postfix']['use_relay_restirictions_maps'] = false +default['postfix']['use_relay_restrictions_maps'] = false default['postfix']['transports'] = {} default['postfix']['access'] = {} default['postfix']['virtual_aliases'] = {} @@ -118,31 +117,284 @@ end # default['postfix']['main']['canonical_maps'] = nil # Master.cf attributes -default['postfix']['master']['submission'] = false +default['postfix']['master']['smtp']['active'] = true +default['postfix']['master']['smtp']['order'] = 10 +default['postfix']['master']['smtp']['type'] = 'inet' +default['postfix']['master']['smtp']['private'] = false +default['postfix']['master']['smtp']['chroot'] = false +default['postfix']['master']['smtp']['command'] = 'smtpd' +default['postfix']['master']['smtp']['args'] = [] + +default['postfix']['master']['submission']['active'] = false +default['postfix']['master']['submission']['order'] = 20 +default['postfix']['master']['submission']['type'] = 'inet' +default['postfix']['master']['submission']['private'] = false +default['postfix']['master']['submission']['chroot'] = false +default['postfix']['master']['submission']['command'] = 'smtpd' +default['postfix']['master']['submission']['args'] = ['-o smtpd_enforce_tls=yes', ' -o smtpd_sasl_auth_enable=yes', '-o smtpd_client_restrictions=permit_sasl_authenticated,reject'] + +default['postfix']['master']['smtps']['active'] = false +default['postfix']['master']['smtps']['order'] = 30 +default['postfix']['master']['smtps']['type'] = 'inet' +default['postfix']['master']['smtps']['private'] = false +default['postfix']['master']['smtps']['chroot'] = false +default['postfix']['master']['smtps']['command'] = 'smtpd' +default['postfix']['master']['smtps']['args'] = ['-o smtpd_tls_wrappermode=yes', '-o smtpd_sasl_auth_enable=yes', '-o smtpd_client_restrictions=permit_sasl_authenticated,reject'] + +default['postfix']['master']['628']['active'] = false +default['postfix']['master']['628']['order'] = 40 +default['postfix']['master']['628']['type'] = 'inet' +default['postfix']['master']['628']['private'] = false +default['postfix']['master']['628']['chroot'] = false +default['postfix']['master']['628']['command'] = 'qmqpdd' +default['postfix']['master']['628']['args'] = [] + +default['postfix']['master']['pickup']['active'] = true +default['postfix']['master']['pickup']['order'] = 50 +default['postfix']['master']['pickup']['type'] = 'fifo' +default['postfix']['master']['pickup']['private'] = false +default['postfix']['master']['pickup']['chroot'] = false +default['postfix']['master']['pickup']['wakeup'] = '60' +default['postfix']['master']['pickup']['maxproc'] = '1' +default['postfix']['master']['pickup']['command'] = 'pickup' +default['postfix']['master']['pickup']['args'] = [] + +default['postfix']['master']['cleanup']['active'] = true +default['postfix']['master']['cleanup']['order'] = 60 +default['postfix']['master']['cleanup']['type'] = 'unix' +default['postfix']['master']['cleanup']['private'] = false +default['postfix']['master']['cleanup']['chroot'] = false +default['postfix']['master']['cleanup']['maxproc'] = '0' +default['postfix']['master']['cleanup']['command'] = 'cleanup' +default['postfix']['master']['cleanup']['args'] = [] + +default['postfix']['master']['qmgr']['active'] = true +default['postfix']['master']['qmgr']['order'] = 70 +default['postfix']['master']['qmgr']['type'] = 'fifo' +default['postfix']['master']['qmgr']['private'] = false +default['postfix']['master']['qmgr']['chroot'] = false +default['postfix']['master']['qmgr']['wakeup'] = '300' +default['postfix']['master']['qmgr']['maxproc'] = '1' +default['postfix']['master']['qmgr']['command'] = 'qmgr' +default['postfix']['master']['qmgr']['args'] = [] + +default['postfix']['master']['tlsmgr']['active'] = true +default['postfix']['master']['tlsmgr']['order'] = 80 +default['postfix']['master']['tlsmgr']['type'] = 'unix' +default['postfix']['master']['tlsmgr']['chroot'] = false +default['postfix']['master']['tlsmgr']['wakeup'] = '1000?' +default['postfix']['master']['tlsmgr']['maxproc'] = '1' +default['postfix']['master']['tlsmgr']['command'] = 'tlsmgr' +default['postfix']['master']['tlsmgr']['args'] = [] + +default['postfix']['master']['rewrite']['active'] = true +default['postfix']['master']['rewrite']['order'] = 90 +default['postfix']['master']['rewrite']['type'] = 'unix' +default['postfix']['master']['rewrite']['chroot'] = false +default['postfix']['master']['rewrite']['command'] = 'trivial-rewrite' +default['postfix']['master']['rewrite']['args'] = [] + +default['postfix']['master']['bounce']['active'] = true +default['postfix']['master']['bounce']['order'] = 100 +default['postfix']['master']['bounce']['type'] = 'unix' +default['postfix']['master']['bounce']['chroot'] = false +default['postfix']['master']['bounce']['maxproc'] = '0' +default['postfix']['master']['bounce']['command'] = 'bounce' +default['postfix']['master']['bounce']['args'] = [] + +default['postfix']['master']['defer']['active'] = true +default['postfix']['master']['defer']['order'] = 110 +default['postfix']['master']['defer']['type'] = 'unix' +default['postfix']['master']['defer']['chroot'] = false +default['postfix']['master']['defer']['maxproc'] = '0' +default['postfix']['master']['defer']['command'] = 'bounce' +default['postfix']['master']['defer']['args'] = [] + +default['postfix']['master']['trace']['active'] = true +default['postfix']['master']['trace']['order'] = 120 +default['postfix']['master']['trace']['type'] = 'unix' +default['postfix']['master']['trace']['chroot'] = false +default['postfix']['master']['trace']['maxproc'] = '0' +default['postfix']['master']['trace']['command'] = 'bounce' +default['postfix']['master']['trace']['args'] = [] + +default['postfix']['master']['verify']['active'] = true +default['postfix']['master']['verify']['order'] = 130 +default['postfix']['master']['verify']['type'] = 'unix' +default['postfix']['master']['verify']['chroot'] = false +default['postfix']['master']['verify']['maxproc'] = '1' +default['postfix']['master']['verify']['command'] = 'verify' +default['postfix']['master']['verify']['args'] = [] + +default['postfix']['master']['flush']['active'] = true +default['postfix']['master']['flush']['order'] = 140 +default['postfix']['master']['flush']['type'] = 'unix' +default['postfix']['master']['flush']['private'] = false +default['postfix']['master']['flush']['chroot'] = false +default['postfix']['master']['flush']['wakeup'] = '1000?' +default['postfix']['master']['flush']['maxproc'] = '0' +default['postfix']['master']['flush']['command'] = 'flush' +default['postfix']['master']['flush']['args'] = [] + +default['postfix']['master']['proxymap']['active'] = true +default['postfix']['master']['proxymap']['order'] = 150 +default['postfix']['master']['proxymap']['type'] = 'unix' +default['postfix']['master']['proxymap']['chroot'] = false +default['postfix']['master']['proxymap']['command'] = 'proxymap' +default['postfix']['master']['proxymap']['args'] = [] + +default['postfix']['master']['smtpunix']['service'] = 'smtp' +default['postfix']['master']['smtpunix']['active'] = true +default['postfix']['master']['smtpunix']['order'] = 160 +default['postfix']['master']['smtpunix']['type'] = 'unix' +default['postfix']['master']['smtpunix']['chroot'] = false +default['postfix']['master']['smtpunix']['maxproc'] = '500' +default['postfix']['master']['smtpunix']['command'] = 'smtp' +default['postfix']['master']['smtpunix']['args'] = [] + +default['postfix']['master']['relay']['active'] = true +default['postfix']['master']['relay']['comment'] = 'When relaying mail as backup MX, disable fallback_relay to avoid MX loops' +default['postfix']['master']['relay']['order'] = 170 +default['postfix']['master']['relay']['type'] = 'unix' +default['postfix']['master']['relay']['chroot'] = false +default['postfix']['master']['relay']['command'] = 'smtp' +default['postfix']['master']['relay']['args'] = ['-o smtp_fallback_relay='] + +default['postfix']['master']['showq']['active'] = true +default['postfix']['master']['showq']['order'] = 180 +default['postfix']['master']['showq']['type'] = 'unix' +default['postfix']['master']['showq']['private'] = false +default['postfix']['master']['showq']['chroot'] = false +default['postfix']['master']['showq']['command'] = 'showq' +default['postfix']['master']['showq']['args'] = [] + +default['postfix']['master']['error']['active'] = true +default['postfix']['master']['error']['order'] = 190 +default['postfix']['master']['error']['type'] = 'unix' +default['postfix']['master']['error']['chroot'] = false +default['postfix']['master']['error']['command'] = 'error' +default['postfix']['master']['error']['args'] = [] + +default['postfix']['master']['discard']['active'] = true +default['postfix']['master']['discard']['order'] = 200 +default['postfix']['master']['discard']['type'] = 'unix' +default['postfix']['master']['discard']['chroot'] = false +default['postfix']['master']['discard']['command'] = 'discard' +default['postfix']['master']['discard']['args'] = [] + +default['postfix']['master']['local']['active'] = true +default['postfix']['master']['local']['order'] = 210 +default['postfix']['master']['local']['type'] = 'unix' +default['postfix']['master']['local']['unpriv'] = false +default['postfix']['master']['local']['chroot'] = false +default['postfix']['master']['local']['command'] = 'local' +default['postfix']['master']['local']['args'] = [] + +default['postfix']['master']['virtual']['active'] = true +default['postfix']['master']['virtual']['order'] = 220 +default['postfix']['master']['virtual']['type'] = 'unix' +default['postfix']['master']['virtual']['unpriv'] = false +default['postfix']['master']['virtual']['chroot'] = false +default['postfix']['master']['virtual']['command'] = 'virtual' +default['postfix']['master']['virtual']['args'] = [] + +default['postfix']['master']['lmtp']['active'] = true +default['postfix']['master']['lmtp']['order'] = 230 +default['postfix']['master']['lmtp']['type'] = 'unix' +default['postfix']['master']['lmtp']['chroot'] = false +default['postfix']['master']['lmtp']['command'] = 'lmtp' +default['postfix']['master']['lmtp']['args'] = [] + +default['postfix']['master']['anvil']['active'] = true +default['postfix']['master']['anvil']['order'] = 240 +default['postfix']['master']['anvil']['type'] = 'unix' +default['postfix']['master']['anvil']['chroot'] = false +default['postfix']['master']['anvil']['maxproc'] = '1' +default['postfix']['master']['anvil']['command'] = 'anvil' +default['postfix']['master']['anvil']['args'] = [] + +default['postfix']['master']['scache']['active'] = true +default['postfix']['master']['scache']['order'] = 250 +default['postfix']['master']['scache']['type'] = 'unix' +default['postfix']['master']['scache']['chroot'] = false +default['postfix']['master']['scache']['maxproc'] = '1' +default['postfix']['master']['scache']['command'] = 'scache' +default['postfix']['master']['scache']['args'] = [] + +default['postfix']['master']['maildrop']['active'] = true +default['postfix']['master']['maildrop']['comment'] = 'See the Postfix MAILDROP_README file for details. To main.cf will be added: maildrop_destination_recipient_limit=1' +default['postfix']['master']['maildrop']['order'] = 510 +default['postfix']['master']['maildrop']['type'] = 'unix' +default['postfix']['master']['maildrop']['unpriv'] = false +default['postfix']['master']['maildrop']['chroot'] = false +default['postfix']['master']['maildrop']['command'] = 'pipe' +default['postfix']['master']['maildrop']['args'] = ['flags=DRhu user=vmail argv=/usr/local/bin/maildrop -d ${recipient}'] + +default['postfix']['master']['old-cyrus']['active'] = false +default['postfix']['master']['old-cyrus']['comment'] = 'The Cyrus deliver program has changed incompatibly, multiple times.' +default['postfix']['master']['old-cyrus']['order'] = 520 +default['postfix']['master']['old-cyrus']['type'] = 'unix' +default['postfix']['master']['old-cyrus']['unpriv'] = false +default['postfix']['master']['old-cyrus']['chroot'] = false +default['postfix']['master']['old-cyrus']['command'] = 'pipe' +default['postfix']['master']['old-cyrus']['args'] = ['flags=R user=cyrus argv=/usr/lib/cyrus-imapd/deliver -e -m ${extension} ${user}'] + +default['postfix']['master']['cyrus']['active'] = true +default['postfix']['master']['cyrus']['comment'] = 'Cyrus 2.1.5 (Amos Gouaux). To main.cf will be added: cyrus_destination_recipient_limit=1' +default['postfix']['master']['cyrus']['order'] = 530 +default['postfix']['master']['cyrus']['type'] = 'unix' +default['postfix']['master']['cyrus']['unpriv'] = false +default['postfix']['master']['cyrus']['chroot'] = false +default['postfix']['master']['cyrus']['command'] = 'pipe' +default['postfix']['master']['cyrus']['args'] = ['user=cyrus argv=/usr/lib/cyrus-imapd/deliver -e -r ${sender} -m ${extension} ${user}'] + +default['postfix']['master']['uucp']['active'] = true +default['postfix']['master']['uucp']['comment'] = 'See the Postfix UUCP_README file for configuration details.' +default['postfix']['master']['uucp']['order'] = 540 +default['postfix']['master']['uucp']['type'] = 'unix' +default['postfix']['master']['uucp']['unpriv'] = false +default['postfix']['master']['uucp']['chroot'] = false +default['postfix']['master']['uucp']['command'] = 'pipe' +default['postfix']['master']['uucp']['args'] = ['flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)'] + +default['postfix']['master']['ifmail']['active'] = false +default['postfix']['master']['ifmail']['order'] = 550 +default['postfix']['master']['ifmail']['type'] = 'unix' +default['postfix']['master']['ifmail']['unpriv'] = false +default['postfix']['master']['ifmail']['chroot'] = false +default['postfix']['master']['ifmail']['command'] = 'pipe' +default['postfix']['master']['ifmail']['args'] = ['flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)'] + +default['postfix']['master']['bsmtp']['active'] = true +default['postfix']['master']['bsmtp']['order'] = 560 +default['postfix']['master']['bsmtp']['type'] = 'unix' +default['postfix']['master']['bsmtp']['unpriv'] = false +default['postfix']['master']['bsmtp']['chroot'] = false +default['postfix']['master']['bsmtp']['command'] = 'pipe' +default['postfix']['master']['bsmtp']['args'] = ['flags=Fq. user=foo argv=/usr/local/sbin/bsmtp -f $sender $nexthop $recipient'] # OS Aliases -case node['platform'] -when 'freebsd' - default['postfix']['aliases'] = { - 'MAILER-DAEMON' => 'postmaster', - 'bin' => 'root', - 'daemon' => 'root', - 'named' => 'root', - 'nobody' => 'root', - 'uucp' => 'root', - 'www' => 'root', - 'ftp-bugs' => 'root', - 'postfix' => 'root', - 'manager' => 'root', - 'dumper' => 'root', - 'operator' => 'root', - 'abuse' => 'postmaster' - } -else - default['postfix']['aliases'] = {} -end +default['postfix']['aliases'] = case node['platform'] + when 'freebsd' + { + 'MAILER-DAEMON' => 'postmaster', + 'bin' => 'root', + 'daemon' => 'root', + 'named' => 'root', + 'nobody' => 'root', + 'uucp' => 'root', + 'www' => 'root', + 'ftp-bugs' => 'root', + 'postfix' => 'root', + 'manager' => 'root', + 'dumper' => 'root', + 'operator' => 'root', + 'abuse' => 'postmaster', + } + else + {} + end if node['postfix']['use_relay_restirictions_maps'] default['postfix']['main']['smtpd_relay_restrictions'] = "hash:#{node['postfix']['relay_restrictions_db']}, reject" end - diff --git a/cookbooks/postfix/metadata.json b/cookbooks/postfix/metadata.json index 5371d01..2b162d5 100644 --- a/cookbooks/postfix/metadata.json +++ b/cookbooks/postfix/metadata.json @@ -1 +1 @@ -{"name":"postfix","version":"3.7.0","description":"Installs and configures postfix for client or outbound relayhost, or to do SASL auth","long_description":"","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{"ubuntu":">= 0.0.0","debian":">= 0.0.0","redhat":">= 0.0.0","centos":">= 0.0.0","amazon":">= 0.0.0","scientific":">= 0.0.0","smartos":">= 0.0.0"},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{"postfix/main":{"display_name":"postfix/main","description":"Hash of Postfix main.cf attributes","type":"hash"},"postfix/aliases":{"display_name":"Postfix Aliases","description":"Hash of Postfix aliases mapping a name to a value. Example 'root' => 'operator@example.com'. See aliases man page for details.","type":"hash"},"postfix/transports":{"display_name":"Postfix Transports","description":"Hash of Postfix transports mapping a destination to a smtp server. Example 'my.domain' => 'smtp:outbound-relay.my.domain'. See transport man page for details.","type":"hash"},"postfix/access":{"display_name":"Postfix Access Table","description":"Hash of Postfix accesses mapping a pattern to a action. Example 'domain.tld' => 'OK'. See access man page for details.","type":"hash"},"postfix/mail_type":{"display_name":"Postfix Mail Type","description":"Is this node a client or server?","default":"client"},"postfix/smtp_sasl_user_name":{"display_name":"Postfix SMTP SASL Username","description":"User to auth SMTP via SASL","default":""},"postfix/smtp_sasl_passwd":{"display_name":"Postfix SMTP SASL Password","description":"Password for smtp_sasl_user_name","default":""},"postfix/relayhost_role":{"display_name":"Postfix Relayhost's role","description":"String containing the role name","default":"relayhost"},"postfix/use_procmail":{"display_name":"Postfix Use procmail?","description":"Whether procmail should be used as the local delivery agent for a server","default":"no"}},"groupings":{},"recipes":{"postfix":"Installs and configures postfix","postfix::sasl_auth":"Set up postfix to auth to a server with sasl","postfix::aliases":"Manages /etc/aliases","postfix::transports":"Manages /etc/postfix/transport","postfix::access":"Manages /etc/postfix/access","postfix::virtual_aliases":"Manages /etc/postfix/virtual","postfix::client":"Searches for the relayhost based on an attribute","postfix::server":"Sets the mail_type attribute to master"},"source_url":"https://github.com/opscode-cookbooks/postfix","issues_url":"https://github.com/opscode-cookbooks/postfix/issues"} \ No newline at end of file +{"name":"postfix","version":"5.0.1","description":"Installs and configures postfix for client or outbound relayhost, or to do SASL auth","long_description":"# postfix Cookbook\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/postfix.svg?branch=master)](https://travis-ci.org/chef-cookbooks/postfix) [![Cookbook Version](https://img.shields.io/cookbook/v/postfix.svg)](https://supermarket.chef.io/cookbooks/postfix)\n\nInstalls and configures postfix for client or outbound relayhost, or to do SASL authentication.\n\nOn RHEL-family systems, sendmail will be replaced with postfix.\n\n## Requirements\n\n### Platforms\n\n- Ubuntu 12.04+\n- Debian 7.0+\n- RHEL/CentOS/Scientific 5.7+, 6.2+\n- Amazon Linux (as of AMIs created after 4/9/2012)\n\nMay work on other platforms with or without modification.\n\n### Chef\n\n- Chef 12.1+\n\n### Cookbooks\n\n- none\n\n## Attributes\n\nSee `attributes/default.rb` for default values.\n\n### Generic cookbook attributes\n\n- `node['postfix']['mail_type']` - Sets the kind of mail configuration. `master` will set up a server (relayhost).\n- `node['postfix']['relayhost_role']` - name of a role used for search in the client recipe.\n- `node['postfix']['multi_environment_relay']` - set to true if nodes should not constrain search for the relayhost in their own environment.\n- `node['postfix']['use_procmail']` - set to true if nodes should use procmail as the delivery agent.\n- `node['postfix']['use_alias_maps']` - set to true if you want the cookbook to use/configure alias maps\n- `node['postfix']['use_transport_maps']` - set to true if you want the cookbook to use/configure transport maps\n- `node['postfix']['use_access_maps']` - set to true if you want the cookbook to use/configure access maps\n- `node['postfix']['use_virtual_aliases']` - set to true if you want the cookbook to use/configure virtual alias maps\n- `node['postfix']['use_relay_restrictions_maps']` - set to true if you want the cookbook to use/configure a list of domains to which postfix will allow relay\n- `node['postfix']['aliases']` - hash of aliases to create with `recipe[postfix::aliases]`, see below under **Recipes** for more information.\n- `node['postfix']['transports']` - hash of transports to create with `recipe[postfix::transports]`, see below under **Recipes** for more information.\n- `node['postfix']['access']` - hash of access to create with `recipe[postfix::access]`, see below under **Recipes** for more information.\n- `node['postfix']['virtual_aliases']` - hash of virtual_aliases to create with `recipe[postfix::virtual_aliases]`, see below under __Recipes__ for more information.\n- `node['postfix']['main_template_source']` - Cookbook source for main.cf template. Default 'postfix'\n- `node['postfix']['master_template_source']` - Cookbook source for master.cf template. Default 'postfix'\n\n### main.cf and sasl_passwd template attributes\n\nThe main.cf template has been simplified to include any attributes in the `node['postfix']['main']` data structure. The following attributes are still included with this cookbook to maintain some semblance of backwards compatibility.\n\nThis change in namespace to `node['postfix']['main']` should allow for greater flexibility, given the large number of configuration variables for the postfix daemon. All of these cookbook attributes correspond to the option of the same name in `/etc/postfix/main.cf`.\n\n- `node['postfix']['main']['biff']` - (yes/no); default no\n- `node['postfix']['main']['append_dot_mydomain']` - (yes/no); default no\n- `node['postfix']['main']['myhostname']` - defaults to fqdn from Ohai\n- `node['postfix']['main']['mydomain']` - defaults to domain from Ohai\n- `node['postfix']['main']['myorigin']` - defaults to $myhostname\n- `node['postfix']['main']['mynetworks']` - default is nil, which forces Postfix to default to loopback addresses.\n- `node['postfix']['main']['inet_interfaces']` - set to `loopback-only`, or `all` for server recipe\n- `node['postfix']['main']['alias_maps']` - set to `hash:/etc/aliases`\n- `node['postfix']['main']['mailbox_size_limit']` - set to `0` (disabled)\n- `node['postfix']['main']['mydestination']` - default fqdn, hostname, localhost.localdomain, localhost\n- `node['postfix']['main']['smtpd_use_tls']` - (yes/no); default yes. See conditional cert/key attributes.\n- `node['postfix']['main']['smtpd_tls_cert_file']` - conditional attribute, set to full path of server's x509 certificate.\n- `node['postfix']['main']['smtpd_tls_key_file']` - conditional attribute, set to full path of server's private key\n- `node['postfix']['main']['smtpd_tls_CAfile']` - set to platform specific CA bundle\n- `node['postfix']['main']['smtpd_tls_session_cache_database']` - set to `btree:${data_directory}/smtpd_scache`\n- `node['postfix']['main']['smtp_use_tls']` - (yes/no); default yes. See following conditional attributes.\n- `node['postfix']['main']['smtp_tls_CAfile']` - set to platform specific CA bundle\n- `node['postfix']['main']['smtp_tls_session_cache_database']` - set to `btree:${data_directory}/smtpd_scache`\n- `node['postfix']['main']['smtp_sasl_auth_enable']` - (yes/no); default no. If enabled, see following conditional attributes.\n- `node['postfix']['main']['smtp_sasl_password_maps']` - Set to `hash:/etc/postfix/sasl_passwd` template file\n- `node['postfix']['main']['smtp_sasl_security_options']` - Set to noanonymous\n- `node['postfix']['main']['relayhost']` - Set to empty string\n- `node['postfix']['sasl']['smtp_sasl_user_name']` - SASL user to authenticate as. Default empty\n- `node['postfix']['sasl']['smtp_sasl_passwd']` - SASL password to use. Default empty.\n- `node['postfix']['sender_canonical_map_entries']` - (hash with key value pairs); default not configured. Setup generic canonical maps. See `man 5 canonical`. If has at least one value, then will be enabled in config.\n- `node['postfix']['smtp_generic_map_entries']` - (hash with key value pairs); default not configured. Setup generic postfix maps. See `man 5 generic`. If has at least one value, then will be enabled in config.\n\nExample of json role config, for setup *_map_entries:\n\n`postfix : {`\n\n`...`\n\n`\"smtp_generic_map_entries\" : { \"root@youinternaldomain.local\" : \"admin@example.com\", \"admin@youinternaldomain.local\" : \"admin@example.com\" }`\n\n`}`\n\n### master.cf template attributes\n\nThe master.cf template has been changed to allow full customization of the file content. For purpose of backwards compatibility default attributes generate the same master.cf. But via `node['postfix']['master']` data structure in your role for instance it can be completelly rewritten.\n\nExamples of json role config, for customize master.cf:\n\n`postfix : {`\n\n`...`\n\nturn some services off or on:\n\n```json\n \"master\" : {\n \"smtps\": {\n \"active\": true\n },\n \"old-cyrus\": {\n \"active\": false\n },\n \"cyrus\": {\n \"active\": false\n },\n \"uucp\": {\n \"active\": false\n },\n \"ifmail\": {\n \"active\": false\n },\n```\n\n`...` define you own service:\n\n```json\n \"spamfilter\": {\n \"comment\": \"My own spamfilter\",\n \"active\": true,\n \"order\": 590,\n \"type\": \"unix\",\n \"unpriv\": false,\n \"chroot\": false,\n \"command\": \"pipe\",\n \"args\": [\"flags=Rq user=spamd argv=/usr/bin/spamfilter.sh -oi -f ${sender} ${recipient}\"]\n }\n```\n\n`...`\n\n`}` `}`\n\nThe possible service hash fields and their meanings: hash key - have to be unique, unless you wish to override default definition.\n\nField | Mandatory | Description\n------- | --------- | --------------------------------------------------------------------\nactive | Yes | Boolean. Defines whether or not the service needs to be in master.cf\ncomment | No | String. If you would like to add a comment line before service line\norder | Yes | Integer. Number to define the order of lines in the file\ntype | Yes | String. Type of the service (inet, unix, fifo)\nprivate | No | Boolean. If present replaced by `y` or `n`, otherwise by `-`\nunpriv | No | Boolean. If present replaced by `y` or `n`, otherwise by `-`\nchroot | No | Boolean. If present replaced by `y` or `n`, otherwise by `-`\nwakeup | No | String. If present value placed in file, otherwise replaced by `-`\nmaxproc | No | String. If present value placed in file, otherwise replaced by `-`\ncommand | Yes | String. The command to be executed.\nargs | Yes | Array of Strings. Arguments passed to command.\n\nFor more information about meaning of the fields consult `master (5)` manual: \n\n## Recipes\n\n### default\n\nInstalls the postfix package and manages the service and the main configuration files (`/etc/postfix/main.cf` and `/etc/postfix/master.cf`). See **Usage** and **Examples** to see how to affect behavior of this recipe through configuration. Depending on the `node['postfix']['use_alias_maps']`, `node['postfix']['use_transport_maps']`, `node['postfix']['use_access_maps']` and `node['postfix']['use_virtual_aliases']` attributes the default recipe can call additional recipes to manage additional postfix configuration files\n\nFor a more dynamic approach to discovery for the relayhost, see the `client` and `server` recipes below.\n\n### client\n\nUse this recipe to have nodes automatically search for the mail relay based which node has the `node['postfix']['relayhost_role']` role. Sets the `node['postfix']['main']['relayhost']` attribute to the first result from the search.\n\nIncludes the default recipe to install, configure and start postfix.\n\nDoes not work with `chef-solo`.\n\n### sasl_auth\n\nSets up the system to authenticate with a remote mail relay using SASL authentication.\n\n### server\n\nTo use Chef Server search to automatically detect a node that is the relayhost, use this recipe in a role that will be relayhost. By default, the role should be \"relayhost\" but you can change the attribute `node['postfix']['relayhost_role']` to modify this.\n\n**Note** This recipe will set the `node['postfix']['mail_type']` to \"master\" with an override attribute.\n\n### maps\n\nGeneral recipe to manage any number of any type postfix lookup tables. You can replace with it recipes like `transport` or `virtual_aliases`, but what is more important - you can create any kinds of maps, which has no own recipe, including database lookup maps configuration. `maps` is a hash keys of which is a lookup table type and value is another hash with filenames as the keys and hash with file content as the value. File content is an any number of key/value pairs which meaning depends on lookup table type. Examlle:\n\n```json\n \"override_attributes\": {\n \"postfix\": {\n \"maps\": {\n \"hash\": {\n \"/etc/postfix/vmailbox\": {\n \"john@example.com\": \"ok\",\n \"john@example.net\": \"ok\",\n },\n \"/etc/postfix/virtual\": {\n \"postmaster@example.com\": \"john@example.com\",\n \"postmaster@example.net\": \"john@example.net\",\n \"root@mail.example.net\": \"john@example.net\"\n },\n \"/etc/postfix/envelope_senders\": {\n \"@example.com\": \"john@example.com\",\n \"@example.net\": \"john@example.net\"\n },\n \"/etc/postfix/relay_recipients\": {\n \"john@example.net\": \"ok\",\n \"john@example.com\": \"ok\",\n \"admin@example.com\": \"ok\",\n }\n },\n \"pgsql\": {\n \"/etc/postfix/pgtest\": {\n \"hosts\": \"db.local:2345\",\n \"user\": \"postfix\",\n \"password\": \"test\",\n \"dbname\": \"postdb\",\n \"query\": \"SELECT replacement FROM aliases WHERE mailbox = '%s'\"\n }\n }\n }\n }\n```\n\nTo use these files in your configuration reference them in `node['postfix']['main']`, for instance:\n\n```json\n \"postfix\": {\n \"main\": {\n \"smtpd_sender_login_maps\": \"hash:/etc/postfix/envelope_senders\",\n \"relay_recipient_maps\": \"hash:/etc/postfix/relay_recipients\",\n \"virtual_mailbox_maps\": \"hash:/etc/postfix/vmailbox\",\n \"virtual_alias_maps\": \"hash:/etc/postfix/virtual\",\n }\n }\n```\n\n### aliases\n\nManage `/etc/aliases` with this recipe. Currently only Ubuntu 10.04 platform has a template for the aliases file. Add your aliases template to the `templates/default` or to the appropriate platform+version directory per the File Specificity rules for templates. Then specify a hash of aliases for the `node['postfix']['aliases']` attribute.\n\nArrays are supported as alias values, since postfix supports comma separated values per alias, simply specify your alias as an array to use this handy feature.\n\n### aliases\n\nManage `/etc/aliases` with this recipe.\n\n### transports\n\nManage `/etc/postfix/transport` with this recipe.\n\n### access\n\nManage `/etc/postfix/access` with this recipe.\n\n### virtual_aliases\n\nManage `/etc/postfix/virtual` with this recipe.\n\n### relay_restrictions\n\nManage `/etc/postfix/relay_restriction` with this recipe The postfix option smtpd_relay_restrictions in main.cf will point to this hash map db.\n\n\n\n## Usage\n\nOn systems that should simply send mail directly to a relay, or out to the internet, use `recipe[postfix]` and modify the `node['postfix']['main']['relayhost']` attribute via a role.\n\nOn systems that should be the MX for a domain, set the attributes accordingly and make sure the `node['postfix']['mail_type']` attribute is `master`. See **Examples** for information on how to use `recipe[postfix::server]` to do this automatically.\n\nIf you need to use SASL authentication to send mail through your ISP (such as on a home network), use `postfix::sasl_auth` and set the appropriate attributes.\n\nFor each of these implementations, see **Examples** for role usage.\n\n### Examples\n\nThe example roles below only have the relevant postfix usage. You may have other contents depending on what you're configuring on your systems.\n\nThe `base` role is applied to all nodes in the environment.\n\n```ruby\nname \"base\"\nrun_list(\"recipe[postfix]\")\noverride_attributes(\n \"postfix\" => {\n \"mail_type\" => \"client\",\n \"main\" => {\n \"mydomain\" => \"example.com\",\n \"myorigin\" => \"example.com\",\n \"relayhost\" => \"[smtp.example.com]\",\n \"smtp_use_tls\" => \"no\"\n }\n }\n)\n```\n\nThe `relayhost` role is applied to the nodes that are relayhosts. Often this is 2 systems using a CNAME of `smtp.example.com`.\n\n```ruby\nname \"relayhost\"\nrun_list(\"recipe[postfix::server]\")\noverride_attributes(\n \"postfix\" => {\n \"mail_type\" => \"master\",\n \"main\" => {\n \"mynetworks\" => [ \"10.3.3.0/24\", \"127.0.0.0/8\" ],\n \"inet_interfaces\" => \"all\",\n \"mydomain\" => \"example.com\",\n \"myorigin\" => \"example.com\"\n }\n)\n```\n\nThe `sasl_relayhost` role is applied to the nodes that are relayhosts and require authenticating with SASL. For example this might be on a household network with an ISP that otherwise blocks direct internet access to SMTP.\n\n```ruby\nname \"sasl_relayhost\"\nrun_list(\"recipe[postfix], recipe[postfix::sasl_auth]\")\noverride_attributes(\n \"postfix\" => {\n \"mail_type\" => \"master\",\n \"main\" => {\n \"mynetworks\" => \"10.3.3.0/24\",\n \"mydomain\" => \"example.com\",\n \"myorigin\" => \"example.com\",\n \"relayhost\" => \"[smtp.comcast.net]:587\",\n \"smtp_sasl_auth_enable\" => \"yes\"\n },\n \"sasl\" => {\n \"smtp_sasl_passwd\" => \"your_password\",\n \"smtp_sasl_user_name\" => \"your_username\"\n }\n }\n)\n```\n\nFor an example of using encrypted data bags to encrypt the SASL password, see the following blog post:\n\n- \n\n#### Examples using the client & server recipes\n\nIf you'd like to use the more dynamic search based approach for discovery, use the server and client recipes. First, create a relayhost role.\n\n```ruby\nname \"relayhost\"\nrun_list(\"recipe[postfix::server]\")\noverride_attributes(\n \"postfix\" => {\n \"main\" => {\n \"mynetworks\" => \"10.3.3.0/24\",\n \"mydomain\" => \"example.com\",\n \"myorigin\" => \"example.com\"\n }\n }\n)\n```\n\nThen, add the `postfix::client` recipe to the run list of your `base` role or equivalent role for postfix clients.\n\n```ruby\nname \"base\"\nrun_list(\"recipe[postfix::client]\")\noverride_attributes(\n \"postfix\" => {\n \"mail_type\" => \"client\",\n \"main\" => {\n \"mydomain\" => \"example.com\",\n \"myorigin\" => \"example.com\"\n }\n }\n)\n```\n\nIf you wish to use a different role name for the relayhost, then also set the attribute in the `base` role. For example, `postfix_master` as the role name:\n\n```ruby\nname \"postfix_master\"\ndescription \"a role for postfix master that isn't relayhost\"\nrun_list(\"recipe[postfix::server]\")\noverride_attributes(\n \"postfix\" => {\n \"main\" => {\n \"mynetworks\" => \"10.3.3.0/24\",\n \"mydomain\" => \"example.com\",\n \"myorigin\" => \"example.com\"\n }\n }\n)\n```\n\nThe base role would look something like this:\n\n```ruby\nname \"base\"\nrun_list(\"recipe[postfix::client]\")\noverride_attributes(\n \"postfix\" => {\n \"relayhost_role\" => \"postfix_master\",\n \"mail_type\" => \"client\",\n \"main\" => {\n \"mydomain\" => \"example.com\",\n \"myorigin\" => \"example.com\"\n }\n }\n)\n```\n\nTo use relay restrictions override the relay restrictions attribute in this format:\n\n```ruby\noverride_attributes(\n \"postfix\" => {\n \"use_relay_restrictions_maps\" => true,\n \"relay_restrictions\" => {\n \"chef.io\" => \"OK\",\n \".chef.io\" => \"OK\",\n \"example.com\" => \"OK\"\n }\n }\n)\n```\n\n## License & Authors\n\n**Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io))\n\n**Copyright:** 2009-2016, Chef Software, Inc.\n\n```\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{"ubuntu":">= 0.0.0","debian":">= 0.0.0","redhat":">= 0.0.0","centos":">= 0.0.0","amazon":">= 0.0.0","oracle":">= 0.0.0","scientific":">= 0.0.0","smartos":">= 0.0.0","fedora":">= 0.0.0"},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{"postfix":"Installs and configures postfix","postfix::sasl_auth":"Set up postfix to auth to a server with sasl","postfix::aliases":"Manages /etc/aliases","postfix::transports":"Manages /etc/postfix/transport","postfix::access":"Manages /etc/postfix/access","postfix::virtual_aliases":"Manages /etc/postfix/virtual","postfix::client":"Searches for the relayhost based on an attribute","postfix::server":"Sets the mail_type attribute to master","postfix::maps":"Manages any number of any type postfix lookup tables"}} \ No newline at end of file diff --git a/cookbooks/postfix/recipes/_attributes.rb b/cookbooks/postfix/recipes/_attributes.rb index 01d7ca8..a570533 100644 --- a/cookbooks/postfix/recipes/_attributes.rb +++ b/cookbooks/postfix/recipes/_attributes.rb @@ -1,5 +1,4 @@ -# encoding: utf-8 -# Copyright:: Copyright 2012-2014, Chef Software, Inc. +# Copyright:: 2012-2016, 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. @@ -15,46 +14,58 @@ # if node['postfix']['use_procmail'] - node.default['postfix']['main']['mailbox_command'] = '/usr/bin/procmail -a "$EXTENSION"' + node.default_unless['postfix']['main']['mailbox_command'] = '/usr/bin/procmail -a "$EXTENSION"' end if node['postfix']['main']['smtpd_use_tls'] == 'yes' - node.default['postfix']['main']['smtpd_tls_cert_file'] = '/etc/ssl/certs/ssl-cert-snakeoil.pem' - node.default['postfix']['main']['smtpd_tls_key_file'] = '/etc/ssl/private/ssl-cert-snakeoil.key' - node.default['postfix']['main']['smtpd_tls_CAfile'] = node['postfix']['cafile'] - node.default['postfix']['main']['smtpd_tls_session_cache_database'] = 'btree:${data_directory}/smtpd_scache' + node.default_unless['postfix']['main']['smtpd_tls_cert_file'] = '/etc/ssl/certs/ssl-cert-snakeoil.pem' + node.default_unless['postfix']['main']['smtpd_tls_key_file'] = '/etc/ssl/private/ssl-cert-snakeoil.key' + node.default_unless['postfix']['main']['smtpd_tls_CAfile'] = node['postfix']['cafile'] + node.default_unless['postfix']['main']['smtpd_tls_session_cache_database'] = 'btree:${data_directory}/smtpd_scache' end if node['postfix']['main']['smtp_use_tls'] == 'yes' - node.default['postfix']['main']['smtp_tls_CAfile'] = node['postfix']['cafile'] - node.default['postfix']['main']['smtp_tls_session_cache_database'] = 'btree:${data_directory}/smtp_scache' + node.default_unless['postfix']['main']['smtp_tls_CAfile'] = node['postfix']['cafile'] + node.default_unless['postfix']['main']['smtp_tls_session_cache_database'] = 'btree:${data_directory}/smtp_scache' end if node['postfix']['main']['smtp_sasl_auth_enable'] == 'yes' - node.default['postfix']['sasl_password_file'] = "#{node['postfix']['conf_dir']}/sasl_passwd" - node.default['postfix']['main']['smtp_sasl_password_maps'] = "hash:#{node['postfix']['sasl_password_file']}" - node.default['postfix']['main']['smtp_sasl_security_options'] = 'noanonymous' - node.default['postfix']['sasl']['smtp_sasl_user_name'] = '' - node.default['postfix']['sasl']['smtp_sasl_passwd'] = '' - node.default['postfix']['main']['relayhost'] = '' + node.default_unless['postfix']['sasl_password_file'] = "#{node['postfix']['conf_dir']}/sasl_passwd" + node.default_unless['postfix']['main']['smtp_sasl_password_maps'] = "hash:#{node['postfix']['sasl_password_file']}" + node.default_unless['postfix']['main']['smtp_sasl_security_options'] = 'noanonymous' + node.default_unless['postfix']['sasl']['smtp_sasl_user_name'] = '' + node.default_unless['postfix']['sasl']['smtp_sasl_passwd'] = '' + node.default_unless['postfix']['main']['relayhost'] = '' end if node['postfix']['use_alias_maps'] - node.default['postfix']['main']['alias_maps'] = ["hash:#{node['postfix']['aliases_db']}"] + node.default_unless['postfix']['main']['alias_maps'] = ["hash:#{node['postfix']['aliases_db']}"] end if node['postfix']['use_transport_maps'] - node.default['postfix']['main']['transport_maps'] = ["hash:#{node['postfix']['transport_db']}"] + node.default_unless['postfix']['main']['transport_maps'] = ["hash:#{node['postfix']['transport_db']}"] end if node['postfix']['use_access_maps'] - node.default['postfix']['main']['access_maps'] = ["hash:#{node['postfix']['access_db']}"] + node.default_unless['postfix']['main']['access_maps'] = ["hash:#{node['postfix']['access_db']}"] end if node['postfix']['use_virtual_aliases'] - node.default['postfix']['main']['virtual_alias_maps'] = ["#{node['postfix']['virtual_alias_db_type']}:#{node['postfix']['virtual_alias_db']}"] + node.default_unless['postfix']['main']['virtual_alias_maps'] = ["#{node['postfix']['virtual_alias_db_type']}:#{node['postfix']['virtual_alias_db']}"] end if node['postfix']['use_virtual_aliases_domains'] - node.default['postfix']['main']['virtual_alias_domains'] = ["#{node['postfix']['virtual_alias_domains_db_type']}:#{node['postfix']['virtual_alias_domains_db']}"] + node.default_unless['postfix']['main']['virtual_alias_domains'] = ["#{node['postfix']['virtual_alias_domains_db_type']}:#{node['postfix']['virtual_alias_domains_db']}"] +end + +if node['postfix']['use_relay_restirictions_maps'] + default['postfix']['main']['smtpd_relay_restrictions'] = "hash:#{node['postfix']['relay_restrictions_db']}, reject" +end + +if node['postfix']['master']['maildrop']['active'] + node.default_unless['postfix']['main']['maildrop_destination_recipient_limit'] = 1 +end + +if node['postfix']['master']['cyrus']['active'] + node.default_unless['postfix']['main']['cyrus_destination_recipient_limit'] = 1 end diff --git a/cookbooks/postfix/recipes/_common.rb b/cookbooks/postfix/recipes/_common.rb index b8fc106..fc0fcc0 100644 --- a/cookbooks/postfix/recipes/_common.rb +++ b/cookbooks/postfix/recipes/_common.rb @@ -1,9 +1,8 @@ -# encoding: utf-8 # Author:: Joshua Timberman() -# Cookbook Name:: common +# Cookbook:: common # Recipe:: default # -# Copyright 2009-2014, Chef Software, Inc. +# Copyright:: 2009-2016, 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. @@ -57,7 +56,7 @@ when 'omnios' # we don't guard this because if the user creation was successful (or happened out of band), then this won't get executed when the action is :nothing. execute '/opt/omni/sbin/postfix set-permissions' - template manifest_path do + template manifest_path do source 'manifest-postfix.xml.erb' owner 'root' group node['root_group'] @@ -87,7 +86,7 @@ unless node['postfix']['sender_canonical_map_entries'].empty? end unless node['postfix']['main'].key?('sender_canonical_maps') - node.set['postfix']['main']['sender_canonical_maps'] = "hash:#{node['postfix']['conf_dir']}/sender_canonical" + node.normal['postfix']['main']['sender_canonical_maps'] = "hash:#{node['postfix']['conf_dir']}/sender_canonical" end end @@ -100,13 +99,13 @@ unless node['postfix']['smtp_generic_map_entries'].empty? template "#{node['postfix']['conf_dir']}/smtp_generic" do owner 'root' group node['root_group'] - mode '0644' + mode '0644' notifies :run, 'execute[update-postfix-smtp_generic]' notifies :reload, 'service[postfix]' end unless node['postfix']['main'].key?('smtp_generic_maps') - node.set['postfix']['main']['smtp_generic_maps'] = "hash:#{node['postfix']['conf_dir']}/smtp_generic" + node.normal['postfix']['main']['smtp_generic_maps'] = "hash:#{node['postfix']['conf_dir']}/smtp_generic" end end diff --git a/cookbooks/postfix/recipes/access.rb b/cookbooks/postfix/recipes/access.rb index b28ab07..34766f6 100644 --- a/cookbooks/postfix/recipes/access.rb +++ b/cookbooks/postfix/recipes/access.rb @@ -1,5 +1,4 @@ -# encoding: utf-8 -# Copyright:: Copyright (c) 2012, Chef Software, Inc. +# Copyright:: 2012-2016, 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/cookbooks/postfix/recipes/aliases.rb b/cookbooks/postfix/recipes/aliases.rb index cd2eb3c..45253f0 100644 --- a/cookbooks/postfix/recipes/aliases.rb +++ b/cookbooks/postfix/recipes/aliases.rb @@ -1,5 +1,4 @@ -# encoding: utf-8 -# Copyright:: Copyright 2012-2014, Chef Software, Inc. +# Copyright:: Copyright 2012-2016, 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. @@ -20,7 +19,7 @@ execute 'update-postfix-aliases' do command 'newaliases' environment PATH: "#{ENV['PATH']}:/opt/omni/bin:/opt/omni/sbin" if platform_family?('omnios') # On FreeBSD, /usr/sbin/newaliases is the sendmail command, and it's in the path before postfix's /usr/local/bin/newaliases - environment ({ 'PATH' => "/usr/local/bin:#{ENV['PATH']}" }) if platform_family?('freebsd') + environment('PATH' => "/usr/local/bin:#{ENV['PATH']}") if platform_family?('freebsd') action :nothing end diff --git a/cookbooks/postfix/recipes/client.rb b/cookbooks/postfix/recipes/client.rb index 2f304f1..edb7283 100644 --- a/cookbooks/postfix/recipes/client.rb +++ b/cookbooks/postfix/recipes/client.rb @@ -1,9 +1,8 @@ -# encoding: utf-8 # Author:: Joshua Timberman() -# Cookbook Name:: postfix +# Cookbook:: postfix # Recipe:: client # -# Copyright 2009-2014, Chef Software, Inc. +# Copyright:: 2009-2016, 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. @@ -37,6 +36,6 @@ else relayhost = results.map { |n| n['ipaddress'] }.first end -node.set['postfix']['main']['relayhost'] = "[#{relayhost}]" +node.normal['postfix']['main']['relayhost'] = "[#{relayhost}]" include_recipe 'postfix' diff --git a/cookbooks/postfix/recipes/default.rb b/cookbooks/postfix/recipes/default.rb index ba28cdc..3fd8a04 100644 --- a/cookbooks/postfix/recipes/default.rb +++ b/cookbooks/postfix/recipes/default.rb @@ -1,9 +1,8 @@ -# encoding: utf-8 # Author:: Joshua Timberman() -# Cookbook Name:: postfix +# Cookbook:: postfix # Recipe:: default # -# Copyright 2009-2014, Chef Software, Inc. +# Copyright:: 2009-2016, 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. @@ -20,31 +19,18 @@ include_recipe 'postfix::_common' -if node['postfix']['main']['smtp_sasl_auth_enable'] == 'yes' - include_recipe 'postfix::sasl_auth' -end +include_recipe 'postfix::sasl_auth' if node['postfix']['main']['smtp_sasl_auth_enable'] == 'yes' -if node['postfix']['use_alias_maps'] - include_recipe 'postfix::aliases' -end +include_recipe 'postfix::aliases' if node['postfix']['use_alias_maps'] -if node['postfix']['use_transport_maps'] - include_recipe 'postfix::transports' -end +include_recipe 'postfix::transports' if node['postfix']['use_transport_maps'] -if node['postfix']['use_access_maps'] - include_recipe 'postfix::access' -end +include_recipe 'postfix::access' if node['postfix']['use_access_maps'] -if node['postfix']['use_virtual_aliases'] - include_recipe 'postfix::virtual_aliases' -end +include_recipe 'postfix::virtual_aliases' if node['postfix']['use_virtual_aliases'] -if node['postfix']['use_virtual_aliases_domains'] - include_recipe 'postfix::virtual_aliases_domains' -end +include_recipe 'postfix::virtual_aliases_domains' if node['postfix']['use_virtual_aliases_domains'] -if node['postfix']['use_relay_restrictions_maps'] - include_recipe 'postfix::relay_restrictions' -end +include_recipe 'postfix::relay_restrictions' if node['postfix']['use_relay_restrictions_maps'] +include_recipe 'postfix::maps' if node['postfix']['maps'] diff --git a/cookbooks/postfix/recipes/maps.rb b/cookbooks/postfix/recipes/maps.rb new file mode 100644 index 0000000..9aa06e8 --- /dev/null +++ b/cookbooks/postfix/recipes/maps.rb @@ -0,0 +1,47 @@ +# encoding: utf-8 +# Copyright:: Copyright (c) 2012, 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. +# 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. +# + +node['postfix']['maps'].each do |type, maps| + if node['platform_family'] == 'debian' + package "postfix-#{type}" if %w(pgsql mysql ldap cdb).include?(type) + end + + separator = if %w(pgsql mysql ldap memcache sqlite).include?(type) + ' = ' + else + ' ' + end + maps.each do |file, content| + execute "update-postmap-#{file}" do + command "postmap #{file}" + environment PATH: "#{ENV['PATH']}:/opt/omni/bin:/opt/omni/sbin" if platform_family?('omnios') + action :nothing + end if %w(btree cdb dbm hash sdbm).include?(type) + template "#{file}-#{type}" do + path file + source 'maps.erb' + only_if "postconf -m | grep -q #{type}" + variables( + map: content, + separator: separator + ) + if %w(btree cdb dbm hash sdbm).include?(type) + notifies :run, "execute[update-postmap-#{file}]" + end + notifies :restart, 'service[postfix]' + end + end +end diff --git a/cookbooks/postfix/recipes/relay_restrictions.rb b/cookbooks/postfix/recipes/relay_restrictions.rb index a96d482..8e458f9 100644 --- a/cookbooks/postfix/recipes/relay_restrictions.rb +++ b/cookbooks/postfix/recipes/relay_restrictions.rb @@ -1,5 +1,4 @@ -# encoding: utf-8 -# Copyright:: Copyright (c) 2012, Chef Software, Inc. +# Copyright:: 2012-2016, 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. @@ -26,4 +25,3 @@ template node['postfix']['relay_restrictions_db'] do source 'relay_restrictions.erb' notifies :run, 'execute[update-postfix-relay-restrictions]' end - diff --git a/cookbooks/postfix/recipes/sasl_auth.rb b/cookbooks/postfix/recipes/sasl_auth.rb index 519798d..d8079ca 100644 --- a/cookbooks/postfix/recipes/sasl_auth.rb +++ b/cookbooks/postfix/recipes/sasl_auth.rb @@ -1,10 +1,9 @@ -# encoding: utf-8 # # Author:: Joshua Timberman() -# Cookbook Name:: postfix +# Cookbook:: postfix # Recipe:: sasl_auth # -# Copyright 2009-2014, Chef Software, Inc. +# Copyright:: 2009-2016, 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. @@ -29,11 +28,11 @@ case node['platform_family'] when 'debian' sasl_pkgs = %w(libsasl2-2 libsasl2-modules ca-certificates) when 'rhel' - if node['platform_version'].to_i < 6 - sasl_pkgs = %w(cyrus-sasl cyrus-sasl-plain openssl) - else - sasl_pkgs = %w(cyrus-sasl cyrus-sasl-plain ca-certificates) - end + sasl_pkgs = if node['platform_version'].to_i < 6 + %w(cyrus-sasl cyrus-sasl-plain openssl) + else + %w(cyrus-sasl cyrus-sasl-plain ca-certificates) + end when 'fedora' sasl_pkgs = %w(cyrus-sasl cyrus-sasl-plain ca-certificates) end @@ -53,7 +52,7 @@ template node['postfix']['sasl_password_file'] do source 'sasl_passwd.erb' owner 'root' group node['root_group'] - mode 0400 + mode '400' notifies :run, 'execute[postmap-sasl_passwd]', :immediately notifies :restart, 'service[postfix]' variables(settings: node['postfix']['sasl']) diff --git a/cookbooks/postfix/recipes/server.rb b/cookbooks/postfix/recipes/server.rb index e733d47..4fd6e57 100644 --- a/cookbooks/postfix/recipes/server.rb +++ b/cookbooks/postfix/recipes/server.rb @@ -1,10 +1,9 @@ -# encoding: utf-8 # # Author:: Joshua Timberman() -# Cookbook Name:: postfix +# Cookbook:: postfix # Recipe:: server # -# Copyright 2009-2014, Chef Software, Inc. +# Copyright:: 2009-2016, 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/cookbooks/postfix/recipes/transports.rb b/cookbooks/postfix/recipes/transports.rb index 24e610d..40eea63 100644 --- a/cookbooks/postfix/recipes/transports.rb +++ b/cookbooks/postfix/recipes/transports.rb @@ -1,5 +1,4 @@ -# encoding: utf-8 -# Copyright:: Copyright (c) 2012, Chef Software, Inc. +# Copyright:: 2012-2016, 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/cookbooks/postfix/recipes/virtual_aliases.rb b/cookbooks/postfix/recipes/virtual_aliases.rb index dadde7f..caedec5 100644 --- a/cookbooks/postfix/recipes/virtual_aliases.rb +++ b/cookbooks/postfix/recipes/virtual_aliases.rb @@ -1,5 +1,4 @@ -# encoding: utf-8 -# Copyright:: Copyright (c) 2012, Chef Software, Inc. +# Copyright:: 2012-2016, 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/cookbooks/postfix/recipes/virtual_aliases_domains.rb b/cookbooks/postfix/recipes/virtual_aliases_domains.rb index 2c708c0..b835c17 100644 --- a/cookbooks/postfix/recipes/virtual_aliases_domains.rb +++ b/cookbooks/postfix/recipes/virtual_aliases_domains.rb @@ -1,5 +1,4 @@ -# encoding: utf-8 -# Copyright:: Copyright (c) 2012, Chef Software, Inc. +# Copyright:: 2012-2016, 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/cookbooks/postfix/templates/default/access.erb b/cookbooks/postfix/templates/default/access.erb index 022f7c5..d054fa9 100644 --- a/cookbooks/postfix/templates/default/access.erb +++ b/cookbooks/postfix/templates/default/access.erb @@ -1,7 +1,6 @@ # -# This file is generated by Chef for <%= node['fqdn'] %> -# -# Local changes will be overwritten +# Auto-generated by Chef. Do not hand edit! +# Local modifications will be overwritten. # # See man 5 access for format diff --git a/cookbooks/postfix/templates/default/aliases.erb b/cookbooks/postfix/templates/default/aliases.erb index 182cbae..3093154 100644 --- a/cookbooks/postfix/templates/default/aliases.erb +++ b/cookbooks/postfix/templates/default/aliases.erb @@ -1,11 +1,10 @@ # -# This file is generated by Chef for <%= node['fqdn'] %> -# -# Local changes will be overwritten +# Auto-generated by Chef. +# Local modifications will be overwritten. # # See man 5 aliases for format postmaster: root <% node['postfix']['aliases'].each do |name, value| %> -<%= name %>: <%= [value].flatten.map{|x| %Q("#{x}")}.join(', ') %> +<%= name %>: <%= [value].flatten.map{|x| if (x.include?("@")) then x else %Q("#{x}") end}.join(', ') %> <% end unless node['postfix']['aliases'].nil? %> diff --git a/cookbooks/postfix/templates/default/main.cf.erb b/cookbooks/postfix/templates/default/main.cf.erb index d4b7ae4..57067d2 100644 --- a/cookbooks/postfix/templates/default/main.cf.erb +++ b/cookbooks/postfix/templates/default/main.cf.erb @@ -1,5 +1,6 @@ ### -# Generated by Chef for <%= node['fqdn'] %> +# Auto-generated by Chef. +# Local modifications will be overwritten. # Configured as <%= node['postfix']['mail_type'] %> ### diff --git a/cookbooks/postfix/templates/default/maps.erb b/cookbooks/postfix/templates/default/maps.erb new file mode 100644 index 0000000..a351e82 --- /dev/null +++ b/cookbooks/postfix/templates/default/maps.erb @@ -0,0 +1,8 @@ +# +# This file is generated by Chef. +# Local changes will be overwritten +# + +<% @map.each do |key, value| -%> +<%= key %><%= @separator %><%= value %> +<% end unless @map.nil? -%> diff --git a/cookbooks/postfix/templates/default/master.cf.erb b/cookbooks/postfix/templates/default/master.cf.erb index ffa2aa5..fb37a6b 100644 --- a/cookbooks/postfix/templates/default/master.cf.erb +++ b/cookbooks/postfix/templates/default/master.cf.erb @@ -1,3 +1,5 @@ +# This file is generated by Chef. +# Local changes will be overwritten # # Postfix master process configuration file. For details on the format # of the file, see the master(5) manual page (command: "man 5 master"). @@ -6,76 +8,60 @@ # service type private unpriv chroot wakeup maxproc command + args # (yes) (yes) (yes) (never) (100) # ========================================================================== -smtp inet n - n - - smtpd -<% if @settings['submission'] -%> -submission inet n - n - - smtpd - -o smtpd_enforce_tls=yes - -o smtpd_sasl_auth_enable=yes - -o smtpd_client_restrictions=permit_sasl_authenticated,reject +<% @settings.sort_by{|k,v| v['order']}.map do |service, properties| -%> +<% next if !properties['active'] -%> +<% if properties.has_key?('comment') -%> +# +#<%= properties['comment'] %> +<% end -%> +<% if properties.has_key?('service') -%> +<%= properties['service'].ljust(10) -%> +<% else -%> +<%= service.ljust(10) -%> +<% end -%> + <%= properties['type'].ljust(6) -%> +<% if properties.has_key?('private') -%> +<% if properties['private'] -%> +<% priv='y' -%> +<% else -%> +<% priv='n' -%> +<% end -%> +<% else -%> +<% priv='-' -%> +<% end -%> +<%= priv.ljust(8) -%> +<% if properties.has_key?('unpriv') -%> +<% if properties['unpriv'] -%> +<% unpriv='y' -%> +<% else -%> +<% unpriv='n' -%> +<% end -%> +<% else -%> +<% unpriv='-' -%> +<% end -%> +<%= unpriv.ljust(8) -%> +<% if properties.has_key?('chroot') -%> +<% if properties['chroot'] -%> +<% chroot='y' -%> +<% else -%> +<% chroot='n' -%> +<% end -%> +<% else -%> +<% chroot='-' -%> +<% end -%> +<%= chroot.ljust(7) -%> +<% if properties.has_key?('wakeup') -%> + <%= properties['wakeup'].ljust(7) -%> +<% else -%> + <%= '-'.ljust(7) -%> +<% end -%> +<% if properties.has_key?('maxproc') -%> + <%= properties['maxproc'].ljust(7) -%> +<% else -%> + <%= '-'.ljust(7) -%> +<% end -%> + <%= properties['command'] %> +<% properties['args'].each do |arg| -%> + <%= arg %> +<% end -%> <% end -%> -#smtps inet n - n - - smtpd -# -o smtpd_tls_wrappermode=yes -# -o smtpd_sasl_auth_enable=yes -# -o smtpd_client_restrictions=permit_sasl_authenticated,reject -#628 inet n - n - - qmqpd -pickup fifo n - n 60 1 pickup -cleanup unix n - n - 0 cleanup -qmgr fifo n - n 300 1 qmgr -#qmgr fifo n - n 300 1 oqmgr -tlsmgr unix - - n 1000? 1 tlsmgr -rewrite unix - - n - - trivial-rewrite -bounce unix - - n - 0 bounce -defer unix - - n - 0 bounce -trace unix - - n - 0 bounce -verify unix - - n - 1 verify -flush unix n - n 1000? 0 flush -proxymap unix - - n - - proxymap -smtp unix - - n - 500 smtp -# When relaying mail as backup MX, disable fallback_relay to avoid MX loops -relay unix - - n - - smtp - -o smtp_fallback_relay= -# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5 -showq unix n - n - - showq -error unix - - n - - error -discard unix - - n - - discard -local unix - n n - - local -virtual unix - n n - - virtual -lmtp unix - - n - - lmtp -anvil unix - - n - 1 anvil -scache unix - - n - 1 scache -# -# ==================================================================== -# Interfaces to non-Postfix software. Be sure to examine the manual -# pages of the non-Postfix software to find out what options it wants. -# -# Many of the following services use the Postfix pipe(8) delivery -# agent. See the pipe(8) man page for information about ${recipient} -# and other message envelope options. -# ==================================================================== -# -# maildrop. See the Postfix MAILDROP_README file for details. -# Also specify in main.cf: maildrop_destination_recipient_limit=1 -# -maildrop unix - n n - - pipe - flags=DRhu user=vmail argv=/usr/local/bin/maildrop -d ${recipient} -# -# The Cyrus deliver program has changed incompatibly, multiple times. -# -old-cyrus unix - n n - - pipe - flags=R user=cyrus argv=/usr/lib/cyrus-imapd/deliver -e -m ${extension} ${user} -# Cyrus 2.1.5 (Amos Gouaux) -# Also specify in main.cf: cyrus_destination_recipient_limit=1 -cyrus unix - n n - - pipe - user=cyrus argv=/usr/lib/cyrus-imapd/deliver -e -r ${sender} -m ${extension} ${user} -# -# See the Postfix UUCP_README file for configuration details. -# -uucp unix - n n - - pipe - flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient) -# -# Other external delivery methods. -# -ifmail unix - n n - - pipe - flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient) -bsmtp unix - n n - - pipe - flags=Fq. user=foo argv=/usr/local/sbin/bsmtp -f $sender $nexthop $recipient diff --git a/cookbooks/postfix/templates/default/relay_restrictions.erb b/cookbooks/postfix/templates/default/relay_restrictions.erb index 4c404c4..85a9eda 100644 --- a/cookbooks/postfix/templates/default/relay_restrictions.erb +++ b/cookbooks/postfix/templates/default/relay_restrictions.erb @@ -1,7 +1,6 @@ # -# This file is generated by Chef for <%= node['fqdn'] %> -# -# Local changes will be overwritten +# Auto-generated by Chef. +# Local modifications will be overwritten. # # Attribute name is the domain name, Attribute value is either OK or REJECT diff --git a/cookbooks/postfix/templates/default/sasl_passwd.erb b/cookbooks/postfix/templates/default/sasl_passwd.erb index f8b1507..18f16b3 100644 --- a/cookbooks/postfix/templates/default/sasl_passwd.erb +++ b/cookbooks/postfix/templates/default/sasl_passwd.erb @@ -1,2 +1,4 @@ -# This file is generated by Chef for <%= node['fqdn'] %> +# Auto-generated by Chef. +# Local modifications will be overwritten. +# <%= node['postfix']['main']['relayhost'] %> <%= @settings['smtp_sasl_user_name'] %>:<%= @settings['smtp_sasl_passwd'] %> diff --git a/cookbooks/postfix/templates/default/sender_canonical.erb b/cookbooks/postfix/templates/default/sender_canonical.erb index 785a1c3..3eb25ef 100644 --- a/cookbooks/postfix/templates/default/sender_canonical.erb +++ b/cookbooks/postfix/templates/default/sender_canonical.erb @@ -1,7 +1,6 @@ # -# This file is generated by Chef for <%= node['fqdn'] %> -# -# Local changes will be overwritten +# Auto-generated by Chef. +# Local modifications will be overwritten. # # See man 5 canonical for format diff --git a/cookbooks/postfix/templates/default/smtp_generic.erb b/cookbooks/postfix/templates/default/smtp_generic.erb index 7aa5d64..47b36d2 100644 --- a/cookbooks/postfix/templates/default/smtp_generic.erb +++ b/cookbooks/postfix/templates/default/smtp_generic.erb @@ -1,7 +1,6 @@ # -# This file is generated by Chef for <%= node['fqdn'] %> -# -# Local changes will be overwritten +# Auto-generated by Chef. +# Local modifications will be overwritten. # # See man 5 generic for format diff --git a/cookbooks/postfix/templates/default/transport.erb b/cookbooks/postfix/templates/default/transport.erb index 4596240..df31153 100644 --- a/cookbooks/postfix/templates/default/transport.erb +++ b/cookbooks/postfix/templates/default/transport.erb @@ -1,7 +1,6 @@ # -# This file is generated by Chef for <%= node['fqdn'] %> -# -# Local changes will be overwritten +# Auto-generated by Chef. +# Local modifications will be overwritten. # # See man 5 transport for format diff --git a/cookbooks/postfix/templates/default/virtual_aliases.erb b/cookbooks/postfix/templates/default/virtual_aliases.erb index fc7e9e1..d1bfadf 100644 --- a/cookbooks/postfix/templates/default/virtual_aliases.erb +++ b/cookbooks/postfix/templates/default/virtual_aliases.erb @@ -1,7 +1,6 @@ # -# This file is generated by Chef for <%= node['fqdn'] %> -# -# Local changes will be overwritten +# Auto-generated by Chef. +# Local modifications will be overwritten. # # See man 5 virtual for format diff --git a/cookbooks/postfix/templates/default/virtual_aliases_domains.erb b/cookbooks/postfix/templates/default/virtual_aliases_domains.erb index a02a35a..d4334b2 100644 --- a/cookbooks/postfix/templates/default/virtual_aliases_domains.erb +++ b/cookbooks/postfix/templates/default/virtual_aliases_domains.erb @@ -1,7 +1,6 @@ # -# This file is generated by Chef for <%= node['fqdn'] %> -# -# Local changes will be overwritten +# Auto-generated by Chef. +# Local modifications will be overwritten. # # See man 5 virtual for format diff --git a/cookbooks/ssh_known_hosts/CHANGELOG.md b/cookbooks/ssh_known_hosts/CHANGELOG.md deleted file mode 100644 index d824cdf..0000000 --- a/cookbooks/ssh_known_hosts/CHANGELOG.md +++ /dev/null @@ -1,73 +0,0 @@ -v2.0.0 (2014-12-02) -------------------- -- [#36] Fix the way keys are rendered -- [#22] Update to README -- [#32] Clean up logging -- [#23] Do not hash public keys -- [#34] Serverspec updates -- [#28] Add data bag caching option -- [#20] Add checspec matchers -- [#33] Add test to verify chefspec matcher - -v1.3.2 (2014-04-23) -------------------- -- [COOK-4579] - Do not use ssh-keyscan stderr - - -v1.3.0 (2014-04-09) -------------------- -- [COOK-4489] Updated ssh-keyscan to include -t type - - -v1.2.0 (2014-02-18) -------------------- -### Bug -- **[COOK-3453](https://tickets.opscode.com/browse/COOK-3453)** - ssh_known_hosts cookbook ruby block executes on every chef run - - -v1.1.0 ------- -[COOK-3765] - support ssh-keyscan using an alternative port number - - -v1.0.2 ------- -### Bug -- **[COOK-3113](https://tickets.opscode.com/browse/COOK-3113)** - Use empty string when result is `nil` - -v1.0.0 ------- -This is a major release because it requires a server that supports the partial search feature. - -- Opscode Hosted Chef -- Opscode Private Chef -- Open Source Chef 11 - -### Improvement - -- [COOK-830]: uses an inordinate amount of RAM when running exception handlers - -v0.7.4 ------- -- [COOK-2440] - `ssh_known_hosts` fails to use data bag entries, doesn't grab items - -v0.7.2 ------- -- [COOK-2364] - Wrong LWRP name used in recipe - -v0.7.0 ------- -- [COOK-2320] - Merge `known_host` LWRP into `ssh_known_hosts` - -v0.6.0 ------- -- [COOK-2268] - Allow to run with chef-solo - -v0.5.0 ------- -- [COOK-1077] - allow adding arbitrary host keys from a data bag - -v0.4.0 ------- -- COOK-493: include fqdn -- COOK-721: corrected permissions diff --git a/cookbooks/ssh_known_hosts/README.md b/cookbooks/ssh_known_hosts/README.md deleted file mode 100644 index d75bd81..0000000 --- a/cookbooks/ssh_known_hosts/README.md +++ /dev/null @@ -1,202 +0,0 @@ -ssh_known_hosts Cookbook -======================== -The Chef `ssh_known_hosts` cookbook exposes resource and default recipe for adding hosts and keys to the `/etc/ssh/ssh_known_hosts` file. - -- The default recipe builds `/etc/ssh/ssh_known_hosts` based either on search indexes using `rsa,dsa` key types and ohai data **or**, when `['ssh_known_hosts']['use_data_bag_cache']` is `true`, on the contents of a data bag that is maintained by the `cacher` recipe running on a worker node. -- The cacher recipe builds and maintains a data bag based on search indexes using `rsa,dsa` key types and ohai data. -- The LWRP provides a way to add custom entries in your own recipes. - -You can also optionally put other host keys in a data bag called "`ssh_known_hosts`". See below for details. - - -Requirements ------------- -Should work on any operating system that supports `/etc/ssh/ssh_known_hosts`. - -The Opscode `partial_search` cookbook is required for the default recipe, as well as a Chef Server that supports partial search: - -- Opscode Hosted Chef -- Opscode Private Chef -- Open Source Chef Server 11 - - -Usage ------ -### LWRP - -Use the LWRP `ssh_known_hosts_entry` to append an entry for the specified host in `/etc/ssh/ssh_known_hosts`. For example: - -```ruby -ssh_known_hosts_entry 'github.com' -``` - -This will append an entry in `/etc/ssh/ssh_known_hosts` like this: - -```text -# github.com SSH-2.0-OpenSSH_5.5p1 Debian-6+squeeze1+github8 -github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ== -``` - -You can optionally specify your own key, if you don't want to use `ssh-keyscan`: - -```ruby -ssh_known_hosts_entry 'github.com' do - key 'node.example.com ssh-rsa ...' -end -``` - -### Cacher - -Use the `cacher` recipe on a single "worker" node somewhere in your cluster to maintain a data bag (`server_data/known_hosts` by default) containing all of your nodes host keys. The advantage to this approach is that is much faster than running a search of all nodes, and substantially lightens the load on locally hosted Chef servers. The drawback is that the data is slightly delayed (because the cacher worker must converge first). - -To use the cacher, simply include the `ssh_known_hosts::cacher` cookbook in a wrapper cookbook or run list on a designated worker node. - -#### Attributes - -The following attributes are set on a per-platform basis, see the `attributes/default.rb`. - -* `node['ssh_known_hosts']['file']` - Sets up the location of the ssh_known_hosts file for the system. - Defaults to '/etc/ssh/ssh_known_hosts' -* `node['ssh_known_hosts']['key_type']` - Determines which key type ssh-keyscan will use to determine the - host key, different systems will have different available key types, check your manpage for available - key types for ssh-keyscan. Defaults to 'rsa,dsa' -* `node['ssh_known_hosts']['use_data_bag_cache']` - Use the data bag maintained by the cacher server to build `/etc/ssh/ssh_known_hosts` instead of a direct search (requires that a node be set up to run the cacher recipe regularly). -* `node['ssh_known_hosts']['cacher']['data_bag']`/`node['ssh_known_hosts']['cacher']['data_bag_item']` - Data bag where cacher recipe should store its keys. - -#### LWRP Attributes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AttributeDescriptionExampleDefault
hostthe host to addgithub.com
key(optional) provide your own keyssh-rsa ...ssh-keyscan -H #{host}
port(optional) the server port that ssh-keyscan will use to gather the public key222222
- -- - - - -### Default Recipe - -Searches the Chef Server for all hosts that have SSH host keys using `rsa,dsa` key types and generates an `/etc/ssh/ssh_known_hosts`. - -#### Adding custom host keys - -There are two ways to add custom host keys. You can either use the provided LWRP (see above), or by creating a data bag called "`ssh_known_hosts`" and adding an item for each host: - -```javascript -{ - "id": "github", - "fqdn": "github.com", - "rsa": "github-rsa-host-key" -} -``` - -There are additional optional values you may use in the data bag: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AttributeDescriptionExampleDefault
ida unique id for this data bag entrygithub
fqdnthe fqdn of the hostgithub.com
rsathe rsa key for this serverssh-rsa AAAAB3...
ipaddressthe ipaddress of the node (if fqdn is missing)1.1.1.1
hostnamelocal hostname of the server (if not a fqdn)myserver.local
dsathe dsa key for this serverssh-dsa ABAAC3...
- -###ChefSpec matchers - -A custom matcher is available for you to use in recipe tests. - -``` -describe 'my_cookbook::my_recipe' do - let(:chef_run) { ChefSpec::Runner.new.converge(described_recipe) } - it { expect(chef_run).to append_to_ssh_known_hosts 'github.com' } -end -``` - - -License and Authors -------------------- -- Author: Scott M. Likens () -- Author: Seth Vargo () -- Author: Lamont Granquist () - -```text -Copyright:: 2011-2013, Opscode, Inc - -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. -``` diff --git a/cookbooks/ssh_known_hosts/libraries/matchers.rb b/cookbooks/ssh_known_hosts/libraries/matchers.rb deleted file mode 100644 index 3037711..0000000 --- a/cookbooks/ssh_known_hosts/libraries/matchers.rb +++ /dev/null @@ -1,7 +0,0 @@ -if defined?(ChefSpec) - - def append_to_ssh_known_hosts(resource) - ChefSpec::Matchers::ResourceMatcher.new(:ssh_known_hosts_entry, :create, resource) - end - -end diff --git a/cookbooks/ssh_known_hosts/metadata.json b/cookbooks/ssh_known_hosts/metadata.json deleted file mode 100644 index 9f59d40..0000000 --- a/cookbooks/ssh_known_hosts/metadata.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "ssh_known_hosts", - "version": "2.0.0", - "description": "Dyanmically generates /etc/ssh/known_hosts based on search indexes", - "long_description": "ssh_known_hosts Cookbook\n========================\nThe Chef `ssh_known_hosts` cookbook exposes resource and default recipe for adding hosts and keys to the `/etc/ssh/ssh_known_hosts` file.\n\n- The default recipe builds `/etc/ssh/ssh_known_hosts` based either on search indexes using `rsa,dsa` key types and ohai data **or**, when `['ssh_known_hosts']['use_data_bag_cache']` is `true`, on the contents of a data bag that is maintained by the `cacher` recipe running on a worker node.\n- The cacher recipe builds and maintains a data bag based on search indexes using `rsa,dsa` key types and ohai data.\n- The LWRP provides a way to add custom entries in your own recipes.\n\nYou can also optionally put other host keys in a data bag called \"`ssh_known_hosts`\". See below for details.\n\n\nRequirements\n------------\nShould work on any operating system that supports `/etc/ssh/ssh_known_hosts`.\n\nThe Opscode `partial_search` cookbook is required for the default recipe, as well as a Chef Server that supports partial search:\n\n- Opscode Hosted Chef\n- Opscode Private Chef\n- Open Source Chef Server 11\n\n\nUsage\n-----\n### LWRP\n\nUse the LWRP `ssh_known_hosts_entry` to append an entry for the specified host in `/etc/ssh/ssh_known_hosts`. For example:\n\n```ruby\nssh_known_hosts_entry 'github.com'\n```\n\nThis will append an entry in `/etc/ssh/ssh_known_hosts` like this:\n\n```text\n# github.com SSH-2.0-OpenSSH_5.5p1 Debian-6+squeeze1+github8\ngithub.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==\n```\n\nYou can optionally specify your own key, if you don't want to use `ssh-keyscan`:\n\n```ruby\nssh_known_hosts_entry 'github.com' do\n key 'node.example.com ssh-rsa ...'\nend\n```\n\n### Cacher\n\nUse the `cacher` recipe on a single \"worker\" node somewhere in your cluster to maintain a data bag (`server_data/known_hosts` by default) containing all of your nodes host keys. The advantage to this approach is that is much faster than running a search of all nodes, and substantially lightens the load on locally hosted Chef servers. The drawback is that the data is slightly delayed (because the cacher worker must converge first).\n\nTo use the cacher, simply include the `ssh_known_hosts::cacher` cookbook in a wrapper cookbook or run list on a designated worker node.\n\n#### Attributes\n\nThe following attributes are set on a per-platform basis, see the `attributes/default.rb`.\n\n* `node['ssh_known_hosts']['file']` - Sets up the location of the ssh_known_hosts file for the system. \n Defaults to '/etc/ssh/ssh_known_hosts'\n* `node['ssh_known_hosts']['key_type']` - Determines which key type ssh-keyscan will use to determine the \n host key, different systems will have different available key types, check your manpage for available \n key types for ssh-keyscan. Defaults to 'rsa,dsa'\n* `node['ssh_known_hosts']['use_data_bag_cache']` - Use the data bag maintained by the cacher server to build `/etc/ssh/ssh_known_hosts` instead of a direct search (requires that a node be set up to run the cacher recipe regularly).\n* `node['ssh_known_hosts']['cacher']['data_bag']`/`node['ssh_known_hosts']['cacher']['data_bag_item']` - Data bag where cacher recipe should store its keys.\n\n#### LWRP Attributes\n\n\n \n \n \n \n \n \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
AttributeDescriptionExampleDefault
hostthe host to addgithub.com
key(optional) provide your own keyssh-rsa ...ssh-keyscan -H #{host}
port(optional) the server port that ssh-keyscan will use to gather the public key222222
\n\n- - -\n\n### Default Recipe\n\nSearches the Chef Server for all hosts that have SSH host keys using `rsa,dsa` key types and generates an `/etc/ssh/ssh_known_hosts`.\n\n#### Adding custom host keys\n\nThere are two ways to add custom host keys. You can either use the provided LWRP (see above), or by creating a data bag called \"`ssh_known_hosts`\" and adding an item for each host:\n\n```javascript\n{\n \"id\": \"github\",\n \"fqdn\": \"github.com\",\n \"rsa\": \"github-rsa-host-key\"\n}\n```\n\nThere are additional optional values you may use in the data bag:\n\n\n \n \n \n \n \n \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
AttributeDescriptionExampleDefault
ida unique id for this data bag entrygithub
fqdnthe fqdn of the hostgithub.com
rsathe rsa key for this serverssh-rsa AAAAB3...
ipaddressthe ipaddress of the node (if fqdn is missing)1.1.1.1
hostnamelocal hostname of the server (if not a fqdn)myserver.local
dsathe dsa key for this serverssh-dsa ABAAC3...
\n\n###ChefSpec matchers\n\nA custom matcher is available for you to use in recipe tests.\n\n``` \ndescribe 'my_cookbook::my_recipe' do\n\tlet(:chef_run) { ChefSpec::Runner.new.converge(described_recipe) }\n\tit { expect(chef_run).to append_to_ssh_known_hosts 'github.com' }\nend\n```\n\n\nLicense and Authors\n-------------------\n- Author: Scott M. Likens ()\n- Author: Seth Vargo ()\n- Author: Lamont Granquist ()\n\n```text\nCopyright:: 2011-2013, Opscode, Inc\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n", - "maintainer": "Opscode, Inc.", - "maintainer_email": "cookbooks@opscode.com", - "license": "Apache 2.0", - "platforms": { - }, - "dependencies": { - "partial_search": ">= 0.0.0" - }, - "recommendations": { - }, - "suggestions": { - }, - "conflicting": { - }, - "providing": { - }, - "replacing": { - }, - "attributes": { - }, - "groupings": { - }, - "recipes": { - "ssh_known_hosts": "Provides an LWRP for managing SSH known hosts. Also includes a recipe for automatically adding all nodes to the SSH known hosts." - } -} \ No newline at end of file diff --git a/cookbooks/ssh_known_hosts/providers/entry.rb b/cookbooks/ssh_known_hosts/providers/entry.rb deleted file mode 100644 index e6e60a1..0000000 --- a/cookbooks/ssh_known_hosts/providers/entry.rb +++ /dev/null @@ -1,78 +0,0 @@ -# -# Author:: Seth Vargo () -# Provider:: entry -# -# Copyright 2013, Seth Vargo -# -# 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. -# - -use_inline_resources if defined?(use_inline_resources) - -def whyrun_supported? - true -end - -action :create do - - if new_resource.key - - if new_resource.key_type == 'rsa' || new_resource.key_type == 'dsa' - key_type = "ssh-#{new_resource.key_type}" - else - key_type = new_resource.key_type - end - - key = "#{new_resource.host} #{key_type} #{new_resource.key}" - - else - - key = `ssh-keyscan -t#{node['ssh_known_hosts']['key_type']} -p #{new_resource.port} #{new_resource.host}` - end - comment = key.split("\n").first || "" - - if key_exists?(key, comment) - Chef::Log.debug "Known hosts key for #{new_resource.name} already exists - skipping" - else - new_keys = (keys + [key]).uniq.sort - file "ssh_known_hosts-#{new_resource.name}" do - path node['ssh_known_hosts']['file'] - action :create - backup false - content "#{new_keys.join($/)}#{$/}" - end - end -end - -private - def keys - unless @keys - if key_file_exists? - lines = ::File.readlines(node['ssh_known_hosts']['file']) - @keys = lines.map {|line| line.chomp}.reject {|line| line.empty?} - else - @keys = [] - end - end - @keys - end - - def key_file_exists? - ::File.exists?(node['ssh_known_hosts']['file']) - end - - def key_exists?(key, comment) - keys.any? do |line| - line.match(/#{Regexp.escape(comment)}|#{Regexp.escape(key)}/) - end - end diff --git a/cookbooks/ssh_known_hosts/recipes/cacher.rb b/cookbooks/ssh_known_hosts/recipes/cacher.rb deleted file mode 100644 index 3ec840b..0000000 --- a/cookbooks/ssh_known_hosts/recipes/cacher.rb +++ /dev/null @@ -1,60 +0,0 @@ -# Gather a list of all nodes, warning if using Chef Solo -if Chef::Config[:solo] - fail 'ssh_known_hosts::cacher requires Chef search - Chef Solo does ' \ - 'not support search!' -else - all_host_keys = partial_search( - :node, 'keys:*', - :keys => { - 'hostname' => [ 'hostname' ], - 'fqdn' => [ 'fqdn' ], - 'ipaddress' => [ 'ipaddress' ], - 'host_rsa_public' => [ 'keys', 'ssh', 'host_rsa_public' ], - 'host_dsa_public' => [ 'keys', 'ssh', 'host_dsa_public' ] - } - ).collect do |host| - { - 'fqdn' => host['fqdn'] || host['ipaddress'] || host['hostname'], - 'key' => host['host_rsa_public'] || host['host_dsa_public'] - } - end - Chef::Log.debug("Partial search got: #{all_host_keys.inspect}") -end - -new_data_bag_content = { - "id" => node['ssh_known_hosts']['cacher']['data_bag_item'], - "keys" => all_host_keys -} - -Chef::Log.debug('New data bag content: ' \ - "#{new_data_bag_content.inspect}") - -if Chef::DataBag.list.key?(node['ssh_known_hosts']['cacher']['data_bag']) - # Check to see if there are actually any changes to be made (so we don't save - # data bags unnecessarily) - existing_data_bag_content = data_bag_item( - node['ssh_known_hosts']['cacher']['data_bag'], - node['ssh_known_hosts']['cacher']['data_bag_item'] - ).raw_data - Chef::Log.debug('Existing data bag content: ' \ - "#{existing_data_bag_content.inspect}") -else - Chef::Log.debug('Data bag ' \ - "\"#{node['ssh_known_hosts']['cacher']['data_bag']}\" not found. " \ - 'Creating.') - new_databag = Chef::DataBag.new - new_databag.name(node['ssh_known_hosts']['cacher']['data_bag']) - new_databag.save -end - -unless (defined? existing_data_bag_content) && - new_data_bag_content == existing_data_bag_content - - Chef::Log.debug('Data bag contents differ. Saving updates.') - - host_key_db_item = Chef::DataBagItem.new - host_key_db_item.data_bag(node['ssh_known_hosts']['cacher']['data_bag']) - host_key_db_item.raw_data = new_data_bag_content - - host_key_db_item.save -end diff --git a/cookbooks/ssh_known_hosts/recipes/default.rb b/cookbooks/ssh_known_hosts/recipes/default.rb deleted file mode 100644 index 9266ad9..0000000 --- a/cookbooks/ssh_known_hosts/recipes/default.rb +++ /dev/null @@ -1,87 +0,0 @@ -# -# Cookbook Name:: ssh_known_hosts -# Recipe:: default -# -# Author:: Scott M. Likens () -# Author:: Joshua Timberman () -# Author:: Seth Vargo () -# -# Copyright 2009, Adapp, Inc. -# Copyright 2011-2013, Opscode, Inc. -# -# 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. - -if node['ssh_known_hosts']['use_data_bag_cache'] - # Load hosts from the ssh known hosts cacher (if the data bag exists) - unless Chef::DataBag.list.key?(node['ssh_known_hosts']['cacher']['data_bag']) - fail 'use_data_bag_cache is set but the configured data bag was not found' - end - - hosts = data_bag_item( - node['ssh_known_hosts']['cacher']['data_bag'], - node['ssh_known_hosts']['cacher']['data_bag_item'] - )['keys'] - Chef::Log.info "hosts data bag: #{hosts.inspect}" -else - # Gather a list of all nodes, warning if using Chef Solo - if Chef::Config[:solo] - Chef::Log.warn 'ssh_known_hosts requires Chef search - Chef Solo does not support search!' - - # On Chef Solo, we still want the current node to be in the ssh_known_hosts - hosts = [node] - else - hosts = partial_search(:node, "keys_ssh:* NOT name:#{node.name}", - :keys => { - 'hostname' => [ 'hostname' ], - 'fqdn' => [ 'fqdn' ], - 'ipaddress' => [ 'ipaddress' ], - 'host_rsa_public' => [ 'keys', 'ssh', 'host_rsa_public' ], - 'host_dsa_public' => [ 'keys', 'ssh', 'host_dsa_public' ] - } - ).collect do |host| - { - 'fqdn' => host['fqdn'] || host['ipaddress'] || host['hostname'], - 'key' => host['host_rsa_public'] || host['host_dsa_public'] - } - end - end -end - -# Add the data from the data_bag to the list of nodes. -# We need to rescue in case the data_bag doesn't exist. -if Chef::DataBag.list.key?('ssh_known_hosts') - begin - hosts += data_bag('ssh_known_hosts').collect do |item| - entry = data_bag_item('ssh_known_hosts', item) - { - 'fqdn' => entry['fqdn'] || entry['ipaddress'] || entry['hostname'], - 'key' => entry['rsa'] || entry['dsa'] - } - end - rescue - Chef::Log.info "Could not load data bag 'ssh_known_hosts'" - end -end - -# Loop over the hosts and add 'em -hosts.each do |host| - unless host['key'].nil? - # The key was specified, so use it - ssh_known_hosts_entry host['fqdn'] do - key host['key'] - end - else - # No key specified, so have known_host perform a DNS lookup - ssh_known_hosts_entry host['fqdn'] - end -end diff --git a/cookbooks/ssh_known_hosts/resources/entry.rb b/cookbooks/ssh_known_hosts/resources/entry.rb deleted file mode 100644 index a0c1b31..0000000 --- a/cookbooks/ssh_known_hosts/resources/entry.rb +++ /dev/null @@ -1,30 +0,0 @@ -# -# Author:: Seth Vargo () -# Resource:: entry -# -# Copyright 2013, Seth Vargo -# -# 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. - -actions :create -default_action :create - -attribute :host, :kind_of => String, :name_attribute => true -attribute :key, :kind_of => String -attribute :key_type, :kind_of => String, :default => 'rsa' -attribute :port, :kind_of => Fixnum, :default => 22 - -def initialize(*args) - super - @action = :create -end diff --git a/cookbooks/sudo/CHANGELOG.md b/cookbooks/sudo/CHANGELOG.md index 4f3bce2..7283d9f 100644 --- a/cookbooks/sudo/CHANGELOG.md +++ b/cookbooks/sudo/CHANGELOG.md @@ -1,10 +1,49 @@ # sudo Cookbook CHANGELOG + This file is used to list changes made in each version of the sudo cookbook. +## 3.3.1 (2017-01-17) + +- fixed command_aliases in README + +## 3.3.0 (2017-01-04) + +- Add attributes for env_keep_add and env_keep_subtract for the base sudoers file +- Sanitize file names in the :remove action so we remove the proper files + +## 3.2.0 (2016-12-27) + +- Convert ~ to __ like we do for i (sudoers.d files) + +## 3.1.0 (2016-10-24) +- add attribute custom_commands for user and group + +## 3.0.0 (2016-09-08) +- Testing updates +- Require Chef 12.1+ + +## 2.11.0 (2016-08-09) +- Add support for NOEXEC flag + +## v2.10.0 (2016-08-04) + +- Added a warning to the LWRP if include_sudoers_d is set to false +- Enabled use_inline_resources in the LWRP +- Added IBM zlinux as a supported platform +- Added suse, opensuse, and opensuseleap to the metadata as they are now tested platforms +- Added chef_version metadata to metadata.rb +- Removed attributes from the metadata.rb as this serves little purpose +- Converted bats integration tests to inspec +- Switched from rubocop to cookstyle for Ruby linting +- Removed the need for the apt cookbook in the test suite by using the apt_update resource instead +- Switched from kitchen-docker to kitchen-dokken and enabled Debian/Opensuse platforms in Travis + ## v2.9.0 (2016-02-07) + - Updated the provider to avoid writing out config files with periods in the filename when a user has a period in their name as these are skipped by the sudo package. A sudo config for invalid.user will write out a config named invalid_user now. ## v2.8.0 (2016-02-04) + - Added a new attribute to the recipe and provider for adding SETENV to sudoer config - Updated development deps to the latest version - Setup test kitchen to run in Travis with kitchen-docker @@ -21,96 +60,133 @@ This file is used to list changes made in each version of the sudo cookbook. - Removed the Guardfile and the gem deps ## v2.7.2 (2015-07-10) + - Adding support for keep_env - misc cleanup ## v2.7.1 (2014-09-18) + - [#53] - removed double space from sudoer.erb template ## v2.7.0 (2014-08-08) + - [#44] Add basic ChefSpec matchers ## v2.6.0 (2014-05-15) + - [COOK-4612] Add support for the command alias (Cmnd_Alias) directive - [COOK-4637] - handle duplicate resources in LWRP ## v2.5.2 (2014-02-27) + Bumping version for toolchain sanity ## v2.5.0 (2014-02-27) + Bumping to 2.5.0 ## v2.4.2 (2014-02-27) + [COOK-4350] - Fix issue with "Defaults" line in sudoer.erb ## v2.4.0 (2014-02-18) + +**BREAKING CHANGE**: The `sysadmin` group has been removed from the template. You will lose sudo access if: + +- You have users that depend on the sysadmin group for sudo access, and +- You are overriding authorization.sudo.groups, but not including `sysadmin` in the list of groups + ### Bug + - **[COOK-4225](https://tickets.chef.io/browse/COOK-4225)** - Mac OS X: /etc/sudoers: syntax error when include_sudoers_d is true ### Improvement + - **[COOK-4014](https://tickets.chef.io/browse/COOK-4014)** - It should be possible to remove the 'sysadmin' group setting from /etc/sudoers - **[COOK-3643](https://tickets.chef.io/browse/COOK-3643)** - FreeBSD support for sudo cookbook ### New Feature + - **[COOK-3409](https://tickets.chef.io/browse/COOK-3409)** - enhance sudo lwrp's default template to allow defining default user parameters ## v2.3.0 + ### Improvement + - **[COOK-3843](https://tickets.chef.io/browse/COOK-3843)** - Make cookbook 'sudo' compatible with Mac OS X ## v2.2.2 + ### Improvement + - **[COOK-3653](https://tickets.chef.io/browse/COOK-3653)** - Change template attribute to kind_of String - **[COOK-3572](https://tickets.chef.io/browse/COOK-3572)** - Add Test Kitchen, Specs, and Travis CI ### Bug + - **[COOK-3610](https://tickets.chef.io/browse/COOK-3610)** - Document "Runas" attribute not described in the LWRP Attributes section - **[COOK-3431](https://tickets.chef.io/browse/COOK-3431)** - Validate correctly with `visudo` ## v2.2.0 + ### New Feature + - **[COOK-3056](https://tickets.chef.io/browse/COOK-3056)** - Allow custom sudoers config prefix ## v2.1.4 + This is a bugfix for 11.6.0 compatibility, as we're not monkey-patching Erubis::Context. ### Bug + - [COOK-3399]: Remove node attribute in comment of sudoers templates ## v2.1.2 + ### Bug + - [COOK-2388]: Chef::ShellOut is deprecated, please use Mixlib::ShellOut - [COOK-2814]: Incorrect syntax in README example ## v2.1.0 + - [COOK-2388] - Chef::ShellOut is deprecated, please use Mixlib::ShellOut - [COOK-2427] - unable to install users cookbook in chef 11 - [COOK-2814] - Incorrect syntax in README example ## v2.0.4 + - [COOK-2078] - syntax highlighting README on GitHub flavored markdown - [COOK-2119] - LWRP template doesn't support multiple commands in a single block. ## v2.0.2 + - [COOK-2109] - lwrp uses incorrect action on underlying file resource. ## v2.0.0 + This is a major release because the LWRP's "nopasswd" attribute is changed from true to false, to match the passwordless attribute in the attributes file. This requires a change to people's LWRP use. + - [COOK-2085] - Incorrect default value in the sudo LWRP's nopasswd attribute ## v1.3.0 + - [COOK-1892] - Revamp sudo cookbook and LWRP - [COOK-2022] - add an attribute for setting /etc/sudoers Defaults ## v1.2.2 + - [COOK-1628] - set host in sudo lwrp ## v1.2.0 + - [COOK-1314] - default package action is now :install instead of :upgrade - [COOK-1549] - Preserve SSH agent credentials upon sudo using an attribute ## v1.1.0 + - [COOK-350] - LWRP to manage sudo files via include dir (/etc/sudoers.d) ## v1.0.2 + - [COOK-903] - freebsd support diff --git a/cookbooks/sudo/MAINTAINERS.md b/cookbooks/sudo/MAINTAINERS.md index c6a51ae..645ed14 100644 --- a/cookbooks/sudo/MAINTAINERS.md +++ b/cookbooks/sudo/MAINTAINERS.md @@ -1,19 +1,15 @@ # Maintainers -This file lists how this cookbook project is maintained. When making changes to the system, this -file tells you who needs to review your patch - you need a simple majority of maintainers -for the relevant subsystems to provide a :+1: on your pull request. Additionally, you need -to not receive a veto from a Lieutenant or the Project Lead. -Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) -for details on the process and how to become a maintainer or the project lead. +This file lists how this cookbook project is maintained. When making changes to the system, this file tells you who needs to review your patch - you need a review from an existing maintainer for the cookbook to provide a :+1: on your pull request. Additionally, you need to not receive a veto from a Lieutenant or the Project Lead. + +Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) for details on the process and how to become a maintainer or the project lead. # Project Maintainer * [Tim Smith](https://github.com/tas50) # Maintainers * [Jennifer Davis](https://github.com/sigje) -* [Sean OMeara](https://github.com/someara) * [Tim Smith](https://github.com/tas50) * [Thom May](https://github.com/thommay) diff --git a/cookbooks/sudo/README.md b/cookbooks/sudo/README.md index f609b7d..a78f833 100644 --- a/cookbooks/sudo/README.md +++ b/cookbooks/sudo/README.md @@ -1,4 +1,5 @@ # sudo cookbook + [![Build Status](https://travis-ci.org/chef-cookbooks/sudo.svg?branch=master)](http://travis-ci.org/chef-cookbooks/sudo) [![Cookbook Version](https://img.shields.io/cookbook/v/sudo.svg)](https://supermarket.chef.io/cookbooks/sudo) The Chef `sudo` cookbook installs the `sudo` package and configures the `/etc/sudoers` file. @@ -6,16 +7,21 @@ The Chef `sudo` cookbook installs the `sudo` package and configures the `/etc/su It also exposes an LWRP for adding and managing sudoers. ## Requirements + ### Platforms + - Debian/Ubuntu - RHEL/CentOS/Scientific/Amazon/Oracle - FreeBSD - Mac OS X +- openSUSE / Suse ### Chef -- Chef 11+ + +- Chef 12.1+ ### Cookbooks + - None ## Attributes @@ -45,6 +51,44 @@ To use attributes for defining sudoers, set the attributes above on the node (or } ``` +```json +{ + "default_attributes": { + "authorization": { + "sudo": { + "command_aliases": [{ + "name": "TEST", + "command_list": [ + "/usr/bin/ls", + "/usr/bin/cat" + ] + }], + "custom_commands": { + "users": [ + { + "user": "test_user", + "passwordless": true, + "command_list": [ + "TEST" + ] + } + ], + "groups": [ + { + "group": "test_group", + "passwordless": false, + "command_list": [ + "TEST" + ] + } + ] + } + } + } + } +} +``` + ```ruby # roles/example.rb default_attributes( @@ -151,7 +195,7 @@ There are two ways for rendering a sudoer-fragment using this LWRP: 1. Using the built-in template 2. Using a custom, cookbook-level template -Both methods will create the `/etc/sudoers.d/#{username}` file with the correct permissions. +Both methods will create the `/etc/sudoers.d/#{resourcename}` file with the correct permissions. The LWRP also performs **fragment validation**. If a sudoer-fragment is not valid, the Chef run will throw an exception and fail. This ensures that your sudoers file is always valid and cannot become corrupt (from this cookbook). @@ -218,6 +262,12 @@ case it is not already true false + + noexec + prevents commands from shelling out + true + false + runas User the command(s) can be run as diff --git a/cookbooks/sudo/attributes/default.rb b/cookbooks/sudo/attributes/default.rb index d1bd74b..d8e7dbf 100644 --- a/cookbooks/sudo/attributes/default.rb +++ b/cookbooks/sudo/attributes/default.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: sudo -# Attribute File:: default +# Cookbook:: sudo +# Attribute:: File:: default # -# Copyright 2008-2016, Chef Software, Inc. +# Copyright:: 2008-2016, 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. @@ -27,6 +27,8 @@ default['authorization']['sudo']['sudoers_defaults'] = ['!lecture,tty_tickets,! default['authorization']['sudo']['command_aliases'] = [] default['authorization']['sudo']['env_keep_add'] = [] default['authorization']['sudo']['env_keep_subtract'] = [] +default['authorization']['sudo']['custom_commands']['users'] = [] +default['authorization']['sudo']['custom_commands']['groups'] = [] default['authorization']['sudo']['prefix'] = case node['platform_family'] when 'smartos' diff --git a/cookbooks/sudo/metadata.json b/cookbooks/sudo/metadata.json index 75479c1..f1afd08 100644 --- a/cookbooks/sudo/metadata.json +++ b/cookbooks/sudo/metadata.json @@ -1 +1 @@ -{"name":"sudo","version":"2.9.0","description":"Installs sudo and configures /etc/sudoers","long_description":"# sudo cookbook\n[![Build Status](https://travis-ci.org/chef-cookbooks/sudo.svg?branch=master)](http://travis-ci.org/chef-cookbooks/sudo) [![Cookbook Version](https://img.shields.io/cookbook/v/sudo.svg)](https://supermarket.chef.io/cookbooks/sudo)\n\nThe Chef `sudo` cookbook installs the `sudo` package and configures the `/etc/sudoers` file.\n\nIt also exposes an LWRP for adding and managing sudoers.\n\n## Requirements\n### Platforms\n- Debian/Ubuntu\n- RHEL/CentOS/Scientific/Amazon/Oracle\n- FreeBSD\n- Mac OS X\n\n### Chef\n- Chef 11+\n\n### Cookbooks\n- None\n\n## Attributes\n- `node['authorization']['sudo']['groups']` - groups to enable sudo access (default: `[ \"sysadmin\" ]`)\n- `node['authorization']['sudo']['users']` - users to enable sudo access (default: `[]`)\n- `node['authorization']['sudo']['passwordless']` - use passwordless sudo (default: `false`)\n- `node['authorization']['sudo']['include_sudoers_d']` - include and manage `/etc/sudoers.d` (default: `false`)\n- `node['authorization']['sudo']['agent_forwarding']` - preserve `SSH_AUTH_SOCK` when sudoing (default: `false`)\n- `node['authorization']['sudo']['sudoers_defaults']` - Array of `Defaults` entries to configure in `/etc/sudoers`\n- `node['authorization']['sudo']['setenv']` - Whether to permit preserving of environment with `sudo -E` (default: `false`)\n\n## Usage\n### Attributes\nTo use attributes for defining sudoers, set the attributes above on the node (or role) itself:\n\n```json\n{\n \"default_attributes\": {\n \"authorization\": {\n \"sudo\": {\n \"groups\": [\"admin\", \"wheel\", \"sysadmin\"],\n \"users\": [\"jerry\", \"greg\"],\n \"passwordless\": \"true\"\n }\n }\n }\n}\n```\n\n```ruby\n# roles/example.rb\ndefault_attributes(\n \"authorization\" => {\n \"sudo\" => {\n \"groups\" => [\"admin\", \"wheel\", \"sysadmin\"],\n \"users\" => [\"jerry\", \"greg\"],\n \"passwordless\" => true\n }\n }\n)\n```\n\n**Note that the template for the sudoers file has the group \"sysadmin\" with ALL:ALL permission, though the group by default does not exist.**\n\n### Sudoers Defaults\nConfigure a node attribute, `node['authorization']['sudo']['sudoers_defaults']` as an array of `Defaults` entries to configure in `/etc/sudoers`. A list of examples for common platforms is listed below:\n\n_Debian_\n\n```ruby\nnode.default['authorization']['sudo']['sudoers_defaults'] = ['env_reset']\n```\n\n_Ubuntu 10.04_\n\n```ruby\nnode.default['authorization']['sudo']['sudoers_defaults'] = ['env_reset']\n```\n\n_Ubuntu 12.04_\n\n```ruby\nnode.default['authorization']['sudo']['sudoers_defaults'] = [\n 'env_reset',\n 'secure_path=\"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"'\n]\n```\n\n_FreeBSD_\n\n```ruby\nnode.default['authorization']['sudo']['sudoers_defaults'] = [\n 'env_reset',\n 'secure_path=\"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"'\n]\n```\n\n_RHEL family 5.x_ The version of sudo in RHEL 5 may not support `+=`, as used in `env_keep`, so its a single string.\n\n```ruby\nnode.default['authorization']['sudo']['sudoers_defaults'] = [\n '!visiblepw',\n 'env_reset',\n 'env_keep = \"COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR \\\n LS_COLORS MAIL PS1 PS2 QTDIR USERNAME \\\n LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION \\\n LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC \\\n LC_PAPER LC_TELEPHONE LC_TIME LC_ALL LANGUAGE LINGUAS \\\n _XKB_CHARSET XAUTHORITY\"'\n]\n```\n\n_RHEL family 6.x_\n\n```ruby\nnode.default['authorization']['sudo']['sudoers_defaults'] = [\n '!visiblepw',\n 'env_reset',\n 'env_keep = \"COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS\"',\n 'env_keep += \"MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE\"',\n 'env_keep += \"LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES\"',\n 'env_keep += \"LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE\"',\n 'env_keep += \"LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY\"',\n 'env_keep += \"HOME\"',\n 'always_set_home',\n 'secure_path = /sbin:/bin:/usr/sbin:/usr/bin'\n]\n```\n\n_Mac OS X_\n\n```ruby\nnode.default['authorization']['sudo']['sudoers_defaults'] = [\n 'env_reset',\n 'env_keep += \"BLOCKSIZE\"',\n 'env_keep += \"COLORFGBG COLORTERM\"',\n 'env_keep += \"__CF_USER_TEXT_ENCODING\"',\n 'env_keep += \"CHARSET LANG LANGUAGE LC_ALL LC_COLLATE LC_CTYPE\"',\n 'env_keep += \"LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME\"',\n 'env_keep += \"LINES COLUMNS\"',\n 'env_keep += \"LSCOLORS\"',\n 'env_keep += \"TZ\"',\n 'env_keep += \"DISPLAY XAUTHORIZATION XAUTHORITY\"',\n 'env_keep += \"EDITOR VISUAL\"',\n 'env_keep += \"HOME MAIL\"'\n]\n```\n\n### LWRP\n**Note** Sudo version 1.7.2 or newer is required to use the sudo LWRP as it relies on the \"#includedir\" directive introduced in version 1.7.2. The recipe does not enforce installing the version. To use this LWRP, set `node['authorization']['sudo']['include_sudoers_d']` to `true`.\n\nThere are two ways for rendering a sudoer-fragment using this LWRP:\n1. Using the built-in template\n2. Using a custom, cookbook-level template\n\nBoth methods will create the `/etc/sudoers.d/#{username}` file with the correct permissions.\n\nThe LWRP also performs **fragment validation**. If a sudoer-fragment is not valid, the Chef run will throw an exception and fail. This ensures that your sudoers file is always valid and cannot become corrupt (from this cookbook).\n\nExample using the built-in template:\n\n```ruby\nsudo 'tomcat' do\n user \"%tomcat\" # or a username\n runas 'app_user' # or 'app_user:tomcat'\n commands ['/etc/init.d/tomcat restart']\nend\n```\n\n```ruby\nsudo 'tomcat' do\n template 'my_tomcat.erb' # local cookbook template\n variables :cmds => ['/etc/init.d/tomcat restart']\nend\n```\n\nIn either case, the following file would be generated in `/etc/sudoers.d/tomcat`\n\n```bash\n# This file is managed by Chef for node.example.com\n# Do NOT modify this file directly.\n\n%tomcat ALL=(app_user) /etc/init.d/tomcat restart\n```\n\n#### LWRP Attributes\n\n \n \n \n \n \n \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
AttributeDescriptionExampleDefault
namename of the `/etc/sudoers.d` filerestart-tomcatcurrent resource name
commandsarray of commands this sudoer can execute['/etc/init.d/tomcat restart']['ALL']
groupgroup to provide sudo privileges to, except `%` is prepended to the name in\ncase it is not already%admin
nopasswdsupply a password to invoke sudotruefalse
runasUser the command(s) can be run asrootALL
templatethe erb template to render instead of the defaultrestart-tomcat.erb
useruser to provide sudo privileges totomcat
defaultsarray of defaults this user has['!requiretty','env_reset']
setenvwhether to permit the preserving of environment with `sudo -E`true
env_keep_addarray of strings to add to env_keep['HOME', 'MY_ENV_VAR MY_OTHER_ENV_VAR']
env_keep_subtractarray of strings to remove from env_keep['DISPLAY', 'MY_SECURE_ENV_VAR']
variablesthe variables to pass to the custom template:commands => ['/etc/init.d/tomcat restart']
\n\n**If you use the template attribute, all other attributes will be ignored except for the variables attribute.**\n\n## Development\nThis section details \"quick development\" steps. For a detailed explanation, see [[Contributing.md]].\n- Clone this repository from GitHub:\n\n ```\n $ git clone git@github.com:chef-cookbooks/sudo.git\n ```\n\n- Create a git branch\n\n ```\n $ git checkout -b my_bug_fix\n ```\n\n- Install dependencies:\n\n ```\n $ bundle install\n ```\n\n- Make your changes/patches/fixes, committing appropiately\n- **Write tests**\n- Run the tests:\n - `bundle exec foodcritic -f any .`\n - `bundle exec rspec`\n - `bundle exec rubocop`\n - `bundle exec kitchen test`\n\n In detail:\n\n - Foodcritic will catch any Chef-specific style errors\n - RSpec will run the unit tests\n - Rubocop will check for Ruby-specific style errors\n - Test Kitchen will run and converge the recipes\n\n## License & Authors\n**Author:** Bryan W. Berry [bryan.berry@gmail.com](mailto:bryan.berry@gmail.com)\n\n**Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io))\n\n**Copyright:** 2008-2016, Chef Software, Inc.\n\n```\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{"redhat":">= 0.0.0","centos":">= 0.0.0","fedora":">= 0.0.0","ubuntu":">= 0.0.0","debian":">= 0.0.0","freebsd":">= 0.0.0","mac_os_x":">= 0.0.0","oracle":">= 0.0.0","scientific":">= 0.0.0"},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{"authorization":{"display_name":"Authorization","description":"Hash of Authorization attributes","type":"hash"},"authorization/sudo":{"display_name":"Authorization Sudoers","description":"Hash of Authorization/Sudo attributes","type":"hash"},"authorization/sudo/users":{"display_name":"Sudo Users","description":"Users who are allowed sudo ALL","type":"array","default":""},"authorization/sudo/groups":{"display_name":"Sudo Groups","description":"Groups who are allowed sudo ALL","type":"array","default":""},"authorization/sudo/passwordless":{"display_name":"Passwordless Sudo","description":"","type":"string","default":"false"},"authorization/sudo/include_sudoers_d":{"display_name":"Include sudoers.d","description":"Whether to create the sudoers.d includedir","type":"string","default":"false"},"authorization/sudo/setenv":{"display_name":"SetEnv Sudo","description":"Whether to permit the preserving of environment via sudo -E","type":"string","default":"false"}},"groupings":{},"recipes":{"sudo":"Installs sudo and configures /etc/sudoers"}} \ No newline at end of file +{"name":"sudo","version":"3.3.1","description":"Installs sudo and configures /etc/sudoers","long_description":"# sudo cookbook\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/sudo.svg?branch=master)](http://travis-ci.org/chef-cookbooks/sudo) [![Cookbook Version](https://img.shields.io/cookbook/v/sudo.svg)](https://supermarket.chef.io/cookbooks/sudo)\n\nThe Chef `sudo` cookbook installs the `sudo` package and configures the `/etc/sudoers` file.\n\nIt also exposes an LWRP for adding and managing sudoers.\n\n## Requirements\n\n### Platforms\n\n- Debian/Ubuntu\n- RHEL/CentOS/Scientific/Amazon/Oracle\n- FreeBSD\n- Mac OS X\n- openSUSE / Suse\n\n### Chef\n\n- Chef 12.1+\n\n### Cookbooks\n\n- None\n\n## Attributes\n- `node['authorization']['sudo']['groups']` - groups to enable sudo access (default: `[ \"sysadmin\" ]`)\n- `node['authorization']['sudo']['users']` - users to enable sudo access (default: `[]`)\n- `node['authorization']['sudo']['passwordless']` - use passwordless sudo (default: `false`)\n- `node['authorization']['sudo']['include_sudoers_d']` - include and manage `/etc/sudoers.d` (default: `false`)\n- `node['authorization']['sudo']['agent_forwarding']` - preserve `SSH_AUTH_SOCK` when sudoing (default: `false`)\n- `node['authorization']['sudo']['sudoers_defaults']` - Array of `Defaults` entries to configure in `/etc/sudoers`\n- `node['authorization']['sudo']['setenv']` - Whether to permit preserving of environment with `sudo -E` (default: `false`)\n\n## Usage\n### Attributes\nTo use attributes for defining sudoers, set the attributes above on the node (or role) itself:\n\n```json\n{\n \"default_attributes\": {\n \"authorization\": {\n \"sudo\": {\n \"groups\": [\"admin\", \"wheel\", \"sysadmin\"],\n \"users\": [\"jerry\", \"greg\"],\n \"passwordless\": \"true\"\n }\n }\n }\n}\n```\n\n```json\n{\n \"default_attributes\": {\n \"authorization\": {\n \"sudo\": {\n \"command_aliases\": [{\n \"name\": \"TEST\",\n \"command_list\": [\n \"/usr/bin/ls\",\n \"/usr/bin/cat\"\n ]\n }],\n \"custom_commands\": {\n \"users\": [\n {\n \"user\": \"test_user\",\n \"passwordless\": true,\n \"command_list\": [\n \"TEST\"\n ]\n }\n ],\n \"groups\": [\n {\n \"group\": \"test_group\",\n \"passwordless\": false,\n \"command_list\": [\n \"TEST\"\n ]\n }\n ]\n }\n }\n }\n }\n}\n```\n\n```ruby\n# roles/example.rb\ndefault_attributes(\n \"authorization\" => {\n \"sudo\" => {\n \"groups\" => [\"admin\", \"wheel\", \"sysadmin\"],\n \"users\" => [\"jerry\", \"greg\"],\n \"passwordless\" => true\n }\n }\n)\n```\n\n**Note that the template for the sudoers file has the group \"sysadmin\" with ALL:ALL permission, though the group by default does not exist.**\n\n### Sudoers Defaults\nConfigure a node attribute, `node['authorization']['sudo']['sudoers_defaults']` as an array of `Defaults` entries to configure in `/etc/sudoers`. A list of examples for common platforms is listed below:\n\n_Debian_\n\n```ruby\nnode.default['authorization']['sudo']['sudoers_defaults'] = ['env_reset']\n```\n\n_Ubuntu 10.04_\n\n```ruby\nnode.default['authorization']['sudo']['sudoers_defaults'] = ['env_reset']\n```\n\n_Ubuntu 12.04_\n\n```ruby\nnode.default['authorization']['sudo']['sudoers_defaults'] = [\n 'env_reset',\n 'secure_path=\"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"'\n]\n```\n\n_FreeBSD_\n\n```ruby\nnode.default['authorization']['sudo']['sudoers_defaults'] = [\n 'env_reset',\n 'secure_path=\"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"'\n]\n```\n\n_RHEL family 5.x_ The version of sudo in RHEL 5 may not support `+=`, as used in `env_keep`, so its a single string.\n\n```ruby\nnode.default['authorization']['sudo']['sudoers_defaults'] = [\n '!visiblepw',\n 'env_reset',\n 'env_keep = \"COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR \\\n LS_COLORS MAIL PS1 PS2 QTDIR USERNAME \\\n LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION \\\n LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC \\\n LC_PAPER LC_TELEPHONE LC_TIME LC_ALL LANGUAGE LINGUAS \\\n _XKB_CHARSET XAUTHORITY\"'\n]\n```\n\n_RHEL family 6.x_\n\n```ruby\nnode.default['authorization']['sudo']['sudoers_defaults'] = [\n '!visiblepw',\n 'env_reset',\n 'env_keep = \"COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS\"',\n 'env_keep += \"MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE\"',\n 'env_keep += \"LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES\"',\n 'env_keep += \"LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE\"',\n 'env_keep += \"LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY\"',\n 'env_keep += \"HOME\"',\n 'always_set_home',\n 'secure_path = /sbin:/bin:/usr/sbin:/usr/bin'\n]\n```\n\n_Mac OS X_\n\n```ruby\nnode.default['authorization']['sudo']['sudoers_defaults'] = [\n 'env_reset',\n 'env_keep += \"BLOCKSIZE\"',\n 'env_keep += \"COLORFGBG COLORTERM\"',\n 'env_keep += \"__CF_USER_TEXT_ENCODING\"',\n 'env_keep += \"CHARSET LANG LANGUAGE LC_ALL LC_COLLATE LC_CTYPE\"',\n 'env_keep += \"LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME\"',\n 'env_keep += \"LINES COLUMNS\"',\n 'env_keep += \"LSCOLORS\"',\n 'env_keep += \"TZ\"',\n 'env_keep += \"DISPLAY XAUTHORIZATION XAUTHORITY\"',\n 'env_keep += \"EDITOR VISUAL\"',\n 'env_keep += \"HOME MAIL\"'\n]\n```\n\n### LWRP\n**Note** Sudo version 1.7.2 or newer is required to use the sudo LWRP as it relies on the \"#includedir\" directive introduced in version 1.7.2. The recipe does not enforce installing the version. To use this LWRP, set `node['authorization']['sudo']['include_sudoers_d']` to `true`.\n\nThere are two ways for rendering a sudoer-fragment using this LWRP:\n1. Using the built-in template\n2. Using a custom, cookbook-level template\n\nBoth methods will create the `/etc/sudoers.d/#{resourcename}` file with the correct permissions.\n\nThe LWRP also performs **fragment validation**. If a sudoer-fragment is not valid, the Chef run will throw an exception and fail. This ensures that your sudoers file is always valid and cannot become corrupt (from this cookbook).\n\nExample using the built-in template:\n\n```ruby\nsudo 'tomcat' do\n user \"%tomcat\" # or a username\n runas 'app_user' # or 'app_user:tomcat'\n commands ['/etc/init.d/tomcat restart']\nend\n```\n\n```ruby\nsudo 'tomcat' do\n template 'my_tomcat.erb' # local cookbook template\n variables :cmds => ['/etc/init.d/tomcat restart']\nend\n```\n\nIn either case, the following file would be generated in `/etc/sudoers.d/tomcat`\n\n```bash\n# This file is managed by Chef for node.example.com\n# Do NOT modify this file directly.\n\n%tomcat ALL=(app_user) /etc/init.d/tomcat restart\n```\n\n#### LWRP Attributes\n\n \n \n \n \n \n \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
AttributeDescriptionExampleDefault
namename of the `/etc/sudoers.d` filerestart-tomcatcurrent resource name
commandsarray of commands this sudoer can execute['/etc/init.d/tomcat restart']['ALL']
groupgroup to provide sudo privileges to, except `%` is prepended to the name in\ncase it is not already%admin
nopasswdsupply a password to invoke sudotruefalse
noexecprevents commands from shelling outtruefalse
runasUser the command(s) can be run asrootALL
templatethe erb template to render instead of the defaultrestart-tomcat.erb
useruser to provide sudo privileges totomcat
defaultsarray of defaults this user has['!requiretty','env_reset']
setenvwhether to permit the preserving of environment with `sudo -E`true
env_keep_addarray of strings to add to env_keep['HOME', 'MY_ENV_VAR MY_OTHER_ENV_VAR']
env_keep_subtractarray of strings to remove from env_keep['DISPLAY', 'MY_SECURE_ENV_VAR']
variablesthe variables to pass to the custom template:commands => ['/etc/init.d/tomcat restart']
\n\n**If you use the template attribute, all other attributes will be ignored except for the variables attribute.**\n\n## Development\nThis section details \"quick development\" steps. For a detailed explanation, see [[Contributing.md]].\n- Clone this repository from GitHub:\n\n ```\n $ git clone git@github.com:chef-cookbooks/sudo.git\n ```\n\n- Create a git branch\n\n ```\n $ git checkout -b my_bug_fix\n ```\n\n- Install dependencies:\n\n ```\n $ bundle install\n ```\n\n- Make your changes/patches/fixes, committing appropiately\n- **Write tests**\n- Run the tests:\n - `bundle exec foodcritic -f any .`\n - `bundle exec rspec`\n - `bundle exec rubocop`\n - `bundle exec kitchen test`\n\n In detail:\n\n - Foodcritic will catch any Chef-specific style errors\n - RSpec will run the unit tests\n - Rubocop will check for Ruby-specific style errors\n - Test Kitchen will run and converge the recipes\n\n## License & Authors\n**Author:** Bryan W. Berry [bryan.berry@gmail.com](mailto:bryan.berry@gmail.com)\n\n**Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io))\n\n**Copyright:** 2008-2016, Chef Software, Inc.\n\n```\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{"redhat":">= 0.0.0","centos":">= 0.0.0","fedora":">= 0.0.0","ubuntu":">= 0.0.0","debian":">= 0.0.0","freebsd":">= 0.0.0","mac_os_x":">= 0.0.0","oracle":">= 0.0.0","scientific":">= 0.0.0","zlinux":">= 0.0.0","suse":">= 0.0.0","opensuse":">= 0.0.0","opensuseleap":">= 0.0.0"},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{"sudo":"Installs sudo and configures /etc/sudoers"}} \ No newline at end of file diff --git a/cookbooks/sudo/providers/default.rb b/cookbooks/sudo/providers/default.rb index 32cea31..e8f524a 100644 --- a/cookbooks/sudo/providers/default.rb +++ b/cookbooks/sudo/providers/default.rb @@ -1,11 +1,11 @@ # # Author:: Bryan W. Berry () # Author:: Seth Vargo () -# Cookbook Name:: sudo +# Cookbook:: sudo # Provider:: default # -# Copyright 2011, Bryan w. Berry -# Copyright 2012, Seth Vargo +# Copyright:: 2011-2016, Bryan w. Berry +# Copyright:: 2012-2016, Seth Vargo # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -20,6 +20,8 @@ # limitations under the License. # +use_inline_resources + # This LWRP supports whyrun mode def whyrun_supported? true @@ -45,7 +47,7 @@ def validate_fragment!(resource) file.rewind cmd = Mixlib::ShellOut.new("visudo -cf #{file.path}").run_command - unless cmd.exitstatus == 0 + unless cmd.exitstatus.zero? Chef::Log.error("Fragment validation failed: \n\n") Chef::Log.error(file.read) Chef::Application.fatal!("Template #{file.path} failed fragment validation!") @@ -87,6 +89,7 @@ def render_sudoer host: new_resource.host, runas: new_resource.runas, nopasswd: new_resource.nopasswd, + noexec: new_resource.noexec, commands: new_resource.commands, command_aliases: new_resource.command_aliases, defaults: new_resource.defaults, @@ -115,12 +118,13 @@ action :install do sudoers_dir.run_action(:create) end + Chef::Log.warn("#{sudo_filename} will be rendered, but will not take effect because node['authorization']['sudo']['include_sudoers_d'] is set to false!") unless node['authorization']['sudo']['include_sudoers_d'] new_resource.updated_by_last_action(true) if render_sudoer end # Removes a user from the sudoers group action :remove do - resource = file "#{node['authorization']['sudo']['prefix']}/sudoers.d/#{new_resource.name}" do + resource = file "#{node['authorization']['sudo']['prefix']}/sudoers.d/#{sudo_filename}" do action :nothing end resource.run_action(:delete) @@ -130,9 +134,9 @@ end private # acording to the sudo man pages sudo will ignore files in an include dir that have a `.` or `~` -# It is quite common for users to have a `.` in their login, so we will convert this to `__` +# We convert either to `__` def sudo_filename - new_resource.name.gsub(/\./, '__') + new_resource.name.gsub(/[\.~]/, '__') end # Capture a template to a string diff --git a/cookbooks/sudo/recipes/default.rb b/cookbooks/sudo/recipes/default.rb index 1e51f8d..249afd1 100644 --- a/cookbooks/sudo/recipes/default.rb +++ b/cookbooks/sudo/recipes/default.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: sudo +# Cookbook:: sudo # Recipe:: default # -# Copyright 2008-2016, Chef Software, Inc. +# Copyright:: 2008-2016, 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. @@ -53,6 +53,8 @@ template "#{prefix}/sudoers" do sudoers_defaults: node['authorization']['sudo']['sudoers_defaults'], command_aliases: node['authorization']['sudo']['command_aliases'], env_keep_add: node['authorization']['sudo']['env_keep_add'], - env_keep_subtract: node['authorization']['sudo']['env_keep_subtract'] + env_keep_subtract: node['authorization']['sudo']['env_keep_subtract'], + custom_commands_users: node['authorization']['sudo']['custom_commands']['users'], + custom_commands_groups: node['authorization']['sudo']['custom_commands']['groups'] ) end diff --git a/cookbooks/sudo/resources/default.rb b/cookbooks/sudo/resources/default.rb index 1086216..67f0172 100644 --- a/cookbooks/sudo/resources/default.rb +++ b/cookbooks/sudo/resources/default.rb @@ -1,9 +1,9 @@ # # Author:: Bryan W. Berry () -# Cookbook Name:: sudo +# Cookbook:: sudo # Resource:: default # -# Copyright 2011-2013, Bryan w. Berry +# Copyright:: 2011-2016, Bryan w. Berry # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ attribute :commands, kind_of: Array, default: ['ALL'] attribute :host, kind_of: String, default: 'ALL' attribute :runas, kind_of: String, default: 'ALL' attribute :nopasswd, equal_to: [true, false], default: false +attribute :noexec, equal_to: [true, false], default: false attribute :template, kind_of: String, default: nil attribute :variables, kind_of: Hash, default: nil attribute :defaults, kind_of: Array, default: [] @@ -46,6 +47,7 @@ state_attrs :commands, :group, :host, :nopasswd, + :noexec, :runas, :template, :user, diff --git a/cookbooks/sudo/templates/default/sudoer.erb b/cookbooks/sudo/templates/default/sudoer.erb index dbd9dc8..02c9898 100644 --- a/cookbooks/sudo/templates/default/sudoer.erb +++ b/cookbooks/sudo/templates/default/sudoer.erb @@ -14,7 +14,7 @@ Defaults env_keep -= "<%= env_keep %>" <% end -%> <% @commands.each do |command| -%> -<%= @sudoer %> <%= @host %>=(<%= @runas %>) <%= 'NOPASSWD:' if @nopasswd %><%= 'SETENV:' if @setenv %><%= command %> +<%= @sudoer %> <%= @host %>=(<%= @runas %>) <%= 'NOEXEC:' if @noexec %><%= 'NOPASSWD:' if @nopasswd %><%= 'SETENV:' if @setenv %><%= command %> <% end -%> <% unless @defaults.empty? %> diff --git a/cookbooks/sudo/templates/default/sudoers.erb b/cookbooks/sudo/templates/default/sudoers.erb index c18126e..84dae15 100644 --- a/cookbooks/sudo/templates/default/sudoers.erb +++ b/cookbooks/sudo/templates/default/sudoers.erb @@ -7,10 +7,26 @@ Defaults <%= defaults %> <% if @agent_forwarding -%> Defaults env_keep+=SSH_AUTH_SOCK <% end -%> +<% @env_keep_add.each do |env_keep| -%> +Defaults env_keep += "<%= env_keep %>" +<% end -%> +<% @env_keep_subtract.each do |env_keep| -%> +Defaults env_keep -= "<%= env_keep %>" +<% end -%> # User privilege specification root ALL=(ALL) ALL +<% @custom_commands_users.each do |commands| -%> +# Privileges for specific command <%= commands[:command_list].join(', ') %> for user <%= commands[:user] %> +<%= commands[:user] %> ALL = <%= "NOPASSWD:" if commands[:passwordless] %> <%= commands[:command_list].join(', ') %> +<% end -%> + +<% @custom_commands_groups.each do |commands| -%> +# Privileges for specific command <%= commands[:command_list].join(', ') %> for group <%= commands[:group] %> +%<%= commands[:group] %> ALL = <%= "NOPASSWD:" if commands[:passwordless] %> <%= commands[:command_list].join(', ') %> +<% end -%> + <% @command_aliases.each do |a| -%> Cmnd_Alias <%= a[:name].upcase %> = <%= a[:command_list].join(', ') %> <% end -%> diff --git a/cookbooks/sudo/templates/mac_os_x/sudoers.erb b/cookbooks/sudo/templates/mac_os_x/sudoers.erb index 851c92e..2699238 100644 --- a/cookbooks/sudo/templates/mac_os_x/sudoers.erb +++ b/cookbooks/sudo/templates/mac_os_x/sudoers.erb @@ -15,6 +15,16 @@ root ALL=(ALL) ALL <%= user %> ALL=(ALL) <%= "NOPASSWD:" if @passwordless %><%= "SETENV:" if @setenv %>ALL <% end -%> +<% @custom_commands_users.each do |commands| -%> +# Privileges for specific command <%= commands[:command_list].join(', ') %> for user <%= commands[:user] %> +<%= commands[:user] %> ALL = <%= "NOPASSWD:" if commands[:passwordless] %> <%= commands[:command_list].join(', ') %> +<% end -%> + +<% @custom_commands_groups.each do |commands| -%> +# Privileges for specific command <%= commands[:command_list].join(', ') %> for group <%= commands[:group] %> +%<%= commands[:group] %> ALL = <%= "NOPASSWD:" if commands[:passwordless] %> <%= commands[:command_list].join(', ') %> +<% end -%> + <% @sudoers_groups.each do |group| -%> # Members of the group '<%= group %>' may gain root privileges %<%= group %> ALL=(ALL) <%= "NOPASSWD:" if @passwordless %><%= "SETENV:" if @setenv %>ALL diff --git a/cookbooks/tar/.foodcritic b/cookbooks/tar/.foodcritic new file mode 100644 index 0000000..b9f8767 --- /dev/null +++ b/cookbooks/tar/.foodcritic @@ -0,0 +1 @@ +~FC016 diff --git a/cookbooks/tar/CHANGELOG.md b/cookbooks/tar/CHANGELOG.md index d586b0b..bc3636c 100644 --- a/cookbooks/tar/CHANGELOG.md +++ b/cookbooks/tar/CHANGELOG.md @@ -1,74 +1,110 @@ -# Tar Cookbook Changelog +# tar Cookbook CHANGELOG + +This file is used to list changes made in each version of the tar cookbook. + +## 2.0.0 (2017-02-16) + +- Converted the existing LWRPs to custom resources and bumped the minimum supported Chef release to 12.5 +- Add all supported platforms to the metadata +- Add full testing of the resources in Travis CI + +## 1.1.0 (2016-12-21) + +- added support for .xz compression type +- Reformat the readme +- Define both Chefspec matchers +- Remove Chef 11 compatibility code + +## 1.0.0 (2016-12-21) + +- This cookbook has been adopted by Chef and will be maintained by the Community Cookbook Team going forward. +- This cookbook now requires Chef 12.1+ to align with the requirements of all Chef maintained cookbooks +- Cookbook boilerplate has been updated + + - chefignore file added + - gitignore file + - Test Kitchen config added + - Berksfile added + - Gemfile added + - Badges added to the readme + - Add maintainers files + - Add rakefile for simplified testing + - Add github templates + - Add license file + - Update author in metadata and add supermarket metadata + - Add contributing and testing docs + - Cookstyle fixes + - Add basic chefspec convergence test + - Add a basic test cookbook + - Add test kitchen testing in Travis ## v0.7.0 (2015-07-08) -* Add adoption notice -* Use `file_cache_path` instead of `file_backup_path` for downloaded artifact - storage -* Fix links to Chef documentation in README +- Add adoption notice +- Use `file_cache_path` instead of `file_backup_path` for downloaded artifact storage +- Fix links to Chef documentation in README ## v0.6.0 (2014-12-03) -* Allow either string or array for tar flags +- Allow either string or array for tar flags ## v0.5.0 (2014-07-28) -* Add support for more attributes of `remote_file` -* Escape downloaded file names +- Add support for more attributes of `remote_file` +- Escape downloaded file names ## v0.4.0 (2014-06-13) -* Add `archive_name` option for when the file name is different from the - package name +- Add `archive_name` option for when the file name is different from the package name ## v0.3.4 (2014-06-05) -* Define ChefSpec::Runner method for tar_extract +- Define ChefSpec::Runner method for tar_extract ## v0.3.3 (2014-06-03) -* Add ChefSpec matchers +- Add ChefSpec matchers ## v0.3.2 (2014-05-05) -* Add checksum to remote file downloads +- Add checksum to remote file downloads ## v0.3.1 (2014-04-04) -* Correct "notifies" definition in tar_extract's remote_file +- Correct "notifies" definition in tar_extract's remote_file ## v0.3.0 (2014-03-21) -* Add `:extract_local` action +- Add `:extract_local` action ## v0.2.0 (2013-12-31) -* Make `tar_extract` only run if needed -* Fix missing space in command line prefix -* Ensure `file_backup_path` exists on initial chef-client run -* Only add headers if needed +- Make `tar_extract` only run if needed +- Fix missing space in command line prefix +- Ensure `file_backup_path` exists on initial chef-client run +- Only add headers if needed ## v0.1.0 (2013-11-26) -* Allow custom HTTP headers when downloading files -* Allow the type of tar compression -* Improve resource notifications +- Allow custom HTTP headers when downloading files +- Allow the type of tar compression +- Improve resource notifications ## v0.0.4 (2013-10-02) -* Remove conditional download requests in favor of built-in functionality in Chef >= 11.6.0. -* Fix readme example -* Foodcritic fixes +- Remove conditional download requests in favor of built-in functionality in Chef >= 11.6.0. +- Fix readme example +- Foodcritic fixes ## v0.0.3 (2013-01-30) -* Conditional requests for downloads -* Allow extract if non-root user -* Formatting fixes +- Conditional requests for downloads +- Allow extract if non-root user +- Formatting fixes ## v0.0.2 (2012-10-13) -* Add `tar_extract` LWRP +- Add `tar_extract` LWRP ## v0.0.1 (2011-09-15) diff --git a/cookbooks/tar/CONTRIBUTING.md b/cookbooks/tar/CONTRIBUTING.md new file mode 100644 index 0000000..ef2f2b8 --- /dev/null +++ b/cookbooks/tar/CONTRIBUTING.md @@ -0,0 +1,2 @@ +Please refer to +https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD diff --git a/cookbooks/tar/MAINTAINERS.md b/cookbooks/tar/MAINTAINERS.md new file mode 100644 index 0000000..645ed14 --- /dev/null +++ b/cookbooks/tar/MAINTAINERS.md @@ -0,0 +1,15 @@ + + +# Maintainers + +This file lists how this cookbook project is maintained. When making changes to the system, this file tells you who needs to review your patch - you need a review from an existing maintainer for the cookbook to provide a :+1: on your pull request. Additionally, you need to not receive a veto from a Lieutenant or the Project Lead. + +Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) for details on the process and how to become a maintainer or the project lead. + +# Project Maintainer +* [Tim Smith](https://github.com/tas50) + +# Maintainers +* [Jennifer Davis](https://github.com/sigje) +* [Tim Smith](https://github.com/tas50) +* [Thom May](https://github.com/thommay) diff --git a/cookbooks/tar/README.md b/cookbooks/tar/README.md index 863919c..b0d8f00 100644 --- a/cookbooks/tar/README.md +++ b/cookbooks/tar/README.md @@ -1,101 +1,95 @@ -*This cookbook is no longer actively maintained and is up for adoption. If you -would like to take over development, go to https://supermarket.chef.io/cookbooks/tar, -click the "Adopt me!" button, and you could be the new maintainer of this cookbook!* +# tar Cookbook -DESCRIPTION -=========== +[![Build Status](https://travis-ci.org/chef-cookbooks/tar.svg?branch=master)](https://travis-ci.org/chef-cookbooks/tar) [![Cookbook Version](https://img.shields.io/cookbook/v/tar.svg)](https://supermarket.chef.io/cookbooks/tar) -Installs tar and two resources for managing remote tar files. -`tar_package` handles remote source package compilation. -`tar_extract` handles retrieving remote tar files and extracting -them locally. +Installs tar and includes resources for managing remote tar files. `tar_package` handles remote source package compilation. `tar_extract` handles retrieving remote tar files and extracting them locally. -LICENSE AND AUTHOR -================== +## Resources -Author:: Nathan L Smith () -Author:: George Miranda () -Author:: Mark Van de Vyver () +### tar_package -Copyright 2011, Cramer Development, Inc. -Copyright 2011, Opscode, Inc. -Copyright 2013, TAQTIQA LLC. +A `tar_package` LWRP provides an easy way to download remote files and compile and install them. This only works for the most basic Autoconf programs that can do `./configure && make && make install`. -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 +#### Actions - 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. - -Resources/Providers -=================== - -A `tar_package` LWRP provides an easy way to download remote files and compile and install them. This only works for the most basic Autoconf programs that can do `./configure && make && make install`. - -A `tar_extract` LWRP provides an easy way to download remote tar files and extract them to a local directory. - -# Actions - -`tar_package` - :install: Installs the package -`tar_extract` -- :extract: Extracts the tar file from a url -- :extract_local: Extracts the tar file from a local file path +#### Properties -# Attribute Parameters - -`tar_package` - source: name attribute. The source remote URL. - prefix: Directory to be used as the `--prefix` configure flag. -- source\_directory: Directory to which source files are download. +- source_directory: Directory to which source files are download. - creates: A file this command creates - if the file exists, the command will not be run. -- configure\_flags: Array of additional flags to be passed to `./configure`. -- archive\_name: Specify a different name for the downloaded archive. Use it if the directory name inside the tar file is different than the name defined in the URL. -Additionally, `tar_package` supports most `remote_file` [attributes](https://docs.chef.io/chef/resources.html#remote-file). +- configure_flags: Array of additional flags to be passed to `./configure`. +- archive_name: Specify a different name for the downloaded archive. Use it if the directory name inside the tar file is different than the name defined in the URL. Additionally, `tar_package` supports most `remote_file` [attributes](https://docs.chef.io/chef/resources.html#remote-file). -`tar_extract` -- source: name attribute. The source remote URL. -- target\_dir: Directory to extract into, e.g. tar xzf -C (target_dir) -- download\_dir: Directory to which tarball is downloaded (defaults to chef cache which requires root `group` and `user`). -- creates: A file this command creates - if the file exists, the command will not be run. -- compress_char: Flag for compression type, such as `z` for `gzip`. `man tar` for options. -- tar\_flags: Array of additional flags to be passed to tar xzf command. -- group: Group name or group ID to extract the archive under. If set to non-root group, point to a `download_dir` the group has permission to access. -- user: User name or user ID to extract the archive under. If set to non-root user, point to a `download_dir` the user has permission to access. -Additionally, `tar_extract` supports most `remote_file` [attributes](https://docs.chef.io/chef/resources.html#remote-file). +#### Example -# Example - - tar_package 'http://pgfoundry.org/frs/download.php/1446/pgpool-3.4.1.tar.gz' do - prefix '/usr/local' - creates '/usr/local/bin/pgpool' - end +``` +tar_package 'http://pgfoundry.org/frs/download.php/1446/pgpool-3.4.1.tar.gz' do + prefix '/usr/local' + creates '/usr/local/bin/pgpool' +end +``` This will download, compile, and install the package from the given URL and install it into /usr/local. - tar_extract 'http://dev.mycoderepo.com/artifacts/mycode-1.2.3.tar.gz' do - target_dir '/opt/myapp/mycode' - creates '/opt/myapp/mycode/lib' - tar_flags [ '-P', '--strip-components 1' ] - end +### tar_extract + +A `tar_extract` LWRP provides an easy way to download remote tar files and extract them to a local directory. + +#### Actions + +- :extract: Extracts the tar file from a url +- :extract_local: Extracts the tar file from a local file path + +#### Properties + +- source: name attribute. The source remote URL. +- target_dir: Directory to extract into, e.g. tar xzf -C (target_dir) +- download_dir: Directory to which tarball is downloaded (defaults to chef cache which requires root `group` and `user`). +- creates: A file this command creates - if the file exists, the command will not be run. +- compress_char: Flag for compression type, such as `z` for `gzip`. `man tar` for options. +- tar_flags: Array of additional flags to be passed to tar xzf command. +- group: Group name or group ID to extract the archive under. If set to non-root group, point to a `download_dir` the group has permission to access. +- user: User name or user ID to extract the archive under. If set to non-root user, point to a `download_dir` the user has permission to access. Additionally, `tar_extract` supports most `remote_file` [attributes](https://docs.chef.io/chef/resources.html#remote-file). + +#### Example + +``` +tar_extract 'http://dev.mycoderepo.com/artifacts/mycode-1.2.3.tar.gz' do + target_dir '/opt/myapp/mycode' + creates '/opt/myapp/mycode/lib' + tar_flags [ '-P', '--strip-components 1' ] +end +``` This will download the tarball to cache, extract the contents to /opt/myapp/mycode, use the file '/opt/myapp/mycode/lib' to determine idempotency, and pass both '-P' and '--strip-components 1' flags to the tar xzf command. - tar_extract '/tmp/mycode-1.2.3.tar.gz' do - action :extract_local - target_dir '/opt/myapp/mycode' - creates '/opt/myapp/mycode/lib' - end +``` +tar_extract '/tmp/mycode-1.2.3.tar.gz' do + action :extract_local + target_dir '/opt/myapp/mycode' + creates '/opt/myapp/mycode/lib' +end +``` This will extract the contents of /tmp/mycode-1.2.3.tar.gz to /opt/myapp/mycode and use the file '/opt/myapp/mycode/lib' to determine idempotency. -# ChefSpec Matchers +## ChefSpec Matchers ChefSpec matchers are defined for tar_package and tar_extract. + +## LICENSE AND AUTHOR + +Author:: Nathan L Smith ([nathan@cramerdev.com](mailto:nathan@cramerdev.com)) Author:: George Miranda ([gmiranda@chef.io](mailto:gmiranda@chef.io)) Author:: Mark Van de Vyver ([mark@@taqtiqa.com](mailto:mark@@taqtiqa.com)) + +Copyright 2011, Cramer Development, Inc. Copyright 2011, Opscode, Inc. Copyright 2013, TAQTIQA LLC. + +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. diff --git a/cookbooks/tar/libraries/matchers.rb b/cookbooks/tar/libraries/matchers.rb index 5a293cc..ac9904c 100644 --- a/cookbooks/tar/libraries/matchers.rb +++ b/cookbooks/tar/libraries/matchers.rb @@ -1,4 +1,5 @@ if defined?(ChefSpec) + ChefSpec.define_matcher :tar_package ChefSpec.define_matcher :tar_extract def install_tar_package(source) diff --git a/cookbooks/tar/metadata.json b/cookbooks/tar/metadata.json index 752547a..0e5ddc0 100644 --- a/cookbooks/tar/metadata.json +++ b/cookbooks/tar/metadata.json @@ -1,41 +1 @@ -{ - "name": "tar", - "description": "Installs tar and two LWRPs to manage remote tar packages", - "long_description": "*This cookbook is no longer actively maintained and is up for adoption. If you\nwould like to take over development, go to https://supermarket.chef.io/cookbooks/tar,\nclick the \"Adopt me!\" button, and you could be the new maintainer of this cookbook!*\n\nDESCRIPTION\n===========\n\nInstalls tar and two resources for managing remote tar files.\n`tar_package` handles remote source package compilation.\n`tar_extract` handles retrieving remote tar files and extracting\nthem locally.\n\nLICENSE AND AUTHOR\n==================\n\nAuthor:: Nathan L Smith ()\nAuthor:: George Miranda ()\nAuthor:: Mark Van de Vyver ()\n\nCopyright 2011, Cramer Development, Inc.\nCopyright 2011, Opscode, Inc.\nCopyright 2013, TAQTIQA LLC.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\nResources/Providers\n===================\n\nA `tar_package` LWRP provides an easy way to download remote files and compile and install them. This only works for the most basic Autoconf programs that can do `./configure && make && make install`.\n\nA `tar_extract` LWRP provides an easy way to download remote tar files and extract them to a local directory.\n\n# Actions\n\n`tar_package`\n- :install: Installs the package\n\n`tar_extract`\n- :extract: Extracts the tar file from a url\n- :extract_local: Extracts the tar file from a local file path\n\n# Attribute Parameters\n\n`tar_package`\n- source: name attribute. The source remote URL.\n- prefix: Directory to be used as the `--prefix` configure flag.\n- source\\_directory: Directory to which source files are download.\n- creates: A file this command creates - if the file exists, the command will not be run.\n- configure\\_flags: Array of additional flags to be passed to `./configure`.\n- archive\\_name: Specify a different name for the downloaded archive. Use it if the directory name inside the tar file is different than the name defined in the URL.\nAdditionally, `tar_package` supports most `remote_file` [attributes](https://docs.chef.io/chef/resources.html#remote-file).\n\n`tar_extract`\n- source: name attribute. The source remote URL.\n- target\\_dir: Directory to extract into, e.g. tar xzf -C (target_dir)\n- download\\_dir: Directory to which tarball is downloaded (defaults to chef cache which requires root `group` and `user`).\n- creates: A file this command creates - if the file exists, the command will not be run.\n- compress_char: Flag for compression type, such as `z` for `gzip`. `man tar` for options.\n- tar\\_flags: Array of additional flags to be passed to tar xzf command.\n- group: Group name or group ID to extract the archive under. If set to non-root group, point to a `download_dir` the group has permission to access.\n- user: User name or user ID to extract the archive under. If set to non-root user, point to a `download_dir` the user has permission to access.\nAdditionally, `tar_extract` supports most `remote_file` [attributes](https://docs.chef.io/chef/resources.html#remote-file).\n\n# Example\n\n tar_package 'http://pgfoundry.org/frs/download.php/1446/pgpool-3.4.1.tar.gz' do\n prefix '/usr/local'\n creates '/usr/local/bin/pgpool'\n end\n\nThis will download, compile, and install the package from the given URL and install it into /usr/local.\n\n tar_extract 'http://dev.mycoderepo.com/artifacts/mycode-1.2.3.tar.gz' do\n target_dir '/opt/myapp/mycode'\n creates '/opt/myapp/mycode/lib'\n tar_flags [ '-P', '--strip-components 1' ]\n end\n\nThis will download the tarball to cache, extract the contents to /opt/myapp/mycode, use the file '/opt/myapp/mycode/lib' to determine idempotency, and pass both '-P' and '--strip-components 1' flags to the tar xzf command.\n\n tar_extract '/tmp/mycode-1.2.3.tar.gz' do\n action :extract_local\n target_dir '/opt/myapp/mycode'\n creates '/opt/myapp/mycode/lib'\n end\n\nThis will extract the contents of /tmp/mycode-1.2.3.tar.gz to /opt/myapp/mycode and use the file '/opt/myapp/mycode/lib' to determine idempotency.\n\n# ChefSpec Matchers\n\nChefSpec matchers are defined for tar_package and tar_extract.\n", - "maintainer": "Cramer Development, Inc.", - "maintainer_email": "sysadmin@cramerdev.com", - "license": "Apache 2.0", - "platforms": { - - }, - "dependencies": { - - }, - "recommendations": { - - }, - "suggestions": { - - }, - "conflicting": { - - }, - "providing": { - - }, - "replacing": { - - }, - "attributes": { - - }, - "groupings": { - - }, - "recipes": { - - }, - "version": "0.7.0", - "source_url": "", - "issues_url": "" -} +{"name":"tar","version":"2.0.0","description":"Installs tar and two resources to manage remote tar packages","long_description":"# tar Cookbook\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/tar.svg?branch=master)](https://travis-ci.org/chef-cookbooks/tar) [![Cookbook Version](https://img.shields.io/cookbook/v/tar.svg)](https://supermarket.chef.io/cookbooks/tar)\n\nInstalls tar and includes resources for managing remote tar files. `tar_package` handles remote source package compilation. `tar_extract` handles retrieving remote tar files and extracting them locally.\n\n## Resources\n\n### tar_package\n\nA `tar_package` LWRP provides an easy way to download remote files and compile and install them. This only works for the most basic Autoconf programs that can do `./configure && make && make install`.\n\n#### Actions\n\n- :install: Installs the package\n\n#### Properties\n\n- source: name attribute. The source remote URL.\n- prefix: Directory to be used as the `--prefix` configure flag.\n- source_directory: Directory to which source files are download.\n- creates: A file this command creates - if the file exists, the command will not be run.\n- configure_flags: Array of additional flags to be passed to `./configure`.\n- archive_name: Specify a different name for the downloaded archive. Use it if the directory name inside the tar file is different than the name defined in the URL. Additionally, `tar_package` supports most `remote_file` [attributes](https://docs.chef.io/chef/resources.html#remote-file).\n\n#### Example\n\n```\ntar_package 'http://pgfoundry.org/frs/download.php/1446/pgpool-3.4.1.tar.gz' do\n prefix '/usr/local'\n creates '/usr/local/bin/pgpool'\nend\n```\n\nThis will download, compile, and install the package from the given URL and install it into /usr/local.\n\n### tar_extract\n\nA `tar_extract` LWRP provides an easy way to download remote tar files and extract them to a local directory.\n\n#### Actions\n\n- :extract: Extracts the tar file from a url\n- :extract_local: Extracts the tar file from a local file path\n\n#### Properties\n\n- source: name attribute. The source remote URL.\n- target_dir: Directory to extract into, e.g. tar xzf -C (target_dir)\n- download_dir: Directory to which tarball is downloaded (defaults to chef cache which requires root `group` and `user`).\n- creates: A file this command creates - if the file exists, the command will not be run.\n- compress_char: Flag for compression type, such as `z` for `gzip`. `man tar` for options.\n- tar_flags: Array of additional flags to be passed to tar xzf command.\n- group: Group name or group ID to extract the archive under. If set to non-root group, point to a `download_dir` the group has permission to access.\n- user: User name or user ID to extract the archive under. If set to non-root user, point to a `download_dir` the user has permission to access. Additionally, `tar_extract` supports most `remote_file` [attributes](https://docs.chef.io/chef/resources.html#remote-file).\n\n#### Example\n\n```\ntar_extract 'http://dev.mycoderepo.com/artifacts/mycode-1.2.3.tar.gz' do\n target_dir '/opt/myapp/mycode'\n creates '/opt/myapp/mycode/lib'\n tar_flags [ '-P', '--strip-components 1' ]\nend\n```\n\nThis will download the tarball to cache, extract the contents to /opt/myapp/mycode, use the file '/opt/myapp/mycode/lib' to determine idempotency, and pass both '-P' and '--strip-components 1' flags to the tar xzf command.\n\n```\ntar_extract '/tmp/mycode-1.2.3.tar.gz' do\n action :extract_local\n target_dir '/opt/myapp/mycode'\n creates '/opt/myapp/mycode/lib'\nend\n```\n\nThis will extract the contents of /tmp/mycode-1.2.3.tar.gz to /opt/myapp/mycode and use the file '/opt/myapp/mycode/lib' to determine idempotency.\n\n## ChefSpec Matchers\n\nChefSpec matchers are defined for tar_package and tar_extract.\n\n## LICENSE AND AUTHOR\n\nAuthor:: Nathan L Smith ([nathan@cramerdev.com](mailto:nathan@cramerdev.com)) Author:: George Miranda ([gmiranda@chef.io](mailto:gmiranda@chef.io)) Author:: Mark Van de Vyver ([mark@@taqtiqa.com](mailto:mark@@taqtiqa.com))\n\nCopyright 2011, Cramer Development, Inc. Copyright 2011, Opscode, Inc. Copyright 2013, TAQTIQA LLC.\n\nLicensed 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\n\n```\nhttp://www.apache.org/licenses/LICENSE-2.0\n```\n\nUnless 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.\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{"ubuntu":">= 0.0.0","debian":">= 0.0.0","redhat":">= 0.0.0","centos":">= 0.0.0","suse":">= 0.0.0","opensuse":">= 0.0.0","opensuseleap":">= 0.0.0","scientific":">= 0.0.0","oracle":">= 0.0.0","amazon":">= 0.0.0","zlinux":">= 0.0.0"},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{}} \ No newline at end of file diff --git a/cookbooks/tar/metadata.rb b/cookbooks/tar/metadata.rb deleted file mode 100644 index aa1d09c..0000000 --- a/cookbooks/tar/metadata.rb +++ /dev/null @@ -1,7 +0,0 @@ -name "tar" -maintainer "Cramer Development, Inc." -maintainer_email "sysadmin@cramerdev.com" -license "Apache 2.0" -description "Installs tar and two LWRPs to manage remote tar packages" -long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -version "0.7.0" diff --git a/cookbooks/tar/providers/extract.rb b/cookbooks/tar/providers/extract.rb deleted file mode 100644 index 1e48417..0000000 --- a/cookbooks/tar/providers/extract.rb +++ /dev/null @@ -1,86 +0,0 @@ -# -# Cookbook Name:: tar -# Provider:: extract -# -# Author:: Nathan L Smith () -# Author:: George Miranda () -# Author:: Mark Van de Vyver () -# -# Copyright 2011, Cramer Development, Inc. -# Copyright 2012, Opscode, Inc. -# Copyright 2013, TAQTIQA LLC. -# -# 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 'shellwords' - -use_inline_resources if defined?(use_inline_resources) - -def whyrun_supported? - true -end - -action :extract do - version = Chef::Version.new(Chef::VERSION[/^(\d+\.\d+\.\d+)/, 1]) - r = new_resource - basename = ::File.basename(r.name) - local_archive = "#{r.download_dir}/#{basename}" - - directory r.download_dir do - recursive true - end - - remote_file basename do - source r.name - checksum r.checksum - path local_archive - backup false - action :create - group r.group - owner r.user - mode r.mode - notifies :run, "execute[extract #{local_archive}]" - if version.major > 11 || (version.major == 11 && version.minor >= 6) - unless r.headers.nil? - headers r.headers - end - use_etag r.use_etag - use_last_modified r.use_last_modified - atomic_update r.atomic_update - force_unlink r.force_unlink - manage_symlink_source r.manage_symlink_source - end - end - - extract_tar(local_archive, new_resource) -end - -action :extract_local do - extract_tar(new_resource.name, new_resource) -end - -def extract_tar(local_archive, r) - execute "extract #{local_archive}" do - if r.tar_flags.kind_of?(String) - flags = r.tar_flags - else - flags = r.tar_flags.join(' ') - end - command "tar xf#{r.compress_char} #{local_archive.shellescape} #{flags}" - cwd r.target_dir - creates r.creates - group r.group - user r.user - action (r.creates || r.not_if.any? || r.only_if.any? ? :run : :nothing) - end -end diff --git a/cookbooks/tar/providers/package.rb b/cookbooks/tar/providers/package.rb deleted file mode 100644 index 1141c46..0000000 --- a/cookbooks/tar/providers/package.rb +++ /dev/null @@ -1,65 +0,0 @@ -# -# Cookbook Name:: tar -# Provider:: package -# -# Author:: Nathan L Smith () -# -# Copyright 2011, Cramer Development, Inc. -# -# 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. -# - -use_inline_resources if defined?(use_inline_resources) - -def whyrun_supported? - true -end - -action :install do - version = Chef::Version.new(Chef::VERSION[/^(\d+\.\d+\.\d+)/, 1]) - r = new_resource - basename = r.archive_name || ::File.basename(r.name) - dirname = basename.chomp('.tar.gz') # Assuming .tar.gz - src_dir = r.source_directory - - remote_file basename do - source r.name - path "#{src_dir}/#{basename}" - backup false - action :create_if_missing - if version.major > 11 || (version.major == 11 && version.minor >= 6) - unless r.headers.nil? - headers r.headers - end - use_etag r.use_etag - use_last_modified r.use_last_modified - atomic_update r.atomic_update - force_unlink r.force_unlink - manage_symlink_source r.manage_symlink_source - end - end - - execute "extract #{basename}" do - command "tar xfz #{basename}" - cwd src_dir - creates "#{src_dir}/#{dirname}" - end - - execute "compile & install #{dirname}" do - flags = [r.prefix ? "--prefix=#{r.prefix}" : nil, *r.configure_flags].compact.join(' ') - command "./configure --quiet #{flags} && make --quiet && make --quiet install" - cwd "#{src_dir}/#{dirname}" - creates r.creates - end -end - diff --git a/cookbooks/tar/recipes/default.rb b/cookbooks/tar/recipes/default.rb index 8d8e2dc..2295cd8 100644 --- a/cookbooks/tar/recipes/default.rb +++ b/cookbooks/tar/recipes/default.rb @@ -4,7 +4,7 @@ # # Author:: Nathan L Smith () # -# Copyright 2011, Cramer Development, Inc. +# Copyright:: 2011, Cramer Development, 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/cookbooks/tar/resources/extract.rb b/cookbooks/tar/resources/extract.rb index 51d8f0e..c4f12e3 100644 --- a/cookbooks/tar/resources/extract.rb +++ b/cookbooks/tar/resources/extract.rb @@ -3,12 +3,12 @@ # Resource:: extract # # Author:: Nathan L Smith () -# Author:: George Miranda () +# Author:: George Miranda () # Author:: Mark Van de Vyver () # -# Copyright 2011, Cramer Development, Inc. -# Copyright 2012, Opscode, Inc. -# Copyright 2013, TAQTIQA LLC. +# Copyright:: 2011, Cramer Development, Inc. +# Copyright:: 2012-2016, Chef Software, Inc. +# Copyright:: 2013, TAQTIQA LLC. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -23,27 +23,75 @@ # limitations under the License. # -actions :extract, :extract_local +property :source, String, name_property: true +property :checksum, String +property :download_dir, String, default: Chef::Config[:file_cache_path] +property :group, String, default: 'root' +property :mode, String, default: '0755' +property :target_dir, String +property :creates, String +property :compress_char, String, default: 'z' +property :tar_flags, [String, Array], default: [] +property :user, String, default: 'root' +property :headers, Hash +property :use_etag, [TrueClass, FalseClass], default: true +property :use_last_modified, [TrueClass, FalseClass], default: true +property :atomic_update, [TrueClass, FalseClass], default: true +property :force_unlink, [TrueClass, FalseClass], default: false +property :manage_symlink_source, [TrueClass, FalseClass] -attribute :source, :kind_of => String, :name_attribute => true -attribute :checksum, :kind_of => String -attribute :download_dir, :kind_of => String, :default => Chef::Config[:file_cache_path] -attribute :group, :kind_of => String, :default => 'root' -attribute :mode, :kind_of => String, :default => '0755' -attribute :target_dir, :kind_of => String -attribute :creates, :kind_of => String -attribute :compress_char, :kind_of => String, :default => 'z' -attribute :tar_flags, :kind_of => [String, Array], :default => Array.new -attribute :user, :kind_of => String, :default => 'root' +require 'shellwords' -version = Chef::Version.new(Chef::VERSION[/^(\d+\.\d+\.\d+)/, 1]) -if version.major > 11 || (version.major == 11 && version.minor >= 6) - attribute :headers, :kind_of => Hash, :default => nil - attribute :use_etag, :kind_of => [TrueClass, FalseClass], :default => true - attribute :use_last_modified, :kind_of => [TrueClass, FalseClass], :default => true - attribute :atomic_update, :kind_of => [TrueClass, FalseClass], :default => true - attribute :force_unlink, :kind_of => [TrueClass, FalseClass], :default => false - attribute :manage_symlink_source, :kind_of => [TrueClass, FalseClass], :default => nil +action :extract do + r = new_resource + basename = ::File.basename(r.name) + extname = ::File.extname(r.name) + r.compress_char = '' if extname.casecmp('.xz') == 0 + local_archive = "#{r.download_dir}/#{basename}" + + directory r.download_dir do + recursive true + end + + remote_file basename do + source r.name + checksum r.checksum + path local_archive + backup false + action :create + group r.group + owner r.user + mode r.mode + headers r.headers unless r.headers.nil? + use_etag r.use_etag + use_last_modified r.use_last_modified + atomic_update r.atomic_update + force_unlink r.force_unlink + manage_symlink_source r.manage_symlink_source + notifies :run, "execute[extract #{local_archive}]" + end + + extract_tar(local_archive, new_resource) end -default_action :extract +action :extract_local do + extract_tar(new_resource.name, new_resource) +end + +action_class.class_eval do + def extract_tar(local_archive, r) + execute "extract #{local_archive}" do + flags = if r.tar_flags.is_a?(String) + r.tar_flags + else + r.tar_flags.join(' ') + end + command "tar xf#{r.compress_char} #{local_archive.shellescape} #{flags}" + cwd r.target_dir + creates r.creates + group r.group + user r.user + action (r.creates || r.not_if.any? || r.only_if.any? ? :run : :nothing) + end + end +end diff --git a/cookbooks/tar/resources/package.rb b/cookbooks/tar/resources/package.rb index 8a68386..dd75489 100644 --- a/cookbooks/tar/resources/package.rb +++ b/cookbooks/tar/resources/package.rb @@ -4,7 +4,7 @@ # # Author:: Nathan L Smith () # -# Copyright 2011, Cramer Development, Inc. +# Copyright:: 2011, Cramer Development, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,24 +19,49 @@ # limitations under the License. # -actions :install +attribute :source, String, name_attribute: true +attribute :headers, Hash, default: {} +attribute :prefix, String +attribute :source_directory, String, default: '/usr/local/src' +attribute :creates, String +attribute :configure_flags, Array, default: [] +attribute :archive_name, String +attribute :headers, Hash +attribute :use_etag, [TrueClass, FalseClass], default: true +attribute :use_last_modified, [TrueClass, FalseClass], default: true +attribute :atomic_update, [TrueClass, FalseClass], default: true +attribute :force_unlink, [TrueClass, FalseClass], default: false +attribute :manage_symlink_source, [TrueClass, FalseClass] -attribute :source, :kind_of => String, :name_attribute => true -attribute :headers, :kind_of => Hash, :default => {} -attribute :prefix, :kind_of => String -attribute :source_directory, :kind_of => String, :default => '/usr/local/src' -attribute :creates, :kind_of => String -attribute :configure_flags, :kind_of => Array, :default => [] -attribute :archive_name, :kind_of => String +action :install do + r = new_resource + basename = r.archive_name || ::File.basename(r.name) + dirname = basename.chomp('.tar.gz') # Assuming .tar.gz + src_dir = r.source_directory -version = Chef::Version.new(Chef::VERSION[/^(\d+\.\d+\.\d+)/, 1]) -if version.major > 11 || (version.major == 11 && version.minor >= 6) - attribute :headers, :kind_of => Hash, :default => nil - attribute :use_etag, :kind_of => [TrueClass, FalseClass], :default => true - attribute :use_last_modified, :kind_of => [TrueClass, FalseClass], :default => true - attribute :atomic_update, :kind_of => [TrueClass, FalseClass], :default => true - attribute :force_unlink, :kind_of => [TrueClass, FalseClass], :default => false - attribute :manage_symlink_source, :kind_of => [TrueClass, FalseClass], :default => nil + remote_file basename do + source r.name + path "#{src_dir}/#{basename}" + backup false + headers r.headers unless r.headers.nil? + use_etag r.use_etag + use_last_modified r.use_last_modified + atomic_update r.atomic_update + force_unlink r.force_unlink + manage_symlink_source r.manage_symlink_source + action :create_if_missing + end + + execute "extract #{basename}" do + command "tar xfz #{basename}" + cwd src_dir + creates "#{src_dir}/#{dirname}" + end + + execute "compile & install #{dirname}" do + flags = [r.prefix ? "--prefix=#{r.prefix}" : nil, *r.configure_flags].compact.join(' ') + command "./configure --quiet #{flags} && make --quiet && make --quiet install" + cwd "#{src_dir}/#{dirname}" + creates r.creates + end end - -default_action :install diff --git a/cookbooks/ufw/.foodcritic b/cookbooks/ufw/.foodcritic new file mode 100644 index 0000000..698ef4c --- /dev/null +++ b/cookbooks/ufw/.foodcritic @@ -0,0 +1 @@ +~FC003 diff --git a/cookbooks/ufw/CHANGELOG.md b/cookbooks/ufw/CHANGELOG.md index 6fc7246..03dceda 100644 --- a/cookbooks/ufw/CHANGELOG.md +++ b/cookbooks/ufw/CHANGELOG.md @@ -1,6 +1,21 @@ # ufw Cookbook CHANGELOG This file is used to list changes made in each version of the ufw cookbook. +## 3.1.0 (2017-03-02) +- Add use of the default['firewall']['allow_ssh'] attribute in the default recipe. Default for this cookbook is set to true, as the default recipe assumed that ssh would be enabled. + +## 3.0.0 (2017-03-01) +- Require Chef 12.4 (Depends on firewall which requires Chef 12.4+ at this point) +- Update default to remove installation of ufw which is duplication from firewall cookbook, and remove state changes + - Due to the change in default recipe, bumping major version in case this is breaking change for some. +- Added debian platform as firewall cookbook supports ufw on debian + +## 2.0.0 (2016-11-25) +- Add chef_version metadata + remove chef 11 compat +- Replace node.set with node.normal +- Require Chef 12.1 +- Fix the recipe to properly converge + ## v1.0.0 (12-14-2015) - Update to use / require the Firewall v2.0.0+ cookbook, which requires Chef 12 - Updated all Opscode references to Chef Software Inc. diff --git a/cookbooks/ufw/MAINTAINERS.md b/cookbooks/ufw/MAINTAINERS.md index c6a51ae..645ed14 100644 --- a/cookbooks/ufw/MAINTAINERS.md +++ b/cookbooks/ufw/MAINTAINERS.md @@ -1,19 +1,15 @@ # Maintainers -This file lists how this cookbook project is maintained. When making changes to the system, this -file tells you who needs to review your patch - you need a simple majority of maintainers -for the relevant subsystems to provide a :+1: on your pull request. Additionally, you need -to not receive a veto from a Lieutenant or the Project Lead. -Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) -for details on the process and how to become a maintainer or the project lead. +This file lists how this cookbook project is maintained. When making changes to the system, this file tells you who needs to review your patch - you need a review from an existing maintainer for the cookbook to provide a :+1: on your pull request. Additionally, you need to not receive a veto from a Lieutenant or the Project Lead. + +Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) for details on the process and how to become a maintainer or the project lead. # Project Maintainer * [Tim Smith](https://github.com/tas50) # Maintainers * [Jennifer Davis](https://github.com/sigje) -* [Sean OMeara](https://github.com/someara) * [Tim Smith](https://github.com/tas50) * [Thom May](https://github.com/thommay) diff --git a/cookbooks/ufw/README.md b/cookbooks/ufw/README.md index 4ce402d..ac7aee7 100644 --- a/cookbooks/ufw/README.md +++ b/cookbooks/ufw/README.md @@ -1,46 +1,53 @@ # Description + [![Build Status](https://travis-ci.org/chef-cookbooks/ufw.svg?branch=master)](http://travis-ci.org/chef-cookbooks/ufw) [![Cookbook Version](https://img.shields.io/cookbook/v/ufw.svg)](https://supermarket.chef.io/cookbooks/ufw) -Configures Uncomplicated Firewall (ufw) on Ubuntu. Including the `ufw` recipe in a run list means the firewall will be enabled and will deny everything except SSH and ICMP ping by default. +Configures Uncomplicated Firewall (ufw) on Ubuntu and Debian. Including the `ufw` recipe in a run list means the firewall will be enabled and will deny everything except SSH and ICMP ping by default. -Rules may be added to the node by adding them to the `['firewall']['rules']` attributes in roles or on the node directly. The `firewall` cookbook has an LWRP that may be used to apply rules directly from other recipes as well. There is no need to explicitly remove rules, they are reevaluated on changes and reset. Rules are applied in the order of the run list, unless ordering is explictly added. +Rules may be added to the node by adding them to the `['firewall']['rules']` attributes in roles or on the node directly. The `firewall` cookbook has an LWRP that may be used to apply rules directly from other recipes as well. There is no need to explicitly remove rules, they are reevaluated on changes and reset. Rules are applied in the order of the run list, unless ordering is explicitly added. ## Requirements + ### Platforms + - Ubuntu +- Debian ### Chef -- Chef 12+ -Since this cookbook has an open-ended dependency on 'firewall', users of Chef11 or earlier should pin 'firewall' to '~>0.9' via the caller's metadata. Otherwise 'poise' v2+ will be invoked which is Chef12+ only. +- Chef 12.4+ ### Cookbooks + - firewall 2.0+ ## Recipes -###default + +### default The `default` recipe looks for the list of firewall rules to apply from the `['firewall']['rules']` attribute added to roles and on the node itself. The list of rules is then applied to the node in the order specified. -###disable +### disable The `disable` recipe is used if there is a need to disable the existing firewall, perhaps for testing. It disables the ufw firewall even if other ufw recipes attempt to enable it. If you remove this recipe, the firewall does not get automatically re-enabled. You will need clear the value of the `['firewall']['state']` to force a recalculation of the firewall rules. This can be done with `knife node edit`. -###databag +### databag The `databag` recipe looks in the `firewall` data bag for to apply firewall rules based on inspecting the runlist for roles and recipe names for keys that map to the data bag items and are applied in the the order specified. -The `databag` recipe calls the `default` recipe after the `['firewall']['rules']` attribute is set to appy the rules, so you may mix roles with databag items if you want (roles apply first, then data bag contents). +The `databag` recipe calls the `default` recipe after the `['firewall']['rules']` attribute is set to apply the rules, so you may mix roles with databag items if you want (roles apply first, then data bag contents). -###recipes +### recipes -The `recipes` recipe applies firewall rules based on inspecting the runlist for recipes that have node[]['firewall']['rules'] attributes. These are appended to node['firewall']['rules'] and applied to the node. Cookbooks may define attributes for recipes like so: +The `recipes` recipe applies firewall rules based on inspecting the runlist for recipes that have node[ -### attributes/default.rb for test cookbook +]['firewall']['rules'] attributes. These are appended to node['firewall']['rules'] and applied to the node. Cookbooks may define attributes for recipes like so: -``` +#### attributes/default.rb for test cookbook + +```ruby default['test']['firewall']['rules'] = [ {"test"=> { "port"=> "27901", @@ -63,16 +70,17 @@ default['test::awesome']['firewall']['rules'] = [ Note that the 'test::awesome' rules are only applied if that specific recipe is in the runlist. Recipe-applied firewall rules are applied after any rules defined in role attributes. -### +### securitylevel -securitylevel The `securitylevel` recipe is used if there are any node['firewall']['securitylevel'] settings that need to be enforced. It is a reference implementation with nothing configured. +The `securitylevel` recipe is used if there are any node['firewall']['securitylevel'] settings that need to be enforced. It is a reference implementation with nothing configured. ## Attributes + Roles and the node may have the `['firewall']['rules']` attribute set. This attribute is a list of hashes, the key will be rule name, the value will be the hash of parameters. Application order is based on run list. ### Example Role -``` +```ruby name "fw_example" description "Firewall rules for Examples" override_attributes( @@ -108,12 +116,15 @@ override_attributes( ) ``` +* default['firewall']['allow_ssh'] Opens port 22 for SSH when set to true. Default set to true. + ## Data Bags + The `firewall` data bag may be used with the `databag` recipe. It will contain items that map to role names (eg. the 'apache' role will map to the 'apache' item in the 'firewall' data bag). Either roles or recipes may be keys (role[webserver] is 'webserver', recipe[apache2] is 'apache2'). If you have recipe-specific firewall rules, you will need to replace the '::' with '**' (double underscores) (eg. recipe[apache2::mod_ssl] is 'apache2**mod_ssl' in the data bag item). The items in the data bag will contain a 'rules' array of hashes to apply to the `['firewall']['rules']` attribute. -``` +```shell % knife data bag create firewall % knife data bag from file firewall examples/data_bags/firewall/apache2.json % knife data bag from file firewall examples/data_bags/firewall/apache2__mod_ssl.json @@ -121,7 +132,7 @@ The items in the data bag will contain a 'rules' array of hashes to apply to the ### Example 'firewall' data bag item -``` +```javascript { "id": "apache2", "rules": [ @@ -138,12 +149,14 @@ The items in the data bag will contain a 'rules' array of hashes to apply to the ``` ## Resources/Providers + The `firewall` cookbook provides the `firewall` and `firewall_rule` LWRPs, for which there is a ufw provider. ## License & Authors + **Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io)) -**Copyright:** 2011-2015, Chef Software, Inc. +**Copyright:** 2011-2014, Chef Software, Inc. ``` Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/cookbooks/ufw/attributes/default.rb b/cookbooks/ufw/attributes/default.rb index 3f2e6d4..44a9aea 100644 --- a/cookbooks/ufw/attributes/default.rb +++ b/cookbooks/ufw/attributes/default.rb @@ -1,2 +1,3 @@ default['firewall']['rules'] = [] default['firewall']['securitylevel'] = '' +default['firewall']['allow_ssh'] = true diff --git a/cookbooks/ufw/metadata.json b/cookbooks/ufw/metadata.json index eb0fdf0..717bd6c 100644 --- a/cookbooks/ufw/metadata.json +++ b/cookbooks/ufw/metadata.json @@ -1 +1 @@ -{"name":"ufw","version":"1.0.0","description":"Installs and configures Uncomplicated Firewall (ufw)","long_description":"# Description\n[![Build Status](https://travis-ci.org/chef-cookbooks/ufw.svg?branch=master)](http://travis-ci.org/chef-cookbooks/ufw) [![Cookbook Version](https://img.shields.io/cookbook/v/ufw.svg)](https://supermarket.chef.io/cookbooks/ufw)\n\nConfigures Uncomplicated Firewall (ufw) on Ubuntu. Including the `ufw` recipe in a run list means the firewall will be enabled and will deny everything except SSH and ICMP ping by default.\n\nRules may be added to the node by adding them to the `['firewall']['rules']` attributes in roles or on the node directly. The `firewall` cookbook has an LWRP that may be used to apply rules directly from other recipes as well. There is no need to explicitly remove rules, they are reevaluated on changes and reset. Rules are applied in the order of the run list, unless ordering is explictly added.\n\n## Requirements\n### Platforms\n- Ubuntu\n\n### Chef\n- Chef 12+\n\nSince this cookbook has an open-ended dependency on 'firewall', users of Chef11 or earlier should pin 'firewall' to '~>0.9' via the caller's metadata. Otherwise 'poise' v2+ will be invoked which is Chef12+ only.\n\n### Cookbooks\n- firewall 2.0+\n\n## Recipes\n###default\n\nThe `default` recipe looks for the list of firewall rules to apply from the `['firewall']['rules']` attribute added to roles and on the node itself. The list of rules is then applied to the node in the order specified.\n\n###disable\n\nThe `disable` recipe is used if there is a need to disable the existing firewall, perhaps for testing. It disables the ufw firewall even if other ufw recipes attempt to enable it.\n\nIf you remove this recipe, the firewall does not get automatically re-enabled. You will need clear the value of the `['firewall']['state']` to force a recalculation of the firewall rules. This can be done with `knife node edit`.\n\n###databag\n\nThe `databag` recipe looks in the `firewall` data bag for to apply firewall rules based on inspecting the runlist for roles and recipe names for keys that map to the data bag items and are applied in the the order specified.\n\nThe `databag` recipe calls the `default` recipe after the `['firewall']['rules']` attribute is set to appy the rules, so you may mix roles with databag items if you want (roles apply first, then data bag contents).\n\n###recipes\n\nThe `recipes` recipe applies firewall rules based on inspecting the runlist for recipes that have node[]['firewall']['rules'] attributes. These are appended to node['firewall']['rules'] and applied to the node. Cookbooks may define attributes for recipes like so:\n\n### attributes/default.rb for test cookbook\n\n```\ndefault['test']['firewall']['rules'] = [\n {\"test\"=> {\n \"port\"=> \"27901\",\n \"protocol\"=> \"udp\"\n }\n }\n]\ndefault['test::awesome']['firewall']['rules'] = [\n {\"awesome\"=> {\n \"port\"=> \"99427\",\n \"protocol\"=> \"udp\"\n }\n },\n {\"awesome2\"=> {\n \"port\"=> \"99428\"\n }\n }\n]\n```\n\nNote that the 'test::awesome' rules are only applied if that specific recipe is in the runlist. Recipe-applied firewall rules are applied after any rules defined in role attributes.\n\n###\n\nsecuritylevel The `securitylevel` recipe is used if there are any node['firewall']['securitylevel'] settings that need to be enforced. It is a reference implementation with nothing configured.\n\n## Attributes\nRoles and the node may have the `['firewall']['rules']` attribute set. This attribute is a list of hashes, the key will be rule name, the value will be the hash of parameters. Application order is based on run list.\n\n### Example Role\n\n```\nname \"fw_example\"\ndescription \"Firewall rules for Examples\"\noverride_attributes(\n \"firewall\" => {\n \"rules\" => [\n {\"tftp\" => {}},\n {\"http\" => {\n \"port\" => \"80\"\n }\n },\n {\"block tomcat from 192.168.1.0/24\" => {\n \"port\" => \"8080\",\n \"source\" => \"192.168.1.0/24\",\n \"action\" => \"deny\"\n }\n },\n {\"Allow access to udp 1.2.3.4 port 5469 from 1.2.3.5 port 5469\" => {\n \"protocol\" => \"udp\",\n \"port\" => \"5469\",\n \"source\" => \"1.2.3.4\",\n \"destination\" => \"1.2.3.5\",\n \"dest_port\" => \"5469\"\n }\n },\n {\"allow to tcp ports 8000-8010 from 192.168.1.0/24\" => {\n \"port_range\" => \"8000..8010\",\n \"source\" => \"192.168.1.0/24\",\n \"protocol\" => \"tcp\" //protocol is mandatory when using port ranges\n }\n }\n ]\n }\n )\n```\n\n## Data Bags\nThe `firewall` data bag may be used with the `databag` recipe. It will contain items that map to role names (eg. the 'apache' role will map to the 'apache' item in the 'firewall' data bag). Either roles or recipes may be keys (role[webserver] is 'webserver', recipe[apache2] is 'apache2'). If you have recipe-specific firewall rules, you will need to replace the '::' with '**' (double underscores) (eg. recipe[apache2::mod_ssl] is 'apache2**mod_ssl' in the data bag item).\n\nThe items in the data bag will contain a 'rules' array of hashes to apply to the `['firewall']['rules']` attribute.\n\n```\n% knife data bag create firewall\n% knife data bag from file firewall examples/data_bags/firewall/apache2.json\n% knife data bag from file firewall examples/data_bags/firewall/apache2__mod_ssl.json\n```\n\n### Example 'firewall' data bag item\n\n```\n{\n \"id\": \"apache2\",\n \"rules\": [\n {\"http\": {\n \"port\": \"80\"\n }},\n {\"block http from 192.168.1.0/24\": {\n \"port\": \"80\",\n \"source\": \"192.168.1.0/24\",\n \"action\": \"deny\"\n }}\n ]\n}\n```\n\n## Resources/Providers\nThe `firewall` cookbook provides the `firewall` and `firewall_rule` LWRPs, for which there is a ufw provider.\n\n## License & Authors\n**Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io))\n\n**Copyright:** 2011-2015, Chef Software, Inc.\n\n```\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{"ubuntu":">= 0.0.0"},"dependencies":{"firewall":">= 2.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{"firewall/rules":{"display_name":"List of firewall rules for the node.","description":"List of firewall rules for the node. Possibly set by node, roles or data bags.","type":"array"},"firewall/securitylevel":{"display_name":"Security level of the node.","description":"Security level of the node, may be set by node, roles or environment."}},"groupings":{},"recipes":{}} \ No newline at end of file +{"name":"ufw","version":"3.1.0","description":"Installs and configures Uncomplicated Firewall (ufw)","long_description":"# Description\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/ufw.svg?branch=master)](http://travis-ci.org/chef-cookbooks/ufw) [![Cookbook Version](https://img.shields.io/cookbook/v/ufw.svg)](https://supermarket.chef.io/cookbooks/ufw)\n\nConfigures Uncomplicated Firewall (ufw) on Ubuntu and Debian. Including the `ufw` recipe in a run list means the firewall will be enabled and will deny everything except SSH and ICMP ping by default.\n\nRules may be added to the node by adding them to the `['firewall']['rules']` attributes in roles or on the node directly. The `firewall` cookbook has an LWRP that may be used to apply rules directly from other recipes as well. There is no need to explicitly remove rules, they are reevaluated on changes and reset. Rules are applied in the order of the run list, unless ordering is explicitly added.\n\n## Requirements\n\n### Platforms\n\n- Ubuntu\n- Debian\n\n### Chef\n\n- Chef 12.4+\n\n### Cookbooks\n\n- firewall 2.0+\n\n## Recipes\n\n### default\n\nThe `default` recipe looks for the list of firewall rules to apply from the `['firewall']['rules']` attribute added to roles and on the node itself. The list of rules is then applied to the node in the order specified.\n\n### disable\n\nThe `disable` recipe is used if there is a need to disable the existing firewall, perhaps for testing. It disables the ufw firewall even if other ufw recipes attempt to enable it.\n\nIf you remove this recipe, the firewall does not get automatically re-enabled. You will need clear the value of the `['firewall']['state']` to force a recalculation of the firewall rules. This can be done with `knife node edit`.\n\n### databag\n\nThe `databag` recipe looks in the `firewall` data bag for to apply firewall rules based on inspecting the runlist for roles and recipe names for keys that map to the data bag items and are applied in the the order specified.\n\nThe `databag` recipe calls the `default` recipe after the `['firewall']['rules']` attribute is set to apply the rules, so you may mix roles with databag items if you want (roles apply first, then data bag contents).\n\n### recipes\n\nThe `recipes` recipe applies firewall rules based on inspecting the runlist for recipes that have node[\n\n]['firewall']['rules'] attributes. These are appended to node['firewall']['rules'] and applied to the node. Cookbooks may define attributes for recipes like so:\n\n#### attributes/default.rb for test cookbook\n\n```ruby\ndefault['test']['firewall']['rules'] = [\n {\"test\"=> {\n \"port\"=> \"27901\",\n \"protocol\"=> \"udp\"\n }\n }\n]\ndefault['test::awesome']['firewall']['rules'] = [\n {\"awesome\"=> {\n \"port\"=> \"99427\",\n \"protocol\"=> \"udp\"\n }\n },\n {\"awesome2\"=> {\n \"port\"=> \"99428\"\n }\n }\n]\n```\n\nNote that the 'test::awesome' rules are only applied if that specific recipe is in the runlist. Recipe-applied firewall rules are applied after any rules defined in role attributes.\n\n### securitylevel\n\nThe `securitylevel` recipe is used if there are any node['firewall']['securitylevel'] settings that need to be enforced. It is a reference implementation with nothing configured.\n\n## Attributes\n\nRoles and the node may have the `['firewall']['rules']` attribute set. This attribute is a list of hashes, the key will be rule name, the value will be the hash of parameters. Application order is based on run list.\n\n### Example Role\n\n```ruby\nname \"fw_example\"\ndescription \"Firewall rules for Examples\"\noverride_attributes(\n \"firewall\" => {\n \"rules\" => [\n {\"tftp\" => {}},\n {\"http\" => {\n \"port\" => \"80\"\n }\n },\n {\"block tomcat from 192.168.1.0/24\" => {\n \"port\" => \"8080\",\n \"source\" => \"192.168.1.0/24\",\n \"action\" => \"deny\"\n }\n },\n {\"Allow access to udp 1.2.3.4 port 5469 from 1.2.3.5 port 5469\" => {\n \"protocol\" => \"udp\",\n \"port\" => \"5469\",\n \"source\" => \"1.2.3.4\",\n \"destination\" => \"1.2.3.5\",\n \"dest_port\" => \"5469\"\n }\n },\n {\"allow to tcp ports 8000-8010 from 192.168.1.0/24\" => {\n \"port_range\" => \"8000..8010\",\n \"source\" => \"192.168.1.0/24\",\n \"protocol\" => \"tcp\" //protocol is mandatory when using port ranges\n }\n }\n ]\n }\n )\n```\n\n* default['firewall']['allow_ssh'] Opens port 22 for SSH when set to true. Default set to true.\n\n## Data Bags\n\nThe `firewall` data bag may be used with the `databag` recipe. It will contain items that map to role names (eg. the 'apache' role will map to the 'apache' item in the 'firewall' data bag). Either roles or recipes may be keys (role[webserver] is 'webserver', recipe[apache2] is 'apache2'). If you have recipe-specific firewall rules, you will need to replace the '::' with '**' (double underscores) (eg. recipe[apache2::mod_ssl] is 'apache2**mod_ssl' in the data bag item).\n\nThe items in the data bag will contain a 'rules' array of hashes to apply to the `['firewall']['rules']` attribute.\n\n```shell\n% knife data bag create firewall\n% knife data bag from file firewall examples/data_bags/firewall/apache2.json\n% knife data bag from file firewall examples/data_bags/firewall/apache2__mod_ssl.json\n```\n\n### Example 'firewall' data bag item\n\n```javascript\n{\n \"id\": \"apache2\",\n \"rules\": [\n {\"http\": {\n \"port\": \"80\"\n }},\n {\"block http from 192.168.1.0/24\": {\n \"port\": \"80\",\n \"source\": \"192.168.1.0/24\",\n \"action\": \"deny\"\n }}\n ]\n}\n```\n\n## Resources/Providers\n\nThe `firewall` cookbook provides the `firewall` and `firewall_rule` LWRPs, for which there is a ufw provider.\n\n## License & Authors\n\n**Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io))\n\n**Copyright:** 2011-2014, Chef Software, Inc.\n\n```\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{"ubuntu":">= 0.0.0"},"dependencies":{"firewall":">= 2.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{},"source_url":"https://github.com/chef-cookbooks/ufw","issues_url":"https://github.com/chef-cookbooks/ufw/issues","chef_version":">= 12.4","ohai_version":{}} \ No newline at end of file diff --git a/cookbooks/ufw/recipes/databag.rb b/cookbooks/ufw/recipes/databag.rb index 66bcad0..fbebae1 100644 --- a/cookbooks/ufw/recipes/databag.rb +++ b/cookbooks/ufw/recipes/databag.rb @@ -1,9 +1,9 @@ # # Author:: Matt Ray -# Cookbook Name:: ufw +# Cookbook:: ufw # Recipe:: databag # -# Copyright 2011-2015, Chef Software, Inc. +# Copyright:: 2011-2017, 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. @@ -51,7 +51,7 @@ rlist.each do |entry| # add the list of firewall rules to the current list item = data_bag_item('firewall', entry) rules = item['rules'] - node.set['firewall']['rules'].concat(rules) unless rules.nil? + node.normal['firewall']['rules'].concat(rules) unless rules.nil? end # now go apply the rules diff --git a/cookbooks/ufw/recipes/default.rb b/cookbooks/ufw/recipes/default.rb index 4e3c0d9..f67c889 100644 --- a/cookbooks/ufw/recipes/default.rb +++ b/cookbooks/ufw/recipes/default.rb @@ -1,9 +1,9 @@ # # Author:: Matt Ray -# Cookbook Name:: ufw +# Cookbook:: ufw # Recipe:: default # -# Copyright 2011-2015, Chef Software, Inc. +# Copyright:: 2011-2017, 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. @@ -18,73 +18,54 @@ # limitations under the License. # -package 'ufw' +firewall 'default' do + action :install +end -old_state = node['firewall']['state'] -new_state = node['firewall']['rules'].to_s -Chef::Log.debug "Old firewall state:#{old_state}" -Chef::Log.debug "New firewall state:#{new_state}" +# leave this on by default +firewall_rule 'ssh' do + port 22 + action :create + only_if { node['firewall']['allow_ssh'] } +end -# check to see if the firewall rules changed. -# the rules are always changed the first run -if old_state == new_state - Chef::Log.info 'Firewall rules unchanged.' -else - Chef::Log.info 'Firewall rules updated.' - node.set['firewall']['state'] = new_state - - # drop rules and re-enable - execute 'ufw --force reset' - - firewall 'ufw' do - action :install - end - - # leave this on by default - firewall_rule 'ssh' do - port 22 - action :create - end - - node['firewall']['rules'].each do |rule_mash| - Chef::Log.debug "ufw:rule \"#{rule_mash}\"" - rule_mash.keys.each do |rule| - Chef::Log.debug "ufw:rule:name \"#{rule}\"" - params = rule_mash[rule] - Chef::Log.debug "ufw:rule:parameters \"#{params}\"" - Chef::Log.debug "ufw:rule:name #{params['name']}" if params['name'] - Chef::Log.debug "ufw:rule:protocol #{params['protocol']}" if params['protocol'] - Chef::Log.debug "ufw:rule:direction #{params['direction']}" if params['direction'] - Chef::Log.debug "ufw:rule:interface #{params['interface']}" if params['interface'] - Chef::Log.debug "ufw:rule:logging #{params['logging']}" if params['logging'] - Chef::Log.debug "ufw:rule:port #{params['port']}" if params['port'] - Chef::Log.debug "ufw:rule:port_range #{params['port_range']}" if params['port_range'] - Chef::Log.debug "ufw:rule:source #{params['source']}" if params['source'] - Chef::Log.debug "ufw:rule:destination #{params['destination']}" if params['destination'] - Chef::Log.debug "ufw:rule:dest_port #{params['dest_port']}" if params['dest_port'] - Chef::Log.debug "ufw:rule:position #{params['position']}" if params['position'] - act = params['action'] - act ||= 'create' - fail 'ufw: port_range was specified to firewall_rule without protocol' if params['port_range'] && !params['protocol'] - Chef::Log.debug "ufw:rule:action :#{act}" - firewall_rule rule do - name params['name'] if params['name'] - protocol params['protocol'].to_sym if params['protocol'] - direction params['direction'].to_sym if params['direction'] - interface params['interface'] if params['interface'] - logging params['logging'].to_sym if params['logging'] - port params['port'].to_i if params['port'] - if params['port_range'] - ends = params['port_range'].split('..').map { |d| Integer(d) } - port_range ends[0]..ends[1] - end - source params['source'] if params['source'] - destination params['destination'] if params['destination'] - dest_port params['dest_port'].to_i if params['dest_port'] - position params['position'].to_i if params['position'] - action act +node['firewall']['rules'].each do |rule_mash| + Chef::Log.debug "ufw:rule \"#{rule_mash}\"" + rule_mash.keys.each do |rule| + Chef::Log.debug "ufw:rule:name \"#{rule}\"" + params = rule_mash[rule] + Chef::Log.debug "ufw:rule:parameters \"#{params}\"" + Chef::Log.debug "ufw:rule:name #{params['name']}" if params['name'] + Chef::Log.debug "ufw:rule:protocol #{params['protocol']}" if params['protocol'] + Chef::Log.debug "ufw:rule:direction #{params['direction']}" if params['direction'] + Chef::Log.debug "ufw:rule:interface #{params['interface']}" if params['interface'] + Chef::Log.debug "ufw:rule:logging #{params['logging']}" if params['logging'] + Chef::Log.debug "ufw:rule:port #{params['port']}" if params['port'] + Chef::Log.debug "ufw:rule:port_range #{params['port_range']}" if params['port_range'] + Chef::Log.debug "ufw:rule:source #{params['source']}" if params['source'] + Chef::Log.debug "ufw:rule:destination #{params['destination']}" if params['destination'] + Chef::Log.debug "ufw:rule:dest_port #{params['dest_port']}" if params['dest_port'] + Chef::Log.debug "ufw:rule:position #{params['position']}" if params['position'] + act = params['action'] + act ||= 'create' + raise 'ufw: port_range was specified to firewall_rule without protocol' if params['port_range'] && !params['protocol'] + Chef::Log.debug "ufw:rule:action :#{act}" + firewall_rule rule do + name params['name'] if params['name'] + protocol params['protocol'].to_sym if params['protocol'] + direction params['direction'].to_sym if params['direction'] + interface params['interface'] if params['interface'] + logging params['logging'].to_sym if params['logging'] + port params['port'].to_i if params['port'] + if params['port_range'] + ends = params['port_range'].split('..').map { |d| Integer(d) } + port_range ends[0]..ends[1] end + source params['source'] if params['source'] + destination params['destination'] if params['destination'] + dest_port params['dest_port'].to_i if params['dest_port'] + position params['position'].to_i if params['position'] + action act end end - end diff --git a/cookbooks/ufw/recipes/disable.rb b/cookbooks/ufw/recipes/disable.rb index 6718bc6..c0261fe 100644 --- a/cookbooks/ufw/recipes/disable.rb +++ b/cookbooks/ufw/recipes/disable.rb @@ -1,9 +1,9 @@ # # Author:: Matt Ray -# Cookbook Name:: ufw +# Cookbook:: ufw # Recipe:: disable # -# Copyright 2011-2015, Chef Software, Inc. +# Copyright:: 2011-2017, 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/cookbooks/ufw/recipes/recipes.rb b/cookbooks/ufw/recipes/recipes.rb index dd03425..1cd634c 100644 --- a/cookbooks/ufw/recipes/recipes.rb +++ b/cookbooks/ufw/recipes/recipes.rb @@ -1,9 +1,9 @@ # # Author:: Matt Ray -# Cookbook Name:: ufw +# Cookbook:: ufw # Recipe:: recipes # -# Copyright 2011-2015, Chef Software, Inc. +# Copyright:: 2011-2017, 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. @@ -27,14 +27,14 @@ node.expand!.recipes.each do |recipe| if recipe != cookbook && node[cookbook] && node[cookbook]['firewall'] && node[cookbook]['firewall']['rules'] rules = node[cookbook]['firewall']['rules'] Chef::Log.debug "ufw::recipes:#{cookbook}:rules #{rules}" - node.set['firewall']['rules'].concat(rules) unless rules.nil? + node.normal['firewall']['rules'].concat(rules) unless rules.nil? end # get the recipe attributes if there are any next unless node[recipe] && node[recipe]['firewall'] && node[recipe]['firewall']['rules'] rules = node[recipe]['firewall']['rules'] Chef::Log.debug "ufw::recipes:#{recipe}:rules #{rules}" - node.set['firewall']['rules'].concat(rules) unless rules.nil? + node.normal['firewall']['rules'].concat(rules) unless rules.nil? end # now go apply the rules diff --git a/cookbooks/ufw/recipes/securitylevel.rb b/cookbooks/ufw/recipes/securitylevel.rb index bfc2ad2..524ac9b 100644 --- a/cookbooks/ufw/recipes/securitylevel.rb +++ b/cookbooks/ufw/recipes/securitylevel.rb @@ -1,9 +1,9 @@ # # Author:: Matt Ray -# Cookbook Name:: ufw +# Cookbook:: ufw # Recipe:: securitylevel # -# Copyright 2011-2015, Chef Software, Inc. +# Copyright:: 2011-2017, 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. @@ -25,17 +25,17 @@ Chef::Log.info "ufw::securitylevel:#{securitylevel}" # verify that only 1 "color" security group is applied" count = node.expand!.roles.count { |role| role =~ /SecurityLevel-(Red|Green|Yellow)/ } if count > 1 - fail Chef::Exceptions::AmbiguousRunlistSpecification, "conflicting SecurityLevel-'color' roles, only 1 may be applied." + raise Chef::Exceptions::AmbiguousRunlistSpecification, "conflicting SecurityLevel-'color' roles, only 1 may be applied." end -case securitylevel -when 'red' - # put special stuff for red here -when 'yellow' - # put special stuff for red here -when 'green' - # put special stuff for red here -end +# case securitylevel +# when 'red' +# # put special stuff for red here +# when 'yellow' +# # put special stuff for red here +# when 'green' +# # put special stuff for red here +# end # now go apply the rules include_recipe 'ufw::default' diff --git a/cookbooks/users/.foodcritic b/cookbooks/users/.foodcritic new file mode 100644 index 0000000..698ef4c --- /dev/null +++ b/cookbooks/users/.foodcritic @@ -0,0 +1 @@ +~FC003 diff --git a/cookbooks/users/CHANGELOG.md b/cookbooks/users/CHANGELOG.md index 14f0a03..ecde6bd 100644 --- a/cookbooks/users/CHANGELOG.md +++ b/cookbooks/users/CHANGELOG.md @@ -1,13 +1,36 @@ # users Cookbook CHANGELOG This file is used to list changes made in each version of the users cookbook. +## 4.0.3 (2016-11-23) +- Update manage provider to return true/false in guard block which avoids warnings during run on Chef 12.14+ + +## 4.0.2 (2016-11-18) +- Deprecate the sysadmins recipe + +## 4.0.1 (2016-09-15) +- Fix creation of user home directory + +## 4.0.0 (2016-09-15) +- Add chef_version to the metadata +- Require Chef 12.1+ +- Testing updates +- Fixed compatibility with Chef 12.14 +- Properly define the Chefspec matcher +- Add a warning if someone includes users::default since that does nothing + +## v3.0.0 +- @onlyhavecans - Fix FreeBSD support +- @stem - Fix user creation on Mac OS X on 10.7 and 10.8 +- Remove old style chef solo code to clean up rubocop issues, move to using cookstyle +- Adding zlinux support + ## v2.0.3 -- ([@nkadel-skyhook][]) - create .ssh directory only if keys are configured. -- ([@signe][]) - allow force parameter to be specified for users configured to be removed. -- ([@FlorentFlament][]) - adding the ability to manage groups for existing users. +- @nkadel-skyhook - create .ssh directory only if keys are configured. +- @signe - allow force parameter to be specified for users configured to be removed. +- @FlorentFlament - adding the ability to manage groups for existing users. ## v2.0.2 (2016-1-25) -- ([@375gnu][]) - validate uid/gid for strings versus numeric +- @375gnu- validate uid/gid for strings versus numeric - fix rubocop errors based on https://github.com/bbatsov/rubocop/issues/2608 - fix kitchen configurations for testing diff --git a/cookbooks/users/MAINTAINERS.md b/cookbooks/users/MAINTAINERS.md index c6a51ae..03c819f 100644 --- a/cookbooks/users/MAINTAINERS.md +++ b/cookbooks/users/MAINTAINERS.md @@ -1,19 +1,15 @@ # Maintainers -This file lists how this cookbook project is maintained. When making changes to the system, this -file tells you who needs to review your patch - you need a simple majority of maintainers -for the relevant subsystems to provide a :+1: on your pull request. Additionally, you need -to not receive a veto from a Lieutenant or the Project Lead. -Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) -for details on the process and how to become a maintainer or the project lead. +This file lists how this cookbook project is maintained. When making changes to the system, this file tells you who needs to review your patch - you need a review from an existing maintainer for the cookbook to provide a :+1: on your pull request. Additionally, you need to not receive a veto from a Lieutenant or the Project Lead. + +Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) for details on the process and how to become a maintainer or the project lead. # Project Maintainer -* [Tim Smith](https://github.com/tas50) +* [Jennifer Davis](https://github.com/sigje) # Maintainers * [Jennifer Davis](https://github.com/sigje) -* [Sean OMeara](https://github.com/someara) * [Tim Smith](https://github.com/tas50) * [Thom May](https://github.com/thommay) diff --git a/cookbooks/users/README.md b/cookbooks/users/README.md index 9a866a6..73979f1 100644 --- a/cookbooks/users/README.md +++ b/cookbooks/users/README.md @@ -1,4 +1,5 @@ # users Cookbook + [![Build Status](https://travis-ci.org/chef-cookbooks/users.svg?branch=master)](http://travis-ci.org/chef-cookbooks/users) [![Cookbook Version](https://img.shields.io/cookbook/v/users.svg)](https://supermarket.chef.io/cookbooks/users) Manages OS users from databags. @@ -13,22 +14,24 @@ A data bag populated with user objects must exist. The default data bag in this ### Chef -- Chef 11+ +- Chef 12.1+ ### Platform Support The following platforms have been tested with Test Kitchen: - Debian / Ubuntu and derivatives -- RHEL and derivatives -- Fedora +- RHEL and derivatives +- Fedora - FreeBSD / OpenBSD - Mac OS X ### Cookbook Dependencies + - none ## Usage + To use the resource `users_manage`, make sure to add the dependency on the users cookbook by the following line to your wrapper cookbook's [metadata.rb](https://docs.chef.io/config_rb_metadata.html): ``` @@ -46,7 +49,7 @@ Then in a recipe: ```ruby users_manage 'GROUPNAME' do group_id GROUPID - action [:remove, :create] + action [:create] data_bag 'DATABAG_NAME' end ``` @@ -56,7 +59,7 @@ Example: ```ruby users_manage 'testgroup' do group_id 3000 - action [:remove, :create] + action [:create] data_bag 'test_home_dir' end ``` @@ -82,23 +85,22 @@ A sample user object in a users databag would look like: } ``` -### Databag Key Definitions +### Databag Key Definitions -* `id`: *String* specifies the username, as well as the data bag object id. -* `password`: *String* specifies the user's password. -* `ssh_keys`: *Array* an array of authorized keys that will be managed by Chef to the user's home directory in .ssh/authorized_keys -* `groups`: *Array* an array of groups that the user will be added to -* `uid`: *Integer* a unique identifier for the user -* `shell`: *String* the user's shell -* `comment`:*String* the [GECOS field](https://en.wikipedia.org/wiki/Gecos_field), generally the User's full name. +- `id`: _String_ specifies the username, as well as the data bag object id. +- `password`: _String_ specifies the user's password. +- `ssh_keys`: _Array_ an array of authorized keys that will be managed by Chef to the user's home directory in .ssh/authorized_keys +- `groups`: _Array_ an array of groups that the user will be added to +- `uid`: _Integer_ a unique identifier for the user +- `shell`: _String_ the user's shell +- `comment`:_String_ the [GECOS field](https://en.wikipedia.org/wiki/Gecos_field), generally the User's full name. Other potential fields: -* `home`: *String* User's home directory. If not assigned, will be set based on platform and username. -* `action`: *String* Supported actions are one's supported by the [user](https://docs.chef.io/resource_user.html#actions) resource. If not specified, the default action is `create`. -* `ssh_private_key`: *String* manages user's private key generally ~/.ssh/id_* -* `ssh_public_key`: *String* manages user's public key generally ~/.ssh/id_*.pub - +- `home`: _String_ User's home directory. If not assigned, will be set based on platform and username. +- `action`: _String_ Supported actions are one's supported by the [user](https://docs.chef.io/resource_user.html#actions) resource. If not specified, the default action is `create`. +- `ssh_private_key`: _String_ manages user's private key generally ~/.ssh/id_* +- `ssh_public_key`: _String_ manages user's public key generally ~/.ssh/id_*.pub ## Resources Overview @@ -113,26 +115,26 @@ Creates the `sysadmin` group and users defined in the `users` databag. ```ruby users_manage 'sysadmin' do group_id 2300 - action [:remove, :create] + action [:create] end ``` -Removes, then creates the `testgroup` group, and users defined in the `test_home_dir` databag. +Creates the `testgroup` group, and users defined in the `test_home_dir` databag. ```ruby users_manage 'testgroup' do group_id 3000 - action [:remove, :create] + action [:create] data_bag 'test_home_dir' end ``` -Removes, then creates the `nfsgroup` group, and users defined in the `test_home_dir` databag and does not manage nfs home directories. +Creates the `nfsgroup` group, and users defined in the `test_home_dir` databag and does not manage nfs home directories. ```ruby users_manage 'nfsgroup' do group_id 4000 - action [:remove, :create] + action [:create] data_bag 'test_home_dir' manage_nfs_home_dirs false end @@ -140,17 +142,21 @@ end #### Parameters -* `data_bag` *String* is the data bag to search -* `search_group` *String* groups name to search for, defaults to resource name -* `group_name` *String* name of the group to create, defaults to resource name -* `group_id` *Integer* numeric id of the group to create, default is to allow the OS to pick next -* `cookbook` *String* name of the cookbook that the authorized_keys template should be found in -* `manage_nfs_home_dirs` *Boolean* whether to manage nfs home directories. +- `data_bag` _String_ is the data bag to search +- `search_group` _String_ groups name to search for, defaults to resource name +- `group_name` _String_ name of the group to create, defaults to resource name +- `group_id` _Integer_ numeric id of the group to create, default is to allow the OS to pick next +- `cookbook` _String_ name of the cookbook that the authorized_keys template should be found in +- `manage_nfs_home_dirs` _Boolean_ whether to manage nfs home directories. Otherwise, this cookbook is specific for setting up `sysadmin` group and users with the sysadmins recipe for now. ## Recipe Overview +### Deprecation Notice + +This recipe has been deprecated and the resource will be removed from the recipe in a new major release of this cookbook in April 2017\. The functionality can easily be recreated and changed to suit your organization by copying the single resource below into your own cookbook. + `sysadmins.rb`: recipe that manages the group sysadmins with group id 2300, and adds users to this group. To use: @@ -164,15 +170,15 @@ The recipe is defined as follows: ```ruby users_manage "sysadmin" do group_id 2300 - action [ :remove, :create ] + action [ :create ] end ``` This `users_manage` resource searches the `users` data bag for the `sysadmin` group attribute, and adds those users to a Unix security group `sysadmin`. The only required attribute is group_id, which represents the numeric Unix gid and _must_ be unique. The default action for the resource is `:create`. -The recipe, by default, will also create the sysadmin group. The sysadmin group will be created with GID 2300. This may become an attribute at a later date. +The recipe, by default, will also create the sysadmin group. The sysadmin group will be created with GID 2300. -## Data bag Overview +## Data bag Overview **Reminder** Data bags generally should not be stored in cookbooks, but in a policy repo within your organization. Data bags are useful across cookbooks, not just for a single cookbook. @@ -289,14 +295,12 @@ $ mkdir data_bags/users $EDITOR data_bags/users/bofh.json ``` -Paste the user's public SSH key into the ssh_keys value. Also make sure the uid is unique, and if you're not using bash, that the shell is installed. +Paste the user's public SSH key into the ssh_keys value. Also make sure the uid is unique, and if you're not using bash, that the shell is installed. The Apache cookbook can set up authentication using OpenIDs, which is set up using the openid key here. See the Chef Software 'apache2' cookbook for more information about this. -## Chef Solo -As of version 1.4.0, this cookbook might work with Chef Solo when using [chef-solo-search by edelight](https://github.com/edelight/chef-solo-search). That cookbook is not a dependency of this one as Chef solo doesn't support dependency resolution using cookbook metadata - all cookbooks must be provided to the node manually when using Chef Solo. - ## License & Authors + **Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io)) **Copyright:** 2009-2016, Chef Software, Inc. diff --git a/cookbooks/users/libraries/matchers.rb b/cookbooks/users/libraries/matchers.rb index 1070fd7..9b3226e 100644 --- a/cookbooks/users/libraries/matchers.rb +++ b/cookbooks/users/libraries/matchers.rb @@ -1,6 +1,6 @@ -# Matchers for chefspec 3 - if defined?(ChefSpec) + ChefSpec.define_matcher :users_manage + def create_users_manage(resource_name) ChefSpec::Matchers::ResourceMatcher.new(:users_manage, :create, diff --git a/cookbooks/users/metadata.json b/cookbooks/users/metadata.json index deac531..260994b 100644 --- a/cookbooks/users/metadata.json +++ b/cookbooks/users/metadata.json @@ -1 +1 @@ -{"name":"users","version":"2.0.3","description":"Creates users from a databag search","long_description":"# users Cookbook\n[![Build Status](https://travis-ci.org/chef-cookbooks/users.svg?branch=master)](http://travis-ci.org/chef-cookbooks/users) [![Cookbook Version](https://img.shields.io/cookbook/v/users.svg)](https://supermarket.chef.io/cookbooks/users)\n\nManages OS users from databags.\n\n## Scope\n\nThis cookbook is concerned with the management of OS users and groups from databags. It also manages the distribution of ssh keys to a user's home directory.\n\n## Requirements\n\nA data bag populated with user objects must exist. The default data bag in this recipe is `users`. See USAGE.\n\n### Chef\n\n- Chef 11+\n\n### Platform Support\n\nThe following platforms have been tested with Test Kitchen:\n\n- Debian / Ubuntu and derivatives\n- RHEL and derivatives \n- Fedora \n- FreeBSD / OpenBSD\n- Mac OS X\n\n### Cookbook Dependencies\n- none\n\n## Usage\nTo use the resource `users_manage`, make sure to add the dependency on the users cookbook by the following line to your wrapper cookbook's [metadata.rb](https://docs.chef.io/config_rb_metadata.html):\n\n```\ndepends 'users'\n```\n\nor to pin to a specific version of the users cookbook, in this case any version of 2.X:\n\n```\ndepends 'users', '~> 2'\n```\n\nThen in a recipe:\n\n```ruby\nusers_manage 'GROUPNAME' do\n group_id GROUPID\n action [:remove, :create]\n data_bag 'DATABAG_NAME'\nend\n```\n\nExample:\n\n```ruby\nusers_manage 'testgroup' do\n group_id 3000\n action [:remove, :create]\n data_bag 'test_home_dir'\nend\n```\n\n**Note**: If you do not specify the data_bag, the default will be to look for a databag called users.\n\n## Databag Definition\n\nA sample user object in a users databag would look like:\n\n```json\n{\n \"id\": \"test_user\",\n \"password\": \"$1$5cE1rI/9$4p0fomh9U4kAI23qUlZVv/\",\n \"ssh_keys\": [\n \"ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU\\nGPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3\\nPbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA\\nt3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/En\\nmZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx\\nNrRFi9wrf+M7Q== chefuser@mylaptop.local\",\n \"ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU\\nGPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3\\nPbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA\\nt3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/En\\nmZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx\\nNQCPO0ZZEa1== chefuser@mylaptop.local\"\n ],\n \"groups\": [ \"testgroup\", \"nfsgroup\" ],\n \"uid\": 9001,\n \"shell\": \"\\/bin\\/bash\",\n \"comment\": \"Test User\"\n}\n```\n\n### Databag Key Definitions \n\n* `id`: *String* specifies the username, as well as the data bag object id.\n* `password`: *String* specifies the user's password.\n* `ssh_keys`: *Array* an array of authorized keys that will be managed by Chef to the user's home directory in .ssh/authorized_keys\n* `groups`: *Array* an array of groups that the user will be added to\n* `uid`: *Integer* a unique identifier for the user\n* `shell`: *String* the user's shell\n* `comment`:*String* the [GECOS field](https://en.wikipedia.org/wiki/Gecos_field), generally the User's full name.\n\nOther potential fields:\n\n* `home`: *String* User's home directory. If not assigned, will be set based on platform and username.\n* `action`: *String* Supported actions are one's supported by the [user](https://docs.chef.io/resource_user.html#actions) resource. If not specified, the default action is `create`.\n* `ssh_private_key`: *String* manages user's private key generally ~/.ssh/id_*\n* `ssh_public_key`: *String* manages user's public key generally ~/.ssh/id_*.pub\n\n\n## Resources Overview\n\n### users_manage\n\nThe `users_manage` resource manages users and groups based off of a data bag search and specified action.\n\n#### Examples\n\nCreates the `sysadmin` group and users defined in the `users` databag.\n\n```ruby\nusers_manage 'sysadmin' do\n group_id 2300\n action [:remove, :create]\nend\n```\n\nRemoves, then creates the `testgroup` group, and users defined in the `test_home_dir` databag.\n\n```ruby\nusers_manage 'testgroup' do\n group_id 3000\n action [:remove, :create]\n data_bag 'test_home_dir'\nend\n```\n\nRemoves, then creates the `nfsgroup` group, and users defined in the `test_home_dir` databag and does not manage nfs home directories.\n\n```ruby\nusers_manage 'nfsgroup' do\n group_id 4000\n action [:remove, :create]\n data_bag 'test_home_dir'\n manage_nfs_home_dirs false\nend\n```\n\n#### Parameters\n\n* `data_bag` *String* is the data bag to search\n* `search_group` *String* groups name to search for, defaults to resource name\n* `group_name` *String* name of the group to create, defaults to resource name\n* `group_id` *Integer* numeric id of the group to create, default is to allow the OS to pick next\n* `cookbook` *String* name of the cookbook that the authorized_keys template should be found in\n* `manage_nfs_home_dirs` *Boolean* whether to manage nfs home directories.\n\nOtherwise, this cookbook is specific for setting up `sysadmin` group and users with the sysadmins recipe for now.\n\n## Recipe Overview\n\n`sysadmins.rb`: recipe that manages the group sysadmins with group id 2300, and adds users to this group.\n\nTo use:\n\n```ruby\ninclude_recipe \"users::sysadmins\"\n```\n\nThe recipe is defined as follows:\n\n```ruby\nusers_manage \"sysadmin\" do\n group_id 2300\n action [ :remove, :create ]\nend\n```\n\nThis `users_manage` resource searches the `users` data bag for the `sysadmin` group attribute, and adds those users to a Unix security group `sysadmin`. The only required attribute is group_id, which represents the numeric Unix gid and _must_ be unique. The default action for the resource is `:create`.\n\nThe recipe, by default, will also create the sysadmin group. The sysadmin group will be created with GID 2300. This may become an attribute at a later date.\n\n## Data bag Overview \n\n**Reminder** Data bags generally should not be stored in cookbooks, but in a policy repo within your organization. Data bags are useful across cookbooks, not just for a single cookbook.\n\nUse knife to create a data bag for users.\n\n```bash\n$ knife data bag create users\n```\n\nCreate a user in the data_bag/users/ directory.\n\nAn optional password hash can be specified that will be used as the user's password.\n\nThe hash can be generated with the following command.\n\n```bash\n$ openssl passwd -1 \"plaintextpassword\"\n```\n\nNote: The ssh_keys attribute below can be either a String or an Array. However, we are recommending the use of an Array.\n\n```json\n{\n \"id\": \"bofh\",\n \"ssh_keys\": \"ssh-rsa AAAAB3Nz...yhCw== bofh\"\n}\n```\n\n```json\n{\n \"id\": \"bofh\",\n \"password\": \"$1$d...HgH0\",\n \"ssh_keys\": [\n \"ssh-rsa AAA123...xyz== foo\",\n \"ssh-rsa AAA456...uvw== bar\"\n ],\n \"groups\": [ \"sysadmin\", \"dba\", \"devops\" ],\n \"uid\": 2001,\n \"shell\": \"\\/bin\\/bash\",\n \"comment\": \"BOFH\"\n}\n```\n\nYou can pass any action listed in the [user](http://docs.chef.io/chef/resources.html#user) resource for Chef via the \"action\" option. For Example:\n\nLock a user, johndoe1.\n\n```bash\n$ knife data bag edit users johndoe1\n```\n\nAnd then change the action to \"lock\":\n\n```javascript\n{\n \"id\": \"johndoe1\",\n \"groups\": [\"sysadmin\", \"dba\", \"devops\"],\n \"uid\": 2002,\n \"action\": \"lock\", // <--\n \"comment\": \"User violated access policy\"\n}\n```\n\nRemove a user, johndoe1.\n\n```bash\n$ knife data bag edit users johndoe1\n```\n\nAnd then change the action to \"remove\":\n\n```javascript\n{\n \"id\": \"johndoe1\",\n \"groups\": [ \"sysadmin\", \"dba\", \"devops\" ],\n \"uid\": 2002,\n \"action\": \"remove\", // <--\n \"comment\": \"User quit, retired, or fired.\"\n}\n```\n\n- Note only user bags with the \"action : remove\" and a search-able \"group\" attribute will be purged by the :remove action.\n- As of v2.0.3 you can use the force parameter within the user data bag object for users with action remove. As per [user docs](https://docs.chef.io/resource_user.html) this may leave the system in an inconsistent state. For example, a user account will be removed even if the user is logged in. A user’s home directory will be removed, even if that directory is shared by multiple users.\n\nIf you have different requirements, for example:\n- You want to search a different data bag specific to a role such as\n- mail. You may change the data_bag searched.\n - data_bag `mail`\n\n- You want to search for a different group attribute named\n- `postmaster`. You may change the search_group attribute. This\n- attribute defaults to the LWRP resource name.\n - search_group `postmaster`\n\n- You want to add the users to a security group other than the\n- lightweight resource name. You may change the group_name attribute.\n- This attribute also defaults to the LWRP resource name.\n - group_name `wheel`\n\nPutting these requirements together our recipe might look like this:\n\n```ruby\nusers_manage \"postmaster\" do\n data_bag \"mail\"\n group_name \"wheel\"\n group_id 10\nend\n```\n\nKnife supports reading data bags from a file and automatically looks in a directory called +data_bags+ in the current directory. The \"bag\" should be a directory with JSON files of each item. For the above:\n\n```bash\n$ mkdir data_bags/users\n$EDITOR data_bags/users/bofh.json\n```\n\nPaste the user's public SSH key into the ssh_keys value. Also make sure the uid is unique, and if you're not using bash, that the shell is installed. \n\nThe Apache cookbook can set up authentication using OpenIDs, which is set up using the openid key here. See the Chef Software 'apache2' cookbook for more information about this.\n\n## Chef Solo\nAs of version 1.4.0, this cookbook might work with Chef Solo when using [chef-solo-search by edelight](https://github.com/edelight/chef-solo-search). That cookbook is not a dependency of this one as Chef solo doesn't support dependency resolution using cookbook metadata - all cookbooks must be provided to the node manually when using Chef Solo.\n\n## License & Authors\n**Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io))\n\n**Copyright:** 2009-2016, Chef Software, Inc.\n\n```\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{"ubuntu":">= 0.0.0","debian":">= 0.0.0","redhat":">= 0.0.0","centos":">= 0.0.0","fedora":">= 0.0.0","freebsd":">= 0.0.0","mac_os_x":">= 0.0.0","scientific":">= 0.0.0","oracle":">= 0.0.0","amazon":">= 0.0.0"},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{"users::default":"Empty recipe for including LWRPs","users::sysadmins":"Create and manage sysadmin group"}} \ No newline at end of file +{"name":"users","version":"4.0.3","description":"Creates users from a databag search","long_description":"# users Cookbook\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/users.svg?branch=master)](http://travis-ci.org/chef-cookbooks/users) [![Cookbook Version](https://img.shields.io/cookbook/v/users.svg)](https://supermarket.chef.io/cookbooks/users)\n\nManages OS users from databags.\n\n## Scope\n\nThis cookbook is concerned with the management of OS users and groups from databags. It also manages the distribution of ssh keys to a user's home directory.\n\n## Requirements\n\nA data bag populated with user objects must exist. The default data bag in this recipe is `users`. See USAGE.\n\n### Chef\n\n- Chef 12.1+\n\n### Platform Support\n\nThe following platforms have been tested with Test Kitchen:\n\n- Debian / Ubuntu and derivatives\n- RHEL and derivatives\n- Fedora\n- FreeBSD / OpenBSD\n- Mac OS X\n\n### Cookbook Dependencies\n\n- none\n\n## Usage\n\nTo use the resource `users_manage`, make sure to add the dependency on the users cookbook by the following line to your wrapper cookbook's [metadata.rb](https://docs.chef.io/config_rb_metadata.html):\n\n```\ndepends 'users'\n```\n\nor to pin to a specific version of the users cookbook, in this case any version of 2.X:\n\n```\ndepends 'users', '~> 2'\n```\n\nThen in a recipe:\n\n```ruby\nusers_manage 'GROUPNAME' do\n group_id GROUPID\n action [:create]\n data_bag 'DATABAG_NAME'\nend\n```\n\nExample:\n\n```ruby\nusers_manage 'testgroup' do\n group_id 3000\n action [:create]\n data_bag 'test_home_dir'\nend\n```\n\n**Note**: If you do not specify the data_bag, the default will be to look for a databag called users.\n\n## Databag Definition\n\nA sample user object in a users databag would look like:\n\n```json\n{\n \"id\": \"test_user\",\n \"password\": \"$1$5cE1rI/9$4p0fomh9U4kAI23qUlZVv/\",\n \"ssh_keys\": [\n \"ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU\\nGPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3\\nPbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA\\nt3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/En\\nmZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx\\nNrRFi9wrf+M7Q== chefuser@mylaptop.local\",\n \"ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU\\nGPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3\\nPbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA\\nt3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/En\\nmZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx\\nNQCPO0ZZEa1== chefuser@mylaptop.local\"\n ],\n \"groups\": [ \"testgroup\", \"nfsgroup\" ],\n \"uid\": 9001,\n \"shell\": \"\\/bin\\/bash\",\n \"comment\": \"Test User\"\n}\n```\n\n### Databag Key Definitions\n\n- `id`: _String_ specifies the username, as well as the data bag object id.\n- `password`: _String_ specifies the user's password.\n- `ssh_keys`: _Array_ an array of authorized keys that will be managed by Chef to the user's home directory in .ssh/authorized_keys\n- `groups`: _Array_ an array of groups that the user will be added to\n- `uid`: _Integer_ a unique identifier for the user\n- `shell`: _String_ the user's shell\n- `comment`:_String_ the [GECOS field](https://en.wikipedia.org/wiki/Gecos_field), generally the User's full name.\n\nOther potential fields:\n\n- `home`: _String_ User's home directory. If not assigned, will be set based on platform and username.\n- `action`: _String_ Supported actions are one's supported by the [user](https://docs.chef.io/resource_user.html#actions) resource. If not specified, the default action is `create`.\n- `ssh_private_key`: _String_ manages user's private key generally ~/.ssh/id_*\n- `ssh_public_key`: _String_ manages user's public key generally ~/.ssh/id_*.pub\n\n## Resources Overview\n\n### users_manage\n\nThe `users_manage` resource manages users and groups based off of a data bag search and specified action.\n\n#### Examples\n\nCreates the `sysadmin` group and users defined in the `users` databag.\n\n```ruby\nusers_manage 'sysadmin' do\n group_id 2300\n action [:create]\nend\n```\n\nCreates the `testgroup` group, and users defined in the `test_home_dir` databag.\n\n```ruby\nusers_manage 'testgroup' do\n group_id 3000\n action [:create]\n data_bag 'test_home_dir'\nend\n```\n\nCreates the `nfsgroup` group, and users defined in the `test_home_dir` databag and does not manage nfs home directories.\n\n```ruby\nusers_manage 'nfsgroup' do\n group_id 4000\n action [:create]\n data_bag 'test_home_dir'\n manage_nfs_home_dirs false\nend\n```\n\n#### Parameters\n\n- `data_bag` _String_ is the data bag to search\n- `search_group` _String_ groups name to search for, defaults to resource name\n- `group_name` _String_ name of the group to create, defaults to resource name\n- `group_id` _Integer_ numeric id of the group to create, default is to allow the OS to pick next\n- `cookbook` _String_ name of the cookbook that the authorized_keys template should be found in\n- `manage_nfs_home_dirs` _Boolean_ whether to manage nfs home directories.\n\nOtherwise, this cookbook is specific for setting up `sysadmin` group and users with the sysadmins recipe for now.\n\n## Recipe Overview\n\n### Deprecation Notice\n\nThis recipe has been deprecated and the resource will be removed from the recipe in a new major release of this cookbook in April 2017\\. The functionality can easily be recreated and changed to suit your organization by copying the single resource below into your own cookbook.\n\n`sysadmins.rb`: recipe that manages the group sysadmins with group id 2300, and adds users to this group.\n\nTo use:\n\n```ruby\ninclude_recipe \"users::sysadmins\"\n```\n\nThe recipe is defined as follows:\n\n```ruby\nusers_manage \"sysadmin\" do\n group_id 2300\n action [ :create ]\nend\n```\n\nThis `users_manage` resource searches the `users` data bag for the `sysadmin` group attribute, and adds those users to a Unix security group `sysadmin`. The only required attribute is group_id, which represents the numeric Unix gid and _must_ be unique. The default action for the resource is `:create`.\n\nThe recipe, by default, will also create the sysadmin group. The sysadmin group will be created with GID 2300.\n\n## Data bag Overview\n\n**Reminder** Data bags generally should not be stored in cookbooks, but in a policy repo within your organization. Data bags are useful across cookbooks, not just for a single cookbook.\n\nUse knife to create a data bag for users.\n\n```bash\n$ knife data bag create users\n```\n\nCreate a user in the data_bag/users/ directory.\n\nAn optional password hash can be specified that will be used as the user's password.\n\nThe hash can be generated with the following command.\n\n```bash\n$ openssl passwd -1 \"plaintextpassword\"\n```\n\nNote: The ssh_keys attribute below can be either a String or an Array. However, we are recommending the use of an Array.\n\n```json\n{\n \"id\": \"bofh\",\n \"ssh_keys\": \"ssh-rsa AAAAB3Nz...yhCw== bofh\"\n}\n```\n\n```json\n{\n \"id\": \"bofh\",\n \"password\": \"$1$d...HgH0\",\n \"ssh_keys\": [\n \"ssh-rsa AAA123...xyz== foo\",\n \"ssh-rsa AAA456...uvw== bar\"\n ],\n \"groups\": [ \"sysadmin\", \"dba\", \"devops\" ],\n \"uid\": 2001,\n \"shell\": \"\\/bin\\/bash\",\n \"comment\": \"BOFH\"\n}\n```\n\nYou can pass any action listed in the [user](http://docs.chef.io/chef/resources.html#user) resource for Chef via the \"action\" option. For Example:\n\nLock a user, johndoe1.\n\n```bash\n$ knife data bag edit users johndoe1\n```\n\nAnd then change the action to \"lock\":\n\n```javascript\n{\n \"id\": \"johndoe1\",\n \"groups\": [\"sysadmin\", \"dba\", \"devops\"],\n \"uid\": 2002,\n \"action\": \"lock\", // <--\n \"comment\": \"User violated access policy\"\n}\n```\n\nRemove a user, johndoe1.\n\n```bash\n$ knife data bag edit users johndoe1\n```\n\nAnd then change the action to \"remove\":\n\n```javascript\n{\n \"id\": \"johndoe1\",\n \"groups\": [ \"sysadmin\", \"dba\", \"devops\" ],\n \"uid\": 2002,\n \"action\": \"remove\", // <--\n \"comment\": \"User quit, retired, or fired.\"\n}\n```\n\n- Note only user bags with the \"action : remove\" and a search-able \"group\" attribute will be purged by the :remove action.\n- As of v2.0.3 you can use the force parameter within the user data bag object for users with action remove. As per [user docs](https://docs.chef.io/resource_user.html) this may leave the system in an inconsistent state. For example, a user account will be removed even if the user is logged in. A user’s home directory will be removed, even if that directory is shared by multiple users.\n\nIf you have different requirements, for example:\n- You want to search a different data bag specific to a role such as\n- mail. You may change the data_bag searched.\n - data_bag `mail`\n\n- You want to search for a different group attribute named\n- `postmaster`. You may change the search_group attribute. This\n- attribute defaults to the LWRP resource name.\n - search_group `postmaster`\n\n- You want to add the users to a security group other than the\n- lightweight resource name. You may change the group_name attribute.\n- This attribute also defaults to the LWRP resource name.\n - group_name `wheel`\n\nPutting these requirements together our recipe might look like this:\n\n```ruby\nusers_manage \"postmaster\" do\n data_bag \"mail\"\n group_name \"wheel\"\n group_id 10\nend\n```\n\nKnife supports reading data bags from a file and automatically looks in a directory called +data_bags+ in the current directory. The \"bag\" should be a directory with JSON files of each item. For the above:\n\n```bash\n$ mkdir data_bags/users\n$EDITOR data_bags/users/bofh.json\n```\n\nPaste the user's public SSH key into the ssh_keys value. Also make sure the uid is unique, and if you're not using bash, that the shell is installed.\n\nThe Apache cookbook can set up authentication using OpenIDs, which is set up using the openid key here. See the Chef Software 'apache2' cookbook for more information about this.\n\n## License & Authors\n\n**Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io))\n\n**Copyright:** 2009-2016, Chef Software, Inc.\n\n```\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{"ubuntu":">= 0.0.0","debian":">= 0.0.0","redhat":">= 0.0.0","centos":">= 0.0.0","fedora":">= 0.0.0","freebsd":">= 0.0.0","mac_os_x":">= 0.0.0","scientific":">= 0.0.0","oracle":">= 0.0.0","amazon":">= 0.0.0","zlinux":">= 0.0.0"},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{"users::default":"Empty recipe","users::sysadmins":"Deprecated recipe to create and manage sysadmin group."}} \ No newline at end of file diff --git a/cookbooks/users/providers/manage.rb b/cookbooks/users/providers/manage.rb index 775d496..83a018c 100644 --- a/cookbooks/users/providers/manage.rb +++ b/cookbooks/users/providers/manage.rb @@ -1,9 +1,9 @@ # -# Cookbook Name:: users +# Cookbook:: users # Provider:: manage # -# Copyright 2011, Eric G. Wolfe -# Copyright 2009-2015, Chef Software, Inc. +# Copyright:: 2011-2016, Eric G. Wolfe +# Copyright:: 2009-2016, 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. @@ -24,26 +24,11 @@ def whyrun_supported? true end -def chef_solo_search_installed? - klass = ::Search.const_get('Helper') - return klass.is_a?(Class) -rescue NameError - return false -end - -def search_missing? - Chef::Config[:solo] && !(Chef::Config[:local_mode] || chef_solo_search_installed?) -end - action :remove do - if search_missing? - Chef::Log.warn('This recipe uses search. Chef Solo does not support search unless you install the chef-solo-search cookbook.') - else - search(new_resource.data_bag, "groups:#{new_resource.search_group} AND action:remove") do |rm_user| - user rm_user['username'] ||= rm_user['id'] do - action :remove - force rm_user['force'] ||= false - end + search(new_resource.data_bag, "groups:#{new_resource.search_group} AND action:remove") do |rm_user| + user rm_user['username'] ||= rm_user['id'] do + action :remove + force rm_user['force'] ||= false end end end @@ -52,121 +37,120 @@ action :create do users_groups = {} users_groups[new_resource.group_name] = [] - if search_missing? - Chef::Log.warn('This recipe uses search. Chef Solo does not support search unless you install the chef-solo-search cookbook.') - else - search(new_resource.data_bag, "groups:#{new_resource.search_group} AND NOT action:remove") do |u| - u['username'] ||= u['id'] - u['groups'].each do |g| - users_groups[g] = [] unless users_groups.key?(g) - users_groups[g] << u['username'] + search(new_resource.data_bag, "groups:#{new_resource.search_group} AND NOT action:remove") do |u| + u['username'] ||= u['id'] + u['groups'].each do |g| + users_groups[g] = [] unless users_groups.key?(g) + users_groups[g] << u['username'] + end + + if node['apache'] && node['apache']['allowed_openids'] + Array(u['openid']).compact.each do |oid| + node.default['apache']['allowed_openids'] << oid unless node['apache']['allowed_openids'].include?(oid) + end + end + + # Platform specific checks + # Set home_basedir + # Set shell on FreeBSD + home_basedir = '/home' + + case node['platform_family'] + when 'mac_os_x' + home_basedir = '/Users' + when 'freebsd' + # Check if we need to prepend shell with /usr/local/? + u['shell'] = (!::File.exist?(u['shell']) && ::File.exist?("/usr/local#{u['shell']}") ? "/usr/local#{u['shell']}" : '/bin/sh') + end + + # Set home to location in data bag, + # or a reasonable default ($home_basedir/$user). + home_dir = (u['home'] ? u['home'] : "#{home_basedir}/#{u['username']}") + + # check whether home dir is null + manage_home = (home_dir == '/dev/null' ? false : true) + + # The user block will fail if the group does not yet exist. + # See the -g option limitations in man 8 useradd for an explanation. + # This should correct that without breaking functionality. + group u['username'] do # ~FC022 + gid validate_id(u['gid']) + only_if { u['gid'] && u['gid'].is_a?(Numeric) } + end + + # Create user object. + # Do NOT try to manage null home directories. + user u['username'] do + uid validate_id(u['uid']) + gid validate_id(u['gid']) if u['gid'] + shell u['shell'] + comment u['comment'] + password u['password'] if u['password'] + salt u['salt'] if u['salt'] + iterations u['iterations'] if u['iterations'] + manage_home manage_home + home home_dir + action u['action'] if u['action'] + end + + if manage_home_files?(home_dir, u['username']) + Chef::Log.debug("Managing home files for #{u['username']}") + + directory "#{home_dir}/.ssh" do + recursive true + owner u['uid'] ? validate_id(u['uid']) : u['username'] + group validate_id(u['gid']) if u['gid'] + mode '0700' + only_if { !!(u['ssh_keys'] || u['ssh_private_key'] || u['ssh_public_key']) } end - if node['apache'] && node['apache']['allowed_openids'] - Array(u['openid']).compact.each do |oid| - node.default['apache']['allowed_openids'] << oid unless node['apache']['allowed_openids'].include?(oid) - end + template "#{home_dir}/.ssh/authorized_keys" do + source 'authorized_keys.erb' + cookbook new_resource.cookbook + owner u['uid'] ? validate_id(u['uid']) : u['username'] + group validate_id(u['gid']) if u['gid'] + mode '0600' + variables ssh_keys: u['ssh_keys'] + only_if { !!(u['ssh_keys']) } end - # Platform specific checks - # Set home_basedir - # Set shell on FreeBSD - home_basedir = '/home' - - case node['platform_family'] - when 'mac_os_x' - home_basedir = '/Users' - when 'freebsd' - # Check if we need to prepend shell with /usr/local/? - u['shell'] = (!File.exist?(u['shell']) && File.exist?("/usr/local#{u['shell']}") ? "/usr/local#{u['shell']}" : '/bin/sh') - end - - # Set home to location in data bag, - # or a reasonable default ($home_basedir/$user). - home_dir = (u['home'] ? u['home'] : "#{home_basedir}/#{u['username']}") - - # check whether home dir is null - manage_home = (home_dir == '/dev/null' ? false : true) - - # The user block will fail if the group does not yet exist. - # See the -g option limitations in man 8 useradd for an explanation. - # This should correct that without breaking functionality. - group u['username'] do - gid validate_id(u['gid']) - only_if { u['gid'] && u['gid'].is_a?(Numeric) } - end - - # Create user object. - # Do NOT try to manage null home directories. - user u['username'] do - uid validate_id(u['uid']) - gid validate_id(u['gid']) if u['gid'] - shell u['shell'] - comment u['comment'] - password u['password'] if u['password'] - supports manage_home: manage_home - home home_dir - action u['action'] if u['action'] - end - - if manage_home_files?(home_dir, u['username']) - Chef::Log.debug("Managing home files for #{u['username']}") - - directory "#{home_dir}/.ssh" do - owner u['uid'] ? validate_id(u['uid']) : u['username'] - group validate_id(u['gid']) if u['gid'] - mode '0700' - only_if { u['ssh_keys'] || u['ssh_private_key'] || u['ssh_public_key'] } - end - - template "#{home_dir}/.ssh/authorized_keys" do - source 'authorized_keys.erb' + if u['ssh_private_key'] + key_type = u['ssh_private_key'].include?('BEGIN RSA PRIVATE KEY') ? 'rsa' : 'dsa' + template "#{home_dir}/.ssh/id_#{key_type}" do + source 'private_key.erb' cookbook new_resource.cookbook owner u['uid'] ? validate_id(u['uid']) : u['username'] group validate_id(u['gid']) if u['gid'] - mode '0600' - variables ssh_keys: u['ssh_keys'] - only_if { u['ssh_keys'] } + mode '0400' + variables private_key: u['ssh_private_key'] end - - if u['ssh_private_key'] - key_type = u['ssh_private_key'].include?('BEGIN RSA PRIVATE KEY') ? 'rsa' : 'dsa' - template "#{home_dir}/.ssh/id_#{key_type}" do - source 'private_key.erb' - cookbook new_resource.cookbook - owner u['uid'] ? validate_id(u['uid']) : u['username'] - group validate_id(u['gid']) if u['gid'] - mode '0400' - variables private_key: u['ssh_private_key'] - end - end - - if u['ssh_public_key'] - key_type = u['ssh_public_key'].include?('ssh-rsa') ? 'rsa' : 'dsa' - template "#{home_dir}/.ssh/id_#{key_type}.pub" do - source 'public_key.pub.erb' - cookbook new_resource.cookbook - owner u['uid'] ? validate_id(u['uid']) : u['username'] - group validate_id(u['gid']) if u['gid'] - mode '0400' - variables public_key: u['ssh_public_key'] - end - end - else - Chef::Log.debug("Not managing home files for #{u['username']}") end - end - # Populating users to appropriates groups - users_groups.each do |g, u| - group g do - members u - append true - action :manage # Do nothing if group doesn't exist - end unless g == new_resource.group_name # Dealing with managed group later + if u['ssh_public_key'] + key_type = u['ssh_public_key'].include?('ssh-rsa') ? 'rsa' : 'dsa' + template "#{home_dir}/.ssh/id_#{key_type}.pub" do + source 'public_key.pub.erb' + cookbook new_resource.cookbook + owner u['uid'] ? validate_id(u['uid']) : u['username'] + group validate_id(u['gid']) if u['gid'] + mode '0400' + variables public_key: u['ssh_public_key'] + end + end + else + Chef::Log.debug("Not managing home files for #{u['username']}") end end + # Populating users to appropriates groups + users_groups.each do |g, u| + group g do + members u + append true + action :manage # Do nothing if group doesn't exist + end unless g == new_resource.group_name # Dealing with managed group later + end + group new_resource.group_name do gid new_resource.group_id if new_resource.group_id members users_groups[new_resource.group_name] diff --git a/cookbooks/users/recipes/default.rb b/cookbooks/users/recipes/default.rb index 9908546..59e688c 100644 --- a/cookbooks/users/recipes/default.rb +++ b/cookbooks/users/recipes/default.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: users +# Cookbook:: users # Recipe:: default # -# Copyright 2009-2015, Chef Software, Inc. +# Copyright:: 2009-2016, 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. @@ -17,4 +17,4 @@ # limitations under the License. # -# Empty default recipe for including LWRPs. +Chef::Log.warn('The default users recipe does nothing. See the readme for information on using the users resources') diff --git a/cookbooks/users/recipes/sysadmins.rb b/cookbooks/users/recipes/sysadmins.rb index c017b10..03f248a 100644 --- a/cookbooks/users/recipes/sysadmins.rb +++ b/cookbooks/users/recipes/sysadmins.rb @@ -1,9 +1,9 @@ # -# Cookbook Name:: users +# Cookbook:: users # Recipe:: sysadmins # -# Copyright 2011, Eric G. Wolfe -# Copyright 2009-2015, Chef Software, Inc. +# Copyright:: 2011-2016, Eric G. Wolfe +# Copyright:: 2009-2016, 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. @@ -18,6 +18,8 @@ # limitations under the License. # +Chef::Log.warn('The sysadmins recipe has been deprecated. We suggest using the users_manage resource in your own cookbook if you need similar functionality. The resource in this recipe will be removed with a major release of the cookbook in April 2017') + # Searches data bag "users" for groups attribute "sysadmin". # Places returned users in Unix group "sysadmin" with GID 2300. users_manage 'sysadmin' do diff --git a/cookbooks/users/resources/manage.rb b/cookbooks/users/resources/manage.rb index 9763696..69e1378 100644 --- a/cookbooks/users/resources/manage.rb +++ b/cookbooks/users/resources/manage.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: users +# Cookbook:: users # Resources:: manage # -# Copyright 2011, Eric G. Wolfe +# Copyright:: 2011-2016, Eric G. Wolfe # # 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/cookbooks/yum-epel/CHANGELOG.md b/cookbooks/yum-epel/CHANGELOG.md index 7e57b60..d5f01c2 100644 --- a/cookbooks/yum-epel/CHANGELOG.md +++ b/cookbooks/yum-epel/CHANGELOG.md @@ -1,18 +1,34 @@ -yum-epel Cookbook CHANGELOG -====================== +# yum-epel Cookbook CHANGELOG + This file is used to list changes made in each version of the yum-epel cookbook. -v0.6.5 (2015-11-23) -------------------- +## v0.7.1 (2016-08-19) +- Remove bats testing +- Fix attribute settings +- Cleanup travis file + +## v0.7.0 (2016-04-27) + +- Added support for IBM zlinux platform +- Added back the Test Kitchen support for local vagrant testing +- Added long_description to the metadata +- Loosen the dependency on the yum cookbook + +## v0.6.5 + +- updated to use `make_cache` option that yum cookbook allows for the yum resource to use. + +## v0.6.5 (2015-11-23) + - Fix setting bool false properties -v0.6.4 (2015-10-27) -------------------- -- Updating default recipe for Chef 13 deprecation warnings. Not - passing nil. +## v0.6.4 (2015-10-27) + +- Updating default recipe for Chef 13 deprecation warnings. Not +- passing nil. + +## v0.6.3 (2015-09-22) -v0.6.3 (2015-09-22) -------------------- - Added standard Chef gitignore and chefignore files - Added the standard chef rubocop config - Update contributing, maintainers, and testing docs @@ -23,66 +39,66 @@ v0.6.3 (2015-09-22) - Add additional distros to the metadata - Added source_url and issues_url metadata -v0.6.2 (2015-06-21) -------------------- +## v0.6.2 (2015-06-21) + - Depending on yum ~> 3.2 - Support for the password attribute wasn't added to the - yum_repository LWRP until yum 3.2.0. +- yum_repository LWRP until yum 3.2.0. + +## v0.6.1 (2015-06-21) -v0.6.1 (2015-06-21) -------------------- - Switching to https for URL links - Using metalink URLs -v0.6.0 (2015-01-03) -------------------- +## v0.6.0 (2015-01-03) + - Adding EL7 support -v0.5.3 (2014-10-28) -------------------- +## v0.5.3 (2014-10-28) + - Revert Use HTTPS for GPG keys and mirror lists -v0.5.2 (2014-10-28) -------------------- +## v0.5.2 (2014-10-28) + - Use HTTPS for GPG keys and mirror lists - Use local key on Amazon Linux -v0.5.0 (2014-09-02) -------------------- +## v0.5.0 (2014-09-02) + - Add all attribute available to LWRP to allow for tuning. -v0.4.0 (2014-07-27) -------------------- +## v0.4.0 (2014-07-27) + - [#9] Allowing list of repositories to reference configurable. -v0.3.6 (2014-04-09) -------------------- +## v0.3.6 (2014-04-09) + - [COOK-4509] add RHEL7 support to yum-epel cookbook -v0.3.4 (2014-02-19) -------------------- +## v0.3.4 (2014-02-19) + COOK-4353 - Fixing typo in readme -v0.3.2 (2014-02-13) -------------------- +## v0.3.2 (2014-02-13) + Updating README to explain the 'managed' parameter -v0.3.0 (2014-02-12) -------------------- +## v0.3.0 (2014-02-12) + [COOK-4292] - Do not manage secondary repos by default -v0.2.0 ------- +## v0.2.0 + Adding Amazon Linux support -v0.1.6 ------- +## v0.1.6 + Fixing up attribute values for EL6 -v0.1.4 ------- +## v0.1.4 + Adding CHANGELOG.md -v0.1.0 ------- +## v0.1.0 + initial release diff --git a/cookbooks/yum-epel/README.md b/cookbooks/yum-epel/README.md index 561f382..d6f37a1 100644 --- a/cookbooks/yum-epel/README.md +++ b/cookbooks/yum-epel/README.md @@ -1,35 +1,28 @@ -yum-epel Cookbook -============ -[![Build Status](https://travis-ci.org/chef-cookbooks/yum-epel.svg?branch=master)](http://travis-ci.org/chef-cookbooks/yum-epel) -[![Cookbook Version](https://img.shields.io/cookbook/v/yum-epel.svg)](https://supermarket.chef.io/cookbooks/yum-epel) +# yum-epel Cookbook +[![Build Status](https://travis-ci.org/chef-cookbooks/yum-epel.svg?branch=master)](http://travis-ci.org/chef-cookbooks/yum-epel) [![Cookbook Version](https://img.shields.io/cookbook/v/yum-epel.svg)](https://supermarket.chef.io/cookbooks/yum-epel) -The yum-epel cookbook takes over management of the default -repositoryids shipped with epel-release. It allows attribute -manipulation of `epel`, `epel-debuginfo`, `epel-source`, `epel-testing`, -`epel-testing-debuginfo`, and `epel-testing-source`. +Extra Packages for Enterprise Linux (or EPEL) is a Fedora Special Interest Group that creates, maintains, and manages a high quality set of additional packages for Enterprise Linux, including, but not limited to, Red Hat Enterprise Linux (RHEL), CentOS and Scientific Linux (SL), Oracle Linux (OL). -Requirements ------------- -#### Platforms -* RHEL/CentOS and derivatives -* Fedora +The yum-epel cookbook takes over management of the default repositoryids shipped with epel-release. It allows attribute manipulation of `epel`, `epel-debuginfo`, `epel-source`, `epel-testing`, `epel-testing-debuginfo`, and `epel-testing-source`. -#### Chef -* Chef 11+ +## Requirements +### Platforms +- RHEL/CentOS and derivatives -#### Cookbooks -* yum version 3.2.0 or higher +### Chef +- Chef 11+ +### Cookbooks +- yum version 3.6.3 or higher -Attributes ----------- +## Attributes The following attributes are set by default -``` ruby +```ruby default['yum-epel']['repositories'] = %w{epel epel-debuginfo epel-source epel-testing epel-testing-debuginfo epel-testing-source} ``` -``` ruby +```ruby default['yum']['epel']['repositoryid'] = 'epel' default['yum']['epel']['description'] = 'Extra Packages for Enterprise Linux 6 - $basearch' default['yum']['epel']['mirrorlist'] = 'http://mirrors.fedoraproject.org/mirrorlist?repo=epel-5&arch=$basearch' @@ -40,7 +33,7 @@ default['yum']['epel']['enabled'] = true default['yum']['epel']['managed'] = true ``` -``` ruby +```ruby default['yum']['epel-debuginfo']['repositoryid'] = 'epel-debuginfo' default['yum']['epel-debuginfo']['description'] = 'Extra Packages for Enterprise Linux 6 - $basearch - Debug' default['yum']['epel-debuginfo']['mirrorlist'] = 'https://mirrors.fedoraproject.org/metalink?repo=epel-debug-6&arch=$basearch' @@ -51,7 +44,7 @@ default['yum']['epel-debuginfo']['enabled'] = false default['yum']['epel-debuginfo']['managed'] = false ``` -``` ruby +```ruby default['yum']['epel-source']['repositoryid'] = 'epel-source' default['yum']['epel-source']['description'] = 'Extra Packages for Enterprise Linux 6 - $basearch - Source' default['yum']['epel-source']['mirrorlist'] = 'http://mirrors.fedoraproject.org/mirrorlist?repo=epel-source-6&arch=$basearch' @@ -62,7 +55,7 @@ default['yum']['epel-source']['enabled'] = false default['yum']['epel-source']['managed'] = false ``` -``` ruby +```ruby default['yum']['epel-testing']['repositoryid'] = 'epel-testing' default['yum']['epel-testing']['description'] = 'Extra Packages for Enterprise Linux 6 - Testing - $basearch' default['yum']['epel-testing']['mirrorlist'] = 'https://mirrors.fedoraproject.org/metalink?repo=testing-epel6&arch=$basearch' @@ -73,7 +66,7 @@ default['yum']['epel-testing']['enabled'] = false default['yum']['epel-testing']['managed'] = false ``` -``` ruby +```ruby default['yum']['epel-testing-debuginfo']['repositoryid'] = 'epel-testing-debuginfo' default['yum']['epel-testing-debuginfo']['description'] = 'Extra Packages for Enterprise Linux 6 - Testing - $basearch Debug' default['yum']['epel-testing-debuginfo']['mirrorlist'] = 'https://mirrors.fedoraproject.org/metalink?repo=testing-debug-epel6&arch=$basearch' @@ -84,7 +77,7 @@ default['yum']['epel-testing-debuginfo']['enabled'] = false default['yum']['epel-testing-debuginfo']['managed'] = false ``` -``` ruby +```ruby default['yum']['epel-testing-source']['repositoryid'] = 'epel-testing-source' default['yum']['epel-testing-source']['description'] = 'Extra Packages for Enterprise Linux 6 - Testing - $basearch Source' default['yum']['epel-testing-source']['mirrorlist'] = 'https://mirrors.fedoraproject.org/metalink?repo=testing-source-epel6&arch=$basearch' @@ -95,11 +88,10 @@ default['yum']['epel-testing-source']['enabled'] = false default['yum']['epel-testing-source']['managed'] = false ``` -Recipes -------- -* default - Walks through node attributes and feeds a yum_resource - parameters. The following is an example a resource generated by the - recipe during compilation. +## Recipes +- default - Walks through node attributes and feeds a yum_resource +- parameters. The following is an example a resource generated by the +- recipe during compilation. ```ruby yum_repository 'epel' do @@ -111,8 +103,7 @@ Recipes end ``` -Usage Example -------------- +## Usage Example To disable the epel repository through a Role or Environment definition ``` @@ -127,22 +118,18 @@ default_attributes( ) ``` -Uncommonly used repositoryids are not managed by default. This is -speeds up integration testing pipelines by avoiding yum-cache builds -that nobody cares about. To enable the epel-testing repository with a -wrapper cookbook, place the following in a recipe: +Uncommonly used repositoryids are not managed by default. This is speeds up integration testing pipelines by avoiding yum-cache builds that nobody cares about. To enable the epel-testing repository with a wrapper cookbook, place the following in a recipe: -``` +```ruby node.default['yum']['epel-testing']['enabled'] = true node.default['yum']['epel-testing']['managed'] = true include_recipe 'yum-epel' ``` -More Examples -------------- +## More Examples Point the epel repositories at an internally hosted server. -``` +```ruby node.default['yum']['epel']['enabled'] = true node.default['yum']['epel']['mirrorlist'] = nil node.default['yum']['epel']['baseurl'] = 'https://internal.example.com/centos/6/os/x86_64' @@ -151,12 +138,11 @@ node.default['yum']['epel']['sslverify'] = false include_recipe 'yum-epel' ``` -License & Authors ------------------ +## License & Authors +**Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io)) -**Author:** Cookbook Engineering Team () +**Copyright:** 2011-2016, Chef Software, Inc. -**Copyright:** 2011-2015, 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/cookbooks/yum-epel/attributes/epel-debuginfo.rb b/cookbooks/yum-epel/attributes/epel-debuginfo.rb index b466e15..1f51fdd 100644 --- a/cookbooks/yum-epel/attributes/epel-debuginfo.rb +++ b/cookbooks/yum-epel/attributes/epel-debuginfo.rb @@ -1,28 +1,15 @@ default['yum']['epel-debuginfo']['repositoryid'] = 'epel-debuginfo' +default['yum']['epel-debuginfo']['description'] = 'Extra Packages for $releasever - $basearch - Debug' -case node['platform'] -when 'amazon' - default['yum']['epel-debuginfo']['description'] = 'Extra Packages for Enterprise Linux 6 - $basearch' - default['yum']['epel-debuginfo']['mirrorlist'] = 'http://mirrors.fedoraproject.org/mirrorlist?repo=epel-6&arch=$basearch' +if node['platform'] == 'amazon' + default['yum']['epel-debuginfo']['mirrorlist'] = 'http://mirrors.fedoraproject.org/mirrorlist?repo=epel-debug-6&arch=$basearch' default['yum']['epel-debuginfo']['gpgkey'] = 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6' else - case node['platform_version'].to_i - when 5 - default['yum']['epel-debuginfo']['description'] = 'Extra Packages for Enterprise Linux 5 - $basearch - Debug' - default['yum']['epel-debuginfo']['mirrorlist'] = 'http://mirrors.fedoraproject.org/mirrorlist?repo=epel-debug-5&arch=$basearch' - default['yum']['epel-debuginfo']['gpgkey'] = 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL' - when 6 - default['yum']['epel-debuginfo']['description'] = 'Extra Packages for Enterprise Linux 6 - $basearch - Debug' - default['yum']['epel-debuginfo']['mirrorlist'] = 'https://mirrors.fedoraproject.org/metalink?repo=epel-debug-6&arch=$basearch' - default['yum']['epel-debuginfo']['gpgkey'] = 'https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6' - when 7 - default['yum']['epel-debuginfo']['description'] = 'Extra Packages for Enterprise Linux 7 - $basearch - Debug' - default['yum']['epel-debuginfo']['mirrorlist'] = 'https://mirrors.fedoraproject.org/metalink?repo=epel-debug-7&arch=$basearch' - default['yum']['epel-debuginfo']['gpgkey'] = 'https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7' - end + default['yum']['epel-debuginfo']['mirrorlist'] = "http://mirrors.fedoraproject.org/mirrorlist?repo=epel-debug-#{node['platform_version'].to_i}&arch=$basearch" + default['yum']['epel-debuginfo']['gpgkey'] = (node['platform_version'].to_i == 5 ? 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL' : "https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-#{node['platform_version'].to_i}") end - default['yum']['epel-debuginfo']['failovermethod'] = 'priority' default['yum']['epel-debuginfo']['gpgcheck'] = true default['yum']['epel-debuginfo']['enabled'] = false default['yum']['epel-debuginfo']['managed'] = false +default['yum']['epel-debuginfo']['make_cache'] = true diff --git a/cookbooks/yum-epel/attributes/epel-source.rb b/cookbooks/yum-epel/attributes/epel-source.rb index 9b1b344..670bcc0 100644 --- a/cookbooks/yum-epel/attributes/epel-source.rb +++ b/cookbooks/yum-epel/attributes/epel-source.rb @@ -1,28 +1,15 @@ default['yum']['epel-source']['repositoryid'] = 'epel-source' - -case node['platform'] -when 'amazon' - default['yum']['epel-source']['description'] = 'Extra Packages for Enterprise Linux 6 - $basearch' - default['yum']['epel-source']['mirrorlist'] = 'http://mirrors.fedoraproject.org/mirrorlist?repo=epel-6&arch=$basearch' +default['yum']['epel-source']['description'] = 'Extra Packages for $releasever - $basearch - Source' +if node['platform'] == 'amazon' + default['yum']['epel-source']['mirrorlist'] = 'http://mirrors.fedoraproject.org/mirrorlist?repo=epel-source-6&arch=$basearch' default['yum']['epel-source']['gpgkey'] = 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6' else - case node['platform_version'].to_i - when 5 - default['yum']['epel-source']['description'] = 'Extra Packages for Enterprise Linux 5 - $basearch - Source' - default['yum']['epel-source']['mirrorlist'] = 'http://mirrors.fedoraproject.org/mirrorlist?repo=epel-source-5&arch=$basearch' - default['yum']['epel-source']['gpgkey'] = 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL' - when 6 - default['yum']['epel-source']['description'] = 'Extra Packages for Enterprise Linux 6 - $basearch - Source' - default['yum']['epel-source']['mirrorlist'] = 'https://mirrors.fedoraproject.org/metalink?repo=epel-source-6&arch=$basearch' - default['yum']['epel-source']['gpgkey'] = 'https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6' - when 7 - default['yum']['epel-source']['description'] = 'Extra Packages for Enterprise Linux 7 - $basearch - Source' - default['yum']['epel-source']['mirrorlist'] = 'https://mirrors.fedoraproject.org/metalink?repo=epel-source-7&arch=$basearch' - default['yum']['epel-source']['gpgkey'] = 'https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7' - end + default['yum']['epel-source']['mirrorlist'] = "http://mirrors.fedoraproject.org/mirrorlist?repo=epel-source-#{node['platform_version'].to_i}&arch=$basearch" + default['yum']['epel-source']['gpgkey'] = (node['platform_version'].to_i == 5 ? 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL' : "https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-#{node['platform_version'].to_i}") end default['yum']['epel-source']['failovermethod'] = 'priority' default['yum']['epel-source']['gpgcheck'] = true default['yum']['epel-source']['enabled'] = false default['yum']['epel-source']['managed'] = false +default['yum']['epel-source']['make_cache'] = true diff --git a/cookbooks/yum-epel/attributes/epel-testing-debuginfo.rb b/cookbooks/yum-epel/attributes/epel-testing-debuginfo.rb index ef5f6f3..fa8234b 100644 --- a/cookbooks/yum-epel/attributes/epel-testing-debuginfo.rb +++ b/cookbooks/yum-epel/attributes/epel-testing-debuginfo.rb @@ -1,28 +1,15 @@ default['yum']['epel-testing-debuginfo']['repositoryid'] = 'epel-testing-debuginfo' - -case node['platform'] -when 'amazon' - default['yum']['epel-testing-debuginfo']['description'] = 'Extra Packages for Enterprise Linux 6 - $basearch' - default['yum']['epel-testing-debuginfo']['mirrorlist'] = 'http://mirrors.fedoraproject.org/mirrorlist?repo=epel-6&arch=$basearch' +default['yum']['epel-testing-debuginfo']['description'] = 'Extra Packages for $releasever - $basearch - Testing Debug' +if node['platform'] == 'amazon' + default['yum']['epel-testing-debuginfo']['mirrorlist'] = 'http://mirrors.fedoraproject.org/mirrorlist?repo=testing-debug-epel6&arch=$basearch' default['yum']['epel-testing-debuginfo']['gpgkey'] = 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6' else - case node['platform_version'].to_i - when 5 - default['yum']['epel-testing-debuginfo']['description'] = 'Extra Packages for Enterprise Linux 5 - Testing - $basearch Debug' - default['yum']['epel-testing-debuginfo']['mirrorlist'] = 'http://mirrors.fedoraproject.org/mirrorlist?repo=testing-debug-epel5&arch=$basearch' - default['yum']['epel-testing-debuginfo']['gpgkey'] = 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL' - when 6 - default['yum']['epel-testing-debuginfo']['description'] = 'Extra Packages for Enterprise Linux 6 - Testing - $basearch Debug' - default['yum']['epel-testing-debuginfo']['mirrorlist'] = 'https://mirrors.fedoraproject.org/metalink?repo=testing-debug-epel6&arch=$basearch' - default['yum']['epel-testing-debuginfo']['gpgkey'] = 'https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6' - when 7 - default['yum']['epel-testing-debuginfo']['description'] = 'Extra Packages for Enterprise Linux 7 - Testing - $basearch Debug' - default['yum']['epel-testing-debuginfo']['mirrorlist'] = 'https://mirrors.fedoraproject.org/metalink?repo=testing-debug-epel7&arch=$basearch' - default['yum']['epel-testing-debuginfo']['gpgkey'] = 'https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7' - end + default['yum']['epel-testing-debuginfo']['mirrorlist'] = "http://mirrors.fedoraproject.org/mirrorlist?repo=testing-debug-epel#{node['platform_version'].to_i}&arch=$basearch" + default['yum']['epel-testing-debuginfo']['gpgkey'] = (node['platform_version'].to_i == 5 ? 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL' : "https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-#{node['platform_version'].to_i}") end default['yum']['epel-testing-debuginfo']['failovermethod'] = 'priority' default['yum']['epel-testing-debuginfo']['gpgcheck'] = true default['yum']['epel-testing-debuginfo']['enabled'] = false default['yum']['epel-testing-debuginfo']['managed'] = false +default['yum']['epel-testing-debuginfo']['make_cache'] = true diff --git a/cookbooks/yum-epel/attributes/epel-testing-source.rb b/cookbooks/yum-epel/attributes/epel-testing-source.rb index 93aa882..731ef06 100644 --- a/cookbooks/yum-epel/attributes/epel-testing-source.rb +++ b/cookbooks/yum-epel/attributes/epel-testing-source.rb @@ -1,28 +1,14 @@ default['yum']['epel-testing-source']['repositoryid'] = 'epel-testing-source' - -case node['platform'] -when 'amazon' - default['yum']['epel-testing-source']['description'] = 'Extra Packages for Enterprise Linux 6 - $basearch' - default['yum']['epel-testing-source']['mirrorlist'] = 'http://mirrors.fedoraproject.org/mirrorlist?repo=epel-6&arch=$basearch' +default['yum']['epel-testing-source']['description'] = 'Extra Packages for $releasever - $basearch - Testing Source' +if node['platform'] == 'amazon' + default['yum']['epel-testing-source']['mirrorlist'] = 'http://mirrors.fedoraproject.org/mirrorlist?repo=testing-source-epel6&arch=$basearch' default['yum']['epel-testing-source']['gpgkey'] = 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6' else - case node['platform_version'].to_i - when 5 - default['yum']['epel-testing-source']['description'] = 'Extra Packages for Enterprise Linux 5 - Testing - $basearch Source' - default['yum']['epel-testing-source']['mirrorlist'] = 'http://mirrors.fedoraproject.org/mirrorlist?repo=testing-source-epel5&arch=$basearch' - default['yum']['epel-testing-source']['gpgkey'] = 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL' - when 6 - default['yum']['epel-testing-source']['description'] = 'Extra Packages for Enterprise Linux 6 - Testing - $basearch Source' - default['yum']['epel-testing-source']['mirrorlist'] = 'https://mirrors.fedoraproject.org/metalink?repo=testing-source-epel6&arch=$basearch' - default['yum']['epel-testing-source']['gpgkey'] = 'https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6' - when 7 - default['yum']['epel-testing-source']['description'] = 'Extra Packages for Enterprise Linux 7 - Testing - $basearch Source' - default['yum']['epel-testing-source']['mirrorlist'] = 'https://mirrors.fedoraproject.org/metalink?repo=testing-source-epel7&arch=$basearch' - default['yum']['epel-testing-source']['gpgkey'] = 'https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7' - end + default['yum']['epel-testing-source']['mirrorlist'] = "http://mirrors.fedoraproject.org/mirrorlist?repo=testing-source-epel#{node['platform_version'].to_i}&arch=$basearch" + default['yum']['epel-testing-source']['gpgkey'] = (node['platform_version'].to_i == 5 ? 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL' : "https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-#{node['platform_version'].to_i}") end - default['yum']['epel-testing-source']['failovermethod'] = 'priority' default['yum']['epel-testing-source']['gpgcheck'] = true default['yum']['epel-testing-source']['enabled'] = false default['yum']['epel-testing-source']['managed'] = false +default['yum']['epel-testing-source']['make_cache'] = true diff --git a/cookbooks/yum-epel/attributes/epel-testing.rb b/cookbooks/yum-epel/attributes/epel-testing.rb index 63df142..2a3c6d8 100644 --- a/cookbooks/yum-epel/attributes/epel-testing.rb +++ b/cookbooks/yum-epel/attributes/epel-testing.rb @@ -1,28 +1,15 @@ default['yum']['epel-testing']['repositoryid'] = 'epel-testing' - -case node['platform'] -when 'amazon' - default['yum']['epel-testing']['description'] = 'Extra Packages for Enterprise Linux 6 - $basearch' - default['yum']['epel-testing']['mirrorlist'] = 'http://mirrors.fedoraproject.org/mirrorlist?repo=epel-6&arch=$basearch' - default['yum']['epel-testing']['gpgkey'] = 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6' +default['yum']['epel-testing']['description'] = 'Extra Packages for $releasever - $basearch - Testing ' +if node['platform'] == 'amazon' + default['yum']['epel-testing-source']['mirrorlist'] = 'http://mirrors.fedoraproject.org/mirrorlist?repo=testing-epel6&arch=$basearch' + default['yum']['epel-testing-source']['gpgkey'] = 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6' else - case node['platform_version'].to_i - when 5 - default['yum']['epel-testing']['description'] = 'Extra Packages for Enterprise Linux 5 - Testing - $basearch' - default['yum']['epel-testing']['mirrorlist'] = 'http://mirrors.fedoraproject.org/mirrorlist?repo=testing-epel5&arch=$basearch' - default['yum']['epel-testing']['gpgkey'] = 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL' - when 6 - default['yum']['epel-testing']['description'] = 'Extra Packages for Enterprise Linux 6 - Testing - $basearch' - default['yum']['epel-testing']['mirrorlist'] = 'https://mirrors.fedoraproject.org/metalink?repo=testing-epel6&arch=$basearch' - default['yum']['epel-testing']['gpgkey'] = 'https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6' - when 7 - default['yum']['epel-testing']['description'] = 'Extra Packages for Enterprise Linux 7 - Testing - $basearch' - default['yum']['epel-testing']['mirrorlist'] = 'https://mirrors.fedoraproject.org/metalink?repo=testing-epel7&arch=$basearch' - default['yum']['epel-testing']['gpgkey'] = 'https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7' - end + default['yum']['epel-testing-source']['mirrorlist'] = "http://mirrors.fedoraproject.org/mirrorlist?repo=testing-source-epel#{node['platform_version'].to_i}&arch=$basearch" + default['yum']['epel-testing-source']['gpgkey'] = (node['platform_version'].to_i == 5 ? 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL' : "https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-#{node['platform_version'].to_i}") end default['yum']['epel-testing']['failovermethod'] = 'priority' default['yum']['epel-testing']['gpgcheck'] = true default['yum']['epel-testing']['enabled'] = false default['yum']['epel-testing']['managed'] = false +default['yum']['epel-testing']['make_cache'] = true diff --git a/cookbooks/yum-epel/attributes/epel.rb b/cookbooks/yum-epel/attributes/epel.rb index 4a15a4a..9ee912f 100644 --- a/cookbooks/yum-epel/attributes/epel.rb +++ b/cookbooks/yum-epel/attributes/epel.rb @@ -1,24 +1,17 @@ default['yum']['epel']['repositoryid'] = 'epel' +default['yum']['epel']['description'] = 'Extra Packages for $releasever - $basearch' -case node['platform'] -when 'amazon' - default['yum']['epel']['description'] = 'Extra Packages for Enterprise Linux 6 - $basearch' - default['yum']['epel']['mirrorlist'] = 'http://mirrors.fedoraproject.org/mirrorlist?repo=epel-6&arch=$basearch' - default['yum']['epel']['gpgkey'] = 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6' +case node['kernel']['machine'] +when 's390x' + default['yum']['epel']['baseurl'] = 'https://kojipkgs.fedoraproject.org/rhel/rc/7/Server/s390x/os/' + default['yum']['epel']['gpgkey'] = 'https://kojipkgs.fedoraproject.org/rhel/rc/7/Server/s390x/os/RPM-GPG-KEY-redhat-release' else - case node['platform_version'].to_i - when 5 - default['yum']['epel']['description'] = 'Extra Packages for Enterprise Linux 5 - $basearch' - default['yum']['epel']['mirrorlist'] = 'http://mirrors.fedoraproject.org/mirrorlist?repo=epel-5&arch=$basearch' - default['yum']['epel']['gpgkey'] = 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL' - when 6 - default['yum']['epel']['description'] = 'Extra Packages for Enterprise Linux 6 - $basearch' - default['yum']['epel']['mirrorlist'] = 'https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch' - default['yum']['epel']['gpgkey'] = 'https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6' - when 7 - default['yum']['epel']['description'] = 'Extra Packages for Enterprise Linux 7 - $basearch' - default['yum']['epel']['mirrorlist'] = 'https://mirrors.fedoraproject.org/metalink?repo=epel-7&arch=$basearch' - default['yum']['epel']['gpgkey'] = 'https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7' + if node['platform'] == 'amazon' + default['yum']['epel']['mirrorlist'] = 'http://mirrors.fedoraproject.org/mirrorlist?repo=epel-6&arch=$basearch' + default['yum']['epel']['gpgkey'] = 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6' + else + default['yum']['epel']['mirrorlist'] = "http://mirrors.fedoraproject.org/mirrorlist?repo=epel-#{node['platform_version'].to_i}&arch=$basearch" + default['yum']['epel']['gpgkey'] = (node['platform_version'].to_i == 5 ? 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL' : "https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-#{node['platform_version'].to_i}") end end @@ -26,3 +19,4 @@ default['yum']['epel']['failovermethod'] = 'priority' default['yum']['epel']['gpgcheck'] = true default['yum']['epel']['enabled'] = true default['yum']['epel']['managed'] = true +default['yum']['epel']['make_cache'] = true diff --git a/cookbooks/yum-epel/metadata.json b/cookbooks/yum-epel/metadata.json index e6ab785..e4c155c 100644 --- a/cookbooks/yum-epel/metadata.json +++ b/cookbooks/yum-epel/metadata.json @@ -1 +1 @@ -{"name":"yum-epel","version":"0.6.5","description":"Installs and configures the EPEL Yum repository","long_description":"","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{"amazon":">= 0.0.0","centos":">= 0.0.0","fedora":">= 0.0.0","oracle":">= 0.0.0","redhat":">= 0.0.0","scientific":">= 0.0.0"},"dependencies":{"yum":"~> 3.2"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{}} \ No newline at end of file +{"name":"yum-epel","version":"0.7.1","description":"Installs and configures the EPEL Yum repository","long_description":"# yum-epel Cookbook\n[![Build Status](https://travis-ci.org/chef-cookbooks/yum-epel.svg?branch=master)](http://travis-ci.org/chef-cookbooks/yum-epel) [![Cookbook Version](https://img.shields.io/cookbook/v/yum-epel.svg)](https://supermarket.chef.io/cookbooks/yum-epel)\n\nExtra Packages for Enterprise Linux (or EPEL) is a Fedora Special Interest Group that creates, maintains, and manages a high quality set of additional packages for Enterprise Linux, including, but not limited to, Red Hat Enterprise Linux (RHEL), CentOS and Scientific Linux (SL), Oracle Linux (OL).\n\nThe yum-epel cookbook takes over management of the default repositoryids shipped with epel-release. It allows attribute manipulation of `epel`, `epel-debuginfo`, `epel-source`, `epel-testing`, `epel-testing-debuginfo`, and `epel-testing-source`.\n\n## Requirements\n### Platforms\n- RHEL/CentOS and derivatives\n\n### Chef\n- Chef 11+\n\n### Cookbooks\n- yum version 3.6.3 or higher\n\n## Attributes\nThe following attributes are set by default\n\n```ruby\ndefault['yum-epel']['repositories'] = %w{epel epel-debuginfo epel-source epel-testing epel-testing-debuginfo epel-testing-source}\n```\n\n```ruby\ndefault['yum']['epel']['repositoryid'] = 'epel'\ndefault['yum']['epel']['description'] = 'Extra Packages for Enterprise Linux 6 - $basearch'\ndefault['yum']['epel']['mirrorlist'] = 'http://mirrors.fedoraproject.org/mirrorlist?repo=epel-5&arch=$basearch'\ndefault['yum']['epel']['gpgkey'] = 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6'\ndefault['yum']['epel']['failovermethod'] = 'priority'\ndefault['yum']['epel']['gpgcheck'] = true\ndefault['yum']['epel']['enabled'] = true\ndefault['yum']['epel']['managed'] = true\n```\n\n```ruby\ndefault['yum']['epel-debuginfo']['repositoryid'] = 'epel-debuginfo'\ndefault['yum']['epel-debuginfo']['description'] = 'Extra Packages for Enterprise Linux 6 - $basearch - Debug'\ndefault['yum']['epel-debuginfo']['mirrorlist'] = 'https://mirrors.fedoraproject.org/metalink?repo=epel-debug-6&arch=$basearch'\ndefault['yum']['epel-debuginfo']['gpgkey'] = 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6'\ndefault['yum']['epel-debuginfo']['failovermethod'] = 'priority'\ndefault['yum']['epel-debuginfo']['gpgcheck'] = true\ndefault['yum']['epel-debuginfo']['enabled'] = false\ndefault['yum']['epel-debuginfo']['managed'] = false\n```\n\n```ruby\ndefault['yum']['epel-source']['repositoryid'] = 'epel-source'\ndefault['yum']['epel-source']['description'] = 'Extra Packages for Enterprise Linux 6 - $basearch - Source'\ndefault['yum']['epel-source']['mirrorlist'] = 'http://mirrors.fedoraproject.org/mirrorlist?repo=epel-source-6&arch=$basearch'\ndefault['yum']['epel-source']['gpgkey'] = 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6'\ndefault['yum']['epel-source']['failovermethod'] = 'priority'\ndefault['yum']['epel-source']['gpgcheck'] = true\ndefault['yum']['epel-source']['enabled'] = false\ndefault['yum']['epel-source']['managed'] = false\n```\n\n```ruby\ndefault['yum']['epel-testing']['repositoryid'] = 'epel-testing'\ndefault['yum']['epel-testing']['description'] = 'Extra Packages for Enterprise Linux 6 - Testing - $basearch'\ndefault['yum']['epel-testing']['mirrorlist'] = 'https://mirrors.fedoraproject.org/metalink?repo=testing-epel6&arch=$basearch'\ndefault['yum']['epel-testing']['gpgkey'] = 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6r'\ndefault['yum']['epel-testing']['failovermethod'] = 'priority'\ndefault['yum']['epel-testing']['gpgcheck'] = true\ndefault['yum']['epel-testing']['enabled'] = false\ndefault['yum']['epel-testing']['managed'] = false\n```\n\n```ruby\ndefault['yum']['epel-testing-debuginfo']['repositoryid'] = 'epel-testing-debuginfo'\ndefault['yum']['epel-testing-debuginfo']['description'] = 'Extra Packages for Enterprise Linux 6 - Testing - $basearch Debug'\ndefault['yum']['epel-testing-debuginfo']['mirrorlist'] = 'https://mirrors.fedoraproject.org/metalink?repo=testing-debug-epel6&arch=$basearch'\ndefault['yum']['epel-testing-debuginfo']['gpgkey'] = 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6'\ndefault['yum']['epel-testing-debuginfo']['failovermethod'] = 'priority'\ndefault['yum']['epel-testing-debuginfo']['gpgcheck'] = true\ndefault['yum']['epel-testing-debuginfo']['enabled'] = false\ndefault['yum']['epel-testing-debuginfo']['managed'] = false\n```\n\n```ruby\ndefault['yum']['epel-testing-source']['repositoryid'] = 'epel-testing-source'\ndefault['yum']['epel-testing-source']['description'] = 'Extra Packages for Enterprise Linux 6 - Testing - $basearch Source'\ndefault['yum']['epel-testing-source']['mirrorlist'] = 'https://mirrors.fedoraproject.org/metalink?repo=testing-source-epel6&arch=$basearch'\ndefault['yum']['epel-testing-source']['gpgkey'] = 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6'\ndefault['yum']['epel-testing-source']['failovermethod'] = 'priority'\ndefault['yum']['epel-testing-source']['gpgcheck'] = true\ndefault['yum']['epel-testing-source']['enabled'] = false\ndefault['yum']['epel-testing-source']['managed'] = false\n```\n\n## Recipes\n- default - Walks through node attributes and feeds a yum_resource\n- parameters. The following is an example a resource generated by the\n- recipe during compilation.\n\n```ruby\n yum_repository 'epel' do\n mirrorlist 'http://mirrors.fedoraproject.org/mirrorlist?repo=epel-5&arch=$basearch'\n description 'Extra Packages for Enterprise Linux 5 - $basearch'\n enabled true\n gpgcheck true\n gpgkey 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL'\n end\n```\n\n## Usage Example\nTo disable the epel repository through a Role or Environment definition\n\n```\ndefault_attributes(\n :yum => {\n :epel => {\n :enabled => {\n false\n }\n }\n }\n )\n```\n\nUncommonly used repositoryids are not managed by default. This is speeds up integration testing pipelines by avoiding yum-cache builds that nobody cares about. To enable the epel-testing repository with a wrapper cookbook, place the following in a recipe:\n\n```ruby\nnode.default['yum']['epel-testing']['enabled'] = true\nnode.default['yum']['epel-testing']['managed'] = true\ninclude_recipe 'yum-epel'\n```\n\n## More Examples\nPoint the epel repositories at an internally hosted server.\n\n```ruby\nnode.default['yum']['epel']['enabled'] = true\nnode.default['yum']['epel']['mirrorlist'] = nil\nnode.default['yum']['epel']['baseurl'] = 'https://internal.example.com/centos/6/os/x86_64'\nnode.default['yum']['epel']['sslverify'] = false\n\ninclude_recipe 'yum-epel'\n```\n\n## License & Authors\n**Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io))\n\n**Copyright:** 2011-2016, Chef Software, Inc.\n\n```\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{"amazon":">= 0.0.0","centos":">= 0.0.0","oracle":">= 0.0.0","redhat":">= 0.0.0","scientific":">= 0.0.0","zlinux":">= 0.0.0"},"dependencies":{"yum":">= 3.6.3"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{},"source_url":"https://github.com/chef-cookbooks/yum-epel","issues_url":"https://github.com/chef-cookbooks/yum-epel/issues","chef_version":{},"ohai_version":{}} \ No newline at end of file diff --git a/cookbooks/yum-epel/recipes/default.rb b/cookbooks/yum-epel/recipes/default.rb index 31f3631..8347394 100644 --- a/cookbooks/yum-epel/recipes/default.rb +++ b/cookbooks/yum-epel/recipes/default.rb @@ -3,7 +3,7 @@ # Cookbook Name:: yum-epel # Recipe:: default # -# Copyright 2013-2015, Chef Software, Inc. +# Copyright 2013-2016, 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. @@ -35,6 +35,7 @@ node['yum-epel']['repositories'].each do |repo| include_config node['yum'][repo]['include_config'] unless node['yum'][repo]['include_config'].nil? includepkgs node['yum'][repo]['includepkgs'] unless node['yum'][repo]['includepkgs'].nil? keepalive node['yum'][repo]['keepalive'] unless node['yum'][repo]['keepalive'].nil? + make_cache node['yum'][repo]['make_cache'] unless node['yum'][repo]['make_cache'].nil? max_retries node['yum'][repo]['max_retries'] unless node['yum'][repo]['max_retries'].nil? metadata_expire node['yum'][repo]['metadata_expire'] unless node['yum'][repo]['metadata_expire'].nil? mirror_expire node['yum'][repo]['mirror_expire'] unless node['yum'][repo]['mirror_expire'].nil? diff --git a/cookbooks/yum/.foodcritic b/cookbooks/yum/.foodcritic new file mode 100644 index 0000000..b9f8767 --- /dev/null +++ b/cookbooks/yum/.foodcritic @@ -0,0 +1 @@ +~FC016 diff --git a/cookbooks/yum/CHANGELOG.md b/cookbooks/yum/CHANGELOG.md index da538bd..045b197 100644 --- a/cookbooks/yum/CHANGELOG.md +++ b/cookbooks/yum/CHANGELOG.md @@ -1,81 +1,144 @@ # yum Cookbook CHANGELOG + This file is used to list changes made in each version of the yum cookbook. +## 5.0.0 (2017-02-12) + +### Breaking changes + +- Removed the yum_repository resource and instead require chef-client 12.14 or later, which has the yum repository functionality built in. This resolves Chef 13 compatibility warnings for any cookbook with the yum cookbook. + +### Other changes + +- Convert yum_globalconfig from an LWRP to a custom resource + +## 4.2.0 (2017-02-12) + +- Make cache in the DNF compat recipe +- Fix `fastestmirror_enabled`. +- Require Chef 12.1 not 12.0 +- Convert to Inspec + +## 4.1.0 (2016-10-21) + +- Purge yum cache before removing a repo not after + +## 4.0.0 (2016-09-06) + +- Remove support for Chef 11 + +## 3.13.0 (2016-09-06) + +- Add deprecation warning for add/remove actions, which were replaced with create/delete in Yum 3.0 +- Remove support for Chef 10 + +## v3.12.0 (2016-08-25) + +- Fixing baseurl to support multiple urls +- Modify releasever attribute for Amazon to match Amazon's default policy for releasever + +## v3.11.0 (2016-06-01) + +- Install yum at compile time in the dnf compatibility recipe +- Add IBM zlinux as a supported platform in the metadata +- Use cookstyle instead of rubocop to provide a consistent linting experience + ## v3.10.0 (2016-02-04) + - Add a new sensitive attribute to the repository resource so prevent writing the diff of the config to Chef output / logs - Update testing dependencies and remove the Guardfile / Guard dependencies ## v3.9.0 (2016-01-14) + - Added dnf_yum_compat recipe to ensure yum is installed on Fedora systems for Chef package resource compatibility. This will no longer be necessary when native dnf package support ships in chef-client. ## v3.8.2 (2015-10-28) -- #141 - Replace clean_headers with clean_metadata + +- # 141 - Replace clean_headers with clean_metadata ## v3.8.1 (2015-10-28) + - Fixing up Chef13 deprecation warnings ## v3.8.0 (2015-10-13) + - adding clean_headers boolean property to yum_resource - restoring Chef 10 backwards compat for the sake of ChefSpec - (unique resource names needed to avoid cloning) - Fixing localpkg_gpgcheck values ## v3.7.1 (2015-09-08) -- #135 - reverting "yum clean headers" as it breaks dnf compat + +- # 135 - reverting "yum clean headers" as it breaks dnf compat ## v3.7.0 (2015-09-05) + - Adding deltarpm toggle - Cleaning 'headers' rather than 'all' ## v3.6.3 (2015-07-13) + - Normalizing sslverify option rendering behavior - Setting default value on the resource to nil - Explictly setting string to render in template if value is supplied - Behavior should default to "True", per man page ## v3.6.2 (2015-07-13) + - Adding -y to makecache, to import key when repo_gpgcheck = true. - Accepting Integer value for max_retries ## v3.6.1 (2015-06-04) + - Executing yum clean before makecache - Adding repo_gpgcheck ## v3.6.0 (2015-04-23) + - Adding "yum clean" before "yum makecache" in yum_repository :create - Adding why_run support to yum_globalconfig ## v3.5.4 (2015-04-07) + - Changing tolerant config line to stringified integer ## v3.5.3 (2015-01-16) + - Adding reposdir to globalconfig template ## v3.5.2 (2014-12-24) + - Fixing redhat-release detection for Redhat 7 ## v3.5.1 (2014-11-24) + - Reverting management of ca-certificates because EL5 was broken ## v3.5.0 (2014-11-24) + - Adding management of ca-certificates package to yum_repository provider ## v3.4.1 (2014-10-29) + - Run yum-makecache only_if new_resource.enabled - Allow setting of reposdir in global yum config and man page - Change default 'obsoletes' behavior to match yum defaults ## v3.4.0 (2014-10-15) + - Dynamically generate the new_resource attributes ## v3.3.2 (2014-09-11) + - Fix globalconfig resource param for http_caching ## v3.3.1 (2014-09-04) + - Fix issue with sslverify if set to false - Add fancy badges ## v3.3.0 (2014-09-03) + - Adding tuning attributes for all supported resource parameters - Adding options hash parameter - Adding (real) rhel-6.5 and centos-7.0 to test-kitchen coverage @@ -87,27 +150,35 @@ This file is used to list changes made in each version of the yum cookbook. - Adding mode parameter to repository resource. Defaults to '0644'. ## v3.2.4 (2014-08-20) -- #82 - Adding a makecache parameter + +- # 82 - Adding a makecache parameter ## v3.2.2 (2014-06-11) -- #77 - Parameter default to be Trueclass instead of "1" -- #78 - add releasever parameter + +- # 77 - Parameter default to be Trueclass instead of "1" + +- # 78 - add releasever parameter ## v3.2.0 (2014-04-09) + - [COOK-4510] - Adding username and password parameters to node attributes - [COOK-4518] - Fix Scientific Linux distroverpkg ## v3.1.6 (2014-03-27) + - [COOK-4463] - support multiple GPG keys - [COOK-4364] - yum_repository delete action fails ## v3.1.4 (2014-03-12) + - [COOK-4417] Expand test harness to encompass 32-bit boxes ## v3.1.2 (2014-02-23) + Fixing bugs around :delete action and cache clean Fixing specs to cover :remove and :delete aliasing properly Adding Travis-ci build matrix bits ## v3.1.0 (2014-02-13) + - Updating testing harness for integration testing on Travis-ci - Adding TESTING.md and Guardfile - PR #67 - Add skip_if_unvailable repository option @@ -118,60 +189,82 @@ Fixing bugs around :delete action and cache clean Fixing specs to cover :remove - Adding support for custom source template to yum_repository ## v3.0.8 (2014-01-27) + Fixing typo in default.rb. yum_globalconfig now passes proxy attribute correctly. ## v3.0.6 (2014-01-27) + Updating default.rb to consume node['yum']['main']['proxy'] ## v3.0.4 (2013-12-29) + ### Bug + - **[COOK-4156](https://tickets.chef.io/browse/COOK-4156)** - yum cookbook creates a yum.conf with "cachefir" directive ## v3.0.2 + Updating globalconfig provider for Chef 10 compatability ## v3.0.0 + 3.0.0 Major rewrite with breaking changes. Recipes broken out into individual cookbooks yum_key resource has been removed yum_repository resource now takes gpgkey as a URL directly yum_repository actions have been reduced to :create and :delete 'name' has been changed to repositoryid to avoid ambiguity chefspec test coverage gpgcheck is set to 'true' by default and must be explicitly disabled ## v2.4.4 + Reverting to Ruby 1.8 hash syntax. ## v2.4.2 + [COOK-3275] LWRP repository.rb :add method fails to create yum repo in some cases which causes :update to fail Amazon rhel ## v2.4.0 + ### Improvement + - [COOK-3025] - Allow per-repo proxy definitions ## v2.3.4 + ### Improvement + - **[COOK-3689](https://tickets.chef.io/browse/COOK-3689)** - Fix warnings about resource cloning - **[COOK-3574](https://tickets.chef.io/browse/COOK-3574)** - Add missing "description" field in metadata ## v2.3.2 + ### Bug + - **[COOK-3145](https://tickets.chef.io/browse/COOK-3145)** - Use correct download URL for epel `key_url` ## v2.3.0 + ### New Feature + - [COOK-2924]: Yum should allow type setting in repo file ## v2.2.4 + ### Bug + - [COOK-2360]: last commit to `yum_repository` changes previous behaviour - [COOK-3015]: Yum cookbook test minitest to fail ## v2.2.2 + ### Improvement + - [COOK-2741]: yum::elrepo - [COOK-2946]: update tests, test kitchen support in yum cookbook ### Bug + - [COOK-2639]: Yum cookbook - epel - always assumes url is a mirror list - [COOK-2663]: Yum should allow metadata_expire setting in repo file - [COOK-2751]: Update yum.ius_release version to 1.0-11 ## v2.2.0 + - [COOK-2189] - yum::ius failed on install (caused from rpm dependency) - [COOK-2196] - Make includepkgs and exclude configurable for each repos - [COOK-2244] - Allow configuring caching using attributes @@ -181,43 +274,55 @@ Reverting to Ruby 1.8 hash syntax. - [COOK-2643] - don't use conditional attribute for `yum_key` `remote_file` ## v2.1.0 + - [COOK-2045] - add remi repository recipe - [COOK-2121] - add `:create` action to `yum_repository` ## v2.0.6 + - [COOK-2037] - minor style fixes - [COOK-2038] - updated README ## v2.0.4 + - [COOK-1908] - unable to install repoforge on CentOS 6 32 bit ## v2.0.2 + - [COOK-1758] - Add default action for repository resource ## v2.0.0 + This version changes the behavior of the EPEL recipe (most commonly used in other Chef cookbooks) on Amazon, and removes an attribute, `node['yum']['epel_release']`. See the README for details. + - [COOK-1772] - Simplify management of EPEL with LWRP ## v1.0.0 + `mirrorlist` in the `yum_repository` LWRP must be set to the mirror list URI to use rather than setting it to true. See README.md. + - [COOK-1088] - use dl.fedoraproject.org for EPEL to prevent redirects - [COOK-1653] - fix mirrorlist - [COOK-1710] - support http proxy - [COOK-1722] - update IUS version ## v0.8.2 + - [COOK-1521] - add :update action to `yum_repository` ## v0.8.0 + - [COOK-1204] - Make 'add' default action for yum_repository - [COOK-1351] - option to not make the yum cache (via attribute) - [COOK-1353] - x86_64 centos path fixes - [COOK-1414] - recipe for repoforge ## v0.6.2 + - Updated README to remove git diff artifacts. ## v0.6.0 + - Default action for the yum_repository LWRP is now add. - [COOK-1227] - clear Chefs internal cache after adding new yum repo - [COOK-1262] - yum::epel should enable existing repo on Amazon Linux @@ -226,11 +331,14 @@ This version changes the behavior of the EPEL recipe (most commonly used in othe - [COOK-1346] - retry remote_file for EPEL in case we get an FTP mirror ## v0.5.2 + - [COOK-825] - epel and ius `remote_file` should notify the `rpm_package` to install ## v0.5.0 + - [COOK-675] - add recipe for handling EPEL repository - [COOK-722] - add recipe for handling IUS repository ## v.0.1.2 + - Remove yum update in default recipe, that doesn't update caches, it updates packages installed. diff --git a/cookbooks/yum/MAINTAINERS.md b/cookbooks/yum/MAINTAINERS.md index f180113..b3548a4 100644 --- a/cookbooks/yum/MAINTAINERS.md +++ b/cookbooks/yum/MAINTAINERS.md @@ -1,16 +1,13 @@ # Maintainers -This file lists how this cookbook project is maintained. When making changes to the system, this -file tells you who needs to review your patch - you need a simple majority of maintainers -for the relevant subsystems to provide a :+1: on your pull request. Additionally, you need -to not receive a veto from a Lieutenant or the Project Lead. -Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) -for details on the process and how to become a maintainer or the project lead. +This file lists how this cookbook project is maintained. When making changes to the system, this file tells you who needs to review your patch - you need a review from an existing maintainer for the cookbook to provide a :+1: on your pull request. Additionally, you need to not receive a veto from a Lieutenant or the Project Lead. + +Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) for details on the process and how to become a maintainer or the project lead. # Project Maintainer -* [Sean OMeara](https://github.com/someara) +* [Tim Smith](https://github.com/tas50) # Maintainers * [Jennifer Davis](https://github.com/sigje) diff --git a/cookbooks/yum/README.md b/cookbooks/yum/README.md index 94527cc..a312325 100644 --- a/cookbooks/yum/README.md +++ b/cookbooks/yum/README.md @@ -1,95 +1,28 @@ # yum Cookbook -[![Build Status](https://travis-ci.org/chef-cookbooks/yum.svg?branch=master)](http://travis-ci.org/chef-cookbooks/yum) [![Cookbook Version](https://img.shields.io/cookbook/v/yum.svg)](https://supermarket.chef.io/cookbooks/yum) [![Code Climate](https://codeclimate.com/github/chef-cookbooks/yum/badges/gpa.svg)](https://codeclimate.com/github/chef-cookbooks/yum) -The Yum cookbook exposes the `yum_globalconfig` and `yum_repository` resources that allows a user to both control global behavior and make individual Yum repositories available for use. These resources aim to allow the user to configure all options listed in the `yum.conf` man page, found at [http://linux.die.net/man/5/yum.conf](http://linux.die.net/man/5/yum.conf) +[![Build Status](https://travis-ci.org/chef-cookbooks/yum.svg?branch=master)](http://travis-ci.org/chef-cookbooks/yum) [![Cookbook Version](https://img.shields.io/cookbook/v/yum.svg)](https://supermarket.chef.io/cookbooks/yum) -## NOTES -WARNING: Yum cookbook version 3.0.0 and above contain non-backwards compatible breaking changes and will not work with cookbooks written against the 2.x and 1.x series. Changes have been made to the yum_repository resource, and the yum_key resource has been eliminated entirely. Recipes have been eliminated and moved into their own cookbooks. Please lock yum to the 2.x series in your Chef environments until all dependent cookbooks have been ported. +The Yum cookbook exposes the `yum_globalconfig` resource which allows a user to control global yum behavior. This resources aims to allow the user to configure all options listed in the `yum.conf` man page, found at ## Requirements + ### Platforms + - RHEL/CentOS and derivatives - Fedora ### Chef -- Chef 11+ + +- Chef 12.14+ ### Cookbooks + - none -## Resources/Providers -### yum_repository -This resource manages a yum repository configuration file at /etc/yum.repos.d/`repositoryid`.repo. When the file needs to be repaired, it calls yum-makecache so packages in the repo become available to the next resource. - -#### Example - -```ruby -# add the Zenoss repository -yum_repository 'zenoss' do - description "Zenoss Stable repo" - baseurl "http://dev.zenoss.com/yum/stable/" - gpgkey 'http://dev.zenoss.com/yum/RPM-GPG-KEY-zenoss' - action :create -end - -# add the EPEL repo -yum_repository 'epel' do - description 'Extra Packages for Enterprise Linux' - mirrorlist 'http://mirrors.fedoraproject.org/mirrorlist?repo=epel-6&arch=$basearch' - gpgkey 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6' - action :create -end -``` - -```ruby -# delete CentOS-Media repo -yum_repository 'CentOS-Media' do - action :delete -end -``` - -#### Actions -- `:create` - creates a repository file and builds the repository listing -- `:delete` - deletes the repository file -- `:makecache` - update yum cache - -#### Parameters -- `baseurl` - Must be a URL to the directory where the yum repository's 'repodata' directory lives. Can be an http://, ftp:// or file:// URL. You can specify multiple URLs in one baseurl statement. -- `cost` - relative cost of accessing this repository. Useful for weighing one repo's packages as greater/less than any other. defaults to 1000 -- `clean_metadata` - Run "yum clean metadata " during repository creation. defaults to true. -- `description` - Maps to the 'name' parameter in a repository .conf. Descriptive name for the repository channel. This directive must be specified. -- `enabled` - Either `true` or `false`. This tells yum whether or not use this repository. -- `enablegroups` - Either `true` or `false`. Determines whether yum will allow the use of package groups for this repository. Default is `true` (package groups are allowed). -- `exclude` - List of packages to exclude from updates or installs. This should be a space separated list in a single string. Shell globs using wildcards (eg. * and ?) are allowed. -- `failovermethod` - Either 'roundrobin' or 'priority'. -- `fastestmirror_enabled` - Either `true` or `false` -- `gpgcheck` - Either `true` or `false`. This tells yum whether or not it should perform a GPG signature check on packages. When this is set in the [main] section it sets the default for all repositories. The default is `true`. -- `gpgkey` - A URL pointing to the ASCII-armored GPG key file for the repository. This option is used if yum needs a public key to verify a package and the required key hasn't been imported into the RPM database. If this option is set, yum will automatically import the key from the specified URL. -- `http_caching` - Either 'all', 'packages', or 'none'. Determines how upstream HTTP caches are instructed to handle any HTTP downloads that Yum does. Defaults to 'all' -- `includepkgs` - Inverse of exclude. This is a list of packages you want to use from a repository. If this option lists only one package then that is all yum will ever see from the repository. Defaults to an empty list. -- `keepalive` - Either `true` or `false`. This tells yum whether or not HTTP/1.1 keepalive should be used with this repository. -- `make_cache` - Optional, Default is `true`, if `false` then `yum -q makecache` will not be ran -- `max_retries` - Set the number of times any attempt to retrieve a file should retry before returning an error. Setting this to '0' makes yum try forever. Default is '10'. -- `metadata_expire` - Time (in seconds) after which the metadata will expire. So that if the current metadata downloaded is less than this many seconds old then yum will not update the metadata against the repository. If you find that yum is not downloading information on updates as often as you would like lower the value of this option. You can also change from the default of using seconds to using days, hours or minutes by appending a d, h or m respectively. The default is 6 hours, to compliment yum-updatesd running once an hour. It's also possible to use the word "never", meaning that the metadata will never expire. Note that when using a metalink file the metalink must always be newer than the metadata for the repository, due to the validation, so this timeout also applies to the metalink file. -- `mirrorlist` - Specifies a URL to a file containing a list of baseurls. This can be used instead of or with the baseurl option. Substitution variables, described below, can be used with this option. As a special hack is the mirrorlist URL contains the word "metalink" then the value of mirrorlist is copied to metalink (if metalink is not set) -- `mirror_expire` - Time (in seconds) after which the mirrorlist locally cached will expire. If the current mirrorlist is less than this many seconds old then yum will not download another copy of the mirrorlist, it has the same extra format as metadata_expire. If you find that yum is not downloading the mirrorlists as often as you would like lower the value of this option. -- `mirrorlist_expire` - alias for mirror_expire -- `mode` - Permissions mode of .repo file on disk. Useful for scenarios where secrets are in the repo file. If set to '600', normal users will not be able to use yum search, yum info, etc. Defaults to '0644' -- `priority` - When the yum-priorities plug-in is enabled, you set priorities on repository entries, where N is an integer from 1 to 99. The default priority for repositories is 99. -- `proxy` - URL to the proxy server that yum should use. -- `proxy_username` - username to use for proxy -- `proxy_password` - password for this proxy -- `report_instanceid` - Report instance ID when using Amazon Linux AMIs and repositories -- `repositoryid` - Must be a unique name for each repository, one word. Defaults to name attribute. -- `sensitive` - Optional, Default is `false`, if `true` then content of repository file is hidden from chef run output. -- `source` - Use a custom template source instead of the default one in the yum cookbook -- `sslcacert` - Path to the directory containing the databases of the certificate authorities yum should use to verify SSL certificates. Defaults to none - uses system default -- `sslclientcert` - Path to the SSL client certificate yum should use to connect to repos/remote sites Defaults to none. -- `sslclientkey` - Path to the SSL client key yum should use to connect to repos/remote sites Defaults to none. -- `sslverify` - Either `true` or `false`. Determines if yum will verify SSL certificates/hosts. Defaults to `true` -- `timeout` - Number of seconds to wait for a connection before timing out. Defaults to 30 seconds. This may be too short of a time for extremely overloaded sites. +## Resources ### yum_globalconfig + This renders a template with global yum configuration parameters. The default recipe uses it to render `/etc/yum.conf`. It is flexible enough to be used in other scenarios, such as building RPMs in isolation by modifying `installroot`. #### Example @@ -104,22 +37,30 @@ yum_globalconfig '/my/chroot/etc/yum.conf' do end ``` -#### Parameters -`yum_globalconfig` can take most of the same parameters as a `yum_repository`, plus more, too numerous to describe here. Below are a few of the more commonly used ones. For a complete list, please consult the `yum.conf` man page, found here: [http://linux.die.net/man/5/yum.conf](http://linux.die.net/man/5/yum.conf) +#### Properties + +`yum_globalconfig` can take most of the same parameters as a `yum_repository`, plus more, too numerous to describe here. Below are a few of the more commonly used ones. For a complete list, please consult the `yum.conf` man page, found here: + - `cachedir` - Directory where yum should store its cache and db files. The default is '/var/cache/yum'. - `keepcache` - Either `true` or `false`. Determines whether or not yum keeps the cache of headers and packages after successful installation. Default is `false` -- `debuglevel` - Debug message output level. Practical range is 0-10. Default is '2'. +- `debuglevel` - Debug message output level. Practical range is 0-10\. Default is '2'. - `exclude` - List of packages to exclude from updates or installs. This should be a space separated list. Shell globs using wildcards (eg. * and ?) are allowed. - `installonlypkgs` = List of package provides that should only ever be installed, never updated. Kernels in particular fall into this category. Defaults to kernel, kernel-bigmem, kernel-enterprise, kernel-smp, kernel-debug, kernel-unsupported, kernel-source, kernel-devel, kernel-PAE, kernel-PAE-debug. - `logfile` - Full directory and file name for where yum should write its log file. -- `exactarch` - Either `true` or `false`. Set to `true` to make 'yum update' only update the architectures of packages that you have installed. ie: with this enabled yum will not install an i686 package to update an x86_64 package. Default is `true` +- `exactarch` - Either `true` or `false`. Set to `true` to make 'yum update' only update the architectures of packages that you have installed. ie: with this enabled yum will not install an i686 package to update an x86_64 package. Default is `true` - `gpgcheck` - Either `true` or `false`. This tells yum whether or not it should perform a GPG signature check on the packages gotten from this repository. +### yum_repository + +This resource is now provided by chef-client 12.14 and later and has been removed from this cookbook. If you require this resource we highly recommend upgrading your chef-client, but if that is not an option you can pin the 4.X yum cookbook. + ## Recipes + - `default` - Configures `yum_globalconfig[/etc/yum.conf]` with values found in node attributes at `node['yum']['main']` -- `dnf_yum_compat` - Installs the yum package using dnf on Fedora systems to provide support for the package resource in recipes. This is necessary as Chef does not yet (as of Q4 2015) have native support for DNF. This recipe should be 1st on a Fedora runlist +- `dnf_yum_compat` - Installs the yum package using dnf on Fedora systems to provide support for the package resource in recipes. This is necessary on chef-client < 12.18\. This recipe should be 1st on a Fedora runlist ## Attributes + The following attributes are set by default ```ruby @@ -135,8 +76,16 @@ default['yum']['main']['installonlypkgs'] = nil default['yum']['main']['installroot'] = nil ``` +For Amazon platform nodes, + +```ruby +default['yum']['main']['releasever'] = 'latest' +``` + ## Related Cookbooks + Recipes from older versions of this cookbook have been moved individual cookbooks. Recipes for managing platform yum configurations and installing specific repositories can be found in one (or more!) of the following cookbook. + - yum-centos - yum-fedora - yum-amazon @@ -148,9 +97,11 @@ Recipes from older versions of this cookbook have been moved individual cookbook - yum-pgdg ## Usage + Put `depends 'yum'` in your metadata.rb to gain access to the yum_repository resource. ## License & Authors + - Author:: Eric G. Wolfe - Author:: Matt Ray ([matt@chef.io](mailto:matt@chef.io)) - Author:: Joshua Timberman ([joshua@chef.io](mailto:joshua@chef.io)) @@ -158,7 +109,7 @@ Put `depends 'yum'` in your metadata.rb to gain access to the yum_repository res ```text Copyright:: 2011 Eric G. Wolfe -Copyright:: 2013-2016 Chef Software, Inc. +Copyright:: 2013-2017 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/cookbooks/yum/attributes/main.rb b/cookbooks/yum/attributes/main.rb index 7c09fff..8eb3784 100644 --- a/cookbooks/yum/attributes/main.rb +++ b/cookbooks/yum/attributes/main.rb @@ -16,7 +16,11 @@ default['yum']['main']['distroverpkg'] = case node['platform'] else "#{node['platform']}-release" end - +# default["yum"]["main"]["releasever"] = nil # /.*/ +default['yum']['main']['releasever'] = case node['platform'] + when 'amazon' + 'latest' + end default['yum']['main']['alwaysprompt'] = nil # [TrueClass, FalseClass] default['yum']['main']['assumeyes'] = nil # [TrueClass, FalseClass] default['yum']['main']['bandwidth'] = nil # /^\d+$/ @@ -78,7 +82,6 @@ default['yum']['main']['proxy_password'] = nil # /.*/ default['yum']['main']['proxy_username'] = nil # /.*/ default['yum']['main']['password'] = nil # /.*/ default['yum']['main']['recent'] = nil # /^\d+$/ -default['yum']['main']['releasever'] = nil # /.*/ default['yum']['main']['repo_gpgcheck'] = nil # [TrueClass, FalseClass] default['yum']['main']['reposdir'] = nil # /.*/ default['yum']['main']['reset_nice'] = nil # [TrueClass, FalseClass] diff --git a/cookbooks/yum/libraries/matchers.rb b/cookbooks/yum/libraries/matchers.rb index 433347b..220238a 100644 --- a/cookbooks/yum/libraries/matchers.rb +++ b/cookbooks/yum/libraries/matchers.rb @@ -1,22 +1,4 @@ -# Matchers for chefspec 3 - if defined?(ChefSpec) - def create_yum_repository(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:yum_repository, :create, resource_name) - end - - def add_yum_repository(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:yum_repository, :add, resource_name) - end - - def delete_yum_repository(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:yum_repository, :delete, resource_name) - end - - def remove_yum_repository(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:yum_repository, :remove, resource_name) - end - def create_yum_globalconfig(resource_name) ChefSpec::Matchers::ResourceMatcher.new(:yum_globalconfig, :create, resource_name) end diff --git a/cookbooks/yum/metadata.json b/cookbooks/yum/metadata.json index aeac5ff..550e2ab 100644 --- a/cookbooks/yum/metadata.json +++ b/cookbooks/yum/metadata.json @@ -1 +1 @@ -{"name":"yum","version":"3.10.0","description":"Configures various yum components on Red Hat-like systems","long_description":"","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{"amazon":">= 0.0.0","centos":">= 0.0.0","fedora":">= 0.0.0","oracle":">= 0.0.0","redhat":">= 0.0.0","scientific":">= 0.0.0"},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{}} \ No newline at end of file +{"name":"yum","version":"5.0.0","description":"Configures various yum components on Red Hat-like systems","long_description":"","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{"amazon":">= 0.0.0","centos":">= 0.0.0","fedora":">= 0.0.0","oracle":">= 0.0.0","redhat":">= 0.0.0","scientific":">= 0.0.0","zlinux":">= 0.0.0"},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{}} \ No newline at end of file diff --git a/cookbooks/yum/providers/repository.rb b/cookbooks/yum/providers/repository.rb deleted file mode 100644 index 8319671..0000000 --- a/cookbooks/yum/providers/repository.rb +++ /dev/null @@ -1,114 +0,0 @@ -# -# Cookbook Name:: yum -# Provider:: repository -# -# Author:: Sean OMeara -# Copyright 2013, Chef -# -# 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. -# - -# In Chef 11 and above, calling the use_inline_resources method will -# make Chef create a new "run_context". When an action is called, any -# nested resources are compiled and converged in isolation from the -# recipe that calls it. - -# Allow for Chef 10 support -use_inline_resources if defined?(use_inline_resources) - -def whyrun_supported? - true -end - -action :create do - # Hack around the lack of "use_inline_resources" before Chef 11 by - # uniquely naming the execute[yum-makecache] resources. Set the - # notifies timing to :immediately for the same reasons. Remove both - # of these when dropping Chef 10 support. - - if new_resource.clean_headers - Chef::Log.warn <<-eos - Use of `clean_headers` in resource yum[#{new_resource.repositoryid}] is now deprecated and will be removed in a future release. - `clean_metadata` should be used instead - eos - end - - template "/etc/yum.repos.d/#{new_resource.repositoryid}.repo" do - if new_resource.source.nil? - source 'repo.erb' - cookbook 'yum' - else - source new_resource.source - end - mode new_resource.mode - sensitive new_resource.sensitive - variables(config: new_resource) - if new_resource.make_cache - notifies :run, "execute[yum clean metadata #{new_resource.repositoryid}]", :immediately if new_resource.clean_metadata || new_resource.clean_headers - notifies :run, "execute[yum-makecache-#{new_resource.repositoryid}]", :immediately - notifies :create, "ruby_block[yum-cache-reload-#{new_resource.repositoryid}]", :immediately - end - end - - execute "yum clean metadata #{new_resource.repositoryid}" do - command "yum clean metadata --disablerepo=* --enablerepo=#{new_resource.repositoryid}" - action :nothing - end - - # get the metadata for this repo only - execute "yum-makecache-#{new_resource.repositoryid}" do - command "yum -q -y makecache --disablerepo=* --enablerepo=#{new_resource.repositoryid}" - action :nothing - only_if { new_resource.enabled } - end - - # reload internal Chef yum cache - ruby_block "yum-cache-reload-#{new_resource.repositoryid}" do - block { Chef::Provider::Package::Yum::YumCache.instance.reload } - action :nothing - end -end - -action :delete do - file "/etc/yum.repos.d/#{new_resource.repositoryid}.repo" do - action :delete - notifies :run, "execute[yum clean all #{new_resource.repositoryid}]", :immediately - notifies :create, "ruby_block[yum-cache-reload-#{new_resource.repositoryid}]", :immediately - end - - execute "yum clean all #{new_resource.repositoryid}" do - command "yum clean all --disablerepo=* --enablerepo=#{new_resource.repositoryid}" - only_if "yum repolist | grep -P '^#{new_resource.repositoryid}([ \t]|$)'" - action :nothing - end - - ruby_block "yum-cache-reload-#{new_resource.repositoryid}" do - block { Chef::Provider::Package::Yum::YumCache.instance.reload } - action :nothing - end -end - -action :makecache do - execute "yum-makecache-#{new_resource.repositoryid}" do - command "yum -q makecache --disablerepo=* --enablerepo=#{new_resource.repositoryid}" - action :run - end - - ruby_block "yum-cache-reload-#{new_resource.repositoryid}" do - block { Chef::Provider::Package::Yum::YumCache.instance.reload } - action :run - end -end - -alias_method :action_add, :action_create -alias_method :action_remove, :action_delete diff --git a/cookbooks/yum/recipes/default.rb b/cookbooks/yum/recipes/default.rb index a89e2d1..2270028 100644 --- a/cookbooks/yum/recipes/default.rb +++ b/cookbooks/yum/recipes/default.rb @@ -3,7 +3,7 @@ # Author:: Joshua Timberman () # Recipe:: yum::default # -# Copyright 2013-2014, Chef Software, Inc () +# Copyright:: 2013-2016, 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/cookbooks/yum/recipes/dnf_yum_compat.rb b/cookbooks/yum/recipes/dnf_yum_compat.rb index dff6df6..f217cb7 100644 --- a/cookbooks/yum/recipes/dnf_yum_compat.rb +++ b/cookbooks/yum/recipes/dnf_yum_compat.rb @@ -2,7 +2,7 @@ # Author:: Tim Smith () # Recipe:: yum::fedora_yum_compat # -# Copyright 2015, Chef Software, Inc () +# Copyright:: 2015-2016, 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. @@ -16,8 +16,14 @@ # See the License for the specific language governing permissions and # limitations under the License. +execute 'make yum cache' do + command 'yum makecache' + action :nothing +end + execute 'install yum' do command 'dnf install yum -y' not_if { ::File.exist?('/var/lib/yum') } - action :run -end + action :nothing + notifies :run, 'execute[make yum cache]', :immediately +end.run_action(:run) diff --git a/cookbooks/yum/resources/globalconfig.rb b/cookbooks/yum/resources/globalconfig.rb index b8d66d9..a452e4c 100644 --- a/cookbooks/yum/resources/globalconfig.rb +++ b/cookbooks/yum/resources/globalconfig.rb @@ -1,9 +1,9 @@ # -# Cookbook Name:: yum +# Cookbook:: yum # Resource:: repository # # Author:: Sean OMeara -# Copyright 2013, Chef +# Copyright:: 2013-2017, 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. @@ -18,92 +18,102 @@ # limitations under the License. # -actions :create, :delete - -default_action :create - # http://linux.die.net/man/5/yum.conf -attribute :alwaysprompt, kind_of: [TrueClass, FalseClass], default: nil -attribute :assumeyes, kind_of: [TrueClass, FalseClass], default: nil -attribute :bandwidth, kind_of: String, regex: /^\d+/, default: nil -attribute :bugtracker_url, kind_of: String, regex: /.*/, default: nil -attribute :clean_requirements_on_remove, kind_of: [TrueClass, FalseClass], default: nil -attribute :cachedir, kind_of: String, regex: /.*/, default: '/var/cache/yum/$basearch/$releasever' -attribute :color, kind_of: String, equal_to: %w(always never), default: nil -attribute :color_list_available_downgrade, kind_of: String, regex: /.*/, default: nil -attribute :color_list_available_install, kind_of: String, regex: /.*/, default: nil -attribute :color_list_available_reinstall, kind_of: String, regex: /.*/, default: nil -attribute :color_list_available_upgrade, kind_of: String, regex: /.*/, default: nil -attribute :color_list_installed_extra, kind_of: String, regex: /.*/, default: nil -attribute :color_list_installed_newer, kind_of: String, regex: /.*/, default: nil -attribute :color_list_installed_older, kind_of: String, regex: /.*/, default: nil -attribute :color_list_installed_reinstall, kind_of: String, regex: /.*/, default: nil -attribute :color_search_match, kind_of: String, regex: /.*/, default: nil -attribute :color_update_installed, kind_of: String, regex: /.*/, default: nil -attribute :color_update_local, kind_of: String, regex: /.*/, default: nil -attribute :color_update_remote, kind_of: String, regex: /.*/, default: nil -attribute :commands, kind_of: String, regex: /.*/, default: nil -attribute :debuglevel, kind_of: String, regex: /^\d+$/, default: '2' -attribute :deltarpm, kind_of: [TrueClass, FalseClass], default: nil -attribute :diskspacecheck, kind_of: [TrueClass, FalseClass], default: nil -attribute :distroverpkg, kind_of: String, regex: /.*/, default: nil -attribute :enable_group_conditionals, kind_of: [TrueClass, FalseClass], default: nil -attribute :errorlevel, kind_of: String, regex: /^\d+$/, default: nil -attribute :exactarch, kind_of: [TrueClass, FalseClass], default: true -attribute :exclude, kind_of: String, regex: /.*/, default: nil -attribute :gpgcheck, kind_of: [TrueClass, FalseClass], default: true -attribute :group_package_types, kind_of: String, regex: /.*/, default: nil -attribute :groupremove_leaf_only, kind_of: [TrueClass, FalseClass], default: nil -attribute :history_list_view, kind_of: String, equal_to: %w(users commands single-user-commands), default: nil -attribute :history_record, kind_of: [TrueClass, FalseClass], default: nil -attribute :history_record_packages, kind_of: String, regex: /.*/, default: nil -attribute :http_caching, kind_of: String, equal_to: %w(packages all none), default: nil -attribute :installonly_limit, kind_of: String, regex: [/^\d+/, /keep/], default: '3' -attribute :installonlypkgs, kind_of: String, regex: /.*/, default: nil -attribute :installroot, kind_of: String, regex: /.*/, default: nil -attribute :keepalive, kind_of: [TrueClass, FalseClass], default: nil -attribute :keepcache, kind_of: [TrueClass, FalseClass], default: false -attribute :kernelpkgnames, kind_of: String, regex: /.*/, default: nil -attribute :localpkg_gpgcheck, kind_of: [TrueClass, FalseClass], default: nil -attribute :logfile, kind_of: String, regex: /.*/, default: '/var/log/yum.log' -attribute :max_retries, kind_of: String, regex: /^\d+$/, default: nil -attribute :mdpolicy, kind_of: String, equal_to: %w(instant group:primary group:small group:main group:all), default: nil -attribute :metadata_expire, kind_of: String, regex: [/^\d+$/, /^\d+[mhd]$/, /never/], default: nil -attribute :mirrorlist_expire, kind_of: String, regex: /^\d+$/, default: nil -attribute :multilib_policy, kind_of: String, equal_to: %w(all best), default: nil -attribute :obsoletes, kind_of: [TrueClass, FalseClass], default: nil -attribute :overwrite_groups, kind_of: [TrueClass, FalseClass], default: nil -attribute :password, kind_of: String, regex: /.*/, default: nil -attribute :path, kind_of: String, regex: /.*/, name_attribute: true -attribute :persistdir, kind_of: String, regex: /.*/, default: nil -attribute :pluginconfpath, kind_of: String, regex: /.*/, default: nil -attribute :pluginpath, kind_of: String, regex: /.*/, default: nil -attribute :plugins, kind_of: [TrueClass, FalseClass], default: true -attribute :protected_multilib, kind_of: [TrueClass, FalseClass], default: nil -attribute :protected_packages, kind_of: String, regex: /.*/, default: nil -attribute :proxy, kind_of: String, regex: /.*/, default: nil -attribute :proxy_password, kind_of: String, regex: /.*/, default: nil -attribute :proxy_username, kind_of: String, regex: /.*/, default: nil -attribute :recent, kind_of: String, regex: /^\d+$/, default: nil -attribute :releasever, kind_of: String, regex: /.*/, default: nil -attribute :repo_gpgcheck, kind_of: [TrueClass, FalseClass], default: nil -attribute :reposdir, kind_of: String, regex: /.*/, default: nil -attribute :reset_nice, kind_of: [TrueClass, FalseClass], default: nil -attribute :rpmverbosity, kind_of: String, equal_to: %w(info critical emergency error warn debug), default: nil -attribute :showdupesfromrepos, kind_of: [TrueClass, FalseClass], default: nil -attribute :skip_broken, kind_of: [TrueClass, FalseClass], default: nil -attribute :ssl_check_cert_permissions, kind_of: [TrueClass, FalseClass], default: nil -attribute :sslcacert, kind_of: String, regex: /.*/, default: nil -attribute :sslclientcert, kind_of: String, regex: /.*/, default: nil -attribute :sslclientkey, kind_of: String, regex: /.*/, default: nil -attribute :sslverify, kind_of: [TrueClass, FalseClass], default: nil -attribute :syslog_device, kind_of: String, regex: /.*/, default: nil -attribute :syslog_facility, kind_of: String, regex: /.*/, default: nil -attribute :syslog_ident, kind_of: String, regex: /.*/, default: nil -attribute :throttle, kind_of: String, regex: [/\d+k/, /\d+M/, /\d+G/], default: nil -attribute :timeout, kind_of: String, regex: /^\d+$/, default: nil -attribute :tolerant, kind_of: [TrueClass, FalseClass], default: nil -attribute :tsflags, kind_of: String, regex: /.*/, default: nil -attribute :username, kind_of: String, regex: /.*/, default: nil +property :alwaysprompt, [TrueClass, FalseClass] +property :assumeyes, [TrueClass, FalseClass] +property :bandwidth, String, regex: /^\d+/ +property :bugtracker_url, String, regex: /.*/ +property :clean_requirements_on_remove, [TrueClass, FalseClass] +property :cachedir, String, regex: /.*/, default: '/var/cache/yum/$basearch/$releasever' +property :color, String, equal_to: %w(always never) +property :color_list_available_downgrade, String, regex: /.*/ +property :color_list_available_install, String, regex: /.*/ +property :color_list_available_reinstall, String, regex: /.*/ +property :color_list_available_upgrade, String, regex: /.*/ +property :color_list_installed_extra, String, regex: /.*/ +property :color_list_installed_newer, String, regex: /.*/ +property :color_list_installed_older, String, regex: /.*/ +property :color_list_installed_reinstall, String, regex: /.*/ +property :color_search_match, String, regex: /.*/ +property :color_update_installed, String, regex: /.*/ +property :color_update_local, String, regex: /.*/ +property :color_update_remote, String, regex: /.*/ +property :commands, String, regex: /.*/ +property :debuglevel, String, regex: /^\d+$/, default: '2' +property :deltarpm, [TrueClass, FalseClass] +property :diskspacecheck, [TrueClass, FalseClass] +property :distroverpkg, String, regex: /.*/ +property :enable_group_conditionals, [TrueClass, FalseClass] +property :errorlevel, String, regex: /^\d+$/ +property :exactarch, [TrueClass, FalseClass], default: true +property :exclude, String, regex: /.*/ +property :gpgcheck, [TrueClass, FalseClass], default: true +property :group_package_types, String, regex: /.*/ +property :groupremove_leaf_only, [TrueClass, FalseClass] +property :history_list_view, String, equal_to: %w(users commands single-user-commands) +property :history_record, [TrueClass, FalseClass] +property :history_record_packages, String, regex: /.*/ +property :http_caching, String, equal_to: %w(packages all none) +property :installonly_limit, String, regex: [/^\d+/, /keep/], default: '3' +property :installonlypkgs, String, regex: /.*/ +property :installroot, String, regex: /.*/ +property :keepalive, [TrueClass, FalseClass] +property :keepcache, [TrueClass, FalseClass], default: false +property :kernelpkgnames, String, regex: /.*/ +property :localpkg_gpgcheck, [TrueClass, FalseClass] +property :logfile, String, regex: /.*/, default: '/var/log/yum.log' +property :max_retries, String, regex: /^\d+$/ +property :mdpolicy, String, equal_to: %w(instant group:primary group:small group:main group:all) +property :metadata_expire, String, regex: [/^\d+$/, /^\d+[mhd]$/, /never/] +property :mirrorlist_expire, String, regex: /^\d+$/ +property :multilib_policy, String, equal_to: %w(all best) +property :obsoletes, [TrueClass, FalseClass] +property :overwrite_groups, [TrueClass, FalseClass] +property :password, String, regex: /.*/ +property :path, String, regex: /.*/, name_property: true +property :persistdir, String, regex: /.*/ +property :pluginconfpath, String, regex: /.*/ +property :pluginpath, String, regex: /.*/ +property :plugins, [TrueClass, FalseClass], default: true +property :protected_multilib, [TrueClass, FalseClass] +property :protected_packages, String, regex: /.*/ +property :proxy, String, regex: /.*/ +property :proxy_password, String, regex: /.*/ +property :proxy_username, String, regex: /.*/ +property :recent, String, regex: /^\d+$/ +property :releasever, String, regex: /.*/ +property :repo_gpgcheck, [TrueClass, FalseClass] +property :reposdir, String, regex: /.*/ +property :reset_nice, [TrueClass, FalseClass] +property :rpmverbosity, String, equal_to: %w(info critical emergency error warn debug) +property :showdupesfromrepos, [TrueClass, FalseClass] +property :skip_broken, [TrueClass, FalseClass] +property :ssl_check_cert_permissions, [TrueClass, FalseClass] +property :sslcacert, String, regex: /.*/ +property :sslclientcert, String, regex: /.*/ +property :sslclientkey, String, regex: /.*/ +property :sslverify, [TrueClass, FalseClass] +property :syslog_device, String, regex: /.*/ +property :syslog_facility, String, regex: /.*/ +property :syslog_ident, String, regex: /.*/ +property :throttle, String, regex: [/\d+k/, /\d+M/, /\d+G/] +property :timeout, String, regex: /^\d+$/ +property :tolerant, [TrueClass, FalseClass] +property :tsflags, String, regex: /.*/ +property :username, String, regex: /.*/ +property :options, Hash -attribute :options, kind_of: Hash +action :create do + template new_resource.path do + source 'main.erb' + cookbook 'yum' + mode '0644' + variables(config: new_resource) + end +end + +action :delete do + file new_resource.path do + action :delete + end +end diff --git a/cookbooks/yum/resources/repository.rb b/cookbooks/yum/resources/repository.rb deleted file mode 100644 index abcaa98..0000000 --- a/cookbooks/yum/resources/repository.rb +++ /dev/null @@ -1,71 +0,0 @@ -# -# Cookbook Name:: yum -# Resource:: repository -# -# Author:: Sean OMeara -# Copyright 2013, Chef -# -# 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. -# - -actions :create, :delete, :add, :remove, :makecache - -default_action :create - -# http://linux.die.net/man/5/yum.conf -attribute :baseurl, kind_of: String, regex: /.*/, default: nil -attribute :cost, kind_of: String, regex: /^\d+$/, default: nil -attribute :clean_headers, kind_of: [TrueClass, FalseClass], default: false # deprecated -attribute :clean_metadata, kind_of: [TrueClass, FalseClass], default: true -attribute :description, kind_of: String, regex: /.*/, default: 'Ye Ole Rpm Repo' -attribute :enabled, kind_of: [TrueClass, FalseClass], default: true -attribute :enablegroups, kind_of: [TrueClass, FalseClass], default: nil -attribute :exclude, kind_of: String, regex: /.*/, default: nil -attribute :failovermethod, kind_of: String, equal_to: %w(priority roundrobin), default: nil -attribute :fastestmirror_enabled, kind_of: [TrueClass, FalseClass], default: nil -attribute :gpgcheck, kind_of: [TrueClass, FalseClass], default: true -attribute :gpgkey, kind_of: [String, Array], regex: /.*/, default: nil -attribute :http_caching, kind_of: String, equal_to: %w(packages all none), default: nil -attribute :include_config, kind_of: String, regex: /.*/, default: nil -attribute :includepkgs, kind_of: String, regex: /.*/, default: nil -attribute :keepalive, kind_of: [TrueClass, FalseClass], default: nil -attribute :make_cache, kind_of: [TrueClass, FalseClass], default: true -attribute :max_retries, kind_of: [String, Integer], default: nil -attribute :metadata_expire, kind_of: String, regex: [/^\d+$/, /^\d+[mhd]$/, /never/], default: nil -attribute :mirrorexpire, kind_of: String, regex: /.*/, default: nil -attribute :mirrorlist, kind_of: String, regex: /.*/, default: nil -attribute :mirror_expire, kind_of: String, regex: [/^\d+$/, /^\d+[mhd]$/], default: nil -attribute :mirrorlist_expire, kind_of: String, regex: [/^\d+$/, /^\d+[mhd]$/], default: nil -attribute :mode, default: '0644' -attribute :priority, kind_of: String, regex: /^(\d?[0-9]|[0-9][0-9])$/, default: nil -attribute :proxy, kind_of: String, regex: /.*/, default: nil -attribute :proxy_username, kind_of: String, regex: /.*/, default: nil -attribute :proxy_password, kind_of: String, regex: /.*/, default: nil -attribute :username, kind_of: String, regex: /.*/, default: nil -attribute :password, kind_of: String, regex: /.*/, default: nil -attribute :repo_gpgcheck, kind_of: [TrueClass, FalseClass], default: nil -attribute :report_instanceid, kind_of: [TrueClass, FalseClass], default: nil -attribute :repositoryid, kind_of: String, regex: /.*/, name_attribute: true -attribute :sensitive, kind_of: [TrueClass, FalseClass], default: false -attribute :skip_if_unavailable, kind_of: [TrueClass, FalseClass], default: nil -attribute :source, kind_of: String, regex: /.*/, default: nil -attribute :sslcacert, kind_of: String, regex: /.*/, default: nil -attribute :sslclientcert, kind_of: String, regex: /.*/, default: nil -attribute :sslclientkey, kind_of: String, regex: /.*/, default: nil -attribute :sslverify, kind_of: [TrueClass, FalseClass], default: nil -attribute :timeout, kind_of: String, regex: /^\d+$/, default: nil - -attribute :options, kind_of: Hash - -alias_method :url, :baseurl -alias_method :keyurl, :gpgkey diff --git a/cookbooks/yum/templates/default/main.erb b/cookbooks/yum/templates/main.erb similarity index 100% rename from cookbooks/yum/templates/default/main.erb rename to cookbooks/yum/templates/main.erb