From 2090bc6b10bd7c90a4879ae0f3af1df04529486b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 31 Mar 2017 19:23:10 +0200 Subject: [PATCH 01/83] Change the port for IPFS's nginx vhost --- .../kosmos-ipfs/recipes/letsencrypt.rb | 17 ++++++++++++----- .../default/nginx_conf_ipfs.kosmos.org.erb | 2 +- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/site-cookbooks/kosmos-ipfs/recipes/letsencrypt.rb b/site-cookbooks/kosmos-ipfs/recipes/letsencrypt.rb index 3be5800..2775c60 100644 --- a/site-cookbooks/kosmos-ipfs/recipes/letsencrypt.rb +++ b/site-cookbooks/kosmos-ipfs/recipes/letsencrypt.rb @@ -23,11 +23,12 @@ template "#{node['nginx']['dir']}/sites-available/ipfs.kosmos.org" do source 'nginx_conf_ipfs.kosmos.org.erb' owner 'www-data' mode 0640 - variables server_name: 'ipfs.kosmos.org', - root_directory: root_directory, - ssl_cert: "/etc/letsencrypt/live/ipfs.kosmos.org/fullchain.pem", - ssl_key: "/etc/letsencrypt/live/ipfs.kosmos.org/privkey.pem", - ipfs_api_port: 5001 + variables server_name: 'ipfs.kosmos.org', + root_directory: root_directory, + ssl_cert: "/etc/letsencrypt/live/ipfs.kosmos.org/fullchain.pem", + ssl_key: "/etc/letsencrypt/live/ipfs.kosmos.org/privkey.pem", + ipfs_api_port: 5001, + ipfs_external_api_port: 5444 notifies :reload, 'service[nginx]', :delayed end @@ -36,6 +37,12 @@ nginx_site 'ipfs.kosmos.org' do enable true end +firewall_rule 'ipfs_api' do + port 5444 + protocol :tcp + command :allow +end + # Generate a Let's Encrypt cert (only if the nginx vhost exists and no cert # has been generated before. The renew cron will take care of renewing execute "letsencrypt cert for ipfs.kosmos.org" do diff --git a/site-cookbooks/kosmos-ipfs/templates/default/nginx_conf_ipfs.kosmos.org.erb b/site-cookbooks/kosmos-ipfs/templates/default/nginx_conf_ipfs.kosmos.org.erb index 7aaff58..94c75a1 100644 --- a/site-cookbooks/kosmos-ipfs/templates/default/nginx_conf_ipfs.kosmos.org.erb +++ b/site-cookbooks/kosmos-ipfs/templates/default/nginx_conf_ipfs.kosmos.org.erb @@ -16,7 +16,7 @@ server { server { <% if File.exist?(@ssl_cert) && File.exist?(@ssl_key) -%> - listen 443 ssl spdy; + listen <%= @ipfs_external_api_port %> ssl spdy; <% else -%> listen 80; <% end -%> From 4260f2568401921575fca65e4b8dd5acd7236a87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Thu, 6 Apr 2017 10:08:08 +0200 Subject: [PATCH 02/83] Add botka to #mastodon and #indieweb on Freenode --- site-cookbooks/kosmos-hubot/recipes/default.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site-cookbooks/kosmos-hubot/recipes/default.rb b/site-cookbooks/kosmos-hubot/recipes/default.rb index 8b44001..f385450 100644 --- a/site-cookbooks/kosmos-hubot/recipes/default.rb +++ b/site-cookbooks/kosmos-hubot/recipes/default.rb @@ -119,7 +119,7 @@ application "botka_freenode" do # Use our own systemd service that depends on redis-server template "nodejs.systemd.service.erb" environment "HUBOT_IRC_SERVER" => "irc.freenode.net", - "HUBOT_IRC_ROOMS" => "#5apps,#kosmos,#kosmos-dev,#remotestorage,#hackerbeach,#unhosted,#sockethub,#opensourcedesign,#openknot,#emberjs", + "HUBOT_IRC_ROOMS" => "#5apps,#kosmos,#kosmos-dev,#remotestorage,#hackerbeach,#unhosted,#sockethub,#opensourcedesign,#openknot,#emberjs,#mastodon,#indieweb", "HUBOT_IRC_NICK" => "botka", "HUBOT_IRC_NICKSERV_USERNAME" => "botka", "HUBOT_IRC_NICKSERV_PASSWORD" => botka_freenode_data_bag_item['nickserv_password'], From de11c0d6916c99dce581bb19d88b87bb629858c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Thu, 6 Apr 2017 21:20:51 +0200 Subject: [PATCH 03/83] Set up an instance of Mastodon for Kosmos Refs #19 Use new application cookbook, update our cookbooks --- .gitignore | 2 + Batali | 9 +- Vagrantfile | 95 ++ batali.manifest | 434 ++++++--- cookbooks/application/CHANGELOG.md | 151 ++-- cookbooks/application/README.md | 373 ++++---- .../files/halite_gem/poise_application.rb | 25 + .../poise_application/app_file_mixin.rb | 61 ++ .../halite_gem/poise_application/app_mixin.rb | 69 ++ .../halite_gem/poise_application/cheftie.rb | 17 + .../halite_gem/poise_application/error.rb | 24 + .../halite_gem/poise_application/resources.rb | 29 + .../resources/application.rb | 259 ++++++ .../resources/application_cookbook_file.rb | 54 ++ .../resources/application_file.rb | 54 ++ .../resources/application_template.rb | 54 ++ .../poise_application/service_mixin.rb | 116 +++ .../halite_gem/poise_application/utils.rb | 51 ++ .../halite_gem/poise_application/version.rb | 20 + cookbooks/application/libraries/default.rb | 180 +--- cookbooks/application/libraries/matchers.rb | 11 - cookbooks/application/metadata.json | 31 +- cookbooks/application/providers/default.rb | 191 ---- cookbooks/application/resources/default.rb | 178 ---- .../templates/default/deploy-ssh-wrapper.erb | 8 - cookbooks/application_git/CHANGELOG.md | 10 + cookbooks/application_git/README.md | 108 +++ .../files/halite_gem/poise-application-git.rb | 17 + .../files/halite_gem/poise_application_git.rb | 21 + .../poise_application_git/cheftie.rb | 17 + .../poise_application_git/resource.rb | 204 +++++ .../poise_application_git/safe_string.rb | 25 + .../poise_application_git/version.rb | 20 + .../application_git/libraries/default.rb | 19 + cookbooks/application_git/metadata.json | 1 + cookbooks/application_javascript/CHANGELOG.md | 5 + cookbooks/application_javascript/README.md | 132 +++ .../poise_application_javascript.rb | 23 + .../poise_application_javascript/app_mixin.rb | 67 ++ .../poise_application_javascript/cheftie.rb | 17 + .../poise_application_javascript/error.rb | 25 + .../poise_application_javascript/resources.rb | 22 + .../resources/javascript.rb | 64 ++ .../resources/javascript_execute.rb | 88 ++ .../resources/javascript_service.rb | 59 ++ .../resources/node_package.rb | 63 ++ .../resources/npm_install.rb | 45 + .../resources/npm_start.rb | 78 ++ .../service_mixin.rb | 57 ++ .../poise_application_javascript/version.rb | 19 + .../libraries/default.rb | 19 + .../application_javascript/metadata.json | 1 + cookbooks/application_nodejs/LICENSE | 201 ----- cookbooks/application_nodejs/README.md | 64 -- cookbooks/application_nodejs/metadata.rb | 12 - .../application_nodejs/providers/nodejs.rb | 130 --- .../default/nodejs.systemd.service.erb | 4 - .../templates/default/nodejs.upstart.conf.erb | 19 - cookbooks/application_ruby/CHANGELOG.md | 86 ++ cookbooks/application_ruby/README.md | 271 ++++++ .../halite_gem/poise_application_ruby.rb | 24 + .../poise_application_ruby/app_mixin.rb | 92 ++ .../poise_application_ruby/cheftie.rb | 17 + .../poise_application_ruby/error.rb | 25 + .../poise_application_ruby/resources.rb | 24 + .../resources/bundle_install.rb | 54 ++ .../resources/rackup.rb | 70 ++ .../poise_application_ruby/resources/rails.rb | 260 ++++++ .../poise_application_ruby/resources/ruby.rb | 63 ++ .../resources/ruby_execute.rb | 89 ++ .../resources/ruby_gem.rb | 46 + .../poise_application_ruby/resources/thin.rb | 64 ++ .../resources/unicorn.rb | 87 ++ .../poise_application_ruby/service_mixin.rb | 66 ++ .../poise_application_ruby/version.rb | 19 + .../application_ruby/libraries/default.rb | 19 + cookbooks/application_ruby/metadata.json | 1 + .../templates/database.yml.erb | 3 + .../templates/secrets.yml.erb | 3 + cookbooks/dmg/.foodcritic | 4 + cookbooks/dmg/CHANGELOG.md | 113 +++ cookbooks/dmg/CONTRIBUTING.md | 2 + cookbooks/dmg/MAINTAINERS.md | 18 + cookbooks/dmg/README.md | 146 ++++ cookbooks/dmg/attributes/default.rb | 20 + .../libraries/matchers.rb} | 17 +- cookbooks/dmg/metadata.json | 1 + cookbooks/dmg/providers/package.rb | 95 ++ .../{application => dmg}/recipes/default.rb | 5 +- cookbooks/dmg/resources/package.rb | 39 + cookbooks/git/.foodcritic | 1 + cookbooks/git/CHANGELOG.md | 257 ++++++ cookbooks/git/CONTRIBUTING.md | 2 + cookbooks/git/MAINTAINERS.md | 15 + cookbooks/git/README.md | 161 ++++ cookbooks/git/attributes/default.rb | 47 + cookbooks/git/libraries/helpers.rb | 48 + cookbooks/git/libraries/matchers.rb | 16 + .../git/libraries/provider_git_client.rb | 13 + .../git/libraries/provider_git_client_osx.rb | 26 + .../libraries/provider_git_client_package.rb | 27 + .../libraries/provider_git_client_source.rb | 66 ++ .../libraries/provider_git_client_windows.rb | 49 ++ .../git/libraries/provider_git_service.rb | 57 ++ .../libraries/provider_git_service_xinetd.rb | 55 ++ .../git/libraries/resource_git_client.rb | 38 + .../git/libraries/resource_git_service.rb | 16 + cookbooks/git/metadata.json | 1 + .../helpers.rb => git/recipes/default.rb} | 16 +- cookbooks/git/recipes/package.rb | 37 + .../ruby_test.rb => git/recipes/server.rb} | 18 +- .../nodejs.rb => git/recipes/source.rb} | 23 +- cookbooks/git/recipes/windows.rb | 24 + cookbooks/git/resources/config.rb | 49 ++ .../git/templates/default/git-xinetd.d.erb | 10 + .../default/sv-git-daemon-log-run.erb | 2 + .../templates/default/sv-git-daemon-run.erb | 3 + cookbooks/mediawiki/recipes/database.rb | 5 + cookbooks/mediawiki/recipes/default.rb | 17 +- cookbooks/mediawiki/recipes/nginx.rb | 27 +- cookbooks/poise-archive/CHANGELOG.md | 38 + cookbooks/poise-archive/README.md | 103 +++ cookbooks/poise-archive/attributes/default.rb | 18 + .../files/halite_gem/poise_archive.rb | 21 + .../poise_archive/archive_providers.rb | 38 + .../poise_archive/archive_providers/base.rb | 132 +++ .../archive_providers/gnu_tar.rb | 88 ++ .../archive_providers/seven_zip.rb | 188 ++++ .../poise_archive/archive_providers/tar.rb | 158 ++++ .../poise_archive/archive_providers/zip.rb | 97 +++ .../files/halite_gem/poise_archive/bzip2.rb | 16 + .../halite_gem/poise_archive/bzip2/LICENSE | 25 + .../poise_archive/bzip2/constants.rb | 83 ++ .../halite_gem/poise_archive/bzip2/crc.rb | 73 ++ .../poise_archive/bzip2/decompressor.rb | 704 +++++++++++++++ .../poise_archive/bzip2/input_data.rb | 43 + .../poise_archive/bzip2/output_data.rb | 57 ++ .../files/halite_gem/poise_archive/cheftie.rb | 18 + .../halite_gem/poise_archive/resources.rb | 26 + .../poise_archive/resources/poise_archive.rb | 151 ++++ .../files/halite_gem/poise_archive/version.rb | 20 + cookbooks/poise-archive/libraries/default.rb | 19 + cookbooks/poise-archive/metadata.json | 1 + cookbooks/poise-javascript/CHANGELOG.md | 16 + cookbooks/poise-javascript/README.md | 332 +++++++ .../poise-javascript/attributes/default.rb | 23 + .../files/halite_gem/poise_javascript.rb | 24 + .../halite_gem/poise_javascript/cheftie.rb | 18 + .../halite_gem/poise_javascript/error.rb | 23 + .../javascript_command_mixin.rb | 56 ++ .../poise_javascript/javascript_providers.rb | 40 + .../javascript_providers/base.rb | 97 +++ .../javascript_providers/dummy.rb | 77 ++ .../javascript_providers/iojs.rb | 64 ++ .../javascript_providers/nodejs.rb | 65 ++ .../javascript_providers/scl.rb | 53 ++ .../javascript_providers/system.rb | 71 ++ .../halite_gem/poise_javascript/resources.rb | 29 + .../resources/javascript_execute.rb | 83 ++ .../resources/javascript_runtime.rb | 85 ++ .../resources/javascript_runtime_test.rb | 226 +++++ .../resources/node_package.rb | 254 ++++++ .../poise_javascript/resources/npm_install.rb | 98 +++ .../halite_gem/poise_javascript/version.rb | 20 + .../poise-javascript/libraries/default.rb | 19 + cookbooks/poise-javascript/metadata.json | 1 + cookbooks/poise-javascript/recipes/default.rb | 19 + cookbooks/poise-languages/CHANGELOG.md | 79 ++ cookbooks/poise-languages/README.md | 27 + .../files/halite_gem/poise_languages.rb | 26 + .../halite_gem/poise_languages/command.rb | 25 + .../poise_languages/command/mixin.rb | 241 +++++ .../files/halite_gem/poise_languages/error.rb | 21 + .../files/halite_gem/poise_languages/scl.rb | 24 + .../halite_gem/poise_languages/scl/mixin.rb | 134 +++ .../poise_languages/scl/resource.rb | 159 ++++ .../halite_gem/poise_languages/static.rb | 34 + .../poise_languages/static/mixin.rb | 144 +++ .../poise_languages/static/resource.rb | 139 +++ .../halite_gem/poise_languages/system.rb | 24 + .../poise_languages/system/mixin.rb | 170 ++++ .../poise_languages/system/resource.rb | 215 +++++ .../files/halite_gem/poise_languages/utils.rb | 68 ++ .../halite_gem/poise_languages/utils/which.rb | 51 ++ .../halite_gem/poise_languages/version.rb | 20 + .../poise-languages/libraries/default.rb | 18 + cookbooks/poise-languages/metadata.json | 1 + cookbooks/poise-ruby/CHANGELOG.md | 25 + cookbooks/poise-ruby/README.md | 305 +++++++ cookbooks/poise-ruby/attributes/default.rb | 23 + .../poise-ruby/files/halite_gem/poise_ruby.rb | 25 + .../halite_gem/poise_ruby/bundler_mixin.rb | 84 ++ .../files/halite_gem/poise_ruby/cheftie.rb | 18 + .../files/halite_gem/poise_ruby/error.rb | 21 + .../files/halite_gem/poise_ruby/resources.rb | 29 + .../poise_ruby/resources/bundle_install.rb | 221 +++++ .../poise_ruby/resources/ruby_execute.rb | 90 ++ .../poise_ruby/resources/ruby_gem.rb | 125 +++ .../poise_ruby/resources/ruby_runtime.rb | 87 ++ .../poise_ruby/resources/ruby_runtime_test.rb | 213 +++++ .../poise_ruby/ruby_command_mixin.rb | 59 ++ .../halite_gem/poise_ruby/ruby_providers.rb | 35 + .../poise_ruby/ruby_providers/base.rb | 117 +++ .../poise_ruby/ruby_providers/chef.rb | 53 ++ .../poise_ruby/ruby_providers/dummy.rb | 77 ++ .../poise_ruby/ruby_providers/scl.rb | 55 ++ .../poise_ruby/ruby_providers/system.rb | 116 +++ .../files/halite_gem/poise_ruby/version.rb | 20 + cookbooks/poise-ruby/libraries/default.rb | 19 + cookbooks/poise-ruby/metadata.json | 1 + cookbooks/poise-ruby/recipes/default.rb | 19 + cookbooks/poise-service/CHANGELOG.md | 74 ++ cookbooks/poise-service/README.md | 414 +++++++++ cookbooks/poise-service/attributes/default.rb | 19 + .../files/halite_gem/poise_service.rb | 25 + .../files/halite_gem/poise_service/cheftie.rb | 18 + .../files/halite_gem/poise_service/error.rb | 20 + .../halite_gem/poise_service/resources.rb | 27 + .../poise_service/resources/poise_service.rb | 165 ++++ .../resources/poise_service_test.rb | 240 +++++ .../resources/poise_service_user.rb | 186 ++++ .../halite_gem/poise_service/service_mixin.rb | 192 ++++ .../poise_service/service_providers.rb | 38 + .../poise_service/service_providers/base.rb | 193 ++++ .../poise_service/service_providers/dummy.rb | 156 ++++ .../service_providers/inittab.rb | 150 ++++ .../service_providers/systemd.rb | 85 ++ .../service_providers/sysvinit.rb | 97 +++ .../service_providers/upstart.rb | 128 +++ .../files/halite_gem/poise_service/utils.rb | 45 + .../files/halite_gem/poise_service/version.rb | 20 + cookbooks/poise-service/libraries/default.rb | 19 + cookbooks/poise-service/metadata.json | 1 + .../templates/default/dummy.json.erb | 7 + .../templates/default/inittab.sh.erb | 15 + .../templates/default/systemd.service.erb | 14 + .../templates/default/sysvinit.sh.erb | 190 ++++ .../templates/default/upstart.conf.erb | 49 ++ cookbooks/poise/CHANGELOG.md | 187 ++++ cookbooks/poise/README.md | 233 +++++ cookbooks/poise/files/halite_gem/poise.rb | 108 +++ .../poise/files/halite_gem/poise/backports.rb | 28 + .../halite_gem/poise/backports/not_passed.rb | 52 ++ .../halite_gem/poise/backports/verify_path.rb | 33 + .../poise/files/halite_gem/poise/error.rb | 24 + .../poise/files/halite_gem/poise/helpers.rb | 36 + .../poise/helpers/chefspec_matchers.rb | 92 ++ .../halite_gem/poise/helpers/defined_in.rb | 128 +++ .../files/halite_gem/poise/helpers/fused.rb | 127 +++ .../poise/helpers/include_recipe.rb | 62 ++ .../halite_gem/poise/helpers/inversion.rb | 414 +++++++++ .../helpers/inversion/options_provider.rb | 41 + .../helpers/inversion/options_resource.rb | 115 +++ .../halite_gem/poise/helpers/lazy_default.rb | 79 ++ .../halite_gem/poise/helpers/lwrp_polyfill.rb | 163 ++++ .../poise/helpers/notifying_block.rb | 78 ++ .../poise/helpers/option_collector.rb | 142 +++ .../poise/helpers/resource_cloning.rb | 72 ++ .../halite_gem/poise/helpers/resource_name.rb | 107 +++ .../poise/helpers/resource_subclass.rb | 82 ++ .../poise/helpers/subcontext_block.rb | 72 ++ .../halite_gem/poise/helpers/subresources.rb | 29 + .../poise/helpers/subresources/child.rb | 276 ++++++ .../poise/helpers/subresources/container.rb | 229 +++++ .../subresources/default_containers.rb | 75 ++ .../poise/helpers/template_content.rb | 168 ++++ .../halite_gem/poise/helpers/win32_user.rb | 64 ++ .../poise/files/halite_gem/poise/provider.rb | 59 ++ .../poise/files/halite_gem/poise/resource.rb | 81 ++ .../files/halite_gem/poise/subcontext.rb | 27 + .../poise/subcontext/resource_collection.rb | 75 ++ .../halite_gem/poise/subcontext/runner.rb | 55 ++ .../poise/files/halite_gem/poise/utils.rb | 181 ++++ .../poise/utils/resource_provider_mixin.rb | 65 ++ .../files/halite_gem/poise/utils/shell_out.rb | 90 ++ .../files/halite_gem/poise/utils/win32.rb | 127 +++ .../poise/files/halite_gem/poise/version.rb | 20 + cookbooks/poise/libraries/default.rb | 18 + cookbooks/poise/metadata.json | 1 + cookbooks/postgresql/.foodcritic | 2 + cookbooks/postgresql/CHANGELOG.md | 344 ++++++-- cookbooks/postgresql/CONTRIBUTING.md | 22 + cookbooks/postgresql/README.md | 587 +++++-------- cookbooks/postgresql/attributes/default.rb | 289 +++--- .../attributes/yum_pgdg_packages.rb | 821 ++++++++++-------- .../minitest/apt_pgdg_postgresql_test.rb | 39 - .../default/tests/minitest/server_test.rb | 44 - cookbooks/postgresql/libraries/default.rb | 534 ++++++------ cookbooks/postgresql/metadata.json | 58 +- cookbooks/postgresql/metadata.rb | 28 - .../postgresql/recipes/apt_pgdg_postgresql.rb | 12 +- .../postgresql/recipes/ca_certificates.rb | 8 +- cookbooks/postgresql/recipes/client.rb | 13 +- cookbooks/postgresql/recipes/config_initdb.rb | 23 +- cookbooks/postgresql/recipes/config_pgtune.rb | 169 ++-- cookbooks/postgresql/recipes/contrib.rb | 23 +- cookbooks/postgresql/recipes/default.rb | 5 +- cookbooks/postgresql/recipes/ruby.rb | 68 +- cookbooks/postgresql/recipes/server.rb | 56 +- cookbooks/postgresql/recipes/server_conf.rb | 35 +- cookbooks/postgresql/recipes/server_debian.rb | 17 +- cookbooks/postgresql/recipes/server_redhat.rb | 80 +- .../postgresql/recipes/yum_pgdg_postgresql.rb | 17 +- cookbooks/postgresql/resources/extension.rb | 57 ++ .../templates/default/pg_hba.conf.erb | 2 +- .../templates/default/postgresql.service.erb | 10 + cookbooks/wordpress/README.md | 1 - cookbooks/wordpress/attributes/default.rb | 19 - cookbooks/wordpress/metadata.rb | 2 +- cookbooks/wordpress/recipes/database.rb | 6 +- data_bags/credentials/mastodon.json | 45 + site-cookbooks/5apps-hubot/metadata.rb | 5 +- .../5apps-hubot/recipes/xmpp_botka.rb | 128 ++- .../5apps-hubot/recipes/xmpp_schlupp.rb | 131 ++- .../5apps-xmpp_server/recipes/default.rb | 11 +- site-cookbooks/backup/recipes/default.rb | 2 +- .../backup/templates/default/config.rb.erb | 23 + .../kosmos-base/recipes/firewall.rb | 18 + .../kosmos-base/recipes/letsencrypt.rb | 2 +- site-cookbooks/kosmos-hubot/metadata.rb | 5 +- .../kosmos-hubot/recipes/default.rb | 227 +++-- .../kosmos-ipfs/recipes/letsencrypt.rb | 37 +- site-cookbooks/kosmos-mastodon/CHANGELOG.md | 11 + site-cookbooks/kosmos-mastodon/README.md | 80 ++ .../kosmos-mastodon/attributes/default.rb | 4 + site-cookbooks/kosmos-mastodon/metadata.rb | 15 + .../kosmos-mastodon/recipes/default.rb | 156 ++++ .../kosmos-mastodon/recipes/nginx.rb | 48 + .../config-environment-production.rb.erb | 119 +++ .../templates/default/env.production.erb | 49 ++ .../mastodon-sidekiq.systemd.service.erb | 17 + .../mastodon-streaming.systemd.service.erb | 15 + .../default/mastodon-web.systemd.service.erb | 19 + .../templates/default/nginx_conf_mastodon.erb | 88 ++ site-cookbooks/kosmos-mediawiki/metadata.rb | 1 - .../kosmos-nginx/recipes/default.rb | 13 +- site-cookbooks/kosmos-ruby/CHANGELOG.md | 11 + site-cookbooks/kosmos-ruby/README.md | 80 ++ .../kosmos-ruby/attributes/default.rb | 1 + site-cookbooks/kosmos-ruby/metadata.rb | 7 + site-cookbooks/kosmos-ruby/recipes/default.rb | 54 ++ site-cookbooks/sockethub/metadata.rb | 3 +- site-cookbooks/sockethub/recipes/default.rb | 46 +- site-cookbooks/sockethub/recipes/proxy.rb | 11 +- .../default/nodejs.systemd.service.erb | 1 + 345 files changed, 22591 insertions(+), 3473 deletions(-) create mode 100644 Vagrantfile create mode 100644 cookbooks/application/files/halite_gem/poise_application.rb create mode 100644 cookbooks/application/files/halite_gem/poise_application/app_file_mixin.rb create mode 100644 cookbooks/application/files/halite_gem/poise_application/app_mixin.rb create mode 100644 cookbooks/application/files/halite_gem/poise_application/cheftie.rb create mode 100644 cookbooks/application/files/halite_gem/poise_application/error.rb create mode 100644 cookbooks/application/files/halite_gem/poise_application/resources.rb create mode 100644 cookbooks/application/files/halite_gem/poise_application/resources/application.rb create mode 100644 cookbooks/application/files/halite_gem/poise_application/resources/application_cookbook_file.rb create mode 100644 cookbooks/application/files/halite_gem/poise_application/resources/application_file.rb create mode 100644 cookbooks/application/files/halite_gem/poise_application/resources/application_template.rb create mode 100644 cookbooks/application/files/halite_gem/poise_application/service_mixin.rb create mode 100644 cookbooks/application/files/halite_gem/poise_application/utils.rb create mode 100644 cookbooks/application/files/halite_gem/poise_application/version.rb delete mode 100644 cookbooks/application/libraries/matchers.rb delete mode 100644 cookbooks/application/providers/default.rb delete mode 100644 cookbooks/application/resources/default.rb delete mode 100644 cookbooks/application/templates/default/deploy-ssh-wrapper.erb create mode 100644 cookbooks/application_git/CHANGELOG.md create mode 100644 cookbooks/application_git/README.md create mode 100644 cookbooks/application_git/files/halite_gem/poise-application-git.rb create mode 100644 cookbooks/application_git/files/halite_gem/poise_application_git.rb create mode 100644 cookbooks/application_git/files/halite_gem/poise_application_git/cheftie.rb create mode 100644 cookbooks/application_git/files/halite_gem/poise_application_git/resource.rb create mode 100644 cookbooks/application_git/files/halite_gem/poise_application_git/safe_string.rb create mode 100644 cookbooks/application_git/files/halite_gem/poise_application_git/version.rb create mode 100644 cookbooks/application_git/libraries/default.rb create mode 100644 cookbooks/application_git/metadata.json create mode 100644 cookbooks/application_javascript/CHANGELOG.md create mode 100644 cookbooks/application_javascript/README.md create mode 100644 cookbooks/application_javascript/files/halite_gem/poise_application_javascript.rb create mode 100644 cookbooks/application_javascript/files/halite_gem/poise_application_javascript/app_mixin.rb create mode 100644 cookbooks/application_javascript/files/halite_gem/poise_application_javascript/cheftie.rb create mode 100644 cookbooks/application_javascript/files/halite_gem/poise_application_javascript/error.rb create mode 100644 cookbooks/application_javascript/files/halite_gem/poise_application_javascript/resources.rb create mode 100644 cookbooks/application_javascript/files/halite_gem/poise_application_javascript/resources/javascript.rb create mode 100644 cookbooks/application_javascript/files/halite_gem/poise_application_javascript/resources/javascript_execute.rb create mode 100644 cookbooks/application_javascript/files/halite_gem/poise_application_javascript/resources/javascript_service.rb create mode 100644 cookbooks/application_javascript/files/halite_gem/poise_application_javascript/resources/node_package.rb create mode 100644 cookbooks/application_javascript/files/halite_gem/poise_application_javascript/resources/npm_install.rb create mode 100644 cookbooks/application_javascript/files/halite_gem/poise_application_javascript/resources/npm_start.rb create mode 100644 cookbooks/application_javascript/files/halite_gem/poise_application_javascript/service_mixin.rb create mode 100644 cookbooks/application_javascript/files/halite_gem/poise_application_javascript/version.rb create mode 100644 cookbooks/application_javascript/libraries/default.rb create mode 100644 cookbooks/application_javascript/metadata.json delete mode 100644 cookbooks/application_nodejs/LICENSE delete mode 100644 cookbooks/application_nodejs/README.md delete mode 100644 cookbooks/application_nodejs/metadata.rb delete mode 100644 cookbooks/application_nodejs/providers/nodejs.rb delete mode 100644 cookbooks/application_nodejs/templates/default/nodejs.systemd.service.erb delete mode 100644 cookbooks/application_nodejs/templates/default/nodejs.upstart.conf.erb create mode 100644 cookbooks/application_ruby/CHANGELOG.md create mode 100644 cookbooks/application_ruby/README.md create mode 100644 cookbooks/application_ruby/files/halite_gem/poise_application_ruby.rb create mode 100644 cookbooks/application_ruby/files/halite_gem/poise_application_ruby/app_mixin.rb create mode 100644 cookbooks/application_ruby/files/halite_gem/poise_application_ruby/cheftie.rb create mode 100644 cookbooks/application_ruby/files/halite_gem/poise_application_ruby/error.rb create mode 100644 cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources.rb create mode 100644 cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/bundle_install.rb create mode 100644 cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/rackup.rb create mode 100644 cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/rails.rb create mode 100644 cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/ruby.rb create mode 100644 cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/ruby_execute.rb create mode 100644 cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/ruby_gem.rb create mode 100644 cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/thin.rb create mode 100644 cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/unicorn.rb create mode 100644 cookbooks/application_ruby/files/halite_gem/poise_application_ruby/service_mixin.rb create mode 100644 cookbooks/application_ruby/files/halite_gem/poise_application_ruby/version.rb create mode 100644 cookbooks/application_ruby/libraries/default.rb create mode 100644 cookbooks/application_ruby/metadata.json create mode 100644 cookbooks/application_ruby/templates/database.yml.erb create mode 100644 cookbooks/application_ruby/templates/secrets.yml.erb create mode 100644 cookbooks/dmg/.foodcritic create mode 100644 cookbooks/dmg/CHANGELOG.md create mode 100644 cookbooks/dmg/CONTRIBUTING.md create mode 100644 cookbooks/dmg/MAINTAINERS.md create mode 100644 cookbooks/dmg/README.md create mode 100644 cookbooks/dmg/attributes/default.rb rename cookbooks/{postgresql/files/default/tests/minitest/default_test.rb => dmg/libraries/matchers.rb} (64%) create mode 100644 cookbooks/dmg/metadata.json create mode 100644 cookbooks/dmg/providers/package.rb rename cookbooks/{application => dmg}/recipes/default.rb (80%) create mode 100644 cookbooks/dmg/resources/package.rb create mode 100644 cookbooks/git/.foodcritic create mode 100644 cookbooks/git/CHANGELOG.md create mode 100644 cookbooks/git/CONTRIBUTING.md create mode 100644 cookbooks/git/MAINTAINERS.md create mode 100644 cookbooks/git/README.md create mode 100644 cookbooks/git/attributes/default.rb create mode 100644 cookbooks/git/libraries/helpers.rb create mode 100644 cookbooks/git/libraries/matchers.rb create mode 100644 cookbooks/git/libraries/provider_git_client.rb create mode 100644 cookbooks/git/libraries/provider_git_client_osx.rb create mode 100644 cookbooks/git/libraries/provider_git_client_package.rb create mode 100644 cookbooks/git/libraries/provider_git_client_source.rb create mode 100644 cookbooks/git/libraries/provider_git_client_windows.rb create mode 100644 cookbooks/git/libraries/provider_git_service.rb create mode 100644 cookbooks/git/libraries/provider_git_service_xinetd.rb create mode 100644 cookbooks/git/libraries/resource_git_client.rb create mode 100644 cookbooks/git/libraries/resource_git_service.rb create mode 100644 cookbooks/git/metadata.json rename cookbooks/{postgresql/files/default/tests/minitest/support/helpers.rb => git/recipes/default.rb} (65%) create mode 100644 cookbooks/git/recipes/package.rb rename cookbooks/{postgresql/files/default/tests/minitest/ruby_test.rb => git/recipes/server.rb} (63%) rename cookbooks/{application_nodejs/resources/nodejs.rb => git/recipes/source.rb} (54%) create mode 100644 cookbooks/git/recipes/windows.rb create mode 100644 cookbooks/git/resources/config.rb create mode 100644 cookbooks/git/templates/default/git-xinetd.d.erb create mode 100644 cookbooks/git/templates/default/sv-git-daemon-log-run.erb create mode 100644 cookbooks/git/templates/default/sv-git-daemon-run.erb create mode 100644 cookbooks/poise-archive/CHANGELOG.md create mode 100644 cookbooks/poise-archive/README.md create mode 100644 cookbooks/poise-archive/attributes/default.rb create mode 100644 cookbooks/poise-archive/files/halite_gem/poise_archive.rb create mode 100644 cookbooks/poise-archive/files/halite_gem/poise_archive/archive_providers.rb create mode 100644 cookbooks/poise-archive/files/halite_gem/poise_archive/archive_providers/base.rb create mode 100644 cookbooks/poise-archive/files/halite_gem/poise_archive/archive_providers/gnu_tar.rb create mode 100644 cookbooks/poise-archive/files/halite_gem/poise_archive/archive_providers/seven_zip.rb create mode 100644 cookbooks/poise-archive/files/halite_gem/poise_archive/archive_providers/tar.rb create mode 100644 cookbooks/poise-archive/files/halite_gem/poise_archive/archive_providers/zip.rb create mode 100644 cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2.rb create mode 100644 cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/LICENSE create mode 100644 cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/constants.rb create mode 100644 cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/crc.rb create mode 100644 cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/decompressor.rb create mode 100644 cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/input_data.rb create mode 100644 cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/output_data.rb create mode 100644 cookbooks/poise-archive/files/halite_gem/poise_archive/cheftie.rb create mode 100644 cookbooks/poise-archive/files/halite_gem/poise_archive/resources.rb create mode 100644 cookbooks/poise-archive/files/halite_gem/poise_archive/resources/poise_archive.rb create mode 100644 cookbooks/poise-archive/files/halite_gem/poise_archive/version.rb create mode 100644 cookbooks/poise-archive/libraries/default.rb create mode 100644 cookbooks/poise-archive/metadata.json create mode 100644 cookbooks/poise-javascript/CHANGELOG.md create mode 100644 cookbooks/poise-javascript/README.md create mode 100644 cookbooks/poise-javascript/attributes/default.rb create mode 100644 cookbooks/poise-javascript/files/halite_gem/poise_javascript.rb create mode 100644 cookbooks/poise-javascript/files/halite_gem/poise_javascript/cheftie.rb create mode 100644 cookbooks/poise-javascript/files/halite_gem/poise_javascript/error.rb create mode 100644 cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_command_mixin.rb create mode 100644 cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_providers.rb create mode 100644 cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_providers/base.rb create mode 100644 cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_providers/dummy.rb create mode 100644 cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_providers/iojs.rb create mode 100644 cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_providers/nodejs.rb create mode 100644 cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_providers/scl.rb create mode 100644 cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_providers/system.rb create mode 100644 cookbooks/poise-javascript/files/halite_gem/poise_javascript/resources.rb create mode 100644 cookbooks/poise-javascript/files/halite_gem/poise_javascript/resources/javascript_execute.rb create mode 100644 cookbooks/poise-javascript/files/halite_gem/poise_javascript/resources/javascript_runtime.rb create mode 100644 cookbooks/poise-javascript/files/halite_gem/poise_javascript/resources/javascript_runtime_test.rb create mode 100644 cookbooks/poise-javascript/files/halite_gem/poise_javascript/resources/node_package.rb create mode 100644 cookbooks/poise-javascript/files/halite_gem/poise_javascript/resources/npm_install.rb create mode 100644 cookbooks/poise-javascript/files/halite_gem/poise_javascript/version.rb create mode 100644 cookbooks/poise-javascript/libraries/default.rb create mode 100644 cookbooks/poise-javascript/metadata.json create mode 100644 cookbooks/poise-javascript/recipes/default.rb create mode 100644 cookbooks/poise-languages/CHANGELOG.md create mode 100644 cookbooks/poise-languages/README.md create mode 100644 cookbooks/poise-languages/files/halite_gem/poise_languages.rb create mode 100644 cookbooks/poise-languages/files/halite_gem/poise_languages/command.rb create mode 100644 cookbooks/poise-languages/files/halite_gem/poise_languages/command/mixin.rb create mode 100644 cookbooks/poise-languages/files/halite_gem/poise_languages/error.rb create mode 100644 cookbooks/poise-languages/files/halite_gem/poise_languages/scl.rb create mode 100644 cookbooks/poise-languages/files/halite_gem/poise_languages/scl/mixin.rb create mode 100644 cookbooks/poise-languages/files/halite_gem/poise_languages/scl/resource.rb create mode 100644 cookbooks/poise-languages/files/halite_gem/poise_languages/static.rb create mode 100644 cookbooks/poise-languages/files/halite_gem/poise_languages/static/mixin.rb create mode 100644 cookbooks/poise-languages/files/halite_gem/poise_languages/static/resource.rb create mode 100644 cookbooks/poise-languages/files/halite_gem/poise_languages/system.rb create mode 100644 cookbooks/poise-languages/files/halite_gem/poise_languages/system/mixin.rb create mode 100644 cookbooks/poise-languages/files/halite_gem/poise_languages/system/resource.rb create mode 100644 cookbooks/poise-languages/files/halite_gem/poise_languages/utils.rb create mode 100644 cookbooks/poise-languages/files/halite_gem/poise_languages/utils/which.rb create mode 100644 cookbooks/poise-languages/files/halite_gem/poise_languages/version.rb create mode 100644 cookbooks/poise-languages/libraries/default.rb create mode 100644 cookbooks/poise-languages/metadata.json create mode 100644 cookbooks/poise-ruby/CHANGELOG.md create mode 100644 cookbooks/poise-ruby/README.md create mode 100644 cookbooks/poise-ruby/attributes/default.rb create mode 100644 cookbooks/poise-ruby/files/halite_gem/poise_ruby.rb create mode 100644 cookbooks/poise-ruby/files/halite_gem/poise_ruby/bundler_mixin.rb create mode 100644 cookbooks/poise-ruby/files/halite_gem/poise_ruby/cheftie.rb create mode 100644 cookbooks/poise-ruby/files/halite_gem/poise_ruby/error.rb create mode 100644 cookbooks/poise-ruby/files/halite_gem/poise_ruby/resources.rb create mode 100644 cookbooks/poise-ruby/files/halite_gem/poise_ruby/resources/bundle_install.rb create mode 100644 cookbooks/poise-ruby/files/halite_gem/poise_ruby/resources/ruby_execute.rb create mode 100644 cookbooks/poise-ruby/files/halite_gem/poise_ruby/resources/ruby_gem.rb create mode 100644 cookbooks/poise-ruby/files/halite_gem/poise_ruby/resources/ruby_runtime.rb create mode 100644 cookbooks/poise-ruby/files/halite_gem/poise_ruby/resources/ruby_runtime_test.rb create mode 100644 cookbooks/poise-ruby/files/halite_gem/poise_ruby/ruby_command_mixin.rb create mode 100644 cookbooks/poise-ruby/files/halite_gem/poise_ruby/ruby_providers.rb create mode 100644 cookbooks/poise-ruby/files/halite_gem/poise_ruby/ruby_providers/base.rb create mode 100644 cookbooks/poise-ruby/files/halite_gem/poise_ruby/ruby_providers/chef.rb create mode 100644 cookbooks/poise-ruby/files/halite_gem/poise_ruby/ruby_providers/dummy.rb create mode 100644 cookbooks/poise-ruby/files/halite_gem/poise_ruby/ruby_providers/scl.rb create mode 100644 cookbooks/poise-ruby/files/halite_gem/poise_ruby/ruby_providers/system.rb create mode 100644 cookbooks/poise-ruby/files/halite_gem/poise_ruby/version.rb create mode 100644 cookbooks/poise-ruby/libraries/default.rb create mode 100644 cookbooks/poise-ruby/metadata.json create mode 100644 cookbooks/poise-ruby/recipes/default.rb create mode 100644 cookbooks/poise-service/CHANGELOG.md create mode 100644 cookbooks/poise-service/README.md create mode 100644 cookbooks/poise-service/attributes/default.rb create mode 100644 cookbooks/poise-service/files/halite_gem/poise_service.rb create mode 100644 cookbooks/poise-service/files/halite_gem/poise_service/cheftie.rb create mode 100644 cookbooks/poise-service/files/halite_gem/poise_service/error.rb create mode 100644 cookbooks/poise-service/files/halite_gem/poise_service/resources.rb create mode 100644 cookbooks/poise-service/files/halite_gem/poise_service/resources/poise_service.rb create mode 100644 cookbooks/poise-service/files/halite_gem/poise_service/resources/poise_service_test.rb create mode 100644 cookbooks/poise-service/files/halite_gem/poise_service/resources/poise_service_user.rb create mode 100644 cookbooks/poise-service/files/halite_gem/poise_service/service_mixin.rb create mode 100644 cookbooks/poise-service/files/halite_gem/poise_service/service_providers.rb create mode 100644 cookbooks/poise-service/files/halite_gem/poise_service/service_providers/base.rb create mode 100644 cookbooks/poise-service/files/halite_gem/poise_service/service_providers/dummy.rb create mode 100644 cookbooks/poise-service/files/halite_gem/poise_service/service_providers/inittab.rb create mode 100644 cookbooks/poise-service/files/halite_gem/poise_service/service_providers/systemd.rb create mode 100644 cookbooks/poise-service/files/halite_gem/poise_service/service_providers/sysvinit.rb create mode 100644 cookbooks/poise-service/files/halite_gem/poise_service/service_providers/upstart.rb create mode 100644 cookbooks/poise-service/files/halite_gem/poise_service/utils.rb create mode 100644 cookbooks/poise-service/files/halite_gem/poise_service/version.rb create mode 100644 cookbooks/poise-service/libraries/default.rb create mode 100644 cookbooks/poise-service/metadata.json create mode 100644 cookbooks/poise-service/templates/default/dummy.json.erb create mode 100644 cookbooks/poise-service/templates/default/inittab.sh.erb create mode 100644 cookbooks/poise-service/templates/default/systemd.service.erb create mode 100644 cookbooks/poise-service/templates/default/sysvinit.sh.erb create mode 100644 cookbooks/poise-service/templates/default/upstart.conf.erb create mode 100644 cookbooks/poise/CHANGELOG.md create mode 100644 cookbooks/poise/README.md create mode 100644 cookbooks/poise/files/halite_gem/poise.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/backports.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/backports/not_passed.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/backports/verify_path.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/error.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/helpers.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/helpers/chefspec_matchers.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/helpers/defined_in.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/helpers/fused.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/helpers/include_recipe.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/helpers/inversion.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/helpers/inversion/options_provider.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/helpers/inversion/options_resource.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/helpers/lazy_default.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/helpers/lwrp_polyfill.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/helpers/notifying_block.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/helpers/option_collector.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/helpers/resource_cloning.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/helpers/resource_name.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/helpers/resource_subclass.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/helpers/subcontext_block.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/helpers/subresources.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/helpers/subresources/child.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/helpers/subresources/container.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/helpers/subresources/default_containers.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/helpers/template_content.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/helpers/win32_user.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/provider.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/resource.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/subcontext.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/subcontext/resource_collection.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/subcontext/runner.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/utils.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/utils/resource_provider_mixin.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/utils/shell_out.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/utils/win32.rb create mode 100644 cookbooks/poise/files/halite_gem/poise/version.rb create mode 100644 cookbooks/poise/libraries/default.rb create mode 100644 cookbooks/poise/metadata.json create mode 100644 cookbooks/postgresql/.foodcritic create mode 100644 cookbooks/postgresql/CONTRIBUTING.md delete mode 100644 cookbooks/postgresql/files/default/tests/minitest/apt_pgdg_postgresql_test.rb delete mode 100644 cookbooks/postgresql/files/default/tests/minitest/server_test.rb delete mode 100644 cookbooks/postgresql/metadata.rb create mode 100644 cookbooks/postgresql/resources/extension.rb create mode 100644 cookbooks/postgresql/templates/default/postgresql.service.erb create mode 100644 data_bags/credentials/mastodon.json create mode 100644 site-cookbooks/kosmos-mastodon/CHANGELOG.md create mode 100644 site-cookbooks/kosmos-mastodon/README.md create mode 100644 site-cookbooks/kosmos-mastodon/attributes/default.rb create mode 100644 site-cookbooks/kosmos-mastodon/metadata.rb create mode 100644 site-cookbooks/kosmos-mastodon/recipes/default.rb create mode 100644 site-cookbooks/kosmos-mastodon/recipes/nginx.rb create mode 100644 site-cookbooks/kosmos-mastodon/templates/default/config-environment-production.rb.erb create mode 100644 site-cookbooks/kosmos-mastodon/templates/default/env.production.erb create mode 100644 site-cookbooks/kosmos-mastodon/templates/default/mastodon-sidekiq.systemd.service.erb create mode 100644 site-cookbooks/kosmos-mastodon/templates/default/mastodon-streaming.systemd.service.erb create mode 100644 site-cookbooks/kosmos-mastodon/templates/default/mastodon-web.systemd.service.erb create mode 100644 site-cookbooks/kosmos-mastodon/templates/default/nginx_conf_mastodon.erb create mode 100644 site-cookbooks/kosmos-ruby/CHANGELOG.md create mode 100644 site-cookbooks/kosmos-ruby/README.md create mode 100644 site-cookbooks/kosmos-ruby/attributes/default.rb create mode 100644 site-cookbooks/kosmos-ruby/metadata.rb create mode 100644 site-cookbooks/kosmos-ruby/recipes/default.rb diff --git a/.gitignore b/.gitignore index d7f3efa..6bf6e4a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ /.chef/encrypted_data_bag_secret /.bundle/ +/.vagrant/ +/nodes/vagrant-node.json diff --git a/Batali b/Batali index 2e532a8..f9723d0 100644 --- a/Batali +++ b/Batali @@ -14,10 +14,10 @@ Batali.define do ref: 'relax_dependencies' cookbook 'postfix' cookbook 'unattended-upgrades' - cookbook 'application_nodejs', - git: 'https://github.com/67p/application_nodejs.git', - ref: 'master' - cookbook 'application', '4.1.6' + cookbook 'application' + cookbook 'application_javascript' + cookbook 'application_ruby' + cookbook 'application_git' cookbook 'users' cookbook 'sudo' cookbook 'hostname' @@ -29,6 +29,7 @@ Batali.define do cookbook 'nginx' cookbook 'build-essential' cookbook 'mysql' + cookbook 'postgresql', '~> 6.1' cookbook 'database' cookbook 'mysql2_chef_gem' cookbook 'omnibus_updater' diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 0000000..ceed2fd --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,95 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +# All Vagrant configuration is done below. The "2" in Vagrant.configure +# configures the configuration version (we support older styles for +# backwards compatibility). Please don't change it unless you know what +# you're doing. +Vagrant.configure(2) do |config| + # The most common configuration options are documented and commented below. + # For a complete reference, please see the online documentation at + # https://docs.vagrantup.com. + + # Every Vagrant development environment requires a box. You can search for + # boxes at https://atlas.hashicorp.com/search. + config.vm.box = "bento/ubuntu-15.04" + + + config.vm.provider "virtualbox" do |vb| + # Customize the amount of memory on the VM: + vb.memory = "1024" + end + + # Disable automatic box update checking. If you disable this, then + # boxes will only be checked for updates when the user runs + # `vagrant box outdated`. This is not recommended. + # config.vm.box_check_update = false + + # Create a forwarded port mapping which allows access to a specific port + # within the machine from a port on the host machine. In the example below, + # accessing "localhost:8080" will access port 80 on the guest machine. + # config.vm.network "forwarded_port", guest: 80, host: 8080 + + # Create a private network, which allows host-only access to the machine + # using a specific IP. + # config.vm.network "private_network", ip: "192.168.33.10" + + # Create a public network, which generally matched to bridged network. + # Bridged networks make the machine appear as another physical device on + # your network. + # config.vm.network "public_network" + + # Share an additional folder to the guest VM. The first argument is + # the path on the host to the actual folder. The second argument is + # the path on the guest to mount the folder. And the optional third + # argument is a set of non-required options. + # config.vm.synced_folder "../data", "/vagrant_data" + + # Provider-specific configuration so you can fine-tune various + # backing providers for Vagrant. These expose provider-specific options. + # Example for VirtualBox: + # + # config.vm.provider "virtualbox" do |vb| + # # Display the VirtualBox GUI when booting the machine + # vb.gui = true + # + # # Customize the amount of memory on the VM: + # vb.memory = "1024" + # end + # + # View the documentation for the provider you are using for more + # information on available options. + + # Define a Vagrant Push strategy for pushing to Atlas. Other push strategies + # such as FTP and Heroku are also available. See the documentation at + # https://docs.vagrantup.com/v2/push/atlas.html for more information. + # config.push.define "atlas" do |push| + # push.app = "YOUR_ATLAS_USERNAME/YOUR_APPLICATION_NAME" + # end + + # Enable provisioning with a shell script. Additional provisioners such as + # Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the + # documentation for more information about their specific syntax and use. + # config.vm.provision "shell", inline: <<-SHELL + # sudo apt-get update + # sudo apt-get install -y apache2 + # SHELL + + config.vm.provision :chef_zero do |chef| + chef.cookbooks_path = ['./cookbooks', './site-cookbooks'] + chef.data_bags_path = './data_bags' + chef.roles_path = './roles' + chef.node_name = "vagrant-node" + chef.nodes_path = './nodes' + chef.environments_path = './environments' + chef.encrypted_data_bag_secret_key_path = '.chef/encrypted_data_bag_secret' + chef.environment = 'development' + # chef.add_recipe 'kosmos-wordpress' + # chef.add_recipe 'sockethub' + chef.add_recipe 'kosmos-mastodon' + # chef.add_recipe 'kosmos-mastodon::nginx' + # chef.add_recipe '5apps-hubot::xmpp_botka' + # chef.add_recipe 'kosmos-hubot' + + end +end diff --git a/batali.manifest b/batali.manifest index 47b4f56..1ed1cd4 100644 --- a/batali.manifest +++ b/batali.manifest @@ -36,7 +36,7 @@ "version": "0.2.0", "source": { "url": "https://github.com/67P/mediawiki-cookbook.git", - "ref": "b76104ab975ed95e238c10ae49722f0dacd7c0b2", + "ref": "41d3c5129b5a6cd9c473e99339885bc1feac5d57", "type": "Batali::Source::Git", "subdirectory": null } @@ -325,29 +325,6 @@ "version": "4.0.9" } }, - { - "name": "postgresql", - "dependencies": [ - [ - "apt", - ">= 1.9.0" - ], - [ - "build-essential", - ">= 0.0.0" - ], - [ - "openssl", - "~> 4.0" - ] - ], - "version": "4.0.0", - "source": { - "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/postgresql/versions/4.0.0/download", - "version": "4.0.0" - } - }, { "name": "apt", "dependencies": [ @@ -612,7 +589,7 @@ ], [ "mysql2_chef_gem", - "~> 1.0.1" + ">= 1.0.1" ], [ "build-essential", @@ -642,7 +619,7 @@ "version": "3.0.0", "source": { "url": "https://github.com/67P/wordpress-cookbook.git", - "ref": "bc6a108fcfb05c3fafd903bcf81ac33617e6cef9", + "ref": "d6401db517476e6f3ab36aa92dfc0f5ed6a8a264", "type": "Batali::Source::Git", "subdirectory": null } @@ -698,105 +675,234 @@ "version": "0.1.2" } }, - { - "name": "application_nodejs", - "dependencies": [ - [ - "nodejs", - "> 0" - ], - [ - "application", - "> 0" - ] - ], - "version": "2.0.1", - "source": { - "url": "https://github.com/67p/application_nodejs.git", - "ref": "0c3494b0cae87bd1e9cbf360e91f1a290b517a66", - "type": "Batali::Source::Git", - "subdirectory": null - } - }, - { - "name": "nodejs", - "dependencies": [ - [ - "yum-epel", - ">= 0.0.0" - ], - [ - "build-essential", - ">= 0.0.0" - ], - [ - "ark", - ">= 0.0.0" - ], - [ - "apt", - ">= 2.9.1" - ], - [ - "homebrew", - ">= 0.0.0" - ] - ], - "version": "3.0.0", - "source": { - "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/nodejs/versions/3.0.0/download", - "version": "3.0.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": "homebrew", - "dependencies": [ - [ - "build-essential", - ">= 2.1.2" - ] - ], - "version": "2.0.5", - "source": { - "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/homebrew/versions/2.0.5/download", - "version": "2.0.5" - } - }, { "name": "application", + "dependencies": [ + [ + "poise", + "~> 2.4" + ], + [ + "poise-service", + "~> 1.0" + ] + ], + "version": "5.1.0", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/application/versions/5.1.0/download", + "version": "5.1.0" + } + }, + { + "name": "poise", "dependencies": [ ], - "version": "4.1.6", + "version": "2.7.2", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/application/versions/4.1.6/download", - "version": "4.1.6" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/poise/versions/2.7.2/download", + "version": "2.7.2" + } + }, + { + "name": "poise-service", + "dependencies": [ + [ + "poise", + "~> 2.0" + ] + ], + "version": "1.4.2", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/poise-service/versions/1.4.2/download", + "version": "1.4.2" + } + }, + { + "name": "application_javascript", + "dependencies": [ + [ + "poise", + "~> 2.0" + ], + [ + "application", + "~> 5.0" + ], + [ + "poise-javascript", + "~> 1.0" + ], + [ + "poise-service", + "~> 1.0" + ] + ], + "version": "1.0.0", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/application_javascript/versions/1.0.0/download", + "version": "1.0.0" + } + }, + { + "name": "poise-javascript", + "dependencies": [ + [ + "poise", + "~> 2.0" + ], + [ + "poise-languages", + "~> 2.0" + ] + ], + "version": "1.1.0", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/poise-javascript/versions/1.1.0/download", + "version": "1.1.0" + } + }, + { + "name": "poise-languages", + "dependencies": [ + [ + "poise", + "~> 2.5" + ], + [ + "poise-archive", + "~> 1.0" + ] + ], + "version": "2.1.0", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/poise-languages/versions/2.1.0/download", + "version": "2.1.0" + } + }, + { + "name": "poise-archive", + "dependencies": [ + [ + "poise", + "~> 2.6" + ] + ], + "version": "1.4.0", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/poise-archive/versions/1.4.0/download", + "version": "1.4.0" + } + }, + { + "name": "application_ruby", + "dependencies": [ + [ + "poise-service", + "~> 1.0" + ], + [ + "poise", + "~> 2.0" + ], + [ + "application", + "~> 5.0" + ], + [ + "poise-ruby", + "~> 2.1" + ] + ], + "version": "4.0.1", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/application_ruby/versions/4.0.1/download", + "version": "4.0.1" + } + }, + { + "name": "poise-ruby", + "dependencies": [ + [ + "poise", + "~> 2.0" + ], + [ + "poise-languages", + "~> 2.0" + ] + ], + "version": "2.2.0", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/poise-ruby/versions/2.2.0/download", + "version": "2.2.0" + } + }, + { + "name": "application_git", + "dependencies": [ + [ + "git", + ">= 0.0.0" + ], + [ + "poise", + "~> 2.0" + ], + [ + "application", + "~> 5.0" + ] + ], + "version": "1.1.0", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/application_git/versions/1.1.0/download", + "version": "1.1.0" + } + }, + { + "name": "git", + "dependencies": [ + [ + "build-essential", + ">= 0.0.0" + ], + [ + "dmg", + ">= 0.0.0" + ], + [ + "yum-epel", + ">= 0.0.0" + ] + ], + "version": "6.0.0", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/git/versions/6.0.0/download", + "version": "6.0.0" + } + }, + { + "name": "dmg", + "dependencies": [ + + ], + "version": "3.1.0", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/dmg/versions/3.1.0/download", + "version": "3.1.0" } }, { @@ -896,6 +1002,29 @@ "version": "2.5.4" } }, + { + "name": "postgresql", + "dependencies": [ + [ + "compat_resource", + ">= 12.16.3" + ], + [ + "build-essential", + ">= 2.0.0" + ], + [ + "openssl", + ">= 4.0" + ] + ], + "version": "6.1.1", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/postgresql/versions/6.1.1/download", + "version": "6.1.1" + } + }, { "name": "omnibus_updater", "dependencies": [ @@ -920,6 +1049,75 @@ "version": "0.2.0" } }, + { + "name": "nodejs", + "dependencies": [ + [ + "yum-epel", + ">= 0.0.0" + ], + [ + "build-essential", + ">= 0.0.0" + ], + [ + "ark", + ">= 0.0.0" + ], + [ + "apt", + ">= 2.9.1" + ], + [ + "homebrew", + ">= 0.0.0" + ] + ], + "version": "3.0.0", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/nodejs/versions/3.0.0/download", + "version": "3.0.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": "homebrew", + "dependencies": [ + [ + "build-essential", + ">= 2.1.2" + ] + ], + "version": "2.0.5", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/homebrew/versions/2.0.5/download", + "version": "2.0.5" + } + }, { "name": "logrotate", "dependencies": [ diff --git a/cookbooks/application/CHANGELOG.md b/cookbooks/application/CHANGELOG.md index 44aab88..1a4498d 100644 --- a/cookbooks/application/CHANGELOG.md +++ b/cookbooks/application/CHANGELOG.md @@ -1,103 +1,96 @@ -application Cookbook CHANGELOG -======================= -This file is used to list changes made in each version of the application cookbook. +# Application Changelog +## v5.1.0 -v4.1.6 ------- -- Support for Chef 12. -- Add `strict_ssh` option to enable host key checking. -- Add `keep_releases` option to control number of releases to keep. -- Allow passing a path to a file for `deploy_key`. +* Add `application_cookbook_file`, `application_file`, and `application_template resources. -v4.1.4 ------- -### Bug -- **[COOK-3343](https://tickets.opscode.com/browse/COOK-3343)** - Can't parse release candidate version number +## v5.0.0 +* Massive rewrite on top of newer Chef patterns. See the 5.0 README for details. -v4.1.2 ------- -### Bug -- **[COOK-3343](https://tickets.opscode.com/browse/COOK-3343)** - Can't parse release candidate version number +## v4.1.6 +* Support for Chef 12. +* Add `strict_ssh` option to enable host key checking. +* Add `keep_releases` option to control number of releases to keep. +* Allow passing a path to a file for `deploy_key`. -v4.1.0 ------- -### Bug -- [COOK-3343] - Can't parse release candidate version number +## v4.1.4 +* [COOK-3343](https://tickets.opscode.com/browse/COOK-3343) - Can't parse release candidate version number. -v4.0.0 ------- -### Breaking -- Removes compatability with Chef 10 +## v4.1.2 + +* [COOK-3343](https://tickets.opscode.com/browse/COOK-3343) - Can't parse release candidate version number. + +## v4.1.0 + +* [COOK-3343] - Can't parse release candidate version number. + +## v4.0.0 + +* Removes compatability with Chef 10. +* [COOK-3564](https://tickets.opscode.com/browse/COOK-3564) - Replace calls to `Chef::Mixin::RecipeDefinitionDSLCore`. + +## v3.0.0 + +* [COOK-3306]: Multiple Memory Leaks in Application Cookbook. + +## v2.0.4 + +* [COOK-2812]: application cookbook doesn't allow to specify a block as `restart_command`. + +## v2.0.2 + +* [COOK-2537]: Provide proper `respond_to` behavior when using `method_missing`. +* [COOK-2713]: application resource should Allow sub-resource attributes to propogate up. ### Improvement -- **[COOK-3564](https://tickets.opscode.com/browse/COOK-3564)** - Replace calls to `Chef::Mixin::RecipeDefinitionDSLCore` +* [COOK-2597]: Allow customization for `shallow_clone` when doing a git deploy. -v3.0.0 ------- -### Bug -- [COOK-3306]: Multiple Memory Leaks in Application Cookbook +## v2.0.0 -v2.0.4 ------- -### Bug -- [COOK-2812]: application cookbook doesn't allow to specify a block as `restart_command` - -v2.0.2 ------- -### Bug -- [COOK-2537]: Provide proper `respond_to` behavior when using `method_missing` -- [COOK-2713]: application resource should Allow sub-resource attributes to propogate up - -### Improvement -- [COOK-2597]: Allow customization for `shallow_clone` when doing a git deploy - -v2.0.0 ------- This release is incompatible with previous releases (hence major version change). The recipes used in older versions are deprecated and completely removed. See README.md for further detail. -- [COOK-1673] - `deploy_revision` in the application cookbook gives an argument error -- [COOK-1820] - Application cookbook: remove deprecated recipes +* [COOK-1673] - `deploy_revision` in the application cookbook gives an argument error. +* [COOK-1820] - Application cookbook: remove deprecated recipes. -v1.0.4 ------- -- [COOK-1567] - Add git submodules to application cookbook +## v1.0.4 -v1.0.2 ------- -- [COOK-1312] - string callbacks fail with method not found (really included this time) -- [COOK-1332] - add `release_path` and `shared_path` methods -- [COOK-1333] - add example for running migrations -- [COOK-1360] - fix minor typos in README -- [COOK-1374] - use runit attributes in unicorn run script +* [COOK-1567] - Add git submodules to application cookbook. + +## v1.0.2 + +* [COOK-1312] - string callbacks fail with method not found (really included this time). +* [COOK-1332] - add `release_path` and `shared_path` methods. +* [COOK-1333] - add example for running migrations. +* [COOK-1360] - fix minor typos in README. +* [COOK-1374] - use runit attributes in unicorn run script. + +## v1.0.0 -v1.0.0 ------- This release introduces the LWRP for application deployment, as well as other improvements. The recipes will be deprecated in August 2012 as indicated by their warning messages and in the README.md. -- [COOK-634] - Implement LWRP for application deployment -- [COOK-1116] - use other SCMs than git -- [COOK-1252] - add `:force_deploy` that maps to corresponding action of deploy resource -- [COOK-1253] - fix rollback error -- [COOK-1312] - string callbacks fail with method not found -- [COOK-1313] - implicit file based hooks aren't invoked -- [COOK-1318] - Create `to_ary` method to resolve issue in resources() lookup on "application[foo]" resources +* [COOK-634] - Implement LWRP for application deployment. +* [COOK-1116] - use other SCMs than git. +* [COOK-1252] - add `:force_deploy` that maps to corresponding action of deploy resource. +* [COOK-1253] - fix rollback error. +* [COOK-1312] - string callbacks fail with method not found. +* [COOK-1313] - implicit file based hooks aren't invoked. +* [COOK-1318] - Create `to_ary` method to resolve issue in resources() lookup on "application[foo]" resources. -v0.99.14 --------- -- [COOK-1065] - use pip in virtualenv during deploy +## v0.99.14 -v0.99.12 --------- -- [COOK-606] application cookbook deployment recipes should use ipaddress instead of fqdn +* [COOK-1065] - use pip in virtualenv during deploy. -v0.99.11 --------- -- make the `_default` `chef_environment` look like production rails env +## v0.99.12 -v0.99.10 --------- -- Use Chef 0.10's `node.chef_environment` instead of `node['app_environment']`. +* [COOK-606] application cookbook deployment recipes should use ipaddress instead of fqdn. + +## v0.99.11 + +* make the `_default` `chef_environment` look like production rails env. + +## v0.99.10 + +* Use Chef 0.10's `node.chef_environment` instead of `node['app_environment']`. diff --git a/cookbooks/application/README.md b/cookbooks/application/README.md index b0d2c4e..6089ca3 100644 --- a/cookbooks/application/README.md +++ b/cookbooks/application/README.md @@ -1,206 +1,259 @@ -Application cookbook -==================== -This cookbook is designed to be able to describe and deploy web applications. It provides the basic infrastructure; other cookbooks are required to support specific combinations of frameworks and application servers. The following cookbooks are available at this time: +# Application cookbook -- [application_java](https://github.com/opscode-cookbooks/application_java) (Java and Tomcat) -- [application_nginx](https://github.com/opscode-cookbooks/application_nginx) (nginx reverse proxy) -- [application_php](https://github.com/opscode-cookbooks/application_php) (PHP with `mod_php_apache2`) -- [application_python](https://github.com/opscode-cookbooks/application_python) (Django with Gunicorn) -- [application_ruby](https://github.com/opscode-cookbooks/application_ruby) (Rails with Passenger or Unicorn) +[![Build Status](https://img.shields.io/travis/poise/application.svg)](https://travis-ci.org/poise/application) +[![Gem Version](https://img.shields.io/gem/v/poise-application.svg)](https://rubygems.org/gems/poise-application) +[![Cookbook Version](https://img.shields.io/cookbook/v/application.svg)](https://supermarket.chef.io/cookbooks/application) +[![Coverage](https://img.shields.io/codeclimate/coverage/github/poise/application.svg)](https://codeclimate.com/github/poise/application) +[![Gemnasium](https://img.shields.io/gemnasium/poise/application.svg)](https://gemnasium.com/poise/application) +[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) +A [Chef](https://www.chef.io/) cookbook to deploy applications. -Backwards Compatibility ------------------------ -- Version 4.0.0 dropped support for Chef 10 -- Version 2.0.0 dropped support for the `apps` data bag. +## Getting Started - -Requirements ------------- -The previous dependencies have been moved out to the application-stack-specific cookbooks, and this cookbook has no external dependencies. - - -Resources/Providers -------------------- -The `application` LWRP configures the basic properties of most applications, regardless of the framework or application server they use. These include: - -- SCM information for the deployment, such as the repository URL and branch name; -- deployment destination, including the filesystem path to deploy to; -- any OS packages to install as dependencies; -- optional callback to control the deployment. - -This LWRP uses the `deploy_revision` LWRP to perform the bulk of its tasks, and many concepts and parameters map directly to it. Check the documentation for `deploy_revision` for more information. - -Configuration of framework-specific aspects of the application are performed by invoking a sub-resource; see the appropriate cookbook for more documentation. - -### Actions -- `:deploy`: deploy an application, including any necessary configuration, restarting the associated service if necessary -- `:force_deploy`: same as `:deploy`, but it will send a `:force_deploy` action to the deploy resource, directing it to deploy the application even if the same revision is already deployed - -### Attribute Parameters -- `name`: name attribute. The name of the application you are setting up. This will be used to derive the default value for other attribute -- `packages`: an Array or Hash of packages to be installed before starting the deployment -- `path`: target path of the deployment; it will be created if it does not exist -- `owner`: the user that shall own the target path -- `group`: the group that shall own the target path -- `keep_releases`: count of keep releases -- `strategy`: the underlying LWRP that will be used to perform the deployment. The default is `:deploy_revision`, and it should never be necessary to change it -- `scm_provider`: the provider class to use for the deployment. It defaults to `Chef::Provider::Git`, you can set it to `Chef::Provider::Subversion` to deploy from an SVN repository -- `repository`: the URL of the repository the application should be checked out from -- `revision`: an identifier pointing to the revision that should be checked out -- `deploy_key`: the private key to use to access the repository via SSH, or path to a file containing the key -- `rollback_on_error`: if true, exceptions during a deployment will be caught and a clean rollback to the previous version will be attempted; the exception will then be re-raised. Defaults to true; change it only if you know what you are doing -- `environment`: a Hash of environment variables to set while running migrations -- `purge_before_symlink`: an Array of paths (relative to the checkout) to remove before creating symlinks -- `create_dirs_before_symlink`: an Array of paths (relative to the checkout) pointing to directories to create before creating symlinks -- `symlinks`: a Hash of shared/dir/path => release/dir/path. It determines which files and dirs in the shared directory get symlinked to the current release directory -- `symlink_before_migrate`: similar to symlinks, except that they will be linked before any migration is run -- `migrate`: if `true` then migrations will be run; defaults to false -- `migration_command`: a command to run to migrate the application from the previous to the current state -- `restart_command`: a command to run when restarting the application -- `environment_name`: the name of a framework-specific "environment" (for example the Rails environment). By default it is the same as the Chef environment, unless it is `_default`, in which case it is set to `production` -- `enable_submodules`: whether to enable git submodules in the deploy, passed into the deploy resource. - -### Callback Attributes -You can also set a few attributes on this LWRP that are interpreted as callback to be called at specific points during a deployment. If you pass a block, it will be evaluated within a new context. If you pass a string, it will be interpreted as a path (relative to the release directory) to a file; if it exists, it will be loaded and evaluated as though it were a Chef recipe. - -The following callback attributes are available: - -- `before_deploy`: invoked immediately after initial setup and before the deployment proper is started. This callback will be invoked on every Chef run -- `before_migrate` -- `before_symlink` -- `before_restart` -- `after_restart` - -### Sub-resources -Anything that is not a known attribute will be interpreted as the name of a sub-resource; the resource will be looked up, and any nested attribute will be passed to it. More than one sub-resource can be added to an application; the order is significant, with the latter sub-resources overriding any sub-resource that comes before. - -Sub-resources can set their own values for some attributes; if they do, they will be merged together with the attribute set on the main resource. The attributes that support this behavior are the following: - -- `environment`: environment variables from the application and from sub-resources will be merged together, with later resources overriding values set in the application or previous resources -- `migration_command`: commands from the application and from sub-resources will be concatenated together joined with '&&' and run as a single shell command. The migration will only succeed if all the commands succeed -- `restart_command`: commands from the application and from sub-resources will be evaluated in order -- `symlink_before_migrate`: will be concatenated as a single array -- `callbacks`: sub-resources callbacks will be invoked first, followed by the application callbacks - - -Usage ------ -To use the application cookbook we recommend creating a cookbook named after the application, e.g. `my_app`. In `metadata.rb` you should declare a dependency on this cookbook and any framework cookbook the application may need. For example a Rails application may include: +The application cookbook provides a central framework to deploy applications +using Chef. Generally this will be web applications using things like Rails, +Django, or NodeJS, but the framework makes no specific assumptions. The core +`application` resource provides DSL support and helpers, but the heavy lifting +is all done in specific plugins detailed below. Each deployment starts with +an `application` resource: ```ruby -depends 'application' -depends 'application_ruby' +application '/path/to/deploy' do + owner 'root' + group 'root' + + # ... +end ``` -The default recipe should describe your application using the `application` LWRP; you may also include additional recipes, for example to set up a database, queues, search engines and other components of your application. - -A recipe using this LWRP may look like this: +The `application` resource uses the Poise subresource system for plugins. This +means you configure the steps of the deployment like normal recipe code inside +the `application` resource, with a few special additions: ```ruby -application 'my_app' do - path '/deploy/to/dir' - owner 'app-user' - group 'app-group' +application '/path/to/deploy' do + # Application resource properties. + owner 'root' + group 'root' - repository 'http://git.example.com/my-app.git' - revision 'production' - - # Apply the rails LWRP from application_ruby - rails do - # Rails-specific configuration. See the README in the - # application_ruby cookbook for more information. + # Subresources, like normal recipe code. + package 'ruby' + git '/path/to/deploy' do + repository 'https://github.com/example/myapp.git' end - - # Apply the passenger_apache2 LWRP, also from application_ruby - passenger_apache2 do - # Passenger-specific configuration. + application_rails '/path/to/deploy' do + database 'mysql://dbhost/myapp' end end ``` -You can of course use any code necessary to determine the value of attributes: +When evaluating the recipe inside the `application` resource, it first checks +for `application_#{resource}`, as well as looking for an LWRP of the same name +in any cookbook starting with `application_`. This means that a resource named +`application_foo` can be used as `foo` inside the `application` resource: ```ruby -application 'my_app' do - repository 'http://git.example.com/my-app.git' - revision node.chef_environment == 'production' ? 'production' : 'develop' +application '/path/to/deploy' do + owner 'root' + group 'root' + + rails '/path/to/deploy' do + database 'mysql://dbhost/myapp' + end end ``` -Attributes from the application and from sub-resources are merged together: +Additionally if a resource inside the `application` block doesn't have a name, +it uses the same name as the application resource itself: ```ruby -application 'my_app' do - restart_command 'kill -1 `cat /var/run/one.pid`' - environment 'LC_ALL' => 'en', 'FOO' => 'bar' +application '/path/to/deploy' do + owner 'root' + group 'root' rails do - restart_command 'touch /tmp/something' - environment 'LC_ALL' => 'en_US' - end - - passenger_apache2 do - environment 'FOO' => 'baz' - end -end - -# at the end, you will have: -# -# restart_command #=> kill -1 `cat /var/run/one.pid` && touch /tmp/something -# environment #=> LC_ALL=en_US FOO=baz -``` - -Most databases have the concept of migrations (or you can just use your own): - -```ruby -application 'my_app' do - path '/deploy/to/dir' - owner 'app-user' - group 'app-group' - - repository 'http://git.example.com/my-app.git' - revision 'production' - - php do - migrate true - migration_command 'your-applications-migrate-command' + database 'mysql://dbhost/myapp' end end ``` -This will run `your-applications-migrate-command`, with the current directory set to the directory of the current checkout. +Other than those two special features, the recipe code inside the `application` +resource is processed just like any other recipe. -To use the application cookbook, we recommend creating a role named after the application, e.g. `my_app`. Create a Ruby DSL role in your chef-repo, or create the role directly with knife. +## Available Plugins + +* [`application_git`](https://github.com/poise/application_git) – Deploy + application code from a git repository. +* [`application_ruby`](https://github.com/poise/application_ruby) – Manage Ruby + deployments, such as Rails or Sinatra applications. +* [`application_python`](https://github.com/poise/application_python) – Manage + Python deployments, such as Django or Flask applications. +* [`application_javascript`](https://github.com/poise/application_javascript) – + Manage server-side JavaScript deployments using Node.js or io.js. +* `application_java` – *Coming soon!* +* `application_go` – *Coming soon!* +* `application_erlang` – *Coming soon!* + +## Requirements + +Chef 12 or newer is required. + +## Resources + +### `application` + +The `application` resource has top-level configuration properties for each +deployment and acts as a container for other deployment plugin resources. ```ruby -name 'my_app' -description 'My application deployment' -run_list([ - 'recipe[my_app::default]' -]) +application '/opt/test_sinatra' do + git 'https://github.com/example/my_sinatra_app.git' + bundle_install do + deployment true + end + unicorn do + port 9000 + end +end ``` -License and Authors -------------------- -- Author: Adam Jacob () -- Author: Andrea Campi () -- Author: Joshua Timberman () -- Author: Noah Kantrowitz () -- Author: Seth Chisamore () +#### Actions -```text -Copyright 2009-2013, Opscode, Inc. +* `:deploy` – Deploy the application. *(default)* +* `:start` - Run `:start` on all subresources that support it. +* `:stop` - Run `:stop` on all subresources that support it. +* `:restart` - Run `:restart` on all subresources that support it. +* `:reload` - Run `:reload` on all subresources that support it. + +#### Properties + +* `path` – Path to deploy the application to. *(name attribute)* +* `environment` – Environment variables for all application deployment steps. +* `group` – System group to deploy the application as. +* `owner` – System user to deploy the application as. +* `action_on_update` – Action to run on the application resource when any + subresource is updated. *(default: restart)* +* `action_on_update_immediately` – Run the `action_on_update` notification with + `:immediately`. *(default: false)* + +### `application_cookbook_file`, `application_file`, `application_template` + +The `application_cookbook_file`, `application_file`, and `application_template` +resources extend the core Chef resources to take some application-level +configuration in to account: + +```ruby +application '/opt/myapp' do + template 'myapp.conf' do + source 'myapp.conf.erb' + end +end +``` + +If the resource name is a relative path, it will be expanded relative to the +application path. If an owner or group is declared for the application, those +will be the default user and group for the resource. + +All other actions and properties are the same as the similar resource in core Chef. + +## Examples + +Some test recipes are available as examples for common application frameworks: + +* [Sinatra](https://github.com/poise/application_ruby/blob/master/test/cookbooks/application_ruby_test/recipes/sinatra.rb) +* [Rails](https://github.com/poise/application_ruby/blob/master/test/cookbooks/application_ruby_test/recipes/rails.rb) +* [Flask](https://github.com/poise/application_python/blob/master/test/cookbooks/application_python_test/recipes/flask.rb) +* [Django](https://github.com/poise/application_python/blob/master/test/cookbooks/application_python_test/recipes/django.rb) +* [Express](https://github.com/poise/application_javascript/blob/master/test/cookbooks/application_javascript_test/recipes/express.rb) + +## Upgrading From 4.x + +While the overall design of the revamped application resource is similar to the +4.x version, some changes will need to be made. The `name` property no longer +exists, with the name attribute being used as the path to the deployment. +The `packages` property has been removed as this is more easily handled via +normal recipe code. + +The SCM-related properties like `repository` and `revision` are now handled by +normal plugins. If you were deploying from a private git repository you will +likely want to use the `application_git` cookbook, otherwise just use the +built-in `git` or `svn` resources as per normal. + +The properties related to the `deploy` resource like `strategy` and `symlinks` +have been removed. The `deploy` resource is no longer used so these aren't +relevant. As a side effect of this, you'll likely want to point the upgraded +deployment at a new folder or manually clean the `current` and `shared` folders +from the existing folder. The pseudo-Capistrano layout used by the `deploy` +resource has few benefits in a config-managed world and introduced a lot of +complexity and moving pieces that are no longer required. + +With the removal of the `deploy` resource, the callback properties and commands +are no longer used as well. Subresources no longer use the complex +actions-as-callbacks arrangement as existed before, instead following normal +Chef recipe flow. Individual subresources may need to be tweaked to work with +newer versions of the cookbooks they come from, though most have stayed similar +in overall approach. + +## Database Migrations and Chef + +Several of the web application deployment plugins include optional support to +run database migrations from Chef. For "toy" applications where the app and +database run together on a single machine, this is fine and is a nice time +saver. For anything more complex I highly recommend not running database +migrations from Chef. Some initial operations like creating the database and/or +database user are more reasonable as they tend to be done only once and by their +nature the application does not yet have users so some level of eventual +consistency is more acceptable. With migrations on a production application, I +encourage using Chef and the application cookbooks to handle deploying the code +and writing configuration files, but use something more specific to run the +actual migration task. [Fabric](http://www.fabfile.org/), +[Capistrano](http://capistranorb.com/), and [Rundeck](http://rundeck.org/) are +all good choices for this orchestration tooling. + +Migrations can generally be applied idempotently but they have unique +constraints (pun definitely intended) that make them tricky in a Chef-like, +convergence-based system. First and foremost is that many table alterations +lock the table for updating for at least some period of time. That can mean that +while staging the new code or configuration data can happen within a window, the +migration itself needs to be run in careful lockstep with the rest of the +deployment process (eg. moving things in and out of load balancers). Beyond +that, while most web frameworks have internal idempotence checks for migrations, +running the process on two servers at the same time can have unexpected effects. + +Overall migrations are best thought of as a procedural step rather than a +declaratively modeled piece of the system. + +## Application Signals and Updates + +The `application` resource exposes `start`, `stop`, `restart`, and `reload` +actions which will dispatch to any subresources attached to the application. +This allows for generic application-level restart or reload signals that will +work with any type of deployment. + +Additionally the `action_on_update` property is used to set a default +notification so any subresource that updates will trigger an application +restart or reload. This can be disabled by setting `action_on_update false` if +you want to take manual control of service restarts. + +## Sponsors + +Development sponsored by [Chef Software](https://www.chef.io/), [Symonds & Son](http://symondsandson.com/), and [Orion](https://www.orionlabs.co/). + +The Poise test server infrastructure is sponsored by [Rackspace](https://rackspace.com/). + +## License + +Copyright 2015, Noah Kantrowitz 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 +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/application/files/halite_gem/poise_application.rb b/cookbooks/application/files/halite_gem/poise_application.rb new file mode 100644 index 0000000..13c9825 --- /dev/null +++ b/cookbooks/application/files/halite_gem/poise_application.rb @@ -0,0 +1,25 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 PoiseApplication + autoload :AppMixin, 'poise_application/app_mixin' + autoload :Error, 'poise_application/error' + autoload :Resources, 'poise_application/resources' + autoload :ServiceMixin, 'poise_application/service_mixin' + autoload :Utils, 'poise_application/utils' + autoload :VERSION, 'poise_application/version' +end diff --git a/cookbooks/application/files/halite_gem/poise_application/app_file_mixin.rb b/cookbooks/application/files/halite_gem/poise_application/app_file_mixin.rb new file mode 100644 index 0000000..9f4a377 --- /dev/null +++ b/cookbooks/application/files/halite_gem/poise_application/app_file_mixin.rb @@ -0,0 +1,61 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 'poise/utils' + +require 'poise_application/app_mixin' + + +module PoiseApplication + # A helper mixin for `file`-like resources to make them take application + # resource data. Relative paths are expanded against the application path and + # the app owner/group are the default user/group for the resource. + # + # @api private + # @since 5.1.0 + module AppFileMixin + include Poise::Utils::ResourceProviderMixin + + module Resource + include PoiseApplication::AppMixin + + def initialize(*) + super + # So our lazy default below can work. Not needed on 12.7+. + remove_instance_variable(:@path) if instance_variable_defined?(:@path) + end + + # @!attribute path + # Override the default path to be relative to the app path. + # @return [String] + attribute(:path, kind_of: String, default: lazy { parent ? ::File.expand_path(name, parent.path) : name }) + + # @!attribute group + # Override the default group to be the app group if unspecified. + # @return [String, Integer] + attribute(:group, kind_of: [String, Integer, NilClass], default: lazy { parent && parent.group }) + + # @!attribute user + # Override the default user to be the app owner if unspecified. + # @return [String, Integer] + attribute(:user, kind_of: [String, Integer, NilClass], default: lazy { parent && parent.owner }) + end + + module Provider + include PoiseApplication::AppMixin + end + end +end diff --git a/cookbooks/application/files/halite_gem/poise_application/app_mixin.rb b/cookbooks/application/files/halite_gem/poise_application/app_mixin.rb new file mode 100644 index 0000000..7ce3d53 --- /dev/null +++ b/cookbooks/application/files/halite_gem/poise_application/app_mixin.rb @@ -0,0 +1,69 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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/mash' +require 'poise/provider' +require 'poise/resource' +require 'poise/utils' + + +module PoiseApplication + # A helper mixin for application resources and providers. These are things + # intended to be used as subresources of the `application` resource. + # + # @since 5.0.0 + module AppMixin + include Poise::Utils::ResourceProviderMixin + + # A helper mixin for application resources. + module Resource + include Poise::Resource + + # Set the parent type and optional flag. + poise_subresource(:application, true) + + # @!attribute path + # Base path for the application. + # @return [String] + attribute(:path, kind_of: String, name_attribute: true) + + # A delegator for accessing the application state. If no application + # parent is found, the state will be tracked internally within the + # resource. + # + # @return [Hash] + def app_state + if parent + parent.app_state + else + # If there isn't a parent, just track within the resource. + @local_app_state ||= Mash.new + end + end + + # Environment variables stored in the application state. + # + # @return [Hash] + def app_state_environment + app_state[:environment] ||= Mash.new + end + end + + module Provider + include Poise::Provider + end + end +end diff --git a/cookbooks/application/files/halite_gem/poise_application/cheftie.rb b/cookbooks/application/files/halite_gem/poise_application/cheftie.rb new file mode 100644 index 0000000..622ba83 --- /dev/null +++ b/cookbooks/application/files/halite_gem/poise_application/cheftie.rb @@ -0,0 +1,17 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 'poise_application/resources' diff --git a/cookbooks/application/files/halite_gem/poise_application/error.rb b/cookbooks/application/files/halite_gem/poise_application/error.rb new file mode 100644 index 0000000..4156956 --- /dev/null +++ b/cookbooks/application/files/halite_gem/poise_application/error.rb @@ -0,0 +1,24 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 PoiseApplication + # Base exception class for poise-application errors. + # + # @since 5.0.0 + class Error < Exception + end +end diff --git a/cookbooks/application/files/halite_gem/poise_application/resources.rb b/cookbooks/application/files/halite_gem/poise_application/resources.rb new file mode 100644 index 0000000..4797a80 --- /dev/null +++ b/cookbooks/application/files/halite_gem/poise_application/resources.rb @@ -0,0 +1,29 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 'poise_application/resources/application' +require 'poise_application/resources/application_cookbook_file' +require 'poise_application/resources/application_file' +require 'poise_application/resources/application_template' + + +module PoiseApplication + # Chef resources and providers for poise-application. + # + # @since 5.0.0 + module Resources + end +end diff --git a/cookbooks/application/files/halite_gem/poise_application/resources/application.rb b/cookbooks/application/files/halite_gem/poise_application/resources/application.rb new file mode 100644 index 0000000..e0efbf2 --- /dev/null +++ b/cookbooks/application/files/halite_gem/poise_application/resources/application.rb @@ -0,0 +1,259 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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' # On 12.4+ this will pull in chef/dsl/resources. +require 'chef/resource' +require 'chef/provider' +require 'poise' + + +module PoiseApplication + module Resources + # (see Application::Resource) + # @since 5.0.0 + module Application + # An `application` resource to manage application deployment. + # + # @since 5.0.0 + # @provides application + # @action deploy + # @action start + # @action stop + # @action restart + # @action reload + # @example + # application '/srv/myapp' do + # git '...' + # poise_service 'myapp' do + # command '/srv/myapp/main' + # end + # end + class Resource < Chef::Resource + include Poise(container: true, container_namespace: false) + provides(:application) + actions(:deploy, :start, :stop, :restart, :reload) + + # @!attribute path + # Application base path. + # @return [String] + attribute(:path, kind_of: String, name_attribute: true) + # @!attribute environment + # Environment variables to set for the whole application. + # @return [Hash] + attribute(:environment, kind_of: Hash, default: lazy { Mash.new }) + # @!attribute owner + # System user that will own the application. This can be overriden in + # individual subresources. + # @return [String] + attribute(:owner, kind_of: String) + # @!attribute group + # System group that will own the application. This can be overriden in + # individual subresources. + # @return [String] + attribute(:group, kind_of: String) + # @!attribute action_on_update + # Action to run when any subresource is updated. Defaults to `:restart`. + # @return [String, Symbol, nil, false] + attribute(:action_on_update, kind_of: [Symbol, String, NilClass, FalseClass], default: :restart) + # @!attribute action_on_update_immediately + # Run the {#action_on_update} notification with `:immediately`. + # @return [Boolean] + attribute(:action_on_update_immediately, equal_to: [true, false], default: false) + + # Run the DSL rewire when the resource object is created. + # @api private + def initialize(*args) + super + _rewire_dsl! if node + end + + # Application-specific state values used as a way to communicate between + # subresources. + # + # @return [Mash] + # @example + # if new_resource.parent && new_resource.parent.app_state['gemfile_path'] + def app_state + @app_state ||= Mash.new(environment: environment) + end + + # Override Container#register_subresource to add our action_on_update. + # + # @api private + def register_subresource(resource) + super.tap do |added| + if added && action_on_update + Chef::Log.debug("[#{self}] Registering #{action_on_update_immediately ? 'immediate ' : ''}#{action_on_update} notification from #{resource}") + resource.notifies action_on_update.to_sym, self, (action_on_update_immediately ? :immediately : :delayed) + end + end + end + + private + + # Find all resources that need to be rewired. This is anything with a + # name starting with application_. + # + # @return [Array] + def _rewire_resources + if defined?(Chef::DSL::Resources) + # Chef >= 12.4. + Chef::DSL::Resources.instance_methods + else + # Chef < 12.4 >= 12.0. + Chef::Resource.descendants.map do |klass| + klass.node_map.instance_variable_get(:@map).keys + if klass.dsl_name.include?('::') + # Probably not valid. + # :nocov: + [] + # :nocov: + else + # Needed for things that don't call provides(). + [klass.dsl_name] + end + end.flatten + end.map {|name| name.to_s }.select {|name| name.start_with?('application_') }.uniq + end + + # Find all cookbooks that might contain LWRPs matching our name scheme. + # + # @return [Array] + def _rewire_cookbooks + # Run context might be unset during test setup. + if run_context + run_context.cookbook_collection.keys.select {|cookbook_name| cookbook_name.start_with?('application_') } + else + [] + end + end + + # Build the mapping of new_name => old_name for each resource to rewire. + # + # @return [Hash] + def _rewire_map + application_cookbooks = _rewire_cookbooks + _rewire_resources.inject({}) do |memo, name| + # Grab the resource class to check if it is an LWRP. + klass = Chef::Resource.resource_for_node(name.to_sym, node) + # Find the part to trim. Check for LWRP first, then just application_. + trim = if klass < Chef::Resource::LWRPBase + application_cookbooks.find {|cookbook_name| name.start_with?(cookbook_name) && name != cookbook_name } || 'application' + else + # Non-LWRPs are assumed to have a better name. + 'application' + end + # Map trimmed to untrimmed. + memo[name[trim.length+1..-1]] = name + memo + end + end + + # Build new DSL methods to implement the foo -> application_foo behavior. + # + # @return [void] + def _rewire_dsl! + # Generate stub methods for all the rewiring. + _rewire_map.each do |new_name, old_name| + # This is defined as a singleton method on self so it looks like + # the DSL but is scoped to just this context. + define_singleton_method(new_name) do |name=nil, *args, &block| + # Store the caller to correct the source_line. + created_at = caller[0] + public_send(old_name, name, *args) do + # Set the declared type to be the native name. + self.declared_type = self.class.resource_name + # Fix the source location. For Chef 12.4 we could do this with the + # declared_at parameter on the initial send. + self.source_line = created_at + # Run the original block. + instance_exec(&block) if block + end + end + end + end + end + + # Provider for `application`. + # + # @since 5.0.0 + # @see Resource + # @provides application + class Provider < Chef::Provider + include Poise + provides(:application) + + # `deploy` action for `application`. Creates the application base folder. + # + # @return [void] + def action_deploy + notifying_block do + directory new_resource.path do + owner new_resource.owner + group new_resource.group + mode '755' + end + end + end + + # `start` action for `application`. Proxies to subresources. + # + # @return [void] + def action_start + proxy_action(:start) + end + + # `stop` action for `application`. Proxies to subresources. + # + # @return [void] + def action_stop + proxy_action(:stop) + end + + # `restart` action for `application`. Proxies to subresources. + # + # @return [void] + def action_restart + proxy_action(:restart) + end + + # `reload` action for `application`. Proxies to subresources. + # + # @return [void] + def action_reload + proxy_action(:reload) + end + + private + + # Proxy an action to any subresources that support it. + # + # @param action [Symbol] Action to proxy. + # @return [void] + def proxy_action(action) + Chef::Log.debug("[#{new_resource} Running proxied #{action} action") + new_resource.subresources.each do |r| + begin + r.run_action(action) if r.allowed_actions.include?(action) + rescue Chef::Exceptions::UnsupportedAction + # Don't care, just move on. + end + end + end + + end + end + end +end diff --git a/cookbooks/application/files/halite_gem/poise_application/resources/application_cookbook_file.rb b/cookbooks/application/files/halite_gem/poise_application/resources/application_cookbook_file.rb new file mode 100644 index 0000000..bcb6830 --- /dev/null +++ b/cookbooks/application/files/halite_gem/poise_application/resources/application_cookbook_file.rb @@ -0,0 +1,54 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 'poise_application/app_file_mixin' + + +module PoiseApplication + module Resources + # (see ApplicationCookbookFile::Resource) + # @since 5.1.0 + module ApplicationCookbookFile + # An `application_cookbook_file` resource to manage Chef cookbook_files inside and + # Application cookbook deployment. + # + # @provides application_cookbook_file + # @action create + # @action create_if_missing + # @action delete + # @action touch + # @example + # application '/srv/myapp' do + # cookbook_file 'myapp.conf' do + # source 'myapp.conf' + # end + # end + class Resource < Chef::Resource::CookbookFile + include PoiseApplication::AppFileMixin + provides(:application_cookbook_file) + actions(:create, :create_if_missing, :delete, :touch) + subclass_providers! + + def initialize(*args) + super + # For older Chef. + @resource_name = :application_cookbook_file + end + end + + end + end +end diff --git a/cookbooks/application/files/halite_gem/poise_application/resources/application_file.rb b/cookbooks/application/files/halite_gem/poise_application/resources/application_file.rb new file mode 100644 index 0000000..a766088 --- /dev/null +++ b/cookbooks/application/files/halite_gem/poise_application/resources/application_file.rb @@ -0,0 +1,54 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 'poise_application/app_file_mixin' + + +module PoiseApplication + module Resources + # (see ApplicationFile::Resource) + # @since 5.1.0 + module ApplicationFile + # An `application_file` resource to manage Chef files inside and + # Application cookbook deployment. + # + # @provides application_file + # @action create + # @action create_if_missing + # @action delete + # @action touch + # @example + # application '/srv/myapp' do + # file 'myapp.conf' do + # source 'myapp.conf.erb' + # end + # end + class Resource < Chef::Resource::File + include PoiseApplication::AppFileMixin + provides(:application_file) + actions(:create, :create_if_missing, :delete, :touch) + subclass_providers! + + def initialize(*args) + super + # For older Chef. + @resource_name = :application_file + end + end + + end + end +end diff --git a/cookbooks/application/files/halite_gem/poise_application/resources/application_template.rb b/cookbooks/application/files/halite_gem/poise_application/resources/application_template.rb new file mode 100644 index 0000000..27e7f0b --- /dev/null +++ b/cookbooks/application/files/halite_gem/poise_application/resources/application_template.rb @@ -0,0 +1,54 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 'poise_application/app_file_mixin' + + +module PoiseApplication + module Resources + # (see ApplicationTemplate::Resource) + # @since 5.1.0 + module ApplicationTemplate + # An `application_template` resource to manage Chef templates inside and + # Application cookbook deployment. + # + # @provides application_template + # @action create + # @action create_if_missing + # @action delete + # @action touch + # @example + # application '/srv/myapp' do + # template 'myapp.conf' do + # source 'myapp.conf.erb' + # end + # end + class Resource < Chef::Resource::Template + include PoiseApplication::AppFileMixin + provides(:application_template) + actions(:create, :create_if_missing, :delete, :touch) + subclass_providers! + + def initialize(*args) + super + # For older Chef. + @resource_name = :application_template + end + end + + end + end +end diff --git a/cookbooks/application/files/halite_gem/poise_application/service_mixin.rb b/cookbooks/application/files/halite_gem/poise_application/service_mixin.rb new file mode 100644 index 0000000..176fb29 --- /dev/null +++ b/cookbooks/application/files/halite_gem/poise_application/service_mixin.rb @@ -0,0 +1,116 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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' +require 'chef/provider' +require 'poise/utils' +require 'poise_service/service_mixin' +require 'poise_service/utils' + +require 'poise_application/app_mixin' +require 'poise_application/utils' + + +module PoiseApplication + # Mixin for application services. This is any resource that will be part of + # an application deployment and involves running a persistent service. + # + # @api public + # @since 5.0.0 + # @example + # module MyApp + # class Resource < Chef::Resource + # include Poise + # provides(:my_app) + # include PoiseApplication::ServiceMixin + # end + # + # class Provider < Chef::Provider + # include Poise + # provides(:my_app) + # include PoiseApplication::ServiceMixin + # + # def action_enable + # notifying_block do + # template '/etc/myapp.conf' do + # # ... + # end + # end + # super + # end + # + # def service_options(r) + # super + # r.command('myapp --serve') + # end + # end + # end + module ServiceMixin + include Poise::Utils::ResourceProviderMixin + + # Mixin for application service resources. + # + # @see ServiceMixin + module Resource + include PoiseService::ServiceMixin::Resource + include PoiseApplication::AppMixin::Resource + + module ClassMethods + # @api private + def included(klass) + super + klass.extend(ClassMethods) + klass.class_exec do + attribute(:path, kind_of: String, name_attribute: true) + # Redefines from the PoiseService version so we get a better default. + attribute(:service_name, kind_of: String, default: lazy { PoiseService::Utils.parse_service_name(path) }) + attribute(:user, kind_of: [String, Integer], default: lazy { parent ? parent.owner : 'root' }) + end + end + end + + extend ClassMethods + end + + # Mixin for application service providers. + # + # @see ServiceMixin + module Provider + include PoiseService::ServiceMixin::Provider + include PoiseApplication::AppMixin::Provider + + private + + # Abstract hook to set parameters on {#service_resource} when it is + # created. This is required to set at least `resource.command`. + # + # @api public + # @param resource [Chef::Resource] Resource instance to set parameters on. + # @return [void] + # @example + # def service_options(resource) + # super + # resource.command('myapp --serve') + # end + def service_options(resource) + super + resource.directory(new_resource.path) + resource.user(new_resource.user) + resource.environment.update(new_resource.app_state_environment) if new_resource.parent + end + end + end +end diff --git a/cookbooks/application/files/halite_gem/poise_application/utils.rb b/cookbooks/application/files/halite_gem/poise_application/utils.rb new file mode 100644 index 0000000..cc3f874 --- /dev/null +++ b/cookbooks/application/files/halite_gem/poise_application/utils.rb @@ -0,0 +1,51 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 'etc' + + +module PoiseApplication + # Utility methods for PoiseApplication. + # + # @api public + # @since 5.0.0 + module Utils + # Methods are also available as module-level methods as well as a mixin. + extend self + + # Try to find the primary group name for a given user. + # + # @param user [String, Integer] User to check, if given as an integer this + # is used as a UID, otherwise it is the username. + # @return [String] + # @example + # attribute(:group, kind_of: [String, Integer], default: lazy { PoiseApplication::Utils.primary_group_for(user) }) + def primary_group_for(user) + # Force a reload in case any users were created earlier in the run. + Etc.endpwent + Etc.endgrent + user = if user.is_a?(Integer) + Etc.getpwuid(user) + else + Etc.getpwnam(user.to_s) + end + Etc.getgrgid(user.gid).name + rescue ArgumentError + # One of the get* calls exploded. ¯\_(ツ)_/¯ + user.to_s + end + end +end diff --git a/cookbooks/application/files/halite_gem/poise_application/version.rb b/cookbooks/application/files/halite_gem/poise_application/version.rb new file mode 100644 index 0000000..bb3f482 --- /dev/null +++ b/cookbooks/application/files/halite_gem/poise_application/version.rb @@ -0,0 +1,20 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 PoiseApplication + VERSION = '5.1.0' +end diff --git a/cookbooks/application/libraries/default.rb b/cookbooks/application/libraries/default.rb index 7cf6d2a..ebf4f00 100644 --- a/cookbooks/application/libraries/default.rb +++ b/cookbooks/application/libraries/default.rb @@ -1,15 +1,11 @@ # -# Author:: Noah Kantrowitz -# Cookbook Name:: application -# Library:: default -# -# Copyright:: 2011-2012, Opscode, Inc +# Copyright 2015, Noah Kantrowitz # # 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 +# 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, @@ -18,172 +14,6 @@ # limitations under the License. # -require "chef/mixin/from_file" - -class Chef - class Resource - # Monkey-Patch the blacklists to prevent infinite recursion in #to_json and similar - # (this is global state,thus the set-union operator to change it idempotently + to not leak) - [ :@application, :@application_provider ].each do |ivar| - FORBIDDEN_IVARS << ivar unless FORBIDDEN_IVARS.include?(ivar) - HIDDEN_IVARS << ivar unless HIDDEN_IVARS.include?(ivar) - end - end -end - -class ApplicationCookbook - - module OptionsCollector - def options - @options ||= {} - end - - def method_missing(method_sym, value=nil, &block) - super - rescue NameError - value ||= block - method_sym = method_sym.to_s.chomp('=').to_sym - options[method_sym] = value if value - options[method_sym] ||= nil - end - end - - module ResourceBase - def self.included(klass) - klass.actions :before_compile, :before_deploy, :before_migrate, :before_symlink, :before_restart, :after_restart - klass.attribute :id, :kind_of => String, :name_attribute => true - klass.attribute :environment, :kind_of => Hash, :default => {} - klass.attribute :purge_before_symlink, :kind_of => Array, :default => [] - klass.attribute :create_dirs_before_symlink, :kind_of => Array, :default => [] - klass.attribute :symlinks, :kind_of => Hash, :default => {} - klass.attribute :symlink_before_migrate, :kind_of => Hash, :default => {} - klass.attribute :migration_command, :kind_of => [String, NilClass], :default => nil - klass.attribute :application - klass.attribute :application_provider - klass.attribute :type - end - - def restart_command(arg=nil, &block) - arg ||= block - raise "Invalid restart command" unless !arg || arg.is_a?(String) || arg.is_a?(Proc) - @restart_command = arg if arg - @restart_command - end - - def method_missing(name, *args) - if application.respond_to? name - application.send(name, *args) - else - super - end - end - - class OptionsBlock - include ApplicationCookbook::OptionsCollector - end - - def options_block(options=nil, &block) - options ||= {} - if block - collector = OptionsBlock.new - collector.instance_eval(&block) - options.update(collector.options) - end - options - end - - def find_matching_role(role, single=true, &block) - return nil if !role - nodes = [] - if node['roles'].include? role - nodes << node - end - if !single || nodes.empty? - search(:node, "role:#{role} AND chef_environment:#{node.chef_environment}") do |n| - nodes << n - end - end - if block - nodes.each do |n| - yield n - end - else - if single - nodes.first - else - nodes - end - end - end - - def find_database_server(role) - dbm = find_matching_role(role) - Chef::Log.warn("No node with role #{role}") if role && !dbm - - if respond_to?(:database) && database.has_key?('host') - database['host'] - elsif dbm && dbm.attribute?('cloud') - dbm['cloud']['local_ipv4'] - elsif dbm - dbm['ipaddress'] - end - end - end - - module ProviderBase - - def self.included(klass) - klass.send(:include, Chef::Mixin::FromFile) - end - - def deploy_provider - @deploy_provider ||= begin - provider = @deploy_resource.provider_for_action(:nothing) - provider.load_current_resource - provider - end - end - - def release_path - deploy_provider.release_path - end - - def shared_path - @deploy_resource.shared_path - end - - def callback(what, callback_code=nil) - Chef::Log.debug("Got callback #{what}: #{callback_code.inspect}") - @collection = Chef::ResourceCollection.new - case callback_code - when Proc - Chef::Log.info "#{@new_resource} running callback #{what}" - safe_recipe_eval(&callback_code) - when String - callback_file = "#{release_path}/#{callback_code}" - unless ::File.exist?(callback_file) - raise RuntimeError, "Can't find your callback file #{callback_file}" - end - run_callback_from_file(callback_file) - when nil - nil - else - raise RuntimeError, "You gave me a callback I don't know what to do with: #{callback_code.inspect}" - end - end - - def run_callback_from_file(callback_file) - if ::File.exist?(callback_file) - Dir.chdir(release_path) do - Chef::Log.info "#{@new_resource} running deploy hook #{callback_file}" - safe_recipe_eval { from_file(callback_file) } - end - end - end - - def safe_recipe_eval(&callback_code) - recipe_eval(&callback_code) - converge if respond_to?(:converge) - end - end -end +raise 'Halite is not compatible with no_lazy_load false, please set no_lazy_load true in your Chef configuration file.' unless Chef::Config[:no_lazy_load] +$LOAD_PATH << File.expand_path('../../files/halite_gem', __FILE__) +require "poise_application/cheftie" diff --git a/cookbooks/application/libraries/matchers.rb b/cookbooks/application/libraries/matchers.rb deleted file mode 100644 index eb94f1e..0000000 --- a/cookbooks/application/libraries/matchers.rb +++ /dev/null @@ -1,11 +0,0 @@ -if defined?(ChefSpec) - - def deploy_application(resource) - ChefSpec::Matchers::ResourceMatcher.new(:application, :deploy, resource) - end - - def force_deploy_application(resource) - ChefSpec::Matchers::ResourceMatcher.new(:application, :force_deploy, resource) - end - -end diff --git a/cookbooks/application/metadata.json b/cookbooks/application/metadata.json index bea510a..a491ee2 100644 --- a/cookbooks/application/metadata.json +++ b/cookbooks/application/metadata.json @@ -1,30 +1 @@ -{ - "name": "application", - "version": "4.1.6", - "description": "Deploys and configures a variety of applications", - "long_description": "Application cookbook\n====================\nThis cookbook is designed to be able to describe and deploy web applications. It provides the basic infrastructure; other cookbooks are required to support specific combinations of frameworks and application servers. The following cookbooks are available at this time:\n\n- [application_java](https://github.com/opscode-cookbooks/application_java) (Java and Tomcat)\n- [application_nginx](https://github.com/opscode-cookbooks/application_nginx) (nginx reverse proxy)\n- [application_php](https://github.com/opscode-cookbooks/application_php) (PHP with `mod_php_apache2`)\n- [application_python](https://github.com/opscode-cookbooks/application_python) (Django with Gunicorn)\n- [application_ruby](https://github.com/opscode-cookbooks/application_ruby) (Rails with Passenger or Unicorn)\n\n\nBackwards Compatibility\n-----------------------\n- Version 4.0.0 dropped support for Chef 10\n- Version 2.0.0 dropped support for the `apps` data bag.\n\n\nRequirements\n------------\nThe previous dependencies have been moved out to the application-stack-specific cookbooks, and this cookbook has no external dependencies.\n\n\nResources/Providers\n-------------------\nThe `application` LWRP configures the basic properties of most applications, regardless of the framework or application server they use. These include:\n\n- SCM information for the deployment, such as the repository URL and branch name;\n- deployment destination, including the filesystem path to deploy to;\n- any OS packages to install as dependencies;\n- optional callback to control the deployment.\n\nThis LWRP uses the `deploy_revision` LWRP to perform the bulk of its tasks, and many concepts and parameters map directly to it. Check the documentation for `deploy_revision` for more information.\n\nConfiguration of framework-specific aspects of the application are performed by invoking a sub-resource; see the appropriate cookbook for more documentation.\n\n### Actions\n- `:deploy`: deploy an application, including any necessary configuration, restarting the associated service if necessary\n- `:force_deploy`: same as `:deploy`, but it will send a `:force_deploy` action to the deploy resource, directing it to deploy the application even if the same revision is already deployed\n\n### Attribute Parameters\n- `name`: name attribute. The name of the application you are setting up. This will be used to derive the default value for other attribute\n- `packages`: an Array or Hash of packages to be installed before starting the deployment\n- `path`: target path of the deployment; it will be created if it does not exist\n- `owner`: the user that shall own the target path\n- `group`: the group that shall own the target path\n- `keep_releases`: count of keep releases\n- `strategy`: the underlying LWRP that will be used to perform the deployment. The default is `:deploy_revision`, and it should never be necessary to change it\n- `scm_provider`: the provider class to use for the deployment. It defaults to `Chef::Provider::Git`, you can set it to `Chef::Provider::Subversion` to deploy from an SVN repository\n- `repository`: the URL of the repository the application should be checked out from\n- `revision`: an identifier pointing to the revision that should be checked out\n- `deploy_key`: the private key to use to access the repository via SSH, or path to a file containing the key\n- `rollback_on_error`: if true, exceptions during a deployment will be caught and a clean rollback to the previous version will be attempted; the exception will then be re-raised. Defaults to true; change it only if you know what you are doing\n- `environment`: a Hash of environment variables to set while running migrations\n- `purge_before_symlink`: an Array of paths (relative to the checkout) to remove before creating symlinks\n- `create_dirs_before_symlink`: an Array of paths (relative to the checkout) pointing to directories to create before creating symlinks\n- `symlinks`: a Hash of shared/dir/path => release/dir/path. It determines which files and dirs in the shared directory get symlinked to the current release directory\n- `symlink_before_migrate`: similar to symlinks, except that they will be linked before any migration is run\n- `migrate`: if `true` then migrations will be run; defaults to false\n- `migration_command`: a command to run to migrate the application from the previous to the current state\n- `restart_command`: a command to run when restarting the application\n- `environment_name`: the name of a framework-specific \"environment\" (for example the Rails environment). By default it is the same as the Chef environment, unless it is `_default`, in which case it is set to `production`\n- `enable_submodules`: whether to enable git submodules in the deploy, passed into the deploy resource.\n\n### Callback Attributes\nYou can also set a few attributes on this LWRP that are interpreted as callback to be called at specific points during a deployment. If you pass a block, it will be evaluated within a new context. If you pass a string, it will be interpreted as a path (relative to the release directory) to a file; if it exists, it will be loaded and evaluated as though it were a Chef recipe.\n\nThe following callback attributes are available:\n\n- `before_deploy`: invoked immediately after initial setup and before the deployment proper is started. This callback will be invoked on every Chef run\n- `before_migrate`\n- `before_symlink`\n- `before_restart`\n- `after_restart`\n\n### Sub-resources\nAnything that is not a known attribute will be interpreted as the name of a sub-resource; the resource will be looked up, and any nested attribute will be passed to it. More than one sub-resource can be added to an application; the order is significant, with the latter sub-resources overriding any sub-resource that comes before.\n\nSub-resources can set their own values for some attributes; if they do, they will be merged together with the attribute set on the main resource. The attributes that support this behavior are the following:\n\n- `environment`: environment variables from the application and from sub-resources will be merged together, with later resources overriding values set in the application or previous resources\n- `migration_command`: commands from the application and from sub-resources will be concatenated together joined with '&&' and run as a single shell command. The migration will only succeed if all the commands succeed\n- `restart_command`: commands from the application and from sub-resources will be evaluated in order\n- `symlink_before_migrate`: will be concatenated as a single array\n- `callbacks`: sub-resources callbacks will be invoked first, followed by the application callbacks\n\n\nUsage\n-----\nTo use the application cookbook we recommend creating a cookbook named after the application, e.g. `my_app`. In `metadata.rb` you should declare a dependency on this cookbook and any framework cookbook the application may need. For example a Rails application may include:\n\n```ruby\ndepends 'application'\ndepends 'application_ruby'\n```\n\nThe default recipe should describe your application using the `application` LWRP; you may also include additional recipes, for example to set up a database, queues, search engines and other components of your application.\n\nA recipe using this LWRP may look like this:\n\n```ruby\napplication 'my_app' do\n path '/deploy/to/dir'\n owner 'app-user'\n group 'app-group'\n\n repository 'http://git.example.com/my-app.git'\n revision 'production'\n\n # Apply the rails LWRP from application_ruby\n rails do\n # Rails-specific configuration. See the README in the\n # application_ruby cookbook for more information.\n end\n\n # Apply the passenger_apache2 LWRP, also from application_ruby\n passenger_apache2 do\n # Passenger-specific configuration.\n end\nend\n```\n\nYou can of course use any code necessary to determine the value of attributes:\n\n```ruby\napplication 'my_app' do\n repository 'http://git.example.com/my-app.git'\n revision node.chef_environment == 'production' ? 'production' : 'develop'\nend\n```\n\nAttributes from the application and from sub-resources are merged together:\n\n```ruby\napplication 'my_app' do\n restart_command 'kill -1 `cat /var/run/one.pid`'\n environment 'LC_ALL' => 'en', 'FOO' => 'bar'\n\n rails do\n restart_command 'touch /tmp/something'\n environment 'LC_ALL' => 'en_US'\n end\n\n passenger_apache2 do\n environment 'FOO' => 'baz'\n end\nend\n\n# at the end, you will have:\n#\n# restart_command #=> kill -1 `cat /var/run/one.pid` && touch /tmp/something\n# environment #=> LC_ALL=en_US FOO=baz\n```\n\nMost databases have the concept of migrations (or you can just use your own):\n\n```ruby\napplication 'my_app' do\n path '/deploy/to/dir'\n owner 'app-user'\n group 'app-group'\n\n repository 'http://git.example.com/my-app.git'\n revision 'production'\n\n php do\n migrate true\n migration_command 'your-applications-migrate-command'\n end\nend\n```\n\nThis will run `your-applications-migrate-command`, with the current directory set to the directory of the current checkout.\n\nTo use the application cookbook, we recommend creating a role named after the application, e.g. `my_app`. Create a Ruby DSL role in your chef-repo, or create the role directly with knife.\n\n```ruby\nname 'my_app'\ndescription 'My application deployment'\nrun_list([\n 'recipe[my_app::default]'\n])\n```\n\nLicense and Authors\n-------------------\n- Author: Adam Jacob ()\n- Author: Andrea Campi ()\n- Author: Joshua Timberman ()\n- Author: Noah Kantrowitz ()\n- Author: Seth Chisamore ()\n\n```text\nCopyright 2009-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\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": { - }, - "dependencies": { - }, - "recommendations": { - }, - "suggestions": { - }, - "conflicting": { - }, - "providing": { - }, - "replacing": { - }, - "attributes": { - }, - "groupings": { - }, - "recipes": { - "application": "Empty placeholder recipe, use the LWRPs, see README.md." - } -} \ No newline at end of file +{"name":"application","version":"5.1.0","description":"A Chef cookbook for deploying application code.","long_description":"# Application cookbook\n\n[![Build Status](https://img.shields.io/travis/poise/application.svg)](https://travis-ci.org/poise/application)\n[![Gem Version](https://img.shields.io/gem/v/poise-application.svg)](https://rubygems.org/gems/poise-application)\n[![Cookbook Version](https://img.shields.io/cookbook/v/application.svg)](https://supermarket.chef.io/cookbooks/application)\n[![Coverage](https://img.shields.io/codeclimate/coverage/github/poise/application.svg)](https://codeclimate.com/github/poise/application)\n[![Gemnasium](https://img.shields.io/gemnasium/poise/application.svg)](https://gemnasium.com/poise/application)\n[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)\n\nA [Chef](https://www.chef.io/) cookbook to deploy applications.\n\n## Getting Started\n\nThe application cookbook provides a central framework to deploy applications\nusing Chef. Generally this will be web applications using things like Rails,\nDjango, or NodeJS, but the framework makes no specific assumptions. The core\n`application` resource provides DSL support and helpers, but the heavy lifting\nis all done in specific plugins detailed below. Each deployment starts with\nan `application` resource:\n\n```ruby\napplication '/path/to/deploy' do\n owner 'root'\n group 'root'\n\n # ...\nend\n```\n\nThe `application` resource uses the Poise subresource system for plugins. This\nmeans you configure the steps of the deployment like normal recipe code inside\nthe `application` resource, with a few special additions:\n\n```ruby\napplication '/path/to/deploy' do\n # Application resource properties.\n owner 'root'\n group 'root'\n\n # Subresources, like normal recipe code.\n package 'ruby'\n git '/path/to/deploy' do\n repository 'https://github.com/example/myapp.git'\n end\n application_rails '/path/to/deploy' do\n database 'mysql://dbhost/myapp'\n end\nend\n```\n\nWhen evaluating the recipe inside the `application` resource, it first checks\nfor `application_#{resource}`, as well as looking for an LWRP of the same name\nin any cookbook starting with `application_`. This means that a resource named\n`application_foo` can be used as `foo` inside the `application` resource:\n\n```ruby\napplication '/path/to/deploy' do\n owner 'root'\n group 'root'\n\n rails '/path/to/deploy' do\n database 'mysql://dbhost/myapp'\n end\nend\n```\n\nAdditionally if a resource inside the `application` block doesn't have a name,\nit uses the same name as the application resource itself:\n\n```ruby\napplication '/path/to/deploy' do\n owner 'root'\n group 'root'\n\n rails do\n database 'mysql://dbhost/myapp'\n end\nend\n```\n\nOther than those two special features, the recipe code inside the `application`\nresource is processed just like any other recipe.\n\n## Available Plugins\n\n* [`application_git`](https://github.com/poise/application_git) – Deploy\n application code from a git repository.\n* [`application_ruby`](https://github.com/poise/application_ruby) – Manage Ruby\n deployments, such as Rails or Sinatra applications.\n* [`application_python`](https://github.com/poise/application_python) – Manage\n Python deployments, such as Django or Flask applications.\n* [`application_javascript`](https://github.com/poise/application_javascript) –\n Manage server-side JavaScript deployments using Node.js or io.js.\n* `application_java` – *Coming soon!*\n* `application_go` – *Coming soon!*\n* `application_erlang` – *Coming soon!*\n\n## Requirements\n\nChef 12 or newer is required.\n\n## Resources\n\n### `application`\n\nThe `application` resource has top-level configuration properties for each\ndeployment and acts as a container for other deployment plugin resources.\n\n```ruby\napplication '/opt/test_sinatra' do\n git 'https://github.com/example/my_sinatra_app.git'\n bundle_install do\n deployment true\n end\n unicorn do\n port 9000\n end\nend\n```\n\n#### Actions\n\n* `:deploy` – Deploy the application. *(default)*\n* `:start` - Run `:start` on all subresources that support it.\n* `:stop` - Run `:stop` on all subresources that support it.\n* `:restart` - Run `:restart` on all subresources that support it.\n* `:reload` - Run `:reload` on all subresources that support it.\n\n#### Properties\n\n* `path` – Path to deploy the application to. *(name attribute)*\n* `environment` – Environment variables for all application deployment steps.\n* `group` – System group to deploy the application as.\n* `owner` – System user to deploy the application as.\n* `action_on_update` – Action to run on the application resource when any\n subresource is updated. *(default: restart)*\n* `action_on_update_immediately` – Run the `action_on_update` notification with\n `:immediately`. *(default: false)*\n\n### `application_cookbook_file`, `application_file`, `application_template`\n\nThe `application_cookbook_file`, `application_file`, and `application_template`\nresources extend the core Chef resources to take some application-level\nconfiguration in to account:\n\n```ruby\napplication '/opt/myapp' do\n template 'myapp.conf' do\n source 'myapp.conf.erb'\n end\nend\n```\n\nIf the resource name is a relative path, it will be expanded relative to the\napplication path. If an owner or group is declared for the application, those\nwill be the default user and group for the resource.\n\nAll other actions and properties are the same as the similar resource in core Chef.\n\n## Examples\n\nSome test recipes are available as examples for common application frameworks:\n\n* [Sinatra](https://github.com/poise/application_ruby/blob/master/test/cookbooks/application_ruby_test/recipes/sinatra.rb)\n* [Rails](https://github.com/poise/application_ruby/blob/master/test/cookbooks/application_ruby_test/recipes/rails.rb)\n* [Flask](https://github.com/poise/application_python/blob/master/test/cookbooks/application_python_test/recipes/flask.rb)\n* [Django](https://github.com/poise/application_python/blob/master/test/cookbooks/application_python_test/recipes/django.rb)\n* [Express](https://github.com/poise/application_javascript/blob/master/test/cookbooks/application_javascript_test/recipes/express.rb)\n\n## Upgrading From 4.x\n\nWhile the overall design of the revamped application resource is similar to the\n4.x version, some changes will need to be made. The `name` property no longer\nexists, with the name attribute being used as the path to the deployment.\nThe `packages` property has been removed as this is more easily handled via\nnormal recipe code.\n\nThe SCM-related properties like `repository` and `revision` are now handled by\nnormal plugins. If you were deploying from a private git repository you will\nlikely want to use the `application_git` cookbook, otherwise just use the\nbuilt-in `git` or `svn` resources as per normal.\n\nThe properties related to the `deploy` resource like `strategy` and `symlinks`\nhave been removed. The `deploy` resource is no longer used so these aren't\nrelevant. As a side effect of this, you'll likely want to point the upgraded\ndeployment at a new folder or manually clean the `current` and `shared` folders\nfrom the existing folder. The pseudo-Capistrano layout used by the `deploy`\nresource has few benefits in a config-managed world and introduced a lot of\ncomplexity and moving pieces that are no longer required.\n\nWith the removal of the `deploy` resource, the callback properties and commands\nare no longer used as well. Subresources no longer use the complex\nactions-as-callbacks arrangement as existed before, instead following normal\nChef recipe flow. Individual subresources may need to be tweaked to work with\nnewer versions of the cookbooks they come from, though most have stayed similar\nin overall approach.\n\n## Database Migrations and Chef\n\nSeveral of the web application deployment plugins include optional support to\nrun database migrations from Chef. For \"toy\" applications where the app and\ndatabase run together on a single machine, this is fine and is a nice time\nsaver. For anything more complex I highly recommend not running database\nmigrations from Chef. Some initial operations like creating the database and/or\ndatabase user are more reasonable as they tend to be done only once and by their\nnature the application does not yet have users so some level of eventual\nconsistency is more acceptable. With migrations on a production application, I\nencourage using Chef and the application cookbooks to handle deploying the code\nand writing configuration files, but use something more specific to run the\nactual migration task. [Fabric](http://www.fabfile.org/),\n[Capistrano](http://capistranorb.com/), and [Rundeck](http://rundeck.org/) are\nall good choices for this orchestration tooling.\n\nMigrations can generally be applied idempotently but they have unique\nconstraints (pun definitely intended) that make them tricky in a Chef-like,\nconvergence-based system. First and foremost is that many table alterations\nlock the table for updating for at least some period of time. That can mean that\nwhile staging the new code or configuration data can happen within a window, the\nmigration itself needs to be run in careful lockstep with the rest of the\ndeployment process (eg. moving things in and out of load balancers). Beyond\nthat, while most web frameworks have internal idempotence checks for migrations,\nrunning the process on two servers at the same time can have unexpected effects.\n\nOverall migrations are best thought of as a procedural step rather than a\ndeclaratively modeled piece of the system.\n\n## Application Signals and Updates\n\nThe `application` resource exposes `start`, `stop`, `restart`, and `reload`\nactions which will dispatch to any subresources attached to the application.\nThis allows for generic application-level restart or reload signals that will\nwork with any type of deployment.\n\nAdditionally the `action_on_update` property is used to set a default\nnotification so any subresource that updates will trigger an application\nrestart or reload. This can be disabled by setting `action_on_update false` if\nyou want to take manual control of service restarts.\n\n## Sponsors\n\nDevelopment sponsored by [Chef Software](https://www.chef.io/), [Symonds & Son](http://symondsandson.com/), and [Orion](https://www.orionlabs.co/).\n\nThe Poise test server infrastructure is sponsored by [Rackspace](https://rackspace.com/).\n\n## License\n\nCopyright 2015, Noah Kantrowitz\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","maintainer":"Noah Kantrowitz","maintainer_email":"noah@coderanger.net","license":"Apache 2.0","platforms":{},"dependencies":{"poise":"~> 2.4","poise-service":"~> 1.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{}} \ No newline at end of file diff --git a/cookbooks/application/providers/default.rb b/cookbooks/application/providers/default.rb deleted file mode 100644 index f9a0a1f..0000000 --- a/cookbooks/application/providers/default.rb +++ /dev/null @@ -1,191 +0,0 @@ -# -# Author:: Noah Kantrowitz -# Cookbook Name:: application -# Provider:: default -# -# Copyright:: 2011-2012, 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. -# - -include ApplicationCookbook::ProviderBase - -action :deploy do - - before_compile - - before_deploy - - run_deploy - -end - -action :force_deploy do - - before_compile - - before_deploy - - run_deploy(true) - -end - -action :restart do - - before_compile - - run_actions_with_context(:before_restart, @run_context) - - run_restart - - run_actions_with_context(:after_restart, @run_context) - - @new_resource.updated_by_last_action(true) - -end - -protected - -def before_compile - new_resource.application_provider self - new_resource.sub_resources.each do |resource| - resource.application_provider self - resource.run_action :before_compile - end -end - -def before_deploy - new_resource.packages.each do |pkg,ver| - package pkg do - action :install - version ver if ver && ver.length > 0 - end - end - - directory new_resource.path do - owner new_resource.owner - group new_resource.group - mode '0755' - recursive true - end - - directory "#{new_resource.path}/shared" do - owner new_resource.owner - group new_resource.group - mode '0755' - recursive true - end - - if new_resource.deploy_key - - if ::File.exists?(new_resource.deploy_key) - deploy_key = open(new_resource.deploy_key, &:read) - else - deploy_key = new_resource.deploy_key - end - - file "#{new_resource.path}/id_deploy" do - content deploy_key - owner new_resource.owner - group new_resource.group - mode '0600' - end - - template "#{new_resource.path}/deploy-ssh-wrapper" do - source "deploy-ssh-wrapper.erb" - cookbook "application" - owner new_resource.owner - group new_resource.group - mode "0755" - variables :id => new_resource.name, :deploy_to => new_resource.path, :strict_ssh => new_resource.strict_ssh - end - end - - ruby_block "#{new_resource.name} before_deploy" do - block do - new_resource.sub_resources.each do |resource| - resource.run_action :before_deploy - end - callback(:before_deploy, new_resource.before_deploy) - end - end -end - -def run_deploy(force = false) - # Alias to a variable so I can use in sub-resources - new_resource = @new_resource - # Also alias to variable so it can be used in sub-resources - app_provider = self - - @deploy_resource = send(new_resource.strategy.to_sym, new_resource.name) do - action force ? :force_deploy : :deploy - scm_provider new_resource.scm_provider - revision new_resource.revision - repository new_resource.repository - enable_submodules new_resource.enable_submodules - user new_resource.owner - group new_resource.group - keep_releases new_resource.keep_releases - deploy_to new_resource.path - ssh_wrapper "#{new_resource.path}/deploy-ssh-wrapper" if new_resource.deploy_key - shallow_clone new_resource.shallow_clone - rollback_on_error new_resource.rollback_on_error - all_environments = ([new_resource.environment]+new_resource.sub_resources.map{|res| res.environment}).inject({}){|acc, val| acc.merge(val)} - environment all_environments - migrate new_resource.migrate - all_migration_commands = ([new_resource.migration_command]+new_resource.sub_resources.map{|res| res.migration_command}).select{|cmd| cmd && !cmd.empty?} - migration_command all_migration_commands.join(' && ') - restart_command do - ([new_resource]+new_resource.sub_resources).each do |res| - cmd = res.restart_command - if cmd.is_a? Proc - app_provider.deploy_provider.instance_eval(&cmd) # @see libraries/default.rb - elsif cmd && !cmd.empty? - execute cmd do - user new_resource.owner - group new_resource.group - environment all_environments - end - end - end - end - purge_before_symlink (new_resource.purge_before_symlink + new_resource.sub_resources.map(&:purge_before_symlink)).flatten - create_dirs_before_symlink (new_resource.create_dirs_before_symlink + new_resource.sub_resources.map(&:create_dirs_before_symlink)).flatten - all_symlinks = [new_resource.symlinks]+new_resource.sub_resources.map{|res| res.symlinks} - symlinks all_symlinks.inject({}){|acc, val| acc.merge(val)} - all_symlinks_before_migrate = [new_resource.symlink_before_migrate]+new_resource.sub_resources.map{|res| res.symlink_before_migrate} - symlink_before_migrate all_symlinks_before_migrate.inject({}){|acc, val| acc.merge(val)} - before_migrate do - app_provider.send(:run_actions_with_context, :before_migrate, @run_context) - end - before_symlink do - app_provider.send(:run_actions_with_context, :before_symlink, @run_context) - end - before_restart do - app_provider.send(:run_actions_with_context, :before_restart, @run_context) - end - after_restart do - app_provider.send(:run_actions_with_context, :after_restart, @run_context) - end - end -end - -def run_actions_with_context(action, context) - new_resource.sub_resources.each do |resource| - saved_run_context = resource.instance_variable_get :@run_context - resource.instance_variable_set :@run_context, context - resource.run_action action - resource.instance_variable_set :@run_context, saved_run_context - end - callback(action, new_resource.send(action)) -end diff --git a/cookbooks/application/resources/default.rb b/cookbooks/application/resources/default.rb deleted file mode 100644 index ad19c50..0000000 --- a/cookbooks/application/resources/default.rb +++ /dev/null @@ -1,178 +0,0 @@ -# -# Author:: Noah Kantrowitz -# Cookbook Name:: application -# Resource:: default -# -# Copyright:: 2011-2012, 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. -# - -require 'weakref' - -include Chef::DSL::Recipe - -def initialize(*args) - super - @action = :deploy - @sub_resources = [] -end - -actions :deploy, :force_deploy - -attribute :name, :kind_of => String, :name_attribute => true -attribute :environment_name, :kind_of => String, :default => (node.chef_environment =~ /_default/ ? "production" : node.chef_environment) -attribute :path, :kind_of => String -attribute :owner, :kind_of => String -attribute :group, :kind_of => String -attribute :keep_releases, :kind_of => Integer, :default => 5 -attribute :strategy, :kind_of => [String, Symbol], :default => :deploy_revision -attribute :scm_provider, :kind_of => [Class, String, Symbol] -attribute :revision, :kind_of => String -attribute :repository, :kind_of => String -attribute :enable_submodules, :kind_of => [TrueClass, FalseClass], :default => false -attribute :environment, :kind_of => Hash, :default => {} -attribute :deploy_key, :kind_of => [String, NilClass], :default => nil -attribute :strict_ssh, :kind_of => [TrueClass, FalseClass], :default => false -attribute :shallow_clone, :kind_of => [TrueClass, FalseClass], :default => false -attribute :force, :kind_of => [TrueClass, FalseClass], :default => false -attribute :rollback_on_error, :kind_of => [TrueClass, FalseClass], :default => true -attribute :purge_before_symlink, :kind_of => Array, :default => [] -attribute :create_dirs_before_symlink, :kind_of => Array, :default => [] -attribute :symlinks, :kind_of => Hash, :default => {} -attribute :symlink_before_migrate, :kind_of => Hash, :default => {} -attribute :migrate, :kind_of => [TrueClass, FalseClass], :default => false -attribute :migration_command, :kind_of => [String, NilClass], :default => nil -attribute :packages, :kind_of => [Array, Hash], :default => [] -attribute :application_provider -attr_reader :sub_resources - -def restart_command(arg=nil, &block) - arg ||= block - set_or_return(:restart_command, arg, :kind_of => [Proc, String]) -end - -# Callback fires before deploy is started. -def before_deploy(arg=nil, &block) - arg ||= block - set_or_return(:before_deploy, arg, :kind_of => [Proc, String]) -end - -# Callback fires before migration is run. -def before_migrate(arg=nil, &block) - arg ||= block - set_or_return(:before_migrate, arg, :kind_of => [Proc, String]) -end - -# Callback fires before symlinking -def before_symlink(arg=nil, &block) - arg ||= block - set_or_return(:before_symlink, arg, :kind_of => [Proc, String]) -end - -# Callback fires before restart -def before_restart(arg=nil, &block) - arg ||= block - set_or_return(:before_restart, arg, :kind_of => [Proc, String]) -end - -# Callback fires after restart -def after_restart(arg=nil, &block) - arg ||= block - set_or_return(:after_restart, arg, :kind_of => [Proc, String]) -end - -def release_path - application_provider.release_path -end - -def shared_path - application_provider.shared_path -end - -def method_missing(name, *args, &block) - # Build the set of names to check for a valid resource - lookup_path = ["application_#{name}"] - run_context.cookbook_collection.each do |cookbook_name, cookbook_ver| - if cookbook_name.start_with?("application_") - lookup_path << "#{cookbook_name}_#{name}" - end - end - lookup_path << name - resource = nil - # Try to find our resource - lookup_path.each do |resource_name| - begin - Chef::Log.debug "Trying to load application resource #{resource_name} for #{name}" - resource = super(resource_name.to_sym, self.name, &block) - break - rescue NameError => e - # Works on any MRI ruby - if e.name == resource_name.to_sym || e.inspect =~ /\b#{resource_name}\b/ - next - else - raise e - end - end - end - raise NameError, "No resource found for #{name}. Tried #{lookup_path.join(', ')}" unless resource - # Enforce action :nothing in case people forget - resource.action :nothing - # Make this a weakref to prevent a cycle between the application resource and the sub resources - resource.application WeakRef.new(self) - resource.type name - @sub_resources << resource - resource -end - -def do_i_respond_to?(*args) - name = args.first.to_s - # Build the set of names to check for a valid resource - lookup_path = ["application_#{name}"] - run_context.cookbook_collection.each do |cookbook_name, cookbook_ver| - if cookbook_name.start_with?("application_") - lookup_path << "#{cookbook_name}_#{name}" - end - end - lookup_path << name - found = false - # Try to find our resource - lookup_path.each do |resource_name| - begin - Chef::Log.debug "Looking for application resource #{resource_name} for #{name}" - Chef::Resource.resource_for_node(resource_name.to_sym, node) - found = true - break - rescue NameError => e - # Keep calm and carry on - end - end - found -end - -# If we are using a current version of ruby, use respond_to_missing? -# instead of respond_to? so we provide proper behavior -if(Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('1.9.1')) - def respond_to_missing?(*args) - super || do_i_respond_to?(*args) - end -else - def respond_to?(*args) - super || do_i_respond_to?(*args) - end -end - -def to_ary - nil -end -alias :to_a :to_ary diff --git a/cookbooks/application/templates/default/deploy-ssh-wrapper.erb b/cookbooks/application/templates/default/deploy-ssh-wrapper.erb deleted file mode 100644 index fcf0c81..0000000 --- a/cookbooks/application/templates/default/deploy-ssh-wrapper.erb +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash -# -# Deploy SSH Wrapper -# App: <%= @id %> -# -# Rendered by Chef - local changes will be replaced - -/usr/bin/env ssh <% unless @strict_ssh %>-o "StrictHostKeyChecking=no" <% end %>-i "<%= @deploy_to %>/id_deploy" $@ diff --git a/cookbooks/application_git/CHANGELOG.md b/cookbooks/application_git/CHANGELOG.md new file mode 100644 index 0000000..2cba57d --- /dev/null +++ b/cookbooks/application_git/CHANGELOG.md @@ -0,0 +1,10 @@ +# Application_Git Changelog + +## v1.1.0 + +* [#2](https://github.com/poise/application_git/issues/2) – Inherit user and group values from the parent `application` resource. +* [#3](https://github.com/poise/application_git/issues/3) – Fix usage with users created during the current Chef run. + +## v1.0.0 + +* Initial release. diff --git a/cookbooks/application_git/README.md b/cookbooks/application_git/README.md new file mode 100644 index 0000000..932fd3a --- /dev/null +++ b/cookbooks/application_git/README.md @@ -0,0 +1,108 @@ +# Application_Git Cookbook + +[![Build Status](https://img.shields.io/travis/poise/application_git.svg)](https://travis-ci.org/poise/application_git) +[![Gem Version](https://img.shields.io/gem/v/poise-application-git.svg)](https://rubygems.org/gems/poise-application-git) +[![Cookbook Version](https://img.shields.io/cookbook/v/application_git.svg)](https://supermarket.chef.io/cookbooks/application_git) +[![Coverage](https://img.shields.io/codecov/c/github/poise/application_git.svg)](https://codecov.io/github/poise/application_git) +[![Gemnasium](https://img.shields.io/gemnasium/poise/application_git.svg)](https://gemnasium.com/poise/application_git) +[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) + +A [Chef](https://www.chef.io/) cookbook to handle deploying code from git when +using the [application cookbook](https://github.com/poise/application). + +## Quick Start + +To deploy from a private GitHub repository: + +```ruby +application '/srv/myapp' do + git 'git@github.com:example/myapp.git' do + deploy_key chef_vault_item('deploy_keys', 'myapp')['key'] + end +end +``` + +## Requirements + +Chef 12 or newer is required. + +## Resources + +### `application_git` + +The `application_git` resource deploys code from git. It extends the core `git` +resource to support deploy keys and disabling strict host key verification. + +```ruby +application '/srv/myapp' do + git 'git@github.com:example/myapp.git' +end +``` + +#### Actions + +All actions work the same as the core `git` resource. + +* `:sync` – Clone and checkout the requested revision *(default)* +* `:checkout` – Checkout the request revision. If the repository isn't already + cloned, this action does nothing. +* `:export` – Export the repository without the `.git` folder. + +#### Properties + +All properties from the core `git` resource work the same way with the following +additions: + +* `deploy_key` – SSH key to use with git. Can be specified either as a path to + key file already created or as a string value containing the key directly. +* `strict_ssh` – Enable strict SSH host key checking. *(default: false)* + +### DSL Usage + +The `application_git` resource can be used directly as a replacement for the +core `git` resource: + +```ruby +application_git '/srv/myapp' do + repository 'git@github.com:example/myapp.git' + deploy_key chef_vault_item('deploy_keys', 'myapp')['key'] +end +``` + +Within the `application` resource, a simplified DSL is available. As with other +`application` plugins, the default name of the resource if unspecified is the +application path. The following two examples are equivalent: + +```ruby +application '/srv/myapp' do + git do + repository 'git@github.com:example/myapp.git' + end +end + +application '/srv/myapp' do + git 'git@github.com:example/myapp.git' +end +``` + +## Sponsors + +Development sponsored by [Chef Software](https://www.chef.io/), [Symonds & Son](http://symondsandson.com/), and [Orion](https://www.orionlabs.co/). + +The Poise test server infrastructure is sponsored by [Rackspace](https://rackspace.com/). + +## License + +Copyright 2015-2016, Noah Kantrowitz + +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/application_git/files/halite_gem/poise-application-git.rb b/cookbooks/application_git/files/halite_gem/poise-application-git.rb new file mode 100644 index 0000000..bc97c9f --- /dev/null +++ b/cookbooks/application_git/files/halite_gem/poise-application-git.rb @@ -0,0 +1,17 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 'poise_application_git' diff --git a/cookbooks/application_git/files/halite_gem/poise_application_git.rb b/cookbooks/application_git/files/halite_gem/poise_application_git.rb new file mode 100644 index 0000000..56cb8bb --- /dev/null +++ b/cookbooks/application_git/files/halite_gem/poise_application_git.rb @@ -0,0 +1,21 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 'poise_application_git/resource' + + +module PoiseApplicationGit +end diff --git a/cookbooks/application_git/files/halite_gem/poise_application_git/cheftie.rb b/cookbooks/application_git/files/halite_gem/poise_application_git/cheftie.rb new file mode 100644 index 0000000..6fcd9c3 --- /dev/null +++ b/cookbooks/application_git/files/halite_gem/poise_application_git/cheftie.rb @@ -0,0 +1,17 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 'poise_application_git/resource' diff --git a/cookbooks/application_git/files/halite_gem/poise_application_git/resource.rb b/cookbooks/application_git/files/halite_gem/poise_application_git/resource.rb new file mode 100644 index 0000000..ffcf3c2 --- /dev/null +++ b/cookbooks/application_git/files/halite_gem/poise_application_git/resource.rb @@ -0,0 +1,204 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 'zlib' + +require 'chef/provider' +require 'chef/resource' +require 'poise_application/app_mixin' +require 'poise_application/resources/application' + +require 'poise_application_git/safe_string' + + +module PoiseApplicationGit + # An `application_git` resource to clone application code from git. + # + # @since 1.0.0 + # @provides application_git + # @action sync + # @action checkout + # @action export + # @example + # application '/srv/myapp' do + # git 'git@github.com:example/myapp.git' do + # deploy_key data_bag_item('deploy_keys', 'myapp')['key'] + # end + # end + class Resource < Chef::Resource::Git + include PoiseApplication::AppMixin + provides(:application_git) + + # @api private + def initialize(*args) + super + # Because the superclass declares this, we have to as well. Should be + # removable at some point when Chef makes everything use the provider + # resolver system instead. + @resource_name = :application_git + @provider = PoiseApplicationGit::Provider + # Clear defaults in older versions of Chef. + remove_instance_variable(:@group) if instance_variable_defined?(:@group) + remove_instance_variable(:@user) if instance_variable_defined?(:@user) + end + + # @!attribute group + # Group to run git as. Defaults to the application group. + # @return [String, Integer, nil, false] + attribute(:group, kind_of: [String, Integer, NilClass, FalseClass], default: lazy { parent && parent.group }) + # @!attribute strict_ssh + # Enable strict SSH host key checking. Defaults to false. + # @return [Boolean] + attribute(:strict_ssh, equal_to: [true, false], default: false) + # @!attribute user + # User to run git as. Defaults to the application owner. + # @return [String, Integer, nil, false] + attribute(:user, kind_of: [String, Integer, NilClass, FalseClass], default: lazy { parent && parent.owner }) + + # @api private + def after_created + # Allow using the repository as the name in an application block. + if parent && !repository + destination(parent.path) + repository(name) + end + end + + # @!attribute deploy_key + # SSH deploy key as either a string value or a path to a key file. + # @return [String] + def deploy_key(val=nil) + # Use a SafeString for literal deploy keys so they aren't shown. + val = SafeString.new(val) if val && !deploy_key_is_local?(val) + set_or_return(:deploy_key, val, kind_of: String) + end + + # Default SSH wrapper path. + # + # @api private + # @return [String] + def ssh_wrapper_path + @ssh_wrapper_path ||= ::File.expand_path("~#{user}/.ssh/ssh_wrapper_#{Zlib.crc32(name)}") + end + + # Guess if the deploy key is a local path or literal value. + # + # @api private + # @param key [String, nil] Key value to check. Defaults to self.key. + # @return [Boolean] + def deploy_key_is_local?(key=nil) + key ||= deploy_key + key && key[0] == '/' + end + + # Path to deploy key. + # + # @api private + # @return [String] + def deploy_key_path + @deploy_key_path ||= if deploy_key_is_local? + deploy_key + else + ::File.expand_path("~#{user}/.ssh/id_deploy_#{Zlib.crc32(name)}") + end + end + end + + # Provider for `application_git`. + # + # @since 1.0.0 + # @see Resource + # @provides application_git + class Provider < Chef::Provider::Git + include PoiseApplication::AppMixin + provides(:application_git) + + # @api private + def initialize(*args) + super + # Set the SSH wrapper path in a late-binding kind of way. This better + # supports situations where the user doesn't exist until Chef converges. + new_resource.ssh_wrapper(new_resource.ssh_wrapper_path) if new_resource.deploy_key + end + + # @api private + def whyrun_supported? + false # Just not dealing with this right now + end + + # Hack our special login in before load_current_resource runs because that + # needs access to the git remote. + # + # @api private + def load_current_resource + include_recipe('git') + notifying_block do + create_dotssh + write_deploy_key + write_ssh_wrapper + end if new_resource.deploy_key + super + end + + private + + # Create a .ssh folder for the user. + # + # @return [void] + def create_dotssh + directory ::File.expand_path("~#{new_resource.user}/.ssh") do + owner new_resource.user + group new_resource.group + mode '755' + end + end + + # Copy the deploy key to a file if needed. + # + # @return [void] + def write_deploy_key + # Check if we have a local path or some actual content + return if new_resource.deploy_key_is_local? + file new_resource.deploy_key_path do + owner new_resource.user + group new_resource.group + mode '600' + content new_resource.deploy_key + sensitive true + end + end + + # Create the SSH wrapper script. + # + # @return [void] + def write_ssh_wrapper + # Write out the GIT_SSH script, it should already be enabled above + file new_resource.ssh_wrapper_path do + owner new_resource.user + group new_resource.group + mode '700' + content %Q{#!/bin/sh\n/usr/bin/env ssh #{'-o "StrictHostKeyChecking=no" ' unless new_resource.strict_ssh}-i "#{new_resource.deploy_key_path}" $@\n} + end + end + + # Patch back in the `#git` from the git provider. This otherwise conflicts + # with the `#git` defined by the DSL, which gets included in such a way + # that the DSL takes priority. + def git(*args, &block) + Chef::Provider::Git.instance_method(:git).bind(self).call(*args, &block) + end + end +end diff --git a/cookbooks/application_git/files/halite_gem/poise_application_git/safe_string.rb b/cookbooks/application_git/files/halite_gem/poise_application_git/safe_string.rb new file mode 100644 index 0000000..c975c49 --- /dev/null +++ b/cookbooks/application_git/files/halite_gem/poise_application_git/safe_string.rb @@ -0,0 +1,25 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 PoiseApplicationGit + # A string that won't be shown in Chef error output + class SafeString < String + def to_text + '"suppressed sensitive value"' + end + end +end diff --git a/cookbooks/application_git/files/halite_gem/poise_application_git/version.rb b/cookbooks/application_git/files/halite_gem/poise_application_git/version.rb new file mode 100644 index 0000000..0a67268 --- /dev/null +++ b/cookbooks/application_git/files/halite_gem/poise_application_git/version.rb @@ -0,0 +1,20 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 PoiseApplicationGit + VERSION = '1.1.0' +end diff --git a/cookbooks/application_git/libraries/default.rb b/cookbooks/application_git/libraries/default.rb new file mode 100644 index 0000000..868f2a0 --- /dev/null +++ b/cookbooks/application_git/libraries/default.rb @@ -0,0 +1,19 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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. +# + +raise 'Halite is not compatible with no_lazy_load false, please set no_lazy_load true in your Chef configuration file.' unless Chef::Config[:no_lazy_load] +$LOAD_PATH << File.expand_path('../../files/halite_gem', __FILE__) +require "poise_application_git/cheftie" diff --git a/cookbooks/application_git/metadata.json b/cookbooks/application_git/metadata.json new file mode 100644 index 0000000..32b4027 --- /dev/null +++ b/cookbooks/application_git/metadata.json @@ -0,0 +1 @@ +{"name":"application_git","version":"1.1.0","description":"A plugin for poise-application to deploy applications from git.","long_description":"# Application_Git Cookbook\n\n[![Build Status](https://img.shields.io/travis/poise/application_git.svg)](https://travis-ci.org/poise/application_git)\n[![Gem Version](https://img.shields.io/gem/v/poise-application-git.svg)](https://rubygems.org/gems/poise-application-git)\n[![Cookbook Version](https://img.shields.io/cookbook/v/application_git.svg)](https://supermarket.chef.io/cookbooks/application_git)\n[![Coverage](https://img.shields.io/codecov/c/github/poise/application_git.svg)](https://codecov.io/github/poise/application_git)\n[![Gemnasium](https://img.shields.io/gemnasium/poise/application_git.svg)](https://gemnasium.com/poise/application_git)\n[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)\n\nA [Chef](https://www.chef.io/) cookbook to handle deploying code from git when\nusing the [application cookbook](https://github.com/poise/application).\n\n## Quick Start\n\nTo deploy from a private GitHub repository:\n\n```ruby\napplication '/srv/myapp' do\n git 'git@github.com:example/myapp.git' do\n deploy_key chef_vault_item('deploy_keys', 'myapp')['key']\n end\nend\n```\n\n## Requirements\n\nChef 12 or newer is required.\n\n## Resources\n\n### `application_git`\n\nThe `application_git` resource deploys code from git. It extends the core `git`\nresource to support deploy keys and disabling strict host key verification.\n\n```ruby\napplication '/srv/myapp' do\n git 'git@github.com:example/myapp.git'\nend\n```\n\n#### Actions\n\nAll actions work the same as the core `git` resource.\n\n* `:sync` – Clone and checkout the requested revision *(default)*\n* `:checkout` – Checkout the request revision. If the repository isn't already\n cloned, this action does nothing.\n* `:export` – Export the repository without the `.git` folder.\n\n#### Properties\n\nAll properties from the core `git` resource work the same way with the following\nadditions:\n\n* `deploy_key` – SSH key to use with git. Can be specified either as a path to\n key file already created or as a string value containing the key directly.\n* `strict_ssh` – Enable strict SSH host key checking. *(default: false)*\n\n### DSL Usage\n\nThe `application_git` resource can be used directly as a replacement for the\ncore `git` resource:\n\n```ruby\napplication_git '/srv/myapp' do\n repository 'git@github.com:example/myapp.git'\n deploy_key chef_vault_item('deploy_keys', 'myapp')['key']\nend\n```\n\nWithin the `application` resource, a simplified DSL is available. As with other\n`application` plugins, the default name of the resource if unspecified is the\napplication path. The following two examples are equivalent:\n\n```ruby\napplication '/srv/myapp' do\n git do\n repository 'git@github.com:example/myapp.git'\n end\nend\n\napplication '/srv/myapp' do\n git 'git@github.com:example/myapp.git'\nend\n```\n\n## Sponsors\n\nDevelopment sponsored by [Chef Software](https://www.chef.io/), [Symonds & Son](http://symondsandson.com/), and [Orion](https://www.orionlabs.co/).\n\nThe Poise test server infrastructure is sponsored by [Rackspace](https://rackspace.com/).\n\n## License\n\nCopyright 2015-2016, Noah Kantrowitz\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","maintainer":"Noah Kantrowitz","maintainer_email":"noah@coderanger.net","license":"Apache 2.0","platforms":{},"dependencies":{"git":">= 0.0.0","poise":"~> 2.0","application":"~> 5.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{}} \ No newline at end of file diff --git a/cookbooks/application_javascript/CHANGELOG.md b/cookbooks/application_javascript/CHANGELOG.md new file mode 100644 index 0000000..ed8506a --- /dev/null +++ b/cookbooks/application_javascript/CHANGELOG.md @@ -0,0 +1,5 @@ +# Application_Javascript Changelog + +## v1.0.0 + +Initial release! diff --git a/cookbooks/application_javascript/README.md b/cookbooks/application_javascript/README.md new file mode 100644 index 0000000..57745f0 --- /dev/null +++ b/cookbooks/application_javascript/README.md @@ -0,0 +1,132 @@ +# Application_Javascript Cookbook + +[![Build Status](https://img.shields.io/travis/poise/application_javascript.svg)](https://travis-ci.org/poise/application_javascript) +[![Gem Version](https://img.shields.io/gem/v/poise-application-javascript.svg)](https://rubygems.org/gems/poise-application-javascript) +[![Cookbook Version](https://img.shields.io/cookbook/v/application_javascript.svg)](https://supermarket.chef.io/cookbooks/application_javascript) +[![Coverage](https://img.shields.io/codecov/c/github/poise/application_javascript.svg)](https://codecov.io/github/poise/application_javascript) +[![Gemnasium](https://img.shields.io/gemnasium/poise/application_javascript.svg)](https://gemnasium.com/poise/application_javascript) +[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) + +A [Chef](https://www.chef.io/) cookbook to deploy server-side JavaScript +applications using Node.js or io.js. + +## Quick Start + +To deploy an Express application from git: + +```ruby +application '/srv/myapp' do + git 'https://github.com/example/myapp.git' + npm_install + npm_start +end +``` + +## Requirements + +Chef 12 or newer is required. + +## Resources + +### `application_javascript` + +The `application_javascript` resource installs a JavaScript runtime for the +deployment. + +```ruby +application '/srv/myapp' do + javascript '3' +end +``` + +All actions and properties are the same as the [`javascript_runtime` resource](https://github.com/poise/poise-javascript#javascript_runtime). + +### `application_javascript_service` + +The `application_javascript_javascript_service` resource creates a service for a +JavaScript command. + +```ruby +application '/srv/myapp' do + javascript_service 'main.js' +end +``` + +#### Actions + +* `:enable` – Create, enable and start the service. *(default)* +* `:disable` – Stop, disable, and destroy the service. +* `:start` – Start the service. +* `:stop` – Stop the service. +* `:restart` – Stop and then start the service. +* `:reload` – Send the configured reload signal to the service. + +#### Properties + +* `command` – Command to run. *(name attribute)* +* `path` – Base path for the application. *(default: application path)* +* `service_name` – Name of the service to create. *(default: auto-detect)* +# `user` – User to run the service as. *(default: application owner)* + +### `application_node_package` + +The `application_node_package` resource installs NPM packages for the deployment. + +```ruby +application '/srv/myapp' do + node_package 'grunt-cli' +end +``` + +All actions and properties are the same as the [`node_package` resource](https://github.com/poise/poise-javascript#node_package), +except that the `group` and `user` properties default to the application-level +data if not specified. + +### `application_npm_start` + +The `application_npm_start` resource creates a service for a JavaScript +application using `npm start`. + +```ruby +application '/srv/myapp' do + npm_start +end +``` + +#### Actions + +* `:enable` – Create, enable and start the service. *(default)* +* `:disable` – Stop, disable, and destroy the service. +* `:start` – Start the service. +* `:stop` – Stop the service. +* `:restart` – Stop and then start the service. +* `:reload` – Send the configured reload signal to the service. + +#### Properties + +* `path` – Base path for the application. *(default: name attribute)* +* `command` – NPM subcommand to run. *(default: start)* +* `service_name` – Name of the service to create. *(default: auto-detect)* +# `user` – User to run the service as. *(default: application owner)* + +## Sponsors + +Development sponsored by [Chef Software](https://www.chef.io/), [Symonds & Son](http://symondsandson.com/), and [Orion](https://www.orionlabs.co/). + +The Poise test server infrastructure is sponsored by [Rackspace](https://rackspace.com/). + +## License + +Copyright 2015, Noah Kantrowitz + +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/application_javascript/files/halite_gem/poise_application_javascript.rb b/cookbooks/application_javascript/files/halite_gem/poise_application_javascript.rb new file mode 100644 index 0000000..d481a29 --- /dev/null +++ b/cookbooks/application_javascript/files/halite_gem/poise_application_javascript.rb @@ -0,0 +1,23 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 PoiseApplicationJavascript + autoload :AppMixin, 'poise_application_javascript/app_mixin' + autoload :Error, 'poise_application_javascript/error' + autoload :Resources, 'poise_application_javascript/resources' + autoload :VERSION, 'poise_application_javascript/version' +end diff --git a/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/app_mixin.rb b/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/app_mixin.rb new file mode 100644 index 0000000..06d4705 --- /dev/null +++ b/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/app_mixin.rb @@ -0,0 +1,67 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 'poise/backports' +require 'poise/utils' +require 'poise_application/app_mixin' +require 'poise_javascript/javascript_command_mixin' + + +module PoiseApplicationJavascript + # A helper mixin for Javascript application resources and providers. + # + # @since 4.0.0 + module AppMixin + include Poise::Utils::ResourceProviderMixin + + # A helper mixin for Javascript application resources. + module Resource + include PoiseApplication::AppMixin::Resource + include PoiseJavascript::JavascriptCommandMixin::Resource + + # @!attribute parent_javascript + # Override the #parent_javascript from JavascriptCommandMixin to grok the + # application level parent as a default value. + # @return [PoiseJavascript::Resources::JavascriptRuntime::Resource, nil] + parent_attribute(:javascript, type: :javascript_runtime, optional: true, default: lazy { app_state_javascript.equal?(self) ? nil : app_state_javascript }) + + # @attribute app_state_javascript + # The application-level Javascript parent. + # @return [PoiseJavascript::Resources::JavascriptRuntime::Resource, nil] + def app_state_javascript(javascript=Poise::NOT_PASSED) + unless javascript == Poise::NOT_PASSED + app_state[:javascript] = javascript + end + app_state[:javascript] + end + + # A merged hash of environment variables for both the application state + # and parent javascript. + # + # @return [Hash] + def app_state_environment_javascript + env = app_state_environment + env = env.merge(parent_javascript.javascript_environment) if parent_javascript + env + end + end + + # A helper mixin for Javascript application providers. + module Provider + include PoiseApplication::AppMixin::Provider + end + end +end diff --git a/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/cheftie.rb b/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/cheftie.rb new file mode 100644 index 0000000..01a8f69 --- /dev/null +++ b/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/cheftie.rb @@ -0,0 +1,17 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 'poise_application_javascript/resources' diff --git a/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/error.rb b/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/error.rb new file mode 100644 index 0000000..71fba33 --- /dev/null +++ b/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/error.rb @@ -0,0 +1,25 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 'poise_application/error' + +module PoiseApplicationJavascript + # Base exception class for poise-application-javascript errors. + # + # @since 1.0.0 + class Error < PoiseApplication::Error + end +end diff --git a/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/resources.rb b/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/resources.rb new file mode 100644 index 0000000..32a7cd3 --- /dev/null +++ b/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/resources.rb @@ -0,0 +1,22 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 'poise_application_javascript/resources/javascript' +require 'poise_application_javascript/resources/javascript_execute' +require 'poise_application_javascript/resources/javascript_service' +require 'poise_application_javascript/resources/node_package' +require 'poise_application_javascript/resources/npm_install' +require 'poise_application_javascript/resources/npm_start' diff --git a/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/resources/javascript.rb b/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/resources/javascript.rb new file mode 100644 index 0000000..e52aabd --- /dev/null +++ b/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/resources/javascript.rb @@ -0,0 +1,64 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 'poise_javascript/resources/javascript_runtime' + +require 'poise_application_javascript/app_mixin' + + +module PoiseApplicationJavascript + module Resources + # (see Javascript::Resource) + # @since 1.0.0 + module Javascript + # An `application_javascript` resource to manage Javascript runtimes + # inside an Application cookbook deployment. + # + # @provides application_javascript + # @provides application_javascript_runtime + # @action install + # @action uninstall + # @example + # application '/app' do + # javascript '3' + # end + class Resource < PoiseJavascript::Resources::JavascriptRuntime::Resource + include PoiseApplicationJavascript::AppMixin + provides(:application_javascript) + # Need the double javascript for application resource rewriting. + provides(:application_javascript_runtime) + container_default(false) + subclass_providers! + + # We want to run the base class version of this, not the one from the + # mixin. HULK SMASH. + def npm_binary + self.class.superclass.instance_method(:npm_binary).bind(self).call + end + + # Set this resource as the app_state's parent javascript. + # + # @api private + def after_created + super.tap do |val| + app_state_javascript(self) + end + end + + end + end + end +end diff --git a/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/resources/javascript_execute.rb b/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/resources/javascript_execute.rb new file mode 100644 index 0000000..f2d6656 --- /dev/null +++ b/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/resources/javascript_execute.rb @@ -0,0 +1,88 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 'poise_javascript/resources/javascript_execute' + +require 'poise_application_javascript/app_mixin' + + +module PoiseApplicationJavascript + module Resources + # (see JavascriptExecute::Resource) + # @since 1.0.0 + module JavascriptExecute + # An `application_javascript_execute` resource to run Javascript commands inside an + # Application cookbook deployment. + # + # @provides application_javascript_execute + # @action run + # @example + # application '/srv/myapp' do + # javascript_execute 'setup.py install' + # end + class Resource < PoiseJavascript::Resources::JavascriptExecute::Resource + include PoiseApplicationJavascript::AppMixin + provides(:application_javascript_execute) + def initialize(*args) + super + # Clear some instance variables so my defaults work. + remove_instance_variable(:@cwd) + remove_instance_variable(:@group) + remove_instance_variable(:@user) + end + + # #!attribute cwd + # Override the default directory to be the app path if unspecified. + # @return [String] + attribute(:cwd, kind_of: [String, NilClass, FalseClass], default: lazy { parent && parent.path }) + + # #!attribute group + # Override the default group to be the app group if unspecified. + # @return [String, Integer] + attribute(:group, kind_of: [String, Integer, NilClass, FalseClass], default: lazy { parent && parent.group }) + + # #!attribute user + # Override the default user to be the app owner if unspecified. + # @return [String, Integer] + attribute(:user, kind_of: [String, Integer, NilClass, FalseClass], default: lazy { parent && parent.owner }) + end + + # The default provider for `application_javascript_execute`. + # + # @see Resource + # @provides application_javascript_execute + class Provider < PoiseJavascript::Resources::JavascriptExecute::Provider + provides(:application_javascript_execute) + + private + + # Override environment to add the application envivonrment instead. + # + # @return [Hash] + def environment + super.tap do |environment| + # Don't use the app_state_environment_javascript because we already have + # those values in place. + environment.update(new_resource.app_state_environment) + # Re-apply the resource environment for correct ordering. + environment.update(new_resource.environment) if new_resource.environment + end + end + end + + end + end +end diff --git a/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/resources/javascript_service.rb b/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/resources/javascript_service.rb new file mode 100644 index 0000000..614b561 --- /dev/null +++ b/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/resources/javascript_service.rb @@ -0,0 +1,59 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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/provider' +require 'chef/resource' +require 'poise' + +require 'poise_application_javascript/service_mixin' + + +module PoiseApplicationJavascript + module Resources + # (see JavascriptService::Resource) + # @since 1.0.0 + module JavascriptService + class Resource < Chef::Resource + include PoiseApplicationJavascript::ServiceMixin + provides(:application_javascript_service) + + # @!attribute command + # Command to run. + # @return [String] + attribute(:command, kind_of: String, name_attribute: true) + # @!attribute path + # Override {PoiseApplicationJavascript::ServiceMixin#path} to make it + # not the name_attribute. + # @return [String] + attribute(:path, kind_of: String, default: lazy { parent && parent.path }) + end + + class Provider < Chef::Provider + include PoiseApplicationJavascript::ServiceMixin + provides(:application_javascript_service) + + private + + # (see PoiseApplication::ServiceMixin#service_options) + def service_options(resource) + super + resource.javascript_command(new_resource.command) + end + + end + end + end +end diff --git a/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/resources/node_package.rb b/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/resources/node_package.rb new file mode 100644 index 0000000..6cad223 --- /dev/null +++ b/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/resources/node_package.rb @@ -0,0 +1,63 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 'poise_javascript/resources/node_package' + +require 'poise_application_javascript/app_mixin' + + +module PoiseApplicationJavascript + module Resources + # (see NodePackage::Resource) + # @since 1.0.0 + module NodePackage + # An `application_node_package` resource to install NPM packages inside + # an Application cookbook deployment. + # + # @provides application_node_package + # @action install + # @action upgrade + # @action remove + # @example + # application '/app' do + # node_package %w{grunt-cli gulp} + # end + class Resource < PoiseJavascript::Resources::NodePackage::Resource + include PoiseApplicationJavascript::AppMixin + provides(:application_node_package) + subclass_providers! + + def initialize(*args) + super + # For older Chef. + @resource_name = :application_node_package + end + + # #!attribute group + # Override the default group to be the app group if unspecified. + # @return [String, Integer] + attribute(:group, kind_of: [String, Integer, NilClass], default: lazy { parent && parent.group }) + + # #!attribute user + # Override the default user to be the app owner if unspecified. + # @return [String, Integer] + attribute(:user, kind_of: [String, Integer, NilClass], default: lazy { parent && parent.owner }) + + # @todo This should handle relative paths against parent.path. + end + end + end +end diff --git a/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/resources/npm_install.rb b/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/resources/npm_install.rb new file mode 100644 index 0000000..4527df0 --- /dev/null +++ b/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/resources/npm_install.rb @@ -0,0 +1,45 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 'poise_javascript/resources/npm_install' + +require 'poise_application_javascript/app_mixin' + + +module PoiseApplicationJavascript + module Resources + # (see NpmInstall::Resource) + # @since 1.0.0 + module NpmInstall + # An `application_npm_install` resource to install package + # dependencies inside an Application cookbook deployment. + # + # @provides application_npm_install + # @action install + # @example + # application '/app' do + # npm_install + # end + class Resource < PoiseJavascript::Resources::NpmInstall::Resource + include PoiseApplicationJavascript::AppMixin + provides(:application_npm_install) + subclass_providers! + + # @todo This should handle relative paths against parent.path. + end + end + end +end diff --git a/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/resources/npm_start.rb b/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/resources/npm_start.rb new file mode 100644 index 0000000..0cf803b --- /dev/null +++ b/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/resources/npm_start.rb @@ -0,0 +1,78 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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' + +require 'chef/provider' +require 'chef/resource' +require 'poise' + +require 'poise_application_javascript/service_mixin' + + +module PoiseApplicationJavascript + module Resources + # (see NpmStart::Resource) + # @since 1.0.0 + module NpmStart + # An `application_npm_start` resource to create a service for a Javascript + # application using `npm start`. + # + # @provides application_npm_start + # @action enable + # @action disable + # @action start + # @action stop + # @action restart + # @action reload + # @example + # application '/app' do + # npm_start + # end + class Resource < Chef::Resource + include PoiseApplicationJavascript::ServiceMixin + provides(:application_npm_start) + + # @!attribute command + # NPM sub-command to run. Defaults to `start`. + # @return [String, Array] + attribute(:command, kind_of: [String, Array], default: 'start') + end + + # The default provider for `application_npm_start`. + # + # @see Resource + # @provides application_npm_start + class Provider < Chef::Provider + include PoiseApplicationJavascript::ServiceMixin + provides(:application_npm_start) + + private + + # (see PoiseApplication::ServiceMixin#service_options) + def service_options(resource) + super + npm_cmd = [new_resource.npm_binary] + Array(new_resource.command) + resource.javascript_command(Shellwords.join(npm_cmd)) + # Make sure node is on $PATH because grrr. + new_path = [::File.dirname(new_resource.javascript), (new_resource.app_state_environment_javascript['PATH'] || ENV['PATH']).to_s].join(::File::PATH_SEPARATOR) + resource.environment['PATH'] = new_path + end + + end + end + end +end diff --git a/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/service_mixin.rb b/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/service_mixin.rb new file mode 100644 index 0000000..f4359a1 --- /dev/null +++ b/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/service_mixin.rb @@ -0,0 +1,57 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 'poise/utils' +require 'poise_application/service_mixin' +require 'poise_languages/utils' + +require 'poise_application_javascript/app_mixin' + + +module PoiseApplicationJavascript + # A helper mixin for Javascript service resources and providers. + # + # @since 1.0.0 + module ServiceMixin + include Poise::Utils::ResourceProviderMixin + + # A helper mixin for Javascript service resources. + module Resource + include PoiseApplication::ServiceMixin::Resource + include PoiseApplicationJavascript::AppMixin::Resource + end + + # A helper mixin for Javascript service providers. + module Provider + include PoiseApplication::ServiceMixin::Provider + include PoiseApplicationJavascript::AppMixin::Provider + + # Set up the service for running Javascript stuff. + def service_options(resource) + super + # Closure scoping for #javascript_command below. + self_ = self + # Create a new singleton method that fills in `node` for you. + resource.define_singleton_method(:javascript_command) do |val| + resource.command("#{self_.new_resource.javascript} #{PoiseLanguages::Utils.absolute_command(val, path: self_.new_resource.app_state_environment_javascript['PATH'])}") + end + # Include env vars as needed. + resource.environment.update(new_resource.parent_javascript.javascript_environment) if new_resource.parent_javascript + end + + end + end +end diff --git a/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/version.rb b/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/version.rb new file mode 100644 index 0000000..4162872 --- /dev/null +++ b/cookbooks/application_javascript/files/halite_gem/poise_application_javascript/version.rb @@ -0,0 +1,19 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 PoiseApplicationJavascript + VERSION = '1.0.0' +end diff --git a/cookbooks/application_javascript/libraries/default.rb b/cookbooks/application_javascript/libraries/default.rb new file mode 100644 index 0000000..2c3ee48 --- /dev/null +++ b/cookbooks/application_javascript/libraries/default.rb @@ -0,0 +1,19 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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. +# + +raise 'Halite is not compatible with no_lazy_load false, please set no_lazy_load true in your Chef configuration file.' unless Chef::Config[:no_lazy_load] +$LOAD_PATH << File.expand_path('../../files/halite_gem', __FILE__) +require "poise_application_javascript/cheftie" diff --git a/cookbooks/application_javascript/metadata.json b/cookbooks/application_javascript/metadata.json new file mode 100644 index 0000000..c09bcbe --- /dev/null +++ b/cookbooks/application_javascript/metadata.json @@ -0,0 +1 @@ +{"name":"application_javascript","version":"1.0.0","description":"A Chef cookbook for deploying server-side JavaScript application code.","long_description":"# Application_Javascript Cookbook\n\n[![Build Status](https://img.shields.io/travis/poise/application_javascript.svg)](https://travis-ci.org/poise/application_javascript)\n[![Gem Version](https://img.shields.io/gem/v/poise-application-javascript.svg)](https://rubygems.org/gems/poise-application-javascript)\n[![Cookbook Version](https://img.shields.io/cookbook/v/application_javascript.svg)](https://supermarket.chef.io/cookbooks/application_javascript)\n[![Coverage](https://img.shields.io/codecov/c/github/poise/application_javascript.svg)](https://codecov.io/github/poise/application_javascript)\n[![Gemnasium](https://img.shields.io/gemnasium/poise/application_javascript.svg)](https://gemnasium.com/poise/application_javascript)\n[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)\n\nA [Chef](https://www.chef.io/) cookbook to deploy server-side JavaScript\napplications using Node.js or io.js.\n\n## Quick Start\n\nTo deploy an Express application from git:\n\n```ruby\napplication '/srv/myapp' do\n git 'https://github.com/example/myapp.git'\n npm_install\n npm_start\nend\n```\n\n## Requirements\n\nChef 12 or newer is required.\n\n## Resources\n\n### `application_javascript`\n\nThe `application_javascript` resource installs a JavaScript runtime for the\ndeployment.\n\n```ruby\napplication '/srv/myapp' do\n javascript '3'\nend\n```\n\nAll actions and properties are the same as the [`javascript_runtime` resource](https://github.com/poise/poise-javascript#javascript_runtime).\n\n### `application_javascript_service`\n\nThe `application_javascript_javascript_service` resource creates a service for a\nJavaScript command.\n\n```ruby\napplication '/srv/myapp' do\n javascript_service 'main.js'\nend\n```\n\n#### Actions\n\n* `:enable` – Create, enable and start the service. *(default)*\n* `:disable` – Stop, disable, and destroy the service.\n* `:start` – Start the service.\n* `:stop` – Stop the service.\n* `:restart` – Stop and then start the service.\n* `:reload` – Send the configured reload signal to the service.\n\n#### Properties\n\n* `command` – Command to run. *(name attribute)*\n* `path` – Base path for the application. *(default: application path)*\n* `service_name` – Name of the service to create. *(default: auto-detect)*\n# `user` – User to run the service as. *(default: application owner)*\n\n### `application_node_package`\n\nThe `application_node_package` resource installs NPM packages for the deployment.\n\n```ruby\napplication '/srv/myapp' do\n node_package 'grunt-cli'\nend\n```\n\nAll actions and properties are the same as the [`node_package` resource](https://github.com/poise/poise-javascript#node_package),\nexcept that the `group` and `user` properties default to the application-level\ndata if not specified.\n\n### `application_npm_start`\n\nThe `application_npm_start` resource creates a service for a JavaScript\napplication using `npm start`.\n\n```ruby\napplication '/srv/myapp' do\n npm_start\nend\n```\n\n#### Actions\n\n* `:enable` – Create, enable and start the service. *(default)*\n* `:disable` – Stop, disable, and destroy the service.\n* `:start` – Start the service.\n* `:stop` – Stop the service.\n* `:restart` – Stop and then start the service.\n* `:reload` – Send the configured reload signal to the service.\n\n#### Properties\n\n* `path` – Base path for the application. *(default: name attribute)*\n* `command` – NPM subcommand to run. *(default: start)*\n* `service_name` – Name of the service to create. *(default: auto-detect)*\n# `user` – User to run the service as. *(default: application owner)*\n\n## Sponsors\n\nDevelopment sponsored by [Chef Software](https://www.chef.io/), [Symonds & Son](http://symondsandson.com/), and [Orion](https://www.orionlabs.co/).\n\nThe Poise test server infrastructure is sponsored by [Rackspace](https://rackspace.com/).\n\n## License\n\nCopyright 2015, Noah Kantrowitz\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","maintainer":"YOUR_COMPANY_NAME","maintainer_email":"YOUR_EMAIL","license":"none","platforms":{},"dependencies":{"poise":"~> 2.0","application":"~> 5.0","poise-javascript":"~> 1.0","poise-service":"~> 1.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{}} \ No newline at end of file diff --git a/cookbooks/application_nodejs/LICENSE b/cookbooks/application_nodejs/LICENSE deleted file mode 100644 index 11069ed..0000000 --- a/cookbooks/application_nodejs/LICENSE +++ /dev/null @@ -1,201 +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/application_nodejs/README.md b/cookbooks/application_nodejs/README.md deleted file mode 100644 index 0a1dba4..0000000 --- a/cookbooks/application_nodejs/README.md +++ /dev/null @@ -1,64 +0,0 @@ -## Description - -This cookbook is designed to be able to describe and deploy Node.js web applications using Upstart. - -Note that this cookbook provides the Node-specific bindings for the `application` cookbook; you will find general documentation in that cookbook. - -## Requirements - -Chef 0.10.0 or higher required (for Chef environment use). - -Upstart 1.4 or higher for the use of `setuid` in the default Upstart configuration template. -This requirement can be worked around by specifying a custom template. - -The following Opscode cookbooks are dependencies: - -* [application](https://github.com/opscode-cookbooks/application) -* [nodejs](https://github.com/mdxp/nodejs-cookbook) - -## Resources/Providers - -The `nodejs` sub-resource LWRP deals with deploying Node.js applications using Upstart. It is not meant to be used by itself; make sure you are familiar with the `application` cookbook before proceeding. - -### Attribute Parameters - -- **npm**: If `true`, `npm` will be used to install the dependencies specified in `packages.json`. Defaults to `true`. -- **template**: The name of the template that will be used to create the Upstart configuration file. If specified, it will be looked up in the application cookbook. Defaults to `nodejs.upstart.conf.erb` from this cookbook. -- **entry_point**: The argument to pass to node. Defaults to `app.js`. - -## Usage - -Here is an example hello world application using [Express](http://expressjs.com): - -``` -application "hello-world" do - path "/srv/node-hello-world" - owner "www-data" - group "www-data" - packages ["git"] - - repository "git://github.com/visionmedia/express.git" - - nodejs do - entry_point "examples/hello-world" - end -end -``` - -## License and Author - -Author:: Conrad Kramer () - -Copyright 2013, Kramer Software Productions, 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/application_nodejs/metadata.rb b/cookbooks/application_nodejs/metadata.rb deleted file mode 100644 index 66dde51..0000000 --- a/cookbooks/application_nodejs/metadata.rb +++ /dev/null @@ -1,12 +0,0 @@ -name "application_nodejs" -maintainer "Conrad Kramer" -maintainer_email "conrad@kramerapps.com" -license "Apache 2.0" -description "Deploys and configures Node.js applications" -long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -version "2.0.1" - -depends "nodejs" -depends "application" - -supports 'ubuntu', ">= 12.04" diff --git a/cookbooks/application_nodejs/providers/nodejs.rb b/cookbooks/application_nodejs/providers/nodejs.rb deleted file mode 100644 index e426f37..0000000 --- a/cookbooks/application_nodejs/providers/nodejs.rb +++ /dev/null @@ -1,130 +0,0 @@ -# -# Author:: Conrad Kramer -# Cookbook Name:: application_node -# Resource:: node -# -# Copyright:: 2013, Kramer Software Productions, 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. -# - -include Chef::DSL::IncludeRecipe - -action :before_compile do - - r = new_resource - - if new_resource.npm - include_recipe 'nodejs::npm' - end - - unless new_resource.restart_command - new_resource.restart_command do - - service "#{r.application.name}_nodejs" do - if platform?('ubuntu') && node[:platform_version].to_f >= 14.04 - provider Chef::Provider::Service::Systemd - else - provider Chef::Provider::Service::Upstart - end - supports :restart => true, :start => true, :stop => true - action [:enable, :restart] - end - - end - end - - new_resource.environment.update({ - 'NODE_ENV' => r.environment_name - }) - -end - -action :before_deploy do - - new_resource.environment['NODE_ENV'] = new_resource.environment_name - - r = new_resource - - service "#{r.application.name}_nodejs" do - if platform?('ubuntu') && node[:platform_version].to_f >= 14.04 - provider Chef::Provider::Service::Systemd - else - provider Chef::Provider::Service::Upstart - end - end - - if platform?('ubuntu') && node[:platform_version].to_f >= 14.04 - execute "systemctl daemon-reload" do - command "systemctl daemon-reload" - action :nothing - end - - template "#{r.application.name}_nodejs.systemd.service.erb" do - path "/lib/systemd/system/#{r.application.name}_nodejs.service" - source r.template ? r.template : 'nodejs.systemd.service.erb' - cookbook r.template ? r.cookbook_name.to_s : 'application_nodejs' - owner 'root' - group 'root' - mode '0644' - variables( - :user => r.owner, - :group => r.group, - :app_dir => r.release_path, - :entry => r.entry_point, - :environment => r.environment - ) - notifies :run, "execute[systemctl daemon-reload]", :delayed - notifies :restart, "service[#{r.application.name}_nodejs]", :delayed - end - else - template "#{new_resource.application.name}.upstart.conf" do - path "/etc/init/#{r.application.name}_nodejs.conf" - source r.template ? r.template : 'nodejs.upstart.conf.erb' - cookbook r.template ? r.cookbook_name.to_s : 'application_nodejs' - owner 'root' - group 'root' - mode '0644' - variables( - :user => r.owner, - :group => r.group, - :app_dir => r.release_path, - :entry => r.entry_point, - :environment => r.environment - ) - notifies :restart, "service[#{r.application.name}_nodejs]", :delayed - end - end -end - -action :before_migrate do - - if new_resource.npm - execute 'npm install' do - cwd new_resource.release_path - user new_resource.owner - group new_resource.group - environment new_resource.environment.merge({ 'HOME' => new_resource.shared_path }) - end - end - -end - -action :before_symlink do -end - -action :before_restart do -end - -action :after_restart do -end diff --git a/cookbooks/application_nodejs/templates/default/nodejs.systemd.service.erb b/cookbooks/application_nodejs/templates/default/nodejs.systemd.service.erb deleted file mode 100644 index 99fa0f0..0000000 --- a/cookbooks/application_nodejs/templates/default/nodejs.systemd.service.erb +++ /dev/null @@ -1,4 +0,0 @@ -[Service] -ExecStart=/usr/bin/env node <%= @entry %> -User=<%= @user %> -Group=<%= @group %> diff --git a/cookbooks/application_nodejs/templates/default/nodejs.upstart.conf.erb b/cookbooks/application_nodejs/templates/default/nodejs.upstart.conf.erb deleted file mode 100644 index ab1e8be..0000000 --- a/cookbooks/application_nodejs/templates/default/nodejs.upstart.conf.erb +++ /dev/null @@ -1,19 +0,0 @@ -#!upstart -description "Node.js Application Server" - -start on (local-filesystems and net-device-up IFACE!=lo) -stop on [!12345] - -console log - -<% @environment.each do |key, value| -%> -env <%= key %>="<%= value %>" -<% end -%> -<% unless @user.nil? -%> -setuid <%= @user %> -<% end -%> -<% unless @group.nil? -%> -setgid <%= @group %> -<% end -%> -chdir <%= @app_dir %> -exec /usr/bin/env node <%= @entry %> diff --git a/cookbooks/application_ruby/CHANGELOG.md b/cookbooks/application_ruby/CHANGELOG.md new file mode 100644 index 0000000..5200030 --- /dev/null +++ b/cookbooks/application_ruby/CHANGELOG.md @@ -0,0 +1,86 @@ +# Application_Ruby Changelog + +## v4.0.1 + +* Correct `gem_binary` results for `application_ruby`. + +## v4.0.0 + +* Massive rewrite on top of newer Chef patterns. See the 4.0 README for details. + +## v3.0.2 + +* No changes, bumping version to get bits in various places in sync. + +## v3.0.0 + +* Major version bump. Breaking backwards compatibility with Chef 10. + +## v2.2.0 + +* [COOK-3895](https://tickets.opscode.com/browse/COOK-3895) - application_ruby use_omnibus_ruby attr needs to default to false. +* [COOK-3894](https://tickets.opscode.com/browse/COOK-3894) - application_ruby cookbook needs version bump to pick up application v4.0 cookbook. +* [COOK-2079](https://tickets.opscode.com/browse/COOK-2079) - Attempting to touch restart.txt should not cause a chef-client run to fail. + +## v2.1.4 + +* [COOK-3625](https://tickets.opscode.com/browse/COOK-3625) - Fix an issue where unicorn fails when node does not provide cpu count. + +## v2.1.2 + +* [COOK-3616](https://tickets.opscode.com/browse/COOK-3616) - Simplify log symlinking for rails apps. + +## v2.1.0 + +* [COOK-3367](https://tickets.opscode.com/browse/COOK-3367) - Support more of unicorn's configuration. +* [COOK-3124](https://tickets.opscode.com/browse/COOK-3124) - Add `memcached_template` attribute to so alternative templates may be used. + +## v2.0.0 + +### Bug + +* [COOK-3306]: Multiple Memory Leaks in Application Cookbook. +* [COOK-3219]: `application_ruby` cookbook bundle install in 1.9.3-based omnibus installs 1.9.x gems into ruby 2.0 apps. + +## v1.1.4 + +* [COOK-2806]: Including `passenger_apache2::mod_rails` does not enable passenger. + +## v1.1.2 + +* [COOK-2638]: cookbook attribute is not treated as a string when specifying `database_yml_template`. +* [COOK-2525]: application_ruby: split runit template into multiple lines. + +## v1.1.0 + +* [COOK-2362] - `application_ruby` unicorn uses `run_restart`. +* [COOK-2363] - `application_ruby` unicorn should set `log_template_name` and `run_template_name`. + +## v1.0.10 + +* [COOK-2260] - pin runit version. + +## v1.0.8 + +* [COOK-2159] - cookbook attribute is not treated as a string. + +## v1.0.6 + +* [COOK-1481] - unicorn provider in application_ruby cookbook should run its restart command as root. + +## v1.0.4 + +* [COOK-1572] - allow specification of 'bundle' command via attribute. + +## v1.0.2 + +* [COOK-1360] - fix typo in README. +* [COOK-1374] - use runit attribute in unicorn run script. +* [COOK-1408] - use user and group from parent resource for runit service. + +## v1.0.0 + +* [COOK-1247] - Initial release - relates to COOK-634. +* [COOK-1248] - special cases memcached. +* [COOK-1258] - Precompile assets for Rails 3. +* [COOK-1297] - Unicorn sub-resource should allow strings for 'port' attribute. diff --git a/cookbooks/application_ruby/README.md b/cookbooks/application_ruby/README.md new file mode 100644 index 0000000..98ea3e3 --- /dev/null +++ b/cookbooks/application_ruby/README.md @@ -0,0 +1,271 @@ +# Application_Ruby Cookbook + +[![Build Status](https://img.shields.io/travis/poise/application_ruby.svg)](https://travis-ci.org/poise/application_ruby) +[![Gem Version](https://img.shields.io/gem/v/poise-application-ruby.svg)](https://rubygems.org/gems/poise-application-ruby) +[![Cookbook Version](https://img.shields.io/cookbook/v/application_ruby.svg)](https://supermarket.chef.io/cookbooks/application_ruby) +[![Coverage](https://img.shields.io/codecov/c/github/poise/application_ruby.svg)](https://codecov.io/github/poise/application_ruby) +[![Gemnasium](https://img.shields.io/gemnasium/poise/application_ruby.svg)](https://gemnasium.com/poise/application_ruby) +[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) + +A [Chef](https://www.chef.io/) cookbook to deploy Ruby applications. + +## Quick Start + +To deploy a Rails application from git: + +```ruby +application '/srv/myapp' do + git 'https://github.com/example/myapp.git' + bundle_install do + deployment true + without %w{development test} + end + rails do + database 'sqlite3:///db.sqlite3' + secret_token 'd78fe08df56c9' + migrate true + end + unicorn do + port 8000 + end +end +``` + +## Requirements + +Chef 12 or newer is required. + +## Resources + +### `application_bundle_install` + +The `application_bundle_install` resource installs gems using Bundler for a +deployment. + +```ruby +application '/srv/myapp' do + bundle_install do + deployment true + without %w{development test} + end +end +``` + +All actions and properties are the same as the [`bundle_install` resource](https://github.com/poise/poise-ruby#bundle_install). + +### `application_rackup` + +The `application_rackup` resource creates a service for `rackup`. + +```ruby +application '/srv/myapp' do + rackup do + port 8000 + end +end +``` + +#### Actions + +* `:enable` – Create, enable and start the service. *(default)* +* `:disable` – Stop, disable, and destroy the service. +* `:start` – Start the service. +* `:stop` – Stop the service. +* `:restart` – Stop and then start the service. +* `:reload` – Send the configured reload signal to the service. + +#### Properties + +* `path` – Base path for the application. *(name attribute)* +* `port` – Port to listen on. *(default: 80)* +* `service_name` – Name of the service to create. *(default: auto-detect)* +# `user` – User to run the service as. *(default: application owner)* + +### `application_rails` + +The `application_rails` resource + +```ruby +application '/srv/myapp' do + rails do + database 'sqlite3:///db.sqlite3' + secret_token 'd78fe08df56c9' + migrate true + end +end +``` + +#### Actions + +* `:deploy` – Create config files and run required deployments steps. *(default)* + +#### Properties + +* `path` – Base path for the application. *(name attribute)* +* `database` – Database settings for Rails. See [the database section + below](#database-parameters) for more information. *(option collector)* +* `migrate` – Run database migrations. *(default: false)* +* `precompile_assets` – Run `rake assets:precompile`. *(default: auto-detect)() +* `rails_env` – Rails environment name. *(default: node.chef_environment)* +* `secret_token` – Secret token for Rails session verification et al. +* `secrets_mode` – Secrets configuration mode. Set to `:yaml` to generate a + Rails 4.2 secrets.yml. Set to `:initializer` to update + `config/initializers/secret_token.rb`. *(default: auto-detect)* + +**NOTE:** At this time `secrets_mode :initializer` is not implemented. + +#### Database Parameters + +The database parameters can be set in three ways: URL, hash, and block. + +If you have a single URL for the parameters, you can pass it directly to +`database`: + +```ruby +rails do + database 'mysql2://myuser@dbhost/myapp' +end +``` + +Passing a single URL will also set the `$DATABASE_URL` environment variable +automatically for compatibility with Heroku-based applications. + +As with other option collector resources, you can pass individual settings as +either a hash or block: + +```ruby +rails do + database do + adapter 'mysql2' + username 'myuser' + host 'dbhost' + database 'myapp' + end +end + +rails do + database({ + adapter: 'mysql2', + username: 'myuser', + host: 'dbhost', + database: 'myapp', + }) +end +``` + +### `application_ruby` + +The `application_ruby` resource installs a Ruby runtime for the deployment. + +```ruby +application '/srv/myapp' do + ruby '2.2' +end +``` + +All actions and properties are the same as the [`ruby_runtime` resource](https://github.com/poise/poise-ruby#ruby_runtime). + +### `application_ruby_gem` + +The `application_ruby_gem` resource installs Ruby gems for the deployment. + +```ruby +application '/srv/myapp' do + ruby_gem 'rake' +end +``` + +All actions and properties are the same as the [`ruby_gem` resource](https://github.com/poise/poise-ruby#ruby_gem). + +### `application_ruby_execute` + +The `application_ruby_execute` resource runs Ruby commands for the deployment. + +```ruby +application '/srv/myapp' do + ruby_execute 'rake' +end +``` + +All actions and properties are the same as the [`ruby_execute` resource](https://github.com/poise/poise-ruby#ruby_execute), +except that the `cwd`, `environment`, `group`, and `user` properties default to +the application-level data if not specified. + +### `application_thin` + +The `application_thin` resource creates a service for `thin`. + +```ruby +application '/srv/myapp' do + thin do + port 8000 + end +end +``` + +#### Actions + +* `:enable` – Create, enable and start the service. *(default)* +* `:disable` – Stop, disable, and destroy the service. +* `:start` – Start the service. +* `:stop` – Stop the service. +* `:restart` – Stop and then start the service. +* `:reload` – Send the configured reload signal to the service. + +#### Properties + +* `path` – Base path for the application. *(name attribute)* +* `config_path` – Path to a Thin configuration file. +* `port` – Port to listen on. *(default: 80)* +* `service_name` – Name of the service to create. *(default: auto-detect)* +# `user` – User to run the service as. *(default: application owner)* + +### `application_unicorn` + +The `application_unicorn` resource creates a service for `unicorn`. + +```ruby +application '/srv/myapp' do + unicorn do + port 8000 + end +end +``` + +#### Actions + +* `:enable` – Create, enable and start the service. *(default)* +* `:disable` – Stop, disable, and destroy the service. +* `:start` – Start the service. +* `:stop` – Stop the service. +* `:restart` – Stop and then start the service. +* `:reload` – Send the configured reload signal to the service. + +#### Properties + +* `path` – Base path for the application. *(name attribute)* +* `port` – Port to listen on. *(default: 80)* +* `service_name` – Name of the service to create. *(default: auto-detect)* +# `user` – User to run the service as. *(default: application owner)* + +## Sponsors + +Development sponsored by [Chef Software](https://www.chef.io/), [Symonds & Son](http://symondsandson.com/), and [Orion](https://www.orionlabs.co/). + +The Poise test server infrastructure is sponsored by [Rackspace](https://rackspace.com/). + +## License + +Copyright 2015, Noah Kantrowitz + +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/application_ruby/files/halite_gem/poise_application_ruby.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby.rb new file mode 100644 index 0000000..7d480bf --- /dev/null +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby.rb @@ -0,0 +1,24 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 PoiseApplicationRuby + autoload :AppMixin, 'poise_application_ruby/app_mixin' + autoload :Error, 'poise_application_ruby/error' + autoload :Resources, 'poise_application_ruby/resources' + autoload :ServiceMixin, 'poise_application_ruby/service_mixin' + autoload :VERSION, 'poise_application_ruby/version' +end diff --git a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/app_mixin.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/app_mixin.rb new file mode 100644 index 0000000..d377f7a --- /dev/null +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/app_mixin.rb @@ -0,0 +1,92 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 'poise/backports' +require 'poise/utils' +require 'poise_application/app_mixin' +require 'poise_ruby/ruby_command_mixin' + + +module PoiseApplicationRuby + # A helper mixin for Ruby application resources and providers. + # + # @since 4.0.0 + module AppMixin + include Poise::Utils::ResourceProviderMixin + + # A helper mixin for Ruby application resources. + module Resource + include PoiseApplication::AppMixin::Resource + include PoiseRuby::RubyCommandMixin::Resource + + # @!attribute parent_ruby + # Override the #parent_ruby from RubyCommandMixin to grok the + # application level parent as a default value. + # @return [PoiseRuby::Resources::RubyRuntime::Resource, nil] + parent_attribute(:ruby, type: :ruby_runtime, optional: true, default: lazy { app_state_ruby.equal?(self) ? nil : app_state_ruby }) + + # @!attribute parent_bundle + # Parent bundle install context. + # @return [PoiseRuby::Resources::BundleInstall::Resource, nil] + parent_attribute(:bundle, type: :ruby_runtime, optional: true, auto: false, default: lazy { app_state_bundle.equal?(self) ? nil : app_state_bundle }) + + # @attribute app_state_ruby + # The application-level Ruby parent. + # @return [PoiseRuby::Resources::RubyRuntime::Resource, nil] + def app_state_ruby(ruby=Poise::NOT_PASSED) + unless ruby == Poise::NOT_PASSED + app_state[:ruby] = ruby + end + app_state[:ruby] + end + + # @attribute app_state_bundle + # The application-level Bundle parent. + # @return [PoiseRuby::Resources::BundleInstall::Resource, nil] + def app_state_bundle(bundle=Poise::NOT_PASSED) + unless bundle == Poise::NOT_PASSED + app_state[:bundle] = bundle + end + app_state[:bundle] + end + + # A merged hash of environment variables for both the application state + # and parent ruby. + # + # @return [Hash] + def app_state_environment_ruby + env = app_state_environment + env = env.merge(parent_ruby.ruby_environment) if parent_ruby + env['BUNDLE_GEMFILE'] = parent_bundle.gemfile_path if parent_bundle + env + end + + # Update ruby_from_parent to transfer {#parent_bundle} too. + # + # @param resource [Chef::Resource] Resource to inherit from. + # @return [void] + def ruby_from_parent(resource) + super + parent_bundle(resource.parent_bundle) if resource.parent_bundle + end + end + + # A helper mixin for Ruby application providers. + module Provider + include PoiseApplication::AppMixin::Provider + end + end +end diff --git a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/cheftie.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/cheftie.rb new file mode 100644 index 0000000..ca8eb03 --- /dev/null +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/cheftie.rb @@ -0,0 +1,17 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 'poise_application_ruby/resources' diff --git a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/error.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/error.rb new file mode 100644 index 0000000..ae21fa0 --- /dev/null +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/error.rb @@ -0,0 +1,25 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 'poise_application/error' + +module PoiseApplicationRuby + # Base exception class for poise-application-ruby errors. + # + # @since 4.0.0 + class Error < PoiseApplication::Error + end +end diff --git a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources.rb new file mode 100644 index 0000000..4b58b49 --- /dev/null +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources.rb @@ -0,0 +1,24 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 'poise_application_ruby/resources/bundle_install' +require 'poise_application_ruby/resources/rackup' +require 'poise_application_ruby/resources/rails' +require 'poise_application_ruby/resources/ruby' +require 'poise_application_ruby/resources/ruby_execute' +require 'poise_application_ruby/resources/ruby_gem' +require 'poise_application_ruby/resources/thin' +require 'poise_application_ruby/resources/unicorn' diff --git a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/bundle_install.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/bundle_install.rb new file mode 100644 index 0000000..d6ccd82 --- /dev/null +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/bundle_install.rb @@ -0,0 +1,54 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 'poise_ruby/resources/bundle_install' + +require 'poise_application_ruby/app_mixin' + + +module PoiseApplicationRuby + module Resources + # (see BundleInstall::Resource) + # @since 4.0.0 + module BundleInstall + # An `application_bundle_install` resource to install a + # [Bundler](http://bundler.io/) Gemfile in a web application. + # + # @note + # This resource is not idempotent itself, it will always run `bundle + # install`. + # @example + # application '/srv/my_app' do + # bundle_install + # end + class Resource < PoiseRuby::Resources::BundleInstall::Resource + include PoiseApplicationRuby::AppMixin + provides(:application_bundle_install) + subclass_providers! + + # Set this resource as the app_state's parent bundle. + # + # @api private + def after_created + super.tap do |val| + app_state_bundle(self) + end + end + end + + end + end +end diff --git a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/rackup.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/rackup.rb new file mode 100644 index 0000000..8b29730 --- /dev/null +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/rackup.rb @@ -0,0 +1,70 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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/provider' +require 'chef/resource' + +require 'poise_application_ruby/service_mixin' + + +module PoiseApplicationRuby + module Resources + # (see Rackup::Resource) + # @since 4.0.0 + module Rackup + class Resource < Chef::Resource + include PoiseApplicationRuby::ServiceMixin + provides(:application_rackup) + + # @!attribute port + # TCP port to listen on. Defaults to 80. + # @return [String, Integer] + attribute(:port, kind_of: [String, Integer], default: 80) + end + + class Provider < Chef::Provider + include PoiseApplicationRuby::ServiceMixin + provides(:application_rackup) + + private + + # Find the path to the config.ru. If the resource path was to a + # directory, apparent /config.ru. + # + # @return [String] + def configru_path + @configru_path ||= if ::File.directory?(new_resource.path) + ::File.join(new_resource.path, 'config.ru') + else + new_resource.path + end + end + + # Set up service options for rackup. + # + # @param resource [PoiseService::Resource] Service resource. + # @return [void] + def service_options(resource) + super + resource.ruby_command("rackup --port #{new_resource.port}") + resource.directory(::File.dirname(configru_path)) + # Older versions of rackup ignore all signals. + resource.stop_signal('KILL') + end + end + end + end +end diff --git a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/rails.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/rails.rb new file mode 100644 index 0000000..3ac56f9 --- /dev/null +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/rails.rb @@ -0,0 +1,260 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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/provider' +require 'chef/resource' + +require 'poise_application_ruby/app_mixin' + + +module PoiseApplicationRuby + module Resources + # (see Rails::Resource) + module Rails + # An `application_rails` resource to configure Ruby on Rails applications. + # + # @since 4.0.0 + # @provides application_rails + # @action deploy + # @example + # application '/srv/myapp' do + # git '...' + # bundle_install + # rails do + # database do + # host node['rails_host'] + # end + # end + # unicorn do + # port 8080 + # end + # end + class Resource < Chef::Resource + include PoiseApplicationRuby::AppMixin + provides(:application_rails) + actions(:deploy) + + # @!attribute database + # Option collector attribute for Rails database configuration. + # @return [Hash] + # @example Setting via block + # database do + # adapter 'postgresql' + # database 'blog' + # end + # @example Setting via URL + # database 'postgresql://localhost/blog' + attribute(:database, option_collector: true, parser: :parse_database_url) + # @!attribute database_config + # Template content attribute for the contents of database.yml. + # @todo Redo this doc to cover the actual attributes created. + # @return [Poise::Helpers::TemplateContent] + attribute(:database_config, template: true, default_source: 'database.yml.erb', default_options: lazy { default_database_options }) + # @!attribute migrate + # Run database migrations. This is a bad idea for real apps. Please + # do not use it. + # @return [Boolean] + attribute(:migrate, equal_to: [true, false], default: false) + # @!attribute precompile_assets + # Set to true to run rake assets:precompile. By default will try to + # auto-detect if Sprockets is in use by looking at config/initializers. + # @see #default_precompile_assets + # @return [Boolean] + attribute(:precompile_assets, equal_to: [true, false], default: lazy { default_precompile_assets }) + # @!attribute rails_env + # Rails environment name. Defaults to the Chef environment name or + # `production` if none is set. + # @see #default_rails_env + # @return [String] + attribute(:rails_env, kind_of: String, default: lazy { default_rails_env }) + # @!attribute secret_token + # Secret token for Rails session verification and other purposes. On + # Rails 4.2 this will be used for secret_key_base. If not set, no + # secrets configuration is written. + # @return [String] + attribute(:secret_token, kind_of: [String, FalseClass]) + # @!attribute secrets_config + # Template content attribute for the contents of secrets.yml. Only + # used when secrets_mode is :yaml. + # @todo Redo this doc to cover the actual attributes created. + # @return [Poise::Helpers::TemplateContent] + attribute(:secrets_config, template: true, default_source: 'secrets.yml.erb', default_options: lazy { default_secrets_options }) + # @!attribute secrets_mode + # Secrets configuration mode. Set to `:yaml` to generate a Rails 4.2 + # secrets.yml. Set to `:initializer` to update + # `config/initializers/secret_token.rb`. If unspecified this is + # auto-detected based on what files exist. + # @return [Symbol] + attribute(:secrets_mode, equal_to: [:yaml, :initializer], default: lazy { default_secrets_mode }) + + private + + # Check if we should run the precompile by default. Looks for the + # assets initializer because that is not present with --skip-sprockets. + # + # @return [Boolean] + def default_precompile_assets + ::File.exists?(::File.join(path, 'config', 'initializers', 'assets.rb')) + end + + # Check the default environment name. + # + # @return [String] + def default_rails_env + node.chef_environment == '_default' ? 'production' : node.chef_environment + end + + # Format a single URL for the database.yml + # + # @return [Hash] + def parse_database_url(url) + {'url' => url} + end + + # Default template variables for the database.yml. + # + # @return [Hash] + def default_database_options + db_config = {'encoding' => 'utf8', 'reconnect' => true, 'pool' => 5}.merge(database) + { + config: { + rails_env => db_config + }, + } + end + + # Check which secrets configuration mode is in use based on files. + # + # @return [Symbol] + def default_secrets_mode + ::File.exists?(::File.join(path, 'config', 'initializers', 'secret_token.rb')) ? :initialize : :yaml + end + + # Default template variables for the secrets.yml. + # + # @return [Hash] + def default_secrets_options + { + config: { + rails_env => { + 'secret_key_base' => secret_token, + } + }, + } + end + end + + # Provider for `application_rails`. + # + # @since 4.0.0 + # @see Resource + # @provides application_rails + class Provider < Chef::Provider + include PoiseApplicationRuby::AppMixin + provides(:application_rails) + + # `deploy` action for `application_rails`. Ensure all configuration + # files are created and other deploy tasks resolved. + # + # @return [void] + def action_deploy + set_state + notifying_block do + write_database_yml unless new_resource.database.empty? + write_secrets_config if new_resource.secret_token + precompile_assets if new_resource.precompile_assets + run_migrations if new_resource.migrate + end + end + + private + + # Set app_state variables for future services et al. + def set_state + new_resource.app_state_environment[:RAILS_ENV] = new_resource.rails_env + new_resource.app_state_environment[:DATABASE_URL] = new_resource.database['url'] if new_resource.database['url'] + end + + # Create a database.yml config file. + def write_database_yml + file ::File.join(new_resource.path, 'config', 'database.yml') do + user new_resource.parent.owner + group new_resource.parent.group + mode '640' + content new_resource.database_config_content + end + end + + # Dispatch to the correct config writer based on the mode. + def write_secrets_config + case new_resource.secrets_mode + when :yaml + write_secrets_yml + when :initializer + write_secrets_initializer + end + end + + # Write a Rails 4.2-style secrets.yml. + def write_secrets_yml + file ::File.join(new_resource.path, 'config', 'secrets.yml') do + user new_resource.parent.owner + group new_resource.parent.group + mode '640' + content new_resource.secrets_config_content + end + end + + # In-place update a config/initializers/secret_token.rb file. + def write_secrets_initializer + # @todo Implement initalizer-style secret support. + raise NotImplementedError.new('Sorry, intializer-style secrets loading is not yet supported.') + end + + # Precompile assets using the rake task. + def precompile_assets + # Currently this will always run so the resource will always update :-/ + # Better fix would be to shell_out! and parse the output? + ruby_execute 'rake assets:precompile' do + command %w{rake assets:precompile} + user new_resource.parent.owner + group new_resource.parent.group + cwd new_resource.parent.path + environment new_resource.app_state_environment + ruby_from_parent new_resource + parent_bundle new_resource.parent_bundle if new_resource.parent_bundle + end + end + + # Run database migrations using the rake task. + def run_migrations + # Currently this will always run so the resource will always update :-/ + # Better fix would be to shell_out! and parse the output? + ruby_execute 'rake db:migrate' do + command %w{rake db:migrate} + user new_resource.parent.owner + group new_resource.parent.group + cwd new_resource.parent.path + environment new_resource.app_state_environment + ruby_from_parent new_resource + parent_bundle new_resource.parent_bundle if new_resource.parent_bundle + end + end + + end + end + end +end diff --git a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/ruby.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/ruby.rb new file mode 100644 index 0000000..2519699 --- /dev/null +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/ruby.rb @@ -0,0 +1,63 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 'poise_ruby/resources/ruby_runtime' + +require 'poise_application_ruby/app_mixin' + + +module PoiseApplicationRuby + module Resources + # (see Ruby::Resource) + # @since 4.0.0 + module Ruby + # An `application_ruby` resource to manage Ruby runtimes + # inside an Application cookbook deployment. + # + # @provides application_ruby + # @provides application_ruby_runtime + # @action install + # @action uninstall + # @example + # application '/app' do + # ruby '2' + # end + class Resource < PoiseRuby::Resources::RubyRuntime::Resource + include PoiseApplicationRuby::AppMixin + provides(:application_ruby) + provides(:application_ruby_runtime) + container_default(false) + subclass_providers! + + # Rebind the parent class #gem_binary instead of the one from + # RubyCommandMixin (by way of AppMixin) + def gem_binary(*args, &block) + self.class.superclass.instance_method(:gem_binary).bind(self).call(*args, &block) + end + + # Set this resource as the app_state's parent ruby. + # + # @api private + def after_created + super.tap do |val| + app_state_ruby(self) + end + end + + end + end + end +end diff --git a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/ruby_execute.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/ruby_execute.rb new file mode 100644 index 0000000..8ca2b19 --- /dev/null +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/ruby_execute.rb @@ -0,0 +1,89 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 'poise_ruby/resources/ruby_execute' + +require 'poise_application_ruby/app_mixin' + + +module PoiseApplicationRuby + module Resources + # (see RubyExecute::Resource) + # @since 4.0.0 + module RubyExecute + # An `application_ruby_execute` resource to run Ruby commands inside an + # Application cookbook deployment. + # + # @provides application_ruby_execute + # @action run + # @example + # application '/srv/myapp' do + # ruby_execute 'rake build' + # end + class Resource < PoiseRuby::Resources::RubyExecute::Resource + include PoiseApplicationRuby::AppMixin + provides(:application_ruby_execute) + + def initialize(*args) + super + # Clear some instance variables so my defaults work. + remove_instance_variable(:@cwd) + remove_instance_variable(:@group) + remove_instance_variable(:@user) + end + + # #!attribute cwd + # Override the default directory to be the app path if unspecified. + # @return [String] + attribute(:cwd, kind_of: [String, NilClass, FalseClass], default: lazy { parent && parent.path }) + + # #!attribute group + # Override the default group to be the app group if unspecified. + # @return [String, Integer] + attribute(:group, kind_of: [String, Integer, NilClass, FalseClass], default: lazy { parent && parent.group }) + + # #!attribute user + # Override the default user to be the app owner if unspecified. + # @return [String, Integer] + attribute(:user, kind_of: [String, Integer, NilClass, FalseClass], default: lazy { parent && parent.owner }) + end + + # The default provider for `application_ruby_execute`. + # + # @see Resource + # @provides application_ruby_execute + class Provider < PoiseRuby::Resources::RubyExecute::Provider + provides(:application_ruby_execute) + + private + + # Override environment to add the application envivonrment instead. + # + # @return [Hash] + def environment + super.tap do |environment| + # Don't use the app_state_environment_ruby because we already have + # those values in place. + environment.update(new_resource.app_state_environment) + # Re-apply the resource environment for correct ordering. + environment.update(new_resource.environment) if new_resource.environment + end + end + end + + end + end +end diff --git a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/ruby_gem.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/ruby_gem.rb new file mode 100644 index 0000000..6a637e2 --- /dev/null +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/ruby_gem.rb @@ -0,0 +1,46 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 'poise_ruby/resources/ruby_gem' + +require 'poise_application_ruby/app_mixin' + + +module PoiseApplicationRuby + module Resources + # (see RubyGem::Resource) + # @since 4.0.0 + module RubyGem + # An `application_ruby_gem` resource to install Ruby gems inside an + # Application cookbook deployment. + # + # @provides application_ruby_gem + # @action install + # @action upgrade + # @action remove + # @example + # application '/srv/myapp' do + # ruby_gem 'rack' + # end + class Resource < PoiseRuby::Resources::RubyGem::Resource + include PoiseApplicationRuby::AppMixin + provides(:application_ruby_gem) + subclass_providers! + end + + end + end +end diff --git a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/thin.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/thin.rb new file mode 100644 index 0000000..a106137 --- /dev/null +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/thin.rb @@ -0,0 +1,64 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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/provider' +require 'chef/resource' + +require 'poise_application_ruby/service_mixin' + + +module PoiseApplicationRuby + module Resources + # (see Thin::Resource) + # @since 4.0.0 + module Thin + class Resource < Chef::Resource + include PoiseApplicationRuby::ServiceMixin + provides(:application_thin) + + attribute(:port, kind_of: [String, Integer], default: 80) + attribute(:config_path, kind_of: String) + end + + class Provider < Chef::Provider + include PoiseApplicationRuby::ServiceMixin + provides(:application_thin) + + private + + # Find the path to the config.ru. If the resource path was to a + # directory, apparent /config.ru. + # + # @return [String] + def configru_path + @configru_path ||= if ::File.directory?(new_resource.path) + ::File.join(new_resource.path, 'config.ru') + else + new_resource.path + end + end + + # (see PoiseApplication::ServiceMixin#service_options) + def service_options(resource) + super + cmd = "thin --rackup #{configru_path} --port #{new_resource.port}" + cmd << " --config #{::File.expand_path(new_resource.config_path, new_resource.path)}" if new_resource.config_path + resource.ruby_command(cmd) + end + end + end + end +end diff --git a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/unicorn.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/unicorn.rb new file mode 100644 index 0000000..3053d3e --- /dev/null +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/unicorn.rb @@ -0,0 +1,87 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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/provider' +require 'chef/resource' + +require 'poise_application_ruby/service_mixin' + + +module PoiseApplicationRuby + module Resources + # (see Unicorn::Resource) + # @since 4.0.0 + module Unicorn + # An `application_unicorn` resource to manage a unicorn web application + # server. + # + # @since 4.0.0 + # @provides application_unicorn + # @action enable + # @action disable + # @action start + # @action stop + # @action restart + # @action reload + # @example + # application '/srv/myapp' do + # git '...' + # bundle_install + # unicorn do + # port 8080 + # end + # end + class Resource < Chef::Resource + include PoiseApplicationRuby::ServiceMixin + provides(:application_unicorn) + + # @!attribute port + # Port to bind to. + attribute(:port, kind_of: [String, Integer], default: 80) + end + + # Provider for `application_unicorn`. + # + # @since 4.0.0 + # @see Resource + # @provides application_unicorn + class Provider < Chef::Provider + include PoiseApplicationRuby::ServiceMixin + provides(:application_unicorn) + + private + + # Find the path to the config.ru. If the resource path was to a + # directory, apparent /config.ru. + # + # @return [String] + def configru_path + @configru_path ||= if ::File.directory?(new_resource.path) + ::File.join(new_resource.path, 'config.ru') + else + new_resource.path + end + end + + # Set service resource options. + def service_options(resource) + super + resource.ruby_command("unicorn --port #{new_resource.port} #{configru_path}") + end + end + end + end +end diff --git a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/service_mixin.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/service_mixin.rb new file mode 100644 index 0000000..08ff095 --- /dev/null +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/service_mixin.rb @@ -0,0 +1,66 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 'poise/utils' +require 'poise_application/service_mixin' +require 'poise_languages/utils' +require 'poise_ruby/bundler_mixin' + +require 'poise_application_ruby/app_mixin' + + +module PoiseApplicationRuby + # A helper mixin for Ruby service resources and providers. + # + # @since 4.0.0 + module ServiceMixin + include Poise::Utils::ResourceProviderMixin + + # A helper mixin for Ruby service resources. + module Resource + include PoiseApplication::ServiceMixin::Resource + include PoiseApplicationRuby::AppMixin::Resource + end + + # A helper mixin for Ruby service providers. + module Provider + include PoiseApplication::ServiceMixin::Provider + include PoiseApplicationRuby::AppMixin::Provider + include PoiseRuby::BundlerMixin + + # Set up the service for running Ruby stuff. + def service_options(resource) + super + # Closure scoping for #ruby_command below. + self_ = self + # Create a new singleton method that fills in Python for you. + resource.define_singleton_method(:ruby_command) do |val| + path = self_.new_resource.app_state_environment_ruby['PATH'] + cmd = if self_.new_resource.parent_bundle + bundle_exec_command(val, path: path) + else + "#{self_.new_resource.ruby} #{PoiseLanguages::Utils.absolute_command(val, path: path)}" + end + resource.command(cmd) + end + # Include env vars as needed. + resource.environment.update(new_resource.parent_ruby.ruby_environment) if new_resource.parent_ruby + resource.environment['BUNDLE_GEMFILE'] = new_resource.parent_bundle.gemfile_path if new_resource.parent_bundle + end + + end + end +end diff --git a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/version.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/version.rb new file mode 100644 index 0000000..48f7d53 --- /dev/null +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/version.rb @@ -0,0 +1,19 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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 PoiseApplicationRuby + VERSION = '4.0.1' +end diff --git a/cookbooks/application_ruby/libraries/default.rb b/cookbooks/application_ruby/libraries/default.rb new file mode 100644 index 0000000..673a63b --- /dev/null +++ b/cookbooks/application_ruby/libraries/default.rb @@ -0,0 +1,19 @@ +# +# Copyright 2015, Noah Kantrowitz +# +# 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. +# + +raise 'Halite is not compatible with no_lazy_load false, please set no_lazy_load true in your Chef configuration file.' unless Chef::Config[:no_lazy_load] +$LOAD_PATH << File.expand_path('../../files/halite_gem', __FILE__) +require "poise_application_ruby/cheftie" diff --git a/cookbooks/application_ruby/metadata.json b/cookbooks/application_ruby/metadata.json new file mode 100644 index 0000000..3707047 --- /dev/null +++ b/cookbooks/application_ruby/metadata.json @@ -0,0 +1 @@ +{"name":"application_ruby","version":"4.0.1","description":"A Chef cookbook for deploying application code.","long_description":"# Application_Ruby Cookbook\n\n[![Build Status](https://img.shields.io/travis/poise/application_ruby.svg)](https://travis-ci.org/poise/application_ruby)\n[![Gem Version](https://img.shields.io/gem/v/poise-application-ruby.svg)](https://rubygems.org/gems/poise-application-ruby)\n[![Cookbook Version](https://img.shields.io/cookbook/v/application_ruby.svg)](https://supermarket.chef.io/cookbooks/application_ruby)\n[![Coverage](https://img.shields.io/codecov/c/github/poise/application_ruby.svg)](https://codecov.io/github/poise/application_ruby)\n[![Gemnasium](https://img.shields.io/gemnasium/poise/application_ruby.svg)](https://gemnasium.com/poise/application_ruby)\n[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)\n\nA [Chef](https://www.chef.io/) cookbook to deploy Ruby applications.\n\n## Quick Start\n\nTo deploy a Rails application from git:\n\n```ruby\napplication '/srv/myapp' do\n git 'https://github.com/example/myapp.git'\n bundle_install do\n deployment true\n without %w{development test}\n end\n rails do\n database 'sqlite3:///db.sqlite3'\n secret_token 'd78fe08df56c9'\n migrate true\n end\n unicorn do\n port 8000\n end\nend\n```\n\n## Requirements\n\nChef 12 or newer is required.\n\n## Resources\n\n### `application_bundle_install`\n\nThe `application_bundle_install` resource installs gems using Bundler for a\ndeployment.\n\n```ruby\napplication '/srv/myapp' do\n bundle_install do\n deployment true\n without %w{development test}\n end\nend\n```\n\nAll actions and properties are the same as the [`bundle_install` resource](https://github.com/poise/poise-ruby#bundle_install).\n\n### `application_rackup`\n\nThe `application_rackup` resource creates a service for `rackup`.\n\n```ruby\napplication '/srv/myapp' do\n rackup do\n port 8000\n end\nend\n```\n\n#### Actions\n\n* `:enable` – Create, enable and start the service. *(default)*\n* `:disable` – Stop, disable, and destroy the service.\n* `:start` – Start the service.\n* `:stop` – Stop the service.\n* `:restart` – Stop and then start the service.\n* `:reload` – Send the configured reload signal to the service.\n\n#### Properties\n\n* `path` – Base path for the application. *(name attribute)*\n* `port` – Port to listen on. *(default: 80)*\n* `service_name` – Name of the service to create. *(default: auto-detect)*\n# `user` – User to run the service as. *(default: application owner)*\n\n### `application_rails`\n\nThe `application_rails` resource\n\n```ruby\napplication '/srv/myapp' do\n rails do\n database 'sqlite3:///db.sqlite3'\n secret_token 'd78fe08df56c9'\n migrate true\n end\nend\n```\n\n#### Actions\n\n* `:deploy` – Create config files and run required deployments steps. *(default)*\n\n#### Properties\n\n* `path` – Base path for the application. *(name attribute)*\n* `database` – Database settings for Rails. See [the database section\n below](#database-parameters) for more information. *(option collector)*\n* `migrate` – Run database migrations. *(default: false)*\n* `precompile_assets` – Run `rake assets:precompile`. *(default: auto-detect)()\n* `rails_env` – Rails environment name. *(default: node.chef_environment)*\n* `secret_token` – Secret token for Rails session verification et al.\n* `secrets_mode` – Secrets configuration mode. Set to `:yaml` to generate a\n Rails 4.2 secrets.yml. Set to `:initializer` to update\n `config/initializers/secret_token.rb`. *(default: auto-detect)*\n\n**NOTE:** At this time `secrets_mode :initializer` is not implemented.\n\n#### Database Parameters\n\nThe database parameters can be set in three ways: URL, hash, and block.\n\nIf you have a single URL for the parameters, you can pass it directly to\n`database`:\n\n```ruby\nrails do\n database 'mysql2://myuser@dbhost/myapp'\nend\n```\n\nPassing a single URL will also set the `$DATABASE_URL` environment variable\nautomatically for compatibility with Heroku-based applications.\n\nAs with other option collector resources, you can pass individual settings as\neither a hash or block:\n\n```ruby\nrails do\n database do\n adapter 'mysql2'\n username 'myuser'\n host 'dbhost'\n database 'myapp'\n end\nend\n\nrails do\n database({\n adapter: 'mysql2',\n username: 'myuser',\n host: 'dbhost',\n database: 'myapp',\n })\nend\n```\n\n### `application_ruby`\n\nThe `application_ruby` resource installs a Ruby runtime for the deployment.\n\n```ruby\napplication '/srv/myapp' do\n ruby '2.2'\nend\n```\n\nAll actions and properties are the same as the [`ruby_runtime` resource](https://github.com/poise/poise-ruby#ruby_runtime).\n\n### `application_ruby_gem`\n\nThe `application_ruby_gem` resource installs Ruby gems for the deployment.\n\n```ruby\napplication '/srv/myapp' do\n ruby_gem 'rake'\nend\n```\n\nAll actions and properties are the same as the [`ruby_gem` resource](https://github.com/poise/poise-ruby#ruby_gem).\n\n### `application_ruby_execute`\n\nThe `application_ruby_execute` resource runs Ruby commands for the deployment.\n\n```ruby\napplication '/srv/myapp' do\n ruby_execute 'rake'\nend\n```\n\nAll actions and properties are the same as the [`ruby_execute` resource](https://github.com/poise/poise-ruby#ruby_execute),\nexcept that the `cwd`, `environment`, `group`, and `user` properties default to\nthe application-level data if not specified.\n\n### `application_thin`\n\nThe `application_thin` resource creates a service for `thin`.\n\n```ruby\napplication '/srv/myapp' do\n thin do\n port 8000\n end\nend\n```\n\n#### Actions\n\n* `:enable` – Create, enable and start the service. *(default)*\n* `:disable` – Stop, disable, and destroy the service.\n* `:start` – Start the service.\n* `:stop` – Stop the service.\n* `:restart` – Stop and then start the service.\n* `:reload` – Send the configured reload signal to the service.\n\n#### Properties\n\n* `path` – Base path for the application. *(name attribute)*\n* `config_path` – Path to a Thin configuration file.\n* `port` – Port to listen on. *(default: 80)*\n* `service_name` – Name of the service to create. *(default: auto-detect)*\n# `user` – User to run the service as. *(default: application owner)*\n\n### `application_unicorn`\n\nThe `application_unicorn` resource creates a service for `unicorn`.\n\n```ruby\napplication '/srv/myapp' do\n unicorn do\n port 8000\n end\nend\n```\n\n#### Actions\n\n* `:enable` – Create, enable and start the service. *(default)*\n* `:disable` – Stop, disable, and destroy the service.\n* `:start` – Start the service.\n* `:stop` – Stop the service.\n* `:restart` – Stop and then start the service.\n* `:reload` – Send the configured reload signal to the service.\n\n#### Properties\n\n* `path` – Base path for the application. *(name attribute)*\n* `port` – Port to listen on. *(default: 80)*\n* `service_name` – Name of the service to create. *(default: auto-detect)*\n# `user` – User to run the service as. *(default: application owner)*\n\n## Sponsors\n\nDevelopment sponsored by [Chef Software](https://www.chef.io/), [Symonds & Son](http://symondsandson.com/), and [Orion](https://www.orionlabs.co/).\n\nThe Poise test server infrastructure is sponsored by [Rackspace](https://rackspace.com/).\n\n## License\n\nCopyright 2015, Noah Kantrowitz\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","maintainer":"YOUR_COMPANY_NAME","maintainer_email":"YOUR_EMAIL","license":"none","platforms":{},"dependencies":{"poise":"~> 2.0","application":"~> 5.0","poise-ruby":"~> 2.1","poise-service":"~> 1.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{}} \ No newline at end of file diff --git a/cookbooks/application_ruby/templates/database.yml.erb b/cookbooks/application_ruby/templates/database.yml.erb new file mode 100644 index 0000000..a1bdc6e --- /dev/null +++ b/cookbooks/application_ruby/templates/database.yml.erb @@ -0,0 +1,3 @@ +# Generated by Chef for <%= @new_resource.to_s %> + +<%= @config.to_yaml %> diff --git a/cookbooks/application_ruby/templates/secrets.yml.erb b/cookbooks/application_ruby/templates/secrets.yml.erb new file mode 100644 index 0000000..a1bdc6e --- /dev/null +++ b/cookbooks/application_ruby/templates/secrets.yml.erb @@ -0,0 +1,3 @@ +# Generated by Chef for <%= @new_resource.to_s %> + +<%= @config.to_yaml %> diff --git a/cookbooks/dmg/.foodcritic b/cookbooks/dmg/.foodcritic new file mode 100644 index 0000000..3318b2a --- /dev/null +++ b/cookbooks/dmg/.foodcritic @@ -0,0 +1,4 @@ +~FC007 +~FC023 +~FC024 +~FC048 diff --git a/cookbooks/dmg/CHANGELOG.md b/cookbooks/dmg/CHANGELOG.md new file mode 100644 index 0000000..9eed8f2 --- /dev/null +++ b/cookbooks/dmg/CHANGELOG.md @@ -0,0 +1,113 @@ +# dmg Cookbook CHANGELOG + +This file is used to list changes made in each version of the dmg cookbook. + +## 3.1.0 (2017-01-18) + +- Fixed pkg,mpkg installation when it was using mounted app name while it was actually mounted under different name for some applications +- Cookstyle fixes + +## 3.0.0 (2016-09-06) + +- Add chef_version metadata +- Run the specs against a mock of OS X +- Testing updates +- Require Chef 12+ + +## v2.4.0 (2016-04-26) + +- Added support for local .dmg files with the file property. See the readme for details +- Resolved all rubocop warnings + +## v2.3.0 (2015-10-20) + +- Add new headers property to the LWRP for custom http headers. See the readme for more information +- Removed pivotal tracker example in the readme +- Added travis and cookbook version badges to the readme +- Added a .foodcritic file to exclude rules +- Updated chefignore and .gitignore files +- Updated platforms in Test Kitchen +- Added standard Rubocop file +- Updated Travis to test using ChefDK for the latest deps +- Added a Berksfile +- Updated contributing and testing docs +- Updated Gemfile with the latest testing deps +- Added maintainers.md and maintainers.toml +- Added rakefile for simplified testing +- Added source_url and issues_url metadata +- Added basic converge chefspec + +## v2.2.2 (2014-11-12) + +- # 23, add chefspec matchers + +## v2.2.0 (2014-02-25) + +- [COOK-4285] Accept long EULAs + +## v2.1.4 (2014-01-26) + +- [COOK-4157] - dmg_package LWRP broken due to "puts" instead of "system" +- [COOK-4065] - dmg cookbook outputs the name of packages when checking if they are installed + +## v2.1.2 + +Cleaning up merge errors + +## v2.1.0 + +### Bug + +- **[COOK-3946](https://tickets.chef.io/browse/COOK-3946)** - Syntax error in resources/package.rb +- **[COOK-2672](https://tickets.chef.io/browse/COOK-2672)** - EULA for package is displayed instead accepted + +## v2.0.8 + +Adding a Chef 10 compatibility check in provider + +## v2.0.6 + +# BUG + +- [COOK-3302] - Sometimes hdiutil detach fails due to cfprefsd running in background + + # IMPROVEMENT + +- Adding foodcritic and rubocop to .travis.yml + +## v2.0.4 + +### Bug + +- **[COOK-3331](https://tickets.chef.io/browse/COOK-3331)** - Fix an issue where `dmg_package` with no source raises an exception + +## v2.0.2 + +### Bug + +- **[COOK-3578](https://tickets.chef.io/browse/COOK-3578)** - Support `package_id`s with spaces +- **[COOK-3302](https://tickets.chef.io/browse/COOK-3302)** - Fix an issue where `hdiutil detach` fails due to `cfprefsd` running in the background + +## v2.0.0 + +### Bug + +- **[COOK-3389](https://tickets.chef.io/browse/COOK-3389)** - Use `rsync` instead of `cp` (potentially a breaking change on some systems) + +## v1.1.0 + +- [COOK-1847] - accept owner parameter for installing packages + +## v1.0.0 + +- [COOK-852] - Support "pkg" in addition to "mpkg" package types + +## v0.7.0 + +- [COOK-854] - use `cp -R` instead of `cp -r` +- [COOK-855] - specify a file or directory to check for prior install + +## v0.6.0 + +- option to install software that is an .mpkg inside a .dmg +- ignore failure on chmod in case mode is already set, or is root owned diff --git a/cookbooks/dmg/CONTRIBUTING.md b/cookbooks/dmg/CONTRIBUTING.md new file mode 100644 index 0000000..ef2f2b8 --- /dev/null +++ b/cookbooks/dmg/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/dmg/MAINTAINERS.md b/cookbooks/dmg/MAINTAINERS.md new file mode 100644 index 0000000..c8f99e2 --- /dev/null +++ b/cookbooks/dmg/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 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/dmg/README.md b/cookbooks/dmg/README.md new file mode 100644 index 0000000..7cbbb13 --- /dev/null +++ b/cookbooks/dmg/README.md @@ -0,0 +1,146 @@ +# dmg Cookbook + +[![Build Status](https://travis-ci.org/chef-cookbooks/dmg.svg?branch=master)](https://travis-ci.org/chef-cookbooks/dmg) [![Cookbook Version](https://img.shields.io/cookbook/v/dmg.svg)](https://supermarket.chef.io/cookbooks/dmg) + +Resource to install OS X applications (.app) from dmg files. + +## Requirements + +### Platforms + +- Mac OS X + +### Chef + +- Chef 12.1+ + +### Cookbooks + +- none + +## Resources/Providers + +### dmg_package + +This resource will install a DMG "Package". It will retrieve the DMG from a remote URL, mount it using OS X's `hdid`, copy the application (.app directory) to the specified destination (/Applications), and detach the image using `hdiutil`. The dmg file will be stored in the `Chef::Config[:file_cache_path]`. If you want to install an application that has already been downloaded (not using the `source` parameter), copy it to the appropriate location. You can find out what directory this is with the following command on the node to run chef: + +```bash +knife exec -E 'p Chef::Config[:file_cache_path]' -c /etc/chef/client.rb +``` + +Optionally, the LWRP can install an "mpkg" or "pkg" package using installer(8). + +#### Actions + +- :install - Installs the application. + +#### Parameter attributes: + +- `app` - This is the name of the application used by default for the /Volumes directory and the .app directory copied to /Applications. +- `source` - remote URL for the dmg to download if specified. Default is nil. +- `file` - local dmg full file path. Default is nil. +- `owner` - owner that should own the package installation. +- `destination` - directory to copy the .app into. Default is /Applications. +- `checksum` - sha256 checksum of the dmg to download. Default is nil. +- `type` - type of package, "app", "pkg" or "mpkg". Default is "app". When using "pkg" or "mpkg", the destination must be /Applications. +- `volumes_dir` - Directory under /Volumes where the dmg is mounted. Not all dmgs are mounted into a /Volumes location matching the name of the dmg. If not specified, this will use the name attribute. +- `package_id` - Package id registered with pkgutil when a pkg or mpkg is installed +- `dmg_name` - Specify the name of the dmg if it is not the same as `app`, or if the name has spaces. +- `dmg_passphrase` - Specify a passphrase to use to unencrypt the dmg while mounting. +- `accept_eula` - Specify whether to accept the EULA. Certain dmgs require acceptance of EULA before mounting. Can be true or false, defaults to false. +- `headers` - Allows custom HTTP headers (like cookies) to be set on the remote_file resource. + +#### Examples + +Install `/Applications/Tunnelblick.app` from the primary download site. + +```ruby +dmg_package 'Tunnelblick' do + source 'http://tunnelblick.googlecode.com/files/Tunnelblick_3.1.2.dmg' + checksum 'a3fae60b6833175f32df20c90cd3a3603a' + action :install +end +``` + +Install Google Chrome. Uses the `dmg_name` because the application name has spaces. Installs in `/Applications/Google Chrome.app`. + +```ruby +dmg_package 'Google Chrome' do + dmg_name 'googlechrome' + source 'https://dl-ssl.google.com/chrome/mac/stable/GGRM/googlechrome.dmg' + checksum '7daa2dc5c46d9bfb14f1d7ff4b33884325e5e63e694810adc58f14795165c91a' + action :install +end +``` + +Install Dropbox. Uses `volumes_dir` because the mounted directory is different than the name of the application directory. Installs in `/Applications/Dropbox.app`. + +```ruby +dmg_package 'Dropbox' do + volumes_dir 'Dropbox Installer' + source 'http://www.dropbox.com/download?plat=mac' + checksum 'b4ea620ca22b0517b75753283ceb82326aca8bc3c86212fbf725de6446a96a13' + action :install +end +``` + +Install MacIrssi to `~/Applications` from the local file downloaded to the cache path into an Applications directory in the current user's home directory. Chef should run as a non-root user for this. + +```ruby +directory "#{ENV['HOME']}/Applications" + +dmg_package 'MacIrssi' do + destination "#{ENV['HOME']}/Applications" + action :install +end +``` + +Install Virtualbox to `/Applications` from the .mpkg: + +```ruby +dmg_package 'Virtualbox' do + source 'http://dlc.sun.com.edgesuite.net/virtualbox/4.0.8/VirtualBox-4.0.8-71778-OSX.dmg' + type 'mpkg' +end +``` + +Install pgAdmin to `/Applications` and automatically accept the EULA: + +```ruby +dmg_package 'pgAdmin3' do + source 'http://wwwmaster.postgresql.org/redir/198/h/pgadmin3/release/v1.12.3/osx/pgadmin3-1.12.3.dmg' + checksum '9435f79d5b52d0febeddfad392adf82db9df159196f496c1ab139a6957242ce9' + accept_eula true +end +``` + +Install Silverlight, with idempotence check based on pkgutil: + +```ruby +dmg_package 'Silerlight' do + source 'http://silverlight.dlservice.microsoft.com/download/D/C/2/DC2D5838-9138-4D25-AA92-52F61F7C51E6/runtime/Silverlight.dmg' + type 'pkg' + checksum '6d4a0ad4552d9815531463eb3f467fb8cf4bffcc' + package_id 'com.microsoft.installSilverlightPlugin' +end +``` + +## License & Authors + +**Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io)) + +**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. +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/dmg/attributes/default.rb b/cookbooks/dmg/attributes/default.rb new file mode 100644 index 0000000..e8cbfae --- /dev/null +++ b/cookbooks/dmg/attributes/default.rb @@ -0,0 +1,20 @@ +# +# Cookbook:: dmg +# Attributes:: default +# +# 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. +# 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. +# +default['dmg']['base_dir'] = '/Applications' +default['dmg']['cache_dir'] = Chef::Config[:file_cache_path] diff --git a/cookbooks/postgresql/files/default/tests/minitest/default_test.rb b/cookbooks/dmg/libraries/matchers.rb similarity index 64% rename from cookbooks/postgresql/files/default/tests/minitest/default_test.rb rename to cookbooks/dmg/libraries/matchers.rb index 8acbabf..5b688c2 100644 --- a/cookbooks/postgresql/files/default/tests/minitest/default_test.rb +++ b/cookbooks/dmg/libraries/matchers.rb @@ -1,5 +1,8 @@ # -# Copyright 2012, Opscode, Inc. +# Cookbook:: dmg +# Library:: matchers +# +# Copyright:: 2014-2016, Fletcher Nichol # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,14 +17,8 @@ # limitations under the License. # -require File.expand_path('../support/helpers', __FILE__) - -describe 'postgresql::default' do - include Helpers::Postgresql - - it 'installs the postgresql client packages' do - node['postgresql']['client']['packages'].each do |pkg| - package(pkg).must_be_installed - end +if defined?(ChefSpec) + def install_dmg_package(app) + ChefSpec::Matchers::ResourceMatcher.new(:dmg_package, :install, app) end end diff --git a/cookbooks/dmg/metadata.json b/cookbooks/dmg/metadata.json new file mode 100644 index 0000000..6e9e1e1 --- /dev/null +++ b/cookbooks/dmg/metadata.json @@ -0,0 +1 @@ +{"name":"dmg","version":"3.1.0","description":"LWRP to install OS X applications from dmgs","long_description":"# dmg Cookbook\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/dmg.svg?branch=master)](https://travis-ci.org/chef-cookbooks/dmg) [![Cookbook Version](https://img.shields.io/cookbook/v/dmg.svg)](https://supermarket.chef.io/cookbooks/dmg)\n\nResource to install OS X applications (.app) from dmg files.\n\n## Requirements\n\n### Platforms\n\n- Mac OS X\n\n### Chef\n\n- Chef 12.1+\n\n### Cookbooks\n\n- none\n\n## Resources/Providers\n\n### dmg_package\n\nThis resource will install a DMG \"Package\". It will retrieve the DMG from a remote URL, mount it using OS X's `hdid`, copy the application (.app directory) to the specified destination (/Applications), and detach the image using `hdiutil`. The dmg file will be stored in the `Chef::Config[:file_cache_path]`. If you want to install an application that has already been downloaded (not using the `source` parameter), copy it to the appropriate location. You can find out what directory this is with the following command on the node to run chef:\n\n```bash\nknife exec -E 'p Chef::Config[:file_cache_path]' -c /etc/chef/client.rb\n```\n\nOptionally, the LWRP can install an \"mpkg\" or \"pkg\" package using installer(8).\n\n#### Actions\n\n- :install - Installs the application.\n\n#### Parameter attributes:\n\n- `app` - This is the name of the application used by default for the /Volumes directory and the .app directory copied to /Applications.\n- `source` - remote URL for the dmg to download if specified. Default is nil.\n- `file` - local dmg full file path. Default is nil.\n- `owner` - owner that should own the package installation.\n- `destination` - directory to copy the .app into. Default is /Applications.\n- `checksum` - sha256 checksum of the dmg to download. Default is nil.\n- `type` - type of package, \"app\", \"pkg\" or \"mpkg\". Default is \"app\". When using \"pkg\" or \"mpkg\", the destination must be /Applications.\n- `volumes_dir` - Directory under /Volumes where the dmg is mounted. Not all dmgs are mounted into a /Volumes location matching the name of the dmg. If not specified, this will use the name attribute.\n- `package_id` - Package id registered with pkgutil when a pkg or mpkg is installed\n- `dmg_name` - Specify the name of the dmg if it is not the same as `app`, or if the name has spaces.\n- `dmg_passphrase` - Specify a passphrase to use to unencrypt the dmg while mounting.\n- `accept_eula` - Specify whether to accept the EULA. Certain dmgs require acceptance of EULA before mounting. Can be true or false, defaults to false.\n- `headers` - Allows custom HTTP headers (like cookies) to be set on the remote_file resource.\n\n#### Examples\n\nInstall `/Applications/Tunnelblick.app` from the primary download site.\n\n```ruby\ndmg_package 'Tunnelblick' do\n source 'http://tunnelblick.googlecode.com/files/Tunnelblick_3.1.2.dmg'\n checksum 'a3fae60b6833175f32df20c90cd3a3603a'\n action :install\nend\n```\n\nInstall Google Chrome. Uses the `dmg_name` because the application name has spaces. Installs in `/Applications/Google Chrome.app`.\n\n```ruby\ndmg_package 'Google Chrome' do\n dmg_name 'googlechrome'\n source 'https://dl-ssl.google.com/chrome/mac/stable/GGRM/googlechrome.dmg'\n checksum '7daa2dc5c46d9bfb14f1d7ff4b33884325e5e63e694810adc58f14795165c91a'\n action :install\nend\n```\n\nInstall Dropbox. Uses `volumes_dir` because the mounted directory is different than the name of the application directory. Installs in `/Applications/Dropbox.app`.\n\n```ruby\ndmg_package 'Dropbox' do\n volumes_dir 'Dropbox Installer'\n source 'http://www.dropbox.com/download?plat=mac'\n checksum 'b4ea620ca22b0517b75753283ceb82326aca8bc3c86212fbf725de6446a96a13'\n action :install\nend\n```\n\nInstall MacIrssi to `~/Applications` from the local file downloaded to the cache path into an Applications directory in the current user's home directory. Chef should run as a non-root user for this.\n\n```ruby\ndirectory \"#{ENV['HOME']}/Applications\"\n\ndmg_package 'MacIrssi' do\n destination \"#{ENV['HOME']}/Applications\"\n action :install\nend\n```\n\nInstall Virtualbox to `/Applications` from the .mpkg:\n\n```ruby\ndmg_package 'Virtualbox' do\n source 'http://dlc.sun.com.edgesuite.net/virtualbox/4.0.8/VirtualBox-4.0.8-71778-OSX.dmg'\n type 'mpkg'\nend\n```\n\nInstall pgAdmin to `/Applications` and automatically accept the EULA:\n\n```ruby\ndmg_package 'pgAdmin3' do\n source 'http://wwwmaster.postgresql.org/redir/198/h/pgadmin3/release/v1.12.3/osx/pgadmin3-1.12.3.dmg'\n checksum '9435f79d5b52d0febeddfad392adf82db9df159196f496c1ab139a6957242ce9'\n accept_eula true\nend\n```\n\nInstall Silverlight, with idempotence check based on pkgutil:\n\n```ruby\ndmg_package 'Silerlight' do\n source 'http://silverlight.dlservice.microsoft.com/download/D/C/2/DC2D5838-9138-4D25-AA92-52F61F7C51E6/runtime/Silverlight.dmg'\n type 'pkg'\n checksum '6d4a0ad4552d9815531463eb3f467fb8cf4bffcc'\n package_id 'com.microsoft.installSilverlightPlugin'\nend\n```\n\n## License & Authors\n\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":{"mac_os_x":">= 0.0.0"},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{}} \ No newline at end of file diff --git a/cookbooks/dmg/providers/package.rb b/cookbooks/dmg/providers/package.rb new file mode 100644 index 0000000..ac0bb9a --- /dev/null +++ b/cookbooks/dmg/providers/package.rb @@ -0,0 +1,95 @@ +# +# Cookbook:: dmg +# Provider:: package +# +# 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. +# 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. +# + +include Chef::Mixin::ShellOut + +use_inline_resources if defined?(use_inline_resources) + +def load_current_resource + @dmgpkg = Chef::Resource::DmgPackage.new(new_resource.name) + @dmgpkg.app(new_resource.app) + Chef::Log.debug("Checking for application #{new_resource.app}") + @dmgpkg.installed(installed?) +end + +action :install do + unless @dmgpkg.installed + + volumes_dir = new_resource.volumes_dir ? new_resource.volumes_dir : new_resource.app + dmg_name = new_resource.dmg_name ? new_resource.dmg_name : new_resource.app + + dmg_file = if new_resource.file.nil? + "#{Chef::Config[:file_cache_path]}/#{dmg_name}.dmg" + else + new_resource.file + end + + remote_file "#{dmg_file} - #{@dmgpkg.name}" do + path dmg_file + source new_resource.source + headers new_resource.headers if new_resource.headers + checksum new_resource.checksum if new_resource.checksum + end if new_resource.source + + passphrase_cmd = new_resource.dmg_passphrase ? "-passphrase #{new_resource.dmg_passphrase}" : '' + ruby_block "attach #{dmg_file}" do + block do + cmd = shell_out("hdiutil imageinfo #{passphrase_cmd} '#{dmg_file}' | grep -q 'Software License Agreement: true'") + software_license_agreement = cmd.exitstatus.zero? + raise "Requires EULA Acceptance; add 'accept_eula true' to package resource" if software_license_agreement && !new_resource.accept_eula + accept_eula_cmd = new_resource.accept_eula ? 'echo Y | PAGER=true' : '' + shell_out!("#{accept_eula_cmd} hdiutil attach #{passphrase_cmd} '#{dmg_file}' -mountpoint '/Volumes/#{volumes_dir}' -quiet") + end + not_if "hdiutil info #{passphrase_cmd} | grep -q 'image-path.*#{dmg_file}'" + end + + case new_resource.type + when 'app' + execute "rsync --force --recursive --links --perms --executability --owner --group --times '/Volumes/#{volumes_dir}/#{new_resource.app}.app' '#{new_resource.destination}'" do + user new_resource.owner if new_resource.owner + end + + file "#{new_resource.destination}/#{new_resource.app}.app/Contents/MacOS/#{new_resource.app}" do + mode '755' + ignore_failure true + end + when 'mpkg', 'pkg' + execute "installation_file=$(ls '/Volumes/#{volumes_dir}' | grep '.#{new_resource.type}$') && sudo installer -pkg \"/Volumes/#{volumes_dir}/$installation_file\" -target /" do + # Prevent cfprefsd from holding up hdiutil detach for certain disk images + environment('__CFPREFERENCES_AVOID_DAEMON' => '1') if Gem::Version.new(node['platform_version']) >= Gem::Version.new('10.8') + end + end + + execute "hdiutil detach '/Volumes/#{volumes_dir}' || hdiutil detach '/Volumes/#{volumes_dir}' -force" + end +end + +private + +def installed? + if ::File.directory?("#{new_resource.destination}/#{new_resource.app}.app") + Chef::Log.info "Already installed; to upgrade, remove \"#{new_resource.destination}/#{new_resource.app}.app\"" + true + elsif shell_out("pkgutil --pkgs='#{new_resource.package_id}'").exitstatus.zero? + Chef::Log.info "Already installed; to upgrade, try \"sudo pkgutil --forget '#{new_resource.package_id}'\"" + true + else + false + end +end diff --git a/cookbooks/application/recipes/default.rb b/cookbooks/dmg/recipes/default.rb similarity index 80% rename from cookbooks/application/recipes/default.rb rename to cookbooks/dmg/recipes/default.rb index ec67eb6..017b9d8 100644 --- a/cookbooks/application/recipes/default.rb +++ b/cookbooks/dmg/recipes/default.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: application +# Cookbook Name:: dmg # Recipe:: default # -# Copyright:: 2012, 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. @@ -16,4 +16,3 @@ # See the License for the specific language governing permissions and # limitations under the License. # -# Empty placeholder recipe, use the LWRPs, see README.md. diff --git a/cookbooks/dmg/resources/package.rb b/cookbooks/dmg/resources/package.rb new file mode 100644 index 0000000..4d1a2d8 --- /dev/null +++ b/cookbooks/dmg/resources/package.rb @@ -0,0 +1,39 @@ +# Encoding: utf-8 +# Cookbook:: dmg +# Resource:: package +# +# Copyright:: 2011-2016, Joshua Timberman +# +# 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 :install + +attribute :app, kind_of: String, name_attribute: true +attribute :source, kind_of: String, default: nil +attribute :file, kind_of: String, default: nil +attribute :owner, kind_of: String, default: nil +attribute :destination, kind_of: String, default: '/Applications' +attribute :checksum, kind_of: String, default: nil +attribute :volumes_dir, kind_of: String, default: nil +attribute :dmg_name, kind_of: String, default: nil +attribute :type, kind_of: String, default: 'app' +attribute :installed, kind_of: [TrueClass, FalseClass], default: false +attribute :package_id, kind_of: String, default: nil +attribute :dmg_passphrase, kind_of: String, default: nil +attribute :accept_eula, kind_of: [TrueClass, FalseClass], default: false +attribute :headers, kind_of: Hash, default: nil + +def initialize(name, run_context = nil) + super + @action = :install +end diff --git a/cookbooks/git/.foodcritic b/cookbooks/git/.foodcritic new file mode 100644 index 0000000..b9f8767 --- /dev/null +++ b/cookbooks/git/.foodcritic @@ -0,0 +1 @@ +~FC016 diff --git a/cookbooks/git/CHANGELOG.md b/cookbooks/git/CHANGELOG.md new file mode 100644 index 0000000..d2f2797 --- /dev/null +++ b/cookbooks/git/CHANGELOG.md @@ -0,0 +1,257 @@ +# git Cookbook CHANGELOG + +This file is used to list changes made in each version of the git cookbook. + +## 6.0.0 (2017-02-14) + +- Fail on deprecations is now enabled so we're fully Chef 13 compatible +- Define the chefspec matchers properly +- Remove the legacy platform mappings that fail on Chef 13 +- Improve the test cookbook / integration tests +- Convert config LWRP to a custom resource and make it fully idempotent +- Require Chef 12.5 or later + +## 5.0.2 (2017-01-18) + +- Remove arch for the metadata +- Avoid deprecation warning during testing +- respond_to?(:chef_version) for < 12.6 compat + +## 5.0.1 (2016-09-15) + +- Clarify we require Chef 12.1 or later + +## 5.0.0 (2016-09-02) + +- Require Chef 12 or later +- Don't depend on the windows cookbook since windows_package is built into Chef 12 +- Updates for testing + +## v4.6.0 (2016-07-05) + +- Added support for compiling git on suse +- Added the ability to pass a new group property to the config provider +- Documented the git_config provider +- Added the tar package on RHEL/Fedora for source installs as some minimal installs lack this package +- Added suse, opensuse, and opensuseleap as supported platforms in the metadata +- Switched to inspec for testing +- Switched to cookstyle for Ruby linting +- Added Travis integration testing of Debian 7/8 + +## v4.5.0 (2016-04-28) + +- Update git versions to 2.8.1 + +## v4.4.1 (2016-03-31) + +- PR #95 support 32 bit and 64 bit installs on windows @smurawski + +## v4.4.0 (2016-03-23) + +- PR #93 bump to latest git @ksubrama + +## v4.3.7 (2016-02-03) + +- PR #90 port node[git][server][export_all] to true/false @scalp42 +- PR #89 make attributes more wrapper friendly @scalp42 +- Update testing deps + rubocop fixes +- README fix @zverulacis + +## v4.3.6 (2016-01-25) + +- Windows fixes + +## v4.3.5 (2015-12-15) + +- Fixed installation on Windows nodes +- Removed the last of the Chef 10 compatibility code +- Added up to date contributing and testing docs +- Updated test deps in the Gemfile +- Removed test kitchen digital ocean config +- Test with kitchen-docker in Travis CI +- Removed uncessary windows cookbook entry from the Berksfile +- Added the chef standard rubocop.yml file and resolved all warnings +- Added chefignore file +- Removed bin dir +- Added maintainers.md and maintainers.toml files +- Added travis and supermarket version badges to the readme + +## v4.3.4 (2015-09-06) + +- Fixing package_id on OSX +- Adding 2.5.1 data for Windows + +## v4.3.3 (2015-07-27) + +- # 76: Use checksum keyname instead of value in source recipe + +## v4.3.2 (2015-07-27) + +- Fixing up Windows provider (issue #73) +- Supporting changes to source_prefix in source provider (#62) + +## v4.3.1 (2015-07-23) + +- Fixing up osx_dmg_source_url + +## v4.3.0 (2015-07-20) + +- Removing references to node attributes from provider code +- Name-spacing of client resource property names +- Addition of windows recipe +- Creation of package recipe + +## v4.2.4 (2015-07-19) + +- Fixing source provider selection bug from 4.2.3 + +## v4.2.3 (2015-07-18) + +- mac_os_x provider mapping +- various rubocops + +## v4.2.2 (2015-04-23) + +- Fix up action in Chef::Resource::GitService +- Adding matchers + +## v4.2.1 (2015-04-17) + +- Fixing Chef 11 support. +- Adding provider mapping file + +## v4.2.0 (2015-04-15) + +- Converting recipes to resources. +- Keeping recipe interface for backwards compat + +## v4.1.0 (2014-12-23) + +- Fixing windows package checksums +- Various test coverage additions + +## v4.0.2 (2014-04-23) + +- [COOK-4482] - Add FreeBSD support for installing git client + +## v4.0.0 (2014-03-18) + +- [COOK-4397] Only use_inline_resources on Chef 11 + +## v3.1.0 (2014-03-12) + +- [COOK-4392] - Cleanup git_config LWRP + +## v3.0.0 (2014-02-28) + +[COOK-4387] Add git_config type [COOK-4388] Fix up rubocops [COOK-4390] Add integration tests for default and server suites + +## v2.10.0 (2014-02-25) + +- [COOK-4146] - wrong dependency in git::source for rhel 6 +- [COOK-3947] - Git cookbook adds itself to the path every run + +## v2.9.0 + +Updating to depend on cookbook yum ~> 3 Fixing style to pass rubocop Updating test scaffolding + +## v2.8.4 + +fixing metadata version error. locking to 3.0 + +## v2.8.1 + +Locking yum dependency to '< 3' + +## v2.8.0 + +### Bug + +- [COOK-3433] - git::server does not correctly set git-daemon's base-path on Debian + +## v2.7.0 + +### Bug + +- **[COOK-3624](https://tickets.chef.io/browse/COOK-3624)** - Don't restart `xinetd` on each Chef client run +- **[COOK-3482](https://tickets.chef.io/browse/COOK-3482)** - Force git to add itself to the current process' PATH + +### New Feature + +- **[COOK-3223](https://tickets.chef.io/browse/COOK-3223)** - Support Omnios and SmartOS package installs + +## v2.6.0 + +### Improvement + +- **[COOK-3193](https://tickets.chef.io/browse/COOK-3193)** - Add proper debian packages + +## v2.5.2 + +### Bug + +- [COOK-2813]: Fix bad string interpolation in source recipe + +## v2.5.0 + +- Relax runit version constraint (now depend on 1.0+). + +## v2.4.0 + +- [COOK-2734] - update git versions + +## v2.3.0 + +- [COOK-2385] - update git::server for `runit_service` resource support + +## v2.2.0 + +- [COOK-2303] - git::server support for RHEL `platform_family` + +## v2.1.4 + +- [COOK-2110] - initial test-kitchen support (only available in GitHub repository) +- [COOK-2253] - pin runit dependency + +## v2.1.2 + +- [COOK-2043] - install git on ubuntu 12.04 not git-core + +## v2.1.0 + +The repository didn't have pushed commits, and so the following changes from earlier-than-latest versions wouldn't be available on the community site. We're releasing 2.1.0 to correct this. + +- [COOK-1943] - Update to git 1.8.0 +- [COOK-2020] - Add setup option attributes to Git Windows package install + +## 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-1668] - git cookbook fails to run due to bad `platform_family` call +- [COOK-1759] - git::source needs additional package for rhel `platform_family` + +## v1.1.2 + +- [COOK-2020] - Add setup option attributes to Git Windows package install + +## v1.1.0 + +- [COOK-1943] - Update to git 1.8.0 + +## v1.0.2 + +- [COOK-1537] - add recipe for source installation + +## v1.0.0 + +- [COOK-1152] - Add support for Mac OS X +- [COOK-1112] - Add support for Windows + +## v0.10.0 + +- [COOK-853] - Git client installation on CentOS + +## v0.9.0 + +- Current public release diff --git a/cookbooks/git/CONTRIBUTING.md b/cookbooks/git/CONTRIBUTING.md new file mode 100644 index 0000000..ef2f2b8 --- /dev/null +++ b/cookbooks/git/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/git/MAINTAINERS.md b/cookbooks/git/MAINTAINERS.md new file mode 100644 index 0000000..645ed14 --- /dev/null +++ b/cookbooks/git/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/git/README.md b/cookbooks/git/README.md new file mode 100644 index 0000000..2196803 --- /dev/null +++ b/cookbooks/git/README.md @@ -0,0 +1,161 @@ +# Git Cookbook + +[![Build Status](https://travis-ci.org/chef-cookbooks/git.svg?branch=master)](https://travis-ci.org/chef-cookbooks/git) [![Cookbook Version](https://img.shields.io/cookbook/v/git.svg)](https://supermarket.chef.io/cookbooks/git) + +Installs git_client from package or source. Optionally sets up a git service under xinetd. + +## Scope + +This cookbook is concerned with the Git SCM utility. It does not address ecosystem tooling or related projects. + +## Requirements + +### Platforms + +The following platforms have been tested with Test Kitchen: + +``` +|---------------+-------| +| centos-6 | X | +|---------------+-------| +| centos-7 | X | +|---------------+-------| +| fedora | X | +|---------------+-------| +| debian-7 | X | +|---------------+-------| +| debian-8 | X | +|---------------+-------| +| ubuntu-14.04 | X | +|---------------+-------| +| ubuntu-16.04 | X | +|---------------+-------| +| openSUSE 13.2 | X | +|---------------+-------| +| openSUSE Leap | X | +|---------------+-------| +``` + +### Chef + +- Chef 12.5+ + +### Cookbooks + +- depends 'build-essential' - For compiling from source +- depends 'dmg' - For macOS Support +- depends 'yum-epel' - For older RHEL platform_family support + +## Usage + +Add `git::default`, `git::source` or `git::windows` to your run_list OR add `depends 'git', '~> 4.3'` to your cookbook's metadata.rb. include_recipe one of the recipes from your cookbook OR use the git_client resource directly, the same way you'd use core Chef resources (file, template, directory, package, etc). + +## Resources Overview + +- `git_client`: Manages a Git client installation on a machine. Acts as a singleton when using the (default) package provider. Source provider available as well. +- `git_service`: Sets up a Git service via xinetd. WARNING: This is insecure and will probably be removed in the future +- `git_config`: Sets up Git configuration on a node. + +### git_client + +The `git_client` resource manages the installation of a Git client on a machine. + +#### Example + +```ruby +git_client 'default' do + action :install +end +``` + +### git_config + +The `git_config` resource manages the configuration of Git client on a machine. + +#### Example + +```ruby +git_config 'url.https://github.com/.insteadOf' do + value 'git://github.com/' + scope 'system' + options '--add' +end +``` + +#### Properties + +Currently, there are distinct sets of resource properties, used by the providers for source, package, macos, and windows. + +# used by linux package providers + +- `package_name` - Package name to install on Linux machines. Defaults to a calculated value based on platform. +- `package_version` - Defaults to nil. +- `package_action` - Defaults to `:install` + +# used by source providers + +- `source_prefix` - Defaults to '/usr/local' +- `source_url` - Defaults to a calculated URL based on source_version +- `source_version` - Defaults to 2.7.4 +- `source_use_pcre` - configure option for build. Defaults to false +- `source_checksum` - Defaults to a known value for the 2.7.4 source tarball + +# used by OSX package providers + +- `osx_dmg_app_name` - Defaults to 'git-2.7.1-intel-universal-mavericks' +- `osx_dmg_package_id` - Defaults to 'GitOSX.Installer.git271.git.pkg' +- `osx_dmg_volumes_dir` - Defaults to 'Git 2.7.1 Mavericks Intel Universal' +- `osx_dmg_url` - Defaults to Sourceforge +- `osx_dmg_checksum` - Defaults to the value for 2.7.1 + +# used by the Windows package providers + +- `windows_display_name` - Windows display name +- `windows_package_url` - Defaults to the Internet +- `windows_package_checksum` - Defaults to the value for 2.7.4 + +## Recipes + +This cookbook ships with ready to use, attribute driven recipes that utilize the `git_client` and `git_service` resources. As of cookbook 4.x, they utilize the same attributes layout scheme from the 3.x. Due to some overlap, it is currently impossible to simultaneously install the Git client as a package and from source by using the "manipulate a the node attributes and run a recipe" technique. If you need both, you'll need to utilize the git_client resource in a recipe. + +## Attributes + +### Windows + +- `node['git']['version']` - git version to install +- `node['git']['url']` - URL to git package +- `node['git']['checksum']` - package SHA256 checksum +- `node['git']['display_name']` - `windows_package` resource Display Name (makes the package install idempotent) + +### Mac OS X + +- `node['git']['osx_dmg']['url']` - URL to git package +- `node['git']['osx_dmg']['checksum']` - package SHA256 checksum + +### Linux + +- `node['git']['prefix']` - git install directory +- `node['git']['version']` - git version to install +- `node['git']['url']` - URL to git tarball +- `node['git']['checksum']` - tarball SHA256 checksum +- `node['git']['use_pcre']` - if true, builds git with PCRE enabled + +## License & Authors + +- Author:: Joshua Timberman ([joshua@chef.io](mailto:joshua@chef.io)) +- Author:: Sean OMeara ([sean@sean.io](mailto:sean@sean.io)) +- Copyright:: 2009-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. +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/git/attributes/default.rb b/cookbooks/git/attributes/default.rb new file mode 100644 index 0000000..a8b339e --- /dev/null +++ b/cookbooks/git/attributes/default.rb @@ -0,0 +1,47 @@ +# +# Author:: Jamie Winsor () +# Cookbook:: git +# Attributes:: default +# +# 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. + +case node['platform_family'] +when 'windows' + default['git']['version'] = '2.8.1' + if node['kernel']['machine'] == 'x86_64' + default['git']['architecture'] = '64' + default['git']['checksum'] = '5e5283990cc91d1e9bd0858f8411e7d0afb70ce26e23680252fb4869288c7cfb' + else + default['git']['architecture'] = '32' + default['git']['checksum'] = '17418c2e507243b9c98db161e9e5e8041d958b93ce6078530569b8edaec6b8a4' + end + default['git']['url'] = 'https://github.com/git-for-windows/git/releases/download/v%{version}.windows.1/Git-%{version}-%{architecture}-bit.exe' + default['git']['display_name'] = "Git version #{node['git']['version']}" +when 'mac_os_x' + default['git']['osx_dmg']['app_name'] = 'git-2.8.1-intel-universal-mavericks' + default['git']['osx_dmg']['volumes_dir'] = 'Git 2.8.1 Mavericks Intel Universal' + default['git']['osx_dmg']['package_id'] = 'GitOSX.Installer.git281Universal.git.pkg' + default['git']['osx_dmg']['url'] = 'http://sourceforge.net/projects/git-osx-installer/files/git-2.8.1-intel-universal-mavericks.dmg/download' + default['git']['osx_dmg']['checksum'] = 'c2912895a1e2018d9be4c646765d511f7c82e0114275505dbd13d1ac70c62023' +else + default['git']['prefix'] = '/usr/local' + default['git']['version'] = '2.8.1' + default['git']['url'] = 'https://nodeload.github.com/git/git/tar.gz/v%{version}' + default['git']['checksum'] = 'e08503ecaf5d3ac10c40f22871c996a392256c8d038d16f52ebf974cba29ae42' + default['git']['use_pcre'] = false +end + +default['git']['server']['base_path'] = '/srv/git' +default['git']['server']['export_all'] = true diff --git a/cookbooks/git/libraries/helpers.rb b/cookbooks/git/libraries/helpers.rb new file mode 100644 index 0000000..bedde84 --- /dev/null +++ b/cookbooks/git/libraries/helpers.rb @@ -0,0 +1,48 @@ +module GitCookbook + module Helpers + # linux packages default to distro offering + def parsed_package_name + return new_resource.package_name if new_resource.package_name + return 'git-core' if node['platform'] == 'ubuntu' && node['platform_version'].to_f < 10.10 + return 'developer/versioning/git' if node['platform'] == 'omnios' + return 'scmgit' if node['platform'] == 'smartos' + 'git' + end + + def parsed_package_version + return new_resource.package_version if new_resource.package_version + end + + # source + def parsed_source_url + return new_resource.source_url if new_resource.source_url + "https://nodeload.github.com/git/git/tar.gz/v#{new_resource.source_version}" + end + + def parsed_source_checksum + return new_resource.source_checksum if new_resource.source_checksum + '8d53703d75890c03e26a915c7af3b7b98d8cfb94382f685a9bcbee1eeaec47b4' # 2.7.4 tarball + end + + # windows + def parsed_windows_display_name + return new_resource.windows_display_name if new_resource.windows_display_name + "Git version #{parsed_windows_package_version}" + end + + def parsed_windows_package_version + return new_resource.windows_package_version if new_resource.windows_package_version + '2.7.4' + end + + def parsed_windows_package_url + return new_resource.windows_package_url if new_resource.windows_package_url + "https://github.com/git-for-windows/git/releases/download/v%#{parsed_windows_package_version}.windows.1/Git-%#{parsed_windows_package_version}-32-bit.exe" + end + + def parsed_windows_package_checksum + return new_resource.windows_package_checksum if new_resource.windows_package_checksum + '49601d5102df249d6f866ecfa1eea68eb5672acc1dbb7e4051099e792f6da5fc' + end + end +end diff --git a/cookbooks/git/libraries/matchers.rb b/cookbooks/git/libraries/matchers.rb new file mode 100644 index 0000000..25ed8df --- /dev/null +++ b/cookbooks/git/libraries/matchers.rb @@ -0,0 +1,16 @@ +if defined?(ChefSpec) + ChefSpec.define_matcher(:git_client) + ChefSpec.define_matcher(:git_service) + + def set_git_config(resource_name) # rubocop:disable Style/AccessorMethodName + ChefSpec::Matchers::ResourceMatcher.new(:git_config, :set, resource_name) + end + + def install_git_client(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:git_client, :install, resource_name) + end + + def install_git_service(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:git_service, :install, resource_name) + end +end diff --git a/cookbooks/git/libraries/provider_git_client.rb b/cookbooks/git/libraries/provider_git_client.rb new file mode 100644 index 0000000..41d7cfd --- /dev/null +++ b/cookbooks/git/libraries/provider_git_client.rb @@ -0,0 +1,13 @@ +class Chef + class Provider + class GitClient < Chef::Provider::LWRPBase + use_inline_resources + + def whyrun_supported? + true + end + + include GitCookbook::Helpers + end + end +end diff --git a/cookbooks/git/libraries/provider_git_client_osx.rb b/cookbooks/git/libraries/provider_git_client_osx.rb new file mode 100644 index 0000000..db604c9 --- /dev/null +++ b/cookbooks/git/libraries/provider_git_client_osx.rb @@ -0,0 +1,26 @@ +class Chef + class Provider + class GitClient + class Osx < Chef::Provider::GitClient + include Chef::DSL::IncludeRecipe + + provides :git_client, os: 'mac_os_x' + + action :install do + dmg_package 'GitOSX-Installer' do + app new_resource.osx_dmg_app_name + package_id new_resource.osx_dmg_package_id + volumes_dir new_resource.osx_dmg_volumes_dir + source new_resource.osx_dmg_url + checksum new_resource.osx_dmg_checksum + type 'pkg' + action :install + end + end + + action :delete do + end + end + end + end +end diff --git a/cookbooks/git/libraries/provider_git_client_package.rb b/cookbooks/git/libraries/provider_git_client_package.rb new file mode 100644 index 0000000..8c750e3 --- /dev/null +++ b/cookbooks/git/libraries/provider_git_client_package.rb @@ -0,0 +1,27 @@ +class Chef + class Provider + class GitClient + class Package < Chef::Provider::GitClient + include Chef::DSL::IncludeRecipe + + provides :git_client, os: 'linux' + + action :install do + # FIXME: rhel 5 + include_recipe 'yum-epel' if node['platform_family'] == 'rhel' && node['platform_version'].to_i == 5 + + # Software installation + package "#{new_resource.name} :create #{parsed_package_name}" do + package_name parsed_package_name + version parsed_package_version + action new_resource.package_action + action :install + end + end + + action :delete do + end + end + end + end +end diff --git a/cookbooks/git/libraries/provider_git_client_source.rb b/cookbooks/git/libraries/provider_git_client_source.rb new file mode 100644 index 0000000..6ab8bc7 --- /dev/null +++ b/cookbooks/git/libraries/provider_git_client_source.rb @@ -0,0 +1,66 @@ +class Chef + class Provider + class GitClient + class Source < Chef::Provider::GitClient + include Chef::DSL::IncludeRecipe + + action :install do + return "#{node['platform']} is not supported by the #{cookbook_name}::#{recipe_name} recipe" unless platform_family?('rhel', 'suse', 'fedora', 'debian') + + include_recipe 'build-essential' + include_recipe 'yum-epel' if node['platform_family'] == 'rhel' && node['platform_version'].to_i == 5 + + # move this to attributes. + case node['platform_family'] + when 'fedora' + pkgs = %w(tar openssl-devel libcurl-devel expat-devel perl-ExtUtils-MakeMaker) + when 'rhel' + case node['platform_version'].to_i + when 5 + pkgs = %w(tar expat-devel gettext-devel curl-devel openssl-devel zlib-devel) + pkgs += %w( pcre-devel ) if new_resource.source_use_pcre + when 6, 7 + pkgs = %w(tar expat-devel gettext-devel libcurl-devel openssl-devel perl-ExtUtils-MakeMaker zlib-devel) + pkgs += %w( pcre-devel ) if new_resource.source_use_pcre + else + pkgs = %w(expat-devel gettext-devel curl-devel openssl-devel perl-ExtUtils-MakeMaker zlib-devel) if node['platform'] == 'amazon' + pkgs += %w( pcre-devel ) if new_resource.source_use_pcre + end + when 'debian' + pkgs = %w(libcurl4-gnutls-dev libexpat1-dev gettext libz-dev libssl-dev) + pkgs += %w( libpcre3-dev ) if new_resource.source_use_pcre + when 'suse' + pkgs = %w(tar libcurl-devel libexpat-devel gettext-tools zlib-devel libopenssl-devel) + pkgs += %w( libpcre2-devel ) if new_resource.source_use_pcre + end + + package pkgs + + # reduce line-noise-eyness + remote_file "#{Chef::Config['file_cache_path']}/git-#{new_resource.source_version}.tar.gz" do + source parsed_source_url # helpers.rb + checksum parsed_source_checksum # helpers.rb + mode '0644' + not_if "test -f #{Chef::Config['file_cache_path']}/git-#{new_resource.source_version}.tar.gz" + end + + # reduce line-noise-eyness + execute "Extracting and Building Git #{new_resource.source_version} from Source" do + cwd Chef::Config['file_cache_path'] + additional_make_params = '' + additional_make_params += 'USE_LIBPCRE=1' if new_resource.source_use_pcre + command <<-COMMAND + (mkdir git-#{new_resource.source_version} && tar -zxf git-#{new_resource.source_version}.tar.gz -C git-#{new_resource.source_version} --strip-components 1) + (cd git-#{new_resource.source_version} && make prefix=#{new_resource.source_prefix} #{additional_make_params} install) + COMMAND + not_if "git --version | grep #{new_resource.source_version}" + not_if "#{new_resource.source_prefix}/bin/git --version | grep #{new_resource.source_version}" + end + end + + action :delete do + end + end + end + end +end diff --git a/cookbooks/git/libraries/provider_git_client_windows.rb b/cookbooks/git/libraries/provider_git_client_windows.rb new file mode 100644 index 0000000..305cdd2 --- /dev/null +++ b/cookbooks/git/libraries/provider_git_client_windows.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true +class Chef + class Provider + class GitClient + class Windows < Chef::Provider::GitClient + include Chef::DSL::IncludeRecipe + + provides :git_client, os: 'windows' + + action :install do + windows_package parsed_windows_display_name do + action :install + source parsed_windows_package_url + checksum parsed_windows_package_checksum + installer_type :inno + end + + # Git is installed to Program Files (x86) on 64-bit machines and + # 'Program Files' on 32-bit machines + PROGRAM_FILES = if node['git']['architecture'] == '32' + ENV['ProgramFiles(x86)'] || ENV['ProgramFiles'] + else + ENV['ProgramW6432'] || ENV['ProgramFiles'] + end + GIT_PATH = "#{PROGRAM_FILES}\\Git\\Cmd".freeze + + # COOK-3482 - windows_path resource doesn't change the current process + # environment variables. Therefore, git won't actually be on the PATH + # until the next chef-client run + ruby_block 'Add Git Path' do + block do + ENV['PATH'] += ";#{GIT_PATH}" + end + not_if { ENV['PATH'] =~ /GIT_PATH/ } + action :nothing + end + + windows_path GIT_PATH do + notifies :create, 'ruby_block[Add Git Path]', :immediately + action :add + end + end + + action :delete do + end + end + end + end +end diff --git a/cookbooks/git/libraries/provider_git_service.rb b/cookbooks/git/libraries/provider_git_service.rb new file mode 100644 index 0000000..7f74e90 --- /dev/null +++ b/cookbooks/git/libraries/provider_git_service.rb @@ -0,0 +1,57 @@ +class Chef + class Provider + class GitClient < Chef::Provider::LWRPBase + use_inline_resources + + def whyrun_supported? + true + end + + include Chef::DSL::IncludeRecipe + include GitCookbook::Helpers + + provides :git_service, os: 'linux' + + action :create do + return "#{node['platform']} is not supported by the #{cookbook_name}::#{recipe_name} recipe" if node['platform'] == 'windows' + + include_recipe 'git' + + directory new_resource.service_base_path do + owner 'root' + group 'root' + mode '0755' + end + + case node['platform_family'] + when 'debian' + package 'xinetd' + when 'rhel' + package 'git-daemon' + else + log 'Platform requires setting up a git daemon service script.' + log "Hint: /usr/bin/git daemon --export-all --user=nobody --group=daemon --base-path=#{new_resource.service_base_path}" + return + end + + template '/etc/xinetd.d/git' do + backup false + source 'git-xinetd.d.erb' + owner 'root' + group 'root' + mode '0644' + variables( + git_daemon_binary: value_for_platform_family( + 'debian' => '/usr/lib/git-core/git-daemon', + 'rhel' => '/usr/libexec/git-core/git-daemon' + ) + ) + end + + service 'xinetd' do + action [:enable, :restart] + end + end + end + end +end diff --git a/cookbooks/git/libraries/provider_git_service_xinetd.rb b/cookbooks/git/libraries/provider_git_service_xinetd.rb new file mode 100644 index 0000000..74b524e --- /dev/null +++ b/cookbooks/git/libraries/provider_git_service_xinetd.rb @@ -0,0 +1,55 @@ +class Chef + class Provider + class GitClient < Chef::Provider::LWRPBase + use_inline_resources + + def whyrun_supported? + true + end + + include Chef::DSL::IncludeRecipe + include GitCookbook::Helpers + + action :create do + return "#{node['platform']} is not supported by the #{cookbook_name}::#{recipe_name} recipe" if node['platform'] == 'windows' + + include_recipe 'git' + + directory new_resource.service_base_path do + owner 'root' + group 'root' + mode '0755' + end + + case node['platform_family'] + when 'debian' + package 'xinetd' + when 'rhel' + package 'git-daemon' + else + log 'Platform requires setting up a git daemon service script.' + log "Hint: /usr/bin/git daemon --export-all --user=nobody --group=daemon --base-path=#{new_resource.service_base_path}" + return + end + + template '/etc/xinetd.d/git' do + backup false + source 'git-xinetd.d.erb' + owner 'root' + group 'root' + mode '0644' + variables( + git_daemon_binary: value_for_platform_family( + 'debian' => '/usr/lib/git-core/git-daemon', + 'rhel' => '/usr/libexec/git-core/git-daemon' + ) + ) + end + + service 'xinetd' do + action [:enable, :restart] + end + end + end + end +end diff --git a/cookbooks/git/libraries/resource_git_client.rb b/cookbooks/git/libraries/resource_git_client.rb new file mode 100644 index 0000000..c426ebe --- /dev/null +++ b/cookbooks/git/libraries/resource_git_client.rb @@ -0,0 +1,38 @@ +require 'chef/resource/lwrp_base' + +class Chef + class Resource + class GitClient < Chef::Resource::LWRPBase + self.resource_name = :git_client + actions :install, :remove + default_action :install + + provides :git_client + + # used by source providers + attribute :source_checksum, kind_of: String, default: nil + attribute :source_prefix, kind_of: String, default: '/usr/local' + attribute :source_url, kind_of: String, default: nil + attribute :source_use_pcre, kind_of: [TrueClass, FalseClass], default: false + attribute :source_version, kind_of: String, default: nil + + # used by linux package providers + attribute :package_name, kind_of: String, default: nil + attribute :package_version, kind_of: String, default: nil + attribute :package_action, kind_of: Symbol, default: :install + + # used by OSX package providers + attribute :osx_dmg_app_name, kind_of: String, default: 'git-2.7.1-intel-universal-mavericks' + attribute :osx_dmg_package_id, kind_of: String, default: 'GitOSX.Installer.git271.git.pkg' + attribute :osx_dmg_volumes_dir, kind_of: String, default: 'Git 2.7.1 Mavericks Intel Universal' + attribute :osx_dmg_url, kind_of: String, default: 'http://sourceforge.net/projects/git-osx-installer/files/git-2.7.1-intel-universal-mavericks.dmg/download' + attribute :osx_dmg_checksum, kind_of: String, default: '260b32e8877eb72d07807b26163aeec42e2d98c350f32051ab1ff0cc33626440' # 2.7.1 + + # used by Windows providers + attribute :windows_display_name, kind_of: String, default: nil + attribute :windows_package_url, kind_of: String, default: nil + attribute :windows_package_checksum, kind_of: String, default: nil + attribute :windows_package_version, kind_of: String, default: nil + end + end +end diff --git a/cookbooks/git/libraries/resource_git_service.rb b/cookbooks/git/libraries/resource_git_service.rb new file mode 100644 index 0000000..a1f2343 --- /dev/null +++ b/cookbooks/git/libraries/resource_git_service.rb @@ -0,0 +1,16 @@ +require 'chef/resource/lwrp_base' + +class Chef + class Resource + class GitService < Chef::Resource::LWRPBase + self.resource_name = :git_service + actions :create + default_action :create + + provides :git_service + + # used by the service xinetd provider + attribute :service_base_path, kind_of: String, default: '/srv/git' + end + end +end diff --git a/cookbooks/git/metadata.json b/cookbooks/git/metadata.json new file mode 100644 index 0000000..28f80e7 --- /dev/null +++ b/cookbooks/git/metadata.json @@ -0,0 +1 @@ +{"name":"git","version":"6.0.0","description":"Installs git and/or sets up a Git server daemon","long_description":"# Git Cookbook\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/git.svg?branch=master)](https://travis-ci.org/chef-cookbooks/git) [![Cookbook Version](https://img.shields.io/cookbook/v/git.svg)](https://supermarket.chef.io/cookbooks/git)\n\nInstalls git_client from package or source. Optionally sets up a git service under xinetd.\n\n## Scope\n\nThis cookbook is concerned with the Git SCM utility. It does not address ecosystem tooling or related projects.\n\n## Requirements\n\n### Platforms\n\nThe following platforms have been tested with Test Kitchen:\n\n```\n|---------------+-------|\n| centos-6 | X |\n|---------------+-------|\n| centos-7 | X |\n|---------------+-------|\n| fedora | X |\n|---------------+-------|\n| debian-7 | X |\n|---------------+-------|\n| debian-8 | X |\n|---------------+-------|\n| ubuntu-14.04 | X |\n|---------------+-------|\n| ubuntu-16.04 | X |\n|---------------+-------|\n| openSUSE 13.2 | X |\n|---------------+-------|\n| openSUSE Leap | X |\n|---------------+-------|\n```\n\n### Chef\n\n- Chef 12.5+\n\n### Cookbooks\n\n- depends 'build-essential' - For compiling from source\n- depends 'dmg' - For macOS Support\n- depends 'yum-epel' - For older RHEL platform_family support\n\n## Usage\n\nAdd `git::default`, `git::source` or `git::windows` to your run_list OR add `depends 'git', '~> 4.3'` to your cookbook's metadata.rb. include_recipe one of the recipes from your cookbook OR use the git_client resource directly, the same way you'd use core Chef resources (file, template, directory, package, etc).\n\n## Resources Overview\n\n- `git_client`: Manages a Git client installation on a machine. Acts as a singleton when using the (default) package provider. Source provider available as well.\n- `git_service`: Sets up a Git service via xinetd. WARNING: This is insecure and will probably be removed in the future\n- `git_config`: Sets up Git configuration on a node.\n\n### git_client\n\nThe `git_client` resource manages the installation of a Git client on a machine.\n\n#### Example\n\n```ruby\ngit_client 'default' do\n action :install\nend\n```\n\n### git_config\n\nThe `git_config` resource manages the configuration of Git client on a machine.\n\n#### Example\n\n```ruby\ngit_config 'url.https://github.com/.insteadOf' do\n value 'git://github.com/'\n scope 'system'\n options '--add'\nend\n```\n\n#### Properties\n\nCurrently, there are distinct sets of resource properties, used by the providers for source, package, macos, and windows.\n\n# used by linux package providers\n\n- `package_name` - Package name to install on Linux machines. Defaults to a calculated value based on platform.\n- `package_version` - Defaults to nil.\n- `package_action` - Defaults to `:install`\n\n# used by source providers\n\n- `source_prefix` - Defaults to '/usr/local'\n- `source_url` - Defaults to a calculated URL based on source_version\n- `source_version` - Defaults to 2.7.4\n- `source_use_pcre` - configure option for build. Defaults to false\n- `source_checksum` - Defaults to a known value for the 2.7.4 source tarball\n\n# used by OSX package providers\n\n- `osx_dmg_app_name` - Defaults to 'git-2.7.1-intel-universal-mavericks'\n- `osx_dmg_package_id` - Defaults to 'GitOSX.Installer.git271.git.pkg'\n- `osx_dmg_volumes_dir` - Defaults to 'Git 2.7.1 Mavericks Intel Universal'\n- `osx_dmg_url` - Defaults to Sourceforge\n- `osx_dmg_checksum` - Defaults to the value for 2.7.1\n\n# used by the Windows package providers\n\n- `windows_display_name` - Windows display name\n- `windows_package_url` - Defaults to the Internet\n- `windows_package_checksum` - Defaults to the value for 2.7.4\n\n## Recipes\n\nThis cookbook ships with ready to use, attribute driven recipes that utilize the `git_client` and `git_service` resources. As of cookbook 4.x, they utilize the same attributes layout scheme from the 3.x. Due to some overlap, it is currently impossible to simultaneously install the Git client as a package and from source by using the \"manipulate a the node attributes and run a recipe\" technique. If you need both, you'll need to utilize the git_client resource in a recipe.\n\n## Attributes\n\n### Windows\n\n- `node['git']['version']` - git version to install\n- `node['git']['url']` - URL to git package\n- `node['git']['checksum']` - package SHA256 checksum\n- `node['git']['display_name']` - `windows_package` resource Display Name (makes the package install idempotent)\n\n### Mac OS X\n\n- `node['git']['osx_dmg']['url']` - URL to git package\n- `node['git']['osx_dmg']['checksum']` - package SHA256 checksum\n\n### Linux\n\n- `node['git']['prefix']` - git install directory\n- `node['git']['version']` - git version to install\n- `node['git']['url']` - URL to git tarball\n- `node['git']['checksum']` - tarball SHA256 checksum\n- `node['git']['use_pcre']` - if true, builds git with PCRE enabled\n\n## License & Authors\n\n- Author:: Joshua Timberman ([joshua@chef.io](mailto:joshua@chef.io))\n- Author:: Sean OMeara ([sean@sean.io](mailto:sean@sean.io))\n- Copyright:: 2009-2017, 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","debian":">= 0.0.0","fedora":">= 0.0.0","freebsd":">= 0.0.0","mac_os_x":">= 10.6.0","omnios":">= 0.0.0","oracle":">= 0.0.0","redhat":">= 0.0.0","smartos":">= 0.0.0","scientific":">= 0.0.0","suse":">= 0.0.0","opensuse":">= 0.0.0","opensuseleap":">= 0.0.0","ubuntu":">= 0.0.0","windows":">= 0.0.0"},"dependencies":{"build-essential":">= 0.0.0","dmg":">= 0.0.0","yum-epel":">= 0.0.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{"git":"Installs git","git::server":"Sets up a runit_service for git daemon","git::source":"Installs git from source"}} \ No newline at end of file diff --git a/cookbooks/postgresql/files/default/tests/minitest/support/helpers.rb b/cookbooks/git/recipes/default.rb similarity index 65% rename from cookbooks/postgresql/files/default/tests/minitest/support/helpers.rb rename to cookbooks/git/recipes/default.rb index fd8fcea..bc7feed 100644 --- a/cookbooks/postgresql/files/default/tests/minitest/support/helpers.rb +++ b/cookbooks/git/recipes/default.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: postgresql_test +# Cookbook:: git # Recipe:: default # -# Copyright 2012, Opscode, 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. @@ -15,15 +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. -# -module Helpers - module Postgresql - require 'chef/mixin/shell_out' - include Chef::Mixin::ShellOut - include MiniTest::Chef::Assertions - include MiniTest::Chef::Context - include MiniTest::Chef::Resources - - end -end +include_recipe 'git::package' diff --git a/cookbooks/git/recipes/package.rb b/cookbooks/git/recipes/package.rb new file mode 100644 index 0000000..e8812f6 --- /dev/null +++ b/cookbooks/git/recipes/package.rb @@ -0,0 +1,37 @@ +# +# Cookbook:: git +# Recipe:: package +# +# 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. + +case node['platform'] +when 'mac_os_x' + # FIXME: The resource has three distinct groups of properties used in + # different providers... should we make multiple resource types instead? + git_client 'default' do + osx_dmg_app_name node['git']['osx_dmg']['app_name'] + osx_dmg_package_id node['git']['osx_dmg']['package_id'] + osx_dmg_volumes_dir node['git']['osx_dmg']['volumes_dir'] + osx_dmg_url node['git']['osx_dmg']['url'] + osx_dmg_checksum node['git']['osx_dmg']['checksum'] + action :install + end +when 'windows' + include_recipe 'git::windows' +else + git_client 'default' do + action :install + end +end diff --git a/cookbooks/postgresql/files/default/tests/minitest/ruby_test.rb b/cookbooks/git/recipes/server.rb similarity index 63% rename from cookbooks/postgresql/files/default/tests/minitest/ruby_test.rb rename to cookbooks/git/recipes/server.rb index 3b3649f..1567cbb 100644 --- a/cookbooks/postgresql/files/default/tests/minitest/ruby_test.rb +++ b/cookbooks/git/recipes/server.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: postgresql_test -# Recipe:: default +# Cookbook:: git +# Recipe:: server # -# Copyright 2012, Opscode, 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. @@ -15,14 +15,8 @@ # 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 File.expand_path('../support/helpers', __FILE__) - -describe 'postgresql::ruby' do - include Helpers::Postgresql - - it 'installs the pg gem in Chefs ruby environment' do - assert Gem::Specification.all_names.grep("pg-.*") - end +git_service 'default' do + service_base_path node['git']['server']['base_path'] + action :create end diff --git a/cookbooks/application_nodejs/resources/nodejs.rb b/cookbooks/git/recipes/source.rb similarity index 54% rename from cookbooks/application_nodejs/resources/nodejs.rb rename to cookbooks/git/recipes/source.rb index 1ee52b3..73429d5 100644 --- a/cookbooks/application_nodejs/resources/nodejs.rb +++ b/cookbooks/git/recipes/source.rb @@ -1,9 +1,8 @@ # -# Author:: Conrad Kramer -# Cookbook Name:: application_node -# Resource:: node +# Cookbook:: git +# Recipe:: source # -# Copyright:: 2013, Kramer Software Productions, LLC. +# Copyright:: 2012-2016, Brian Flad, Fletcher Nichol # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -16,10 +15,14 @@ # 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. -# -include ApplicationCookbook::ResourceBase - -attribute :npm, :kind_of => [NilClass, TrueClass, FalseClass], :default => true -attribute :template, :kind_of => [String, NilClass], :default => nil -attribute :entry_point, :kind_of => String, :default => 'app.js' +# drive version from node attributes +git_client 'default' do + provider Chef::Provider::GitClient::Source + source_checksum node['git']['checksum'] + source_prefix node['git']['prefix'] + source_url format(node['git']['url'], version: node['git']['version']) + source_use_pcre node['git']['use_pcre'] + source_version node['git']['version'] + action :install +end diff --git a/cookbooks/git/recipes/windows.rb b/cookbooks/git/recipes/windows.rb new file mode 100644 index 0000000..7fd5882 --- /dev/null +++ b/cookbooks/git/recipes/windows.rb @@ -0,0 +1,24 @@ +# +# Cookbook:: git +# Recipe:: windows +# +# 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. + +git_client 'default' do + windows_display_name node['git']['display_name'] + windows_package_url format(node['git']['url'], version: node['git']['version'], architecture: node['git']['architecture']) + windows_package_checksum node['git']['checksum'] + action :install +end diff --git a/cookbooks/git/resources/config.rb b/cookbooks/git/resources/config.rb new file mode 100644 index 0000000..2f3d88c --- /dev/null +++ b/cookbooks/git/resources/config.rb @@ -0,0 +1,49 @@ +property :key, String, name_attribute: true +property :value, String +property :scope, equal_to: %w(local global system), default: 'global', desired_state: false +property :path, String, desired_state: false +property :user, String, desired_state: false +property :group, String, desired_state: false +property :options, String, desired_state: false + +attr_accessor :exists + +require 'mixlib/shellout' + +def initialize(*args) + super + + @run_context.include_recipe 'git' +end + +load_current_value do + cmd_env = user ? { 'USER' => user, 'HOME' => ::Dir.home(user) } : nil + config_vals = Mixlib::ShellOut.new("git config --get --#{scope} #{key}", user: user, group: group, cwd: path, env: cmd_env) + config_vals.run_command + if config_vals.stdout.empty? + value nil + else + value config_vals.stdout.chomp + end +end + +action :set do + converge_if_changed do + execute "#{config_cmd} #{new_resource.key} \"#{new_resource.value}\" #{new_resource.options}".rstrip do + cwd new_resource.path + user new_resource.user + group new_resource.group + environment cmd_env + end + end +end + +action_class.class_eval do + def config_cmd + "git config --#{new_resource.scope}" + end + + def cmd_env + new_resource.user ? { 'USER' => new_resource.user, 'HOME' => ::Dir.home(new_resource.user) } : nil + end +end diff --git a/cookbooks/git/templates/default/git-xinetd.d.erb b/cookbooks/git/templates/default/git-xinetd.d.erb new file mode 100644 index 0000000..3c6bb3b --- /dev/null +++ b/cookbooks/git/templates/default/git-xinetd.d.erb @@ -0,0 +1,10 @@ +service git +{ + disable = no + socket_type = stream + wait = no + user = nobody + server = <%= @git_daemon_binary %> + server_args = --base-path=<%= node["git"]["server"]["base_path"] %> <%= node['git']['server']['export_all'] ? '--export-all' : nil %> --syslog --inetd --verbose + log_on_failure += USERID +} diff --git a/cookbooks/git/templates/default/sv-git-daemon-log-run.erb b/cookbooks/git/templates/default/sv-git-daemon-log-run.erb new file mode 100644 index 0000000..a79a518 --- /dev/null +++ b/cookbooks/git/templates/default/sv-git-daemon-log-run.erb @@ -0,0 +1,2 @@ +#!/bin/sh +exec svlogd -tt ./main diff --git a/cookbooks/git/templates/default/sv-git-daemon-run.erb b/cookbooks/git/templates/default/sv-git-daemon-run.erb new file mode 100644 index 0000000..f340a23 --- /dev/null +++ b/cookbooks/git/templates/default/sv-git-daemon-run.erb @@ -0,0 +1,3 @@ +#!/bin/sh +exec 2>&1 +exec /usr/bin/git daemon <%= node['git']['server']['export_all'] ? '--export-all' : nil %> --user=nobody --group=daemon --syslog --base-path=<%= node["git"]["server"]["base_path"] %> <%= node["git"]["server"]["base_path"] %> diff --git a/cookbooks/mediawiki/recipes/database.rb b/cookbooks/mediawiki/recipes/database.rb index df4a145..382d65c 100644 --- a/cookbooks/mediawiki/recipes/database.rb +++ b/cookbooks/mediawiki/recipes/database.rb @@ -22,6 +22,11 @@ end socket = "/var/run/mysql-#{db['instance_name']}/mysqld.sock" if node['platform_family'] == 'debian' + directory "/var/run/mysqld" do + action :create + owner "mysql" + group "mysql" + end link '/var/run/mysqld/mysqld.sock' do to socket not_if 'test -f /var/run/mysqld/mysqld.sock' diff --git a/cookbooks/mediawiki/recipes/default.rb b/cookbooks/mediawiki/recipes/default.rb index 17e55d4..34e251c 100644 --- a/cookbooks/mediawiki/recipes/default.rb +++ b/cookbooks/mediawiki/recipes/default.rb @@ -10,7 +10,15 @@ include_recipe "apt" include_recipe "php::default" -include_recipe "php::module_apc" + +if node['platform'] == 'ubuntu' and node['platform_version'] >= '16.04' + # APC is now apcu in PHP 7 + include_recipe "php::module_apcu" + # Dependency + package "php7.0-mbstring" +else + include_recipe "php::module_apc" +end include_recipe "php::module_mysql" include_recipe "mediawiki::database" @@ -38,8 +46,11 @@ when "debian" package "libicu-dev" end -php_pear "intl" do - action :install +if platform?('ubuntu') && node[:platform_version].to_f < 16.04 + # bundled with PHP since version 5.3 + php_pear "intl" do + action :install + end end # Configure mediawiki database diff --git a/cookbooks/mediawiki/recipes/nginx.rb b/cookbooks/mediawiki/recipes/nginx.rb index 79561cb..22ff455 100644 --- a/cookbooks/mediawiki/recipes/nginx.rb +++ b/cookbooks/mediawiki/recipes/nginx.rb @@ -7,32 +7,7 @@ node.set_unless['php-fpm']['pools'] = [] include_recipe "php-fpm" include_recipe 'php-fpm::repository' unless node['php-fpm']['skip_repository_install'] - -if node['php-fpm']['package_name'].nil? - if platform_family?("rhel") - php_fpm_package_name = "php-fpm" - else - php_fpm_package_name = "php5-fpm" - end -else - php_fpm_package_name = node['php-fpm']['package_name'] -end - -package php_fpm_package_name do - action :install -end - -if node['php-fpm']['service_name'].nil? - php_fpm_service_name = php_fpm_package_name -else - php_fpm_service_name = node['php-fpm']['service_name'] -end - -service "php-fpm" do - service_name php_fpm_service_name - supports :start => true, :stop => true, :restart => true, :reload => true - action [ :enable, :start ] -end +include_recipe "php-fpm::install" php_fpm_pool "www" do enable false diff --git a/cookbooks/poise-archive/CHANGELOG.md b/cookbooks/poise-archive/CHANGELOG.md new file mode 100644 index 0000000..f95577a --- /dev/null +++ b/cookbooks/poise-archive/CHANGELOG.md @@ -0,0 +1,38 @@ +# Poise-Archive Changelog + +## v1.4.0 + +* Added support for using 7-Zip on Windows. +* Fixed handling of `.tar.xz` archives on RHEL and CentOS. + +## v1.3.0 + +* Add support for unpacking directly from a URL. + +## v1.2.1 + +* [#1](https://github.com/poise/poise-archive/issues/1) Restore file permissions + for ZIP files. + +## v1.2.0 + +* Add back a tar-binary provider called `GnuTar`, used by default on Linux. +* Support for ZIP files via RubyZip. +* Full Windows support, including with the `user` and `group` properties. + +## v1.1.2 + +* Fix compat with older Ruby that doesn't include `Entry#symlink?`. + +## v1.1.1 + +* Fix GNU tar longlink extension. + +## v1.1.0 + +* Scrap the original tar implementation in favor of a 100% pure-Ruby solution. + This should work on all platforms exactly the same. Hopefully. + +## v1.0.0 + +* Initial release! diff --git a/cookbooks/poise-archive/README.md b/cookbooks/poise-archive/README.md new file mode 100644 index 0000000..46893e6 --- /dev/null +++ b/cookbooks/poise-archive/README.md @@ -0,0 +1,103 @@ +# Poise-Archive Cookbook + +[![Build Status](https://img.shields.io/travis/poise/poise-archive.svg)](https://travis-ci.org/poise/poise-archive) +[![Gem Version](https://img.shields.io/gem/v/poise-archive.svg)](https://rubygems.org/gems/poise-archive) +[![Cookbook Version](https://img.shields.io/cookbook/v/poise-archive.svg)](https://supermarket.chef.io/cookbooks/poise-archive) +[![Coverage](https://img.shields.io/codecov/c/github/poise/poise-archive.svg)](https://codecov.io/github/poise/poise-archive) +[![Gemnasium](https://img.shields.io/gemnasium/poise/poise-archive.svg)](https://gemnasium.com/poise/poise-archive) +[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) + +A [Chef](https://www.chef.io/) cookbook to unpack file archives. + +It supports `.tar`, `.tar.gz`, `.tar.bz2`, and `.zip` archive files. + +## Quick Start + +To download an unpack and archive: + +```ruby +poise_archive 'https://example.com/myapp.tgz' do + destination '/opt/myapp' +end +``` + +## Requirements + +Chef 12.1 or newer is required. + +## Platforms + +This cookbook supports all platforms (including Windows) but some Unix platforms +(Solaris, AIX) may see very slow tar file unpacking when using the pure-Ruby fallback +implementation. + +## Resources + +### `poise_archive` + +The `poise_archive` resource unpacks file archives. + +```ruby +poise_archive '/tmp/myapp-1.2.0.tar' do + destination '/srv/myapp-1.2.0' +end +``` + +A URL can also be passed as the source path, optionally with extra properties to +be merged with `source_properties`. + +```ruby +poise_archive 'http://example.com/myapp-1.2.0.zip' do + destination '/srv/myapp-1.2.0' +end + +poise_archive ['http://example.com/myapp-1.2.0.zip', {headers: {'Authentication' => '...'}}] do + destination '/srv/myapp-1.2.0' +end +``` + +#### Actions + +* `:unpack` – Unpack the archive. *(default)* + +#### Properties + +* `path` – Path to the archive. If relative, it is taken as a file inside + `Chef::Config[:file_cache_path]`. If a URL, it is downloaded to a cache file + first. *(name attribute)* +* `destination` – Path to unpack the archive to. If not specified, the path of + the archive without the file extension is used. Required when unpacking from + a URL. *(default: auto)* +* `group` – Group to run the unpack as. +* `keep_existing` – Keep existing files in the destination directory when + unpacking. *(default: false)* +* `source_properties` – Property key/value pairs to be applied to the + `remote_file` file resource when downloading a URL. *(default: {retries: 5})* +* `strip_components` – Number of intermediary directories to skip when + unpacking. Works like GNU tar's `--strip-components`. *(default: 1)* +* `user` – User to run the unpack as. + +## Sponsors + +Development sponsored by [Bloomberg](http://www.bloomberg.com/company/technology/). + +The Poise test server infrastructure is sponsored by [Rackspace](https://rackspace.com/). + +## License + +Copyright 2016-2017, Noah Kantrowitz + +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. + +BZip2 implementation is based on RBzip2. Copyright Sebastian Staudt, Brian Lopez. +RBzip2 code used under the terms of the new BSD license. diff --git a/cookbooks/poise-archive/attributes/default.rb b/cookbooks/poise-archive/attributes/default.rb new file mode 100644 index 0000000..5c92d99 --- /dev/null +++ b/cookbooks/poise-archive/attributes/default.rb @@ -0,0 +1,18 @@ +# +# Copyright 2017, Noah Kantrowitz +# +# 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. +# + +default['poise-archive']['seven_zip']['version'] = '16.04' +default['poise-archive']['seven_zip']['url'] = 'http://www.7-zip.org/a/7z%{version_tag}%{arch_tag}.exe' diff --git a/cookbooks/poise-archive/files/halite_gem/poise_archive.rb b/cookbooks/poise-archive/files/halite_gem/poise_archive.rb new file mode 100644 index 0000000..e796045 --- /dev/null +++ b/cookbooks/poise-archive/files/halite_gem/poise_archive.rb @@ -0,0 +1,21 @@ +# +# Copyright 2016-2017, Noah Kantrowitz +# +# 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 PoiseArchive + autoload :Resources, 'poise_archive/resources' + autoload :VERSION, 'poise_archive/version' +end diff --git a/cookbooks/poise-archive/files/halite_gem/poise_archive/archive_providers.rb b/cookbooks/poise-archive/files/halite_gem/poise_archive/archive_providers.rb new file mode 100644 index 0000000..8d0d29f --- /dev/null +++ b/cookbooks/poise-archive/files/halite_gem/poise_archive/archive_providers.rb @@ -0,0 +1,38 @@ +# +# Copyright 2016-2017, Noah Kantrowitz +# +# 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/platform/provider_priority_map' + +require 'poise_archive/archive_providers/gnu_tar' +require 'poise_archive/archive_providers/seven_zip' +require 'poise_archive/archive_providers/tar' +require 'poise_archive/archive_providers/zip' + + +module PoiseArchive + # Providers for the poise_archive resource. + # + # @since 1.0.0 + module ArchiveProviders + # Set up priority maps + Chef::Platform::ProviderPriorityMap.instance.priority(:poise_archive, [ + PoiseArchive::ArchiveProviders::Zip, + PoiseArchive::ArchiveProviders::GnuTar, + PoiseArchive::ArchiveProviders::SevenZip, + PoiseArchive::ArchiveProviders::Tar, + ]) + end +end diff --git a/cookbooks/poise-archive/files/halite_gem/poise_archive/archive_providers/base.rb b/cookbooks/poise-archive/files/halite_gem/poise_archive/archive_providers/base.rb new file mode 100644 index 0000000..a249e72 --- /dev/null +++ b/cookbooks/poise-archive/files/halite_gem/poise_archive/archive_providers/base.rb @@ -0,0 +1,132 @@ +# +# Copyright 2016-2017, Noah Kantrowitz +# +# 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 'fileutils' + +require 'chef/provider' +require 'poise' + + +module PoiseArchive + module ArchiveProviders + # The provider base class for `poise_archive`. + # + # @see PoiseArchive::Resources::PoiseArchive::Resource + # @provides poise_archive + class Base < Chef::Provider + include Poise + + # Set the file extension this provider will handle. + # + # @param match [RegExp] Regular expression to match against the archive + # file name. + # @return [void] + # @example + # class MyProvider < Base + # provides_extension(/\.hqx$/) + # end + def self.provides_extension(match) + provides(:poise_archive) + @provides_extension = match + end + + # Override normal provider resolution to also check file extension if one + # was specified in the provider. + # + # @api private + def self.provides?(node, resource) + super && (!@provides_extension || @provides_extension.match(resource.path)) + end + + # `unpack` action for `poise_archive`. + # + # @return [void] + def action_unpack + if new_resource.is_url? + download_resource = download_file + # Check if the download resource updated, if not don't run the rest + # of the unpack for idempotence. I could also check + # new_resource.updated? but this seems more future proof. + return if !download_resource.updated_by_last_action? + end + converge_by("unpack archive #{new_resource.path} to #{new_resource.destination}") do + notifying_block do + create_directory + end + empty_directory + unpack_archive + end + end + + private + + # Download the source file to a cache path. + # + # @return [Chef::Resource] + def download_file + # resource_state used for closure breaking on the notifying block. + resource_state = [] + notifying_block do + # TODO handle cookbook:// for cookbook_file "downloads". + resource_state << remote_file(new_resource.absolute_path) do + source new_resource.path + retries 5 # As a default, could be overridden by source_properties. + new_resource.merged_source_properties.each do |key, value| + send(key, value) + end + end + end + # Return the download resource for state tracking. + resource_state.first + end + + # Make sure the destination directory exists. + # + # @return [void] + def create_directory + directory new_resource.destination do + group new_resource.group if new_resource.group + owner new_resource.user if new_resource.user + # There is explicitly no mode being set here. If a non-default mode + # is needed, you should manage that outside of poise_archive. + end + end + + # Remove all existing content from the destination so we can unpack the + # new content. + # + # @return [void] + def empty_directory + # If you want to keep it, not my problem. + return if new_resource.keep_existing + dest = new_resource.destination + Dir.entries(dest).each do |entry| + next if entry == '.' || entry == '..' + FileUtils.remove_entry_secure(::File.join(dest, entry)) + end + end + + # Run the provider-specific unpack behavior. + # + # @abstract + # @return [void] + def unpack_archive + raise NotImplementedError + end + + end + end +end diff --git a/cookbooks/poise-archive/files/halite_gem/poise_archive/archive_providers/gnu_tar.rb b/cookbooks/poise-archive/files/halite_gem/poise_archive/archive_providers/gnu_tar.rb new file mode 100644 index 0000000..196f844 --- /dev/null +++ b/cookbooks/poise-archive/files/halite_gem/poise_archive/archive_providers/gnu_tar.rb @@ -0,0 +1,88 @@ +# +# Copyright 2016-2017, Noah Kantrowitz +# +# 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 'fileutils' +require 'tmpdir' + +require 'poise_archive/archive_providers/base' + + +module PoiseArchive + module ArchiveProviders + # The `gnu_tar` provider class for `poise_archive` to install from TAR + # archives using GNU's tar executable. + # + # @see PoiseArchive::Resources::PoiseArchive::Resource + # @provides poise_archive + class GnuTar < Base + provides_extension(/\.t(ar|gz|bz|xz)/) + + # Only use this if we are on Linux. Everyone else gets the slow Ruby code. + # + # @api private + def self.provides?(node, _resource) + super && node['os'] == 'linux' + end + + private + + def unpack_archive + notifying_block do + install_prereqs + end + unpack_tar + end + + # Install any needed prereqs. + # + # @return [void] + def install_prereqs + utils = ['tar'] + utils << 'bzip2' if new_resource.absolute_path =~ /\.t?bz/ + if new_resource.absolute_path =~ /\.t?xz/ + xz_package = node.value_for_platform_family( + debian: 'xz-utils', + rhel: 'xz', + ) + utils << xz_package if xz_package + end + # This is a resource. + package utils + end + + # Unpack the archive and process `strip_components`. + # + # @return [void] + def unpack_tar + # Build the tar command. + cmd = %w{tar} + cmd << "--strip-components=#{new_resource.strip_components}" if new_resource.strip_components && new_resource.strip_components > 0 + cmd << if new_resource.absolute_path =~ /\.t?gz/ + '-xzvf' + elsif new_resource.absolute_path =~ /\.t?bz/ + '-xjvf' + elsif new_resource.absolute_path =~ /\.t?xz/ + '-xJvf' + else + '-xvf' + end + cmd << new_resource.absolute_path + poise_shell_out!(cmd, cwd: new_resource.destination, group: new_resource.group, user: new_resource.user) + end + + end + end +end diff --git a/cookbooks/poise-archive/files/halite_gem/poise_archive/archive_providers/seven_zip.rb b/cookbooks/poise-archive/files/halite_gem/poise_archive/archive_providers/seven_zip.rb new file mode 100644 index 0000000..59ed852 --- /dev/null +++ b/cookbooks/poise-archive/files/halite_gem/poise_archive/archive_providers/seven_zip.rb @@ -0,0 +1,188 @@ +# +# Copyright 2017, Noah Kantrowitz +# +# 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 'fileutils' +require 'tmpdir' + + +require 'poise_archive/archive_providers/base' + + +module PoiseArchive + module ArchiveProviders + # The `seven_zip` provider class for `poise_archive` to upack archives + # using 7-Zip. + # + # @since 1.4.0 + # @see PoiseArchive::Resources::PoiseArchive::Resource + # @provides poise_archive + class SevenZip < Base + provides_extension(/\.(t(ar|gz|bz|xz)|zip|7z)/) + + # Only works on Windows, because use less silly things elsewhere. + # + # @api private + def self.provides?(node, _resource) + super && node['platform_family'] == 'windows' + end + + private + + def unpack_archive + notifying_block do + install_seven_zip + end + # Create a temp directory to unpack in to. Do I want to try and force + # this to be on the same filesystem as the target? + self.class.mktmpdir do |tmpdir| + unpack_using_seven_zip(tmpdir) + chown_files(tmpdir) if new_resource.user || new_resource.group + move_files(tmpdir) + end + end + + # Install 7-Zip to a cache folder. + # + # @api private + # @return [void] + def install_seven_zip + url = seven_zip_url + path = "#{Chef::Config[:file_cache_path]}/#{url.split(/\//).last}" + + install = execute "#{windows_path(path)} /S /D=#{seven_zip_home}" do + action :nothing + end + + remote_file path do + source url + notifies :run, install, :immediately + end + end + + # Unpack the whole archive to a temp directory. + # + # @api private + # @param tmpdir [String] Temp directory to unpack to. + # @return [void] + def unpack_using_seven_zip(tmpdir) + if new_resource.absolute_path =~ /\.t(ar\.)?(gz|bz(2)?|xz)$/ + # 7-Zip doesn't know to unpack both levels of the archive on its own + # so we need to handle this more explicitly. + shell_out!("#{seven_zip_home}\\7z.exe x -so \"#{windows_path(new_resource.absolute_path)}\" | #{seven_zip_home}\\7z.exe x -si -ttar -o\"#{windows_path(tmpdir)}\"") + else + shell_out!("#{seven_zip_home}\\7z.exe x -o\"#{windows_path(tmpdir)}\" \"#{windows_path(new_resource.absolute_path)}\"") + end + end + + # Fix file ownership if requested. + # + # @api private + # @param tmpdir [String] Temp directory to change ownership in. + # @return [void] + def chown_files(tmpdir) + notifying_block do + Dir["#{tmpdir}/**/*"].each do |path| + declare_resource(::File.directory?(path) ? :directory : :file, path) do + owner new_resource.user if new_resource.user + group new_resource.group if new_resource.group + end + end + end + end + + # Manual implementation of --strip-components since 7-Zip doesn't support + # it internally. + # + # @api private + # @param tmpdir [String] Temp directory to move from. + # @return [void] + def move_files(tmpdir) + entries_at_depth(tmpdir, new_resource.strip_components).each do |source| + target = ::File.join(new_resource.destination, ::File.basename(source)) + # If we are in keep_existing mode, the target might exist already. + # This is not a great solution and won't have exactly the same behavior + # as the other providers, but it's something at least. + FileUtils.rm_rf(target) if ::File.exist?(target) + # At some point this might need to fall back to a real copy. + ::File.rename(source, target) + end + end + + # Compute the URL to download the 7-Zip installer from. + # + # @api private + # @return [String] + def seven_zip_url + node['poise-archive']['seven_zip']['url'] % { + version: node['poise-archive']['seven_zip']['version'], + version_tag: node['poise-archive']['seven_zip']['version'].gsub(/\./, ''), + arch: node['kernel']['machine'], + arch_tag: node['kernel']['machine'] == 'x86_64' ? '-x64' : '', + } + end + + # Path to install 7-Zip in to. + # + # @api private + # @return [String] + def seven_zip_home + "#{windows_path(Chef::Config[:file_cache_path])}\\seven_zip_#{node['poise-archive']['seven_zip']['version']}" + end + + # Flip the slashes in a path because 7z wants "normal" paths. + # + # @api private + # @param path [String] Path to convert. + # @return [String] + def windows_path(path) + path.gsub(/\//, '\\') + end + + # Find the absolute paths for entries under a path at a depth. + # + # @api private + # @param path [String] Base path to search under. + # @param depth [Integer] Number of intermediary directories to skip. + # @return [Array] + def entries_at_depth(path, depth) + entries = [path] + current_depth = 0 + while current_depth <= depth + entries.map! do |ent| + if ::File.directory?(ent) + Dir.entries(ent).select {|e| e != '.' && e != '..' }.map {|e| ::File.join(ent, e) } + else + [] + end + end + entries.flatten! + current_depth += 1 + end + entries + end + + # Indirection so I can stub this for testing without breaking RSpec. + # + # @api private + def self.mktmpdir(*args, &block) + # :nocov: + Dir.mktmpdir(*args, &block) + # :nocov: + end + + end + end +end diff --git a/cookbooks/poise-archive/files/halite_gem/poise_archive/archive_providers/tar.rb b/cookbooks/poise-archive/files/halite_gem/poise_archive/archive_providers/tar.rb new file mode 100644 index 0000000..50c3643 --- /dev/null +++ b/cookbooks/poise-archive/files/halite_gem/poise_archive/archive_providers/tar.rb @@ -0,0 +1,158 @@ +# +# Copyright 2016-2017, Noah Kantrowitz +# +# 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/package' +require 'zlib' + +require 'poise_archive/archive_providers/base' +require 'poise_archive/bzip2' + + +module PoiseArchive + module ArchiveProviders + # The `tar` provider class for `poise_archive` to install from tar archives. + # + # @see PoiseArchive::Resources::PoiseArchive::Resource + # @provides poise_archive + class Tar < Base + provides_extension(/\.t(ar|gz|bz)/) + + # Hack that GNU tar uses for paths over 100 bytes. + # + # @api private + # @see #unpack_tar + TAR_LONGLINK = '././@LongLink' + + private + + def unpack_archive + unpack_tar + chown_entries if new_resource.user || new_resource.group + end + + # Unpack the archive. + # + # @return [void] + def unpack_tar + @tar_entry_paths = [] + tar_each_with_longlink do |entry| + entry_name = entry.full_name.split(/\//).drop(new_resource.strip_components).join('/') + # If strip_components wiped out the name, don't process this entry. + next if entry_name.empty? + dest = ::File.join(new_resource.destination, entry_name) + if entry.directory? + Dir.mkdir(dest, entry.header.mode) + @tar_entry_paths << [:directory, dest] + elsif entry.file? + ::File.open(dest, 'wb', entry.header.mode) do |dest_f| + while buf = entry.read(4096) + dest_f.write(buf) + end + end + @tar_entry_paths << [:file, dest] + elsif entry.header.typeflag == '2' # symlink? is new in Ruby 2.0, apparently. + ::File.symlink(entry.header.linkname, dest) + @tar_entry_paths << [:link, dest] + else + raise RuntimeError.new("Unknown tar entry type #{entry.header.typeflag.inspect} in #{new_resource.path}") + end + end + end + + def tar_each_with_longlink(&block) + entry_name = nil + tar_each do |entry| + if entry.full_name == TAR_LONGLINK + # Stash the longlink name so it will be used for the next entry. + entry_name = entry.read.strip + # And then skip forward because this isn't a real block. + next + end + # For entries not preceded by a longlink block, use the normal name. + entry_name ||= entry.full_name + # Make the entry return the correct name. + entry.define_singleton_method(:full_name) { entry_name } + block.call(entry) + # Reset entry_name for the next entry. + entry_name = nil + end + end + + # Sequence the opening, iteration, and closing. + # + # @param block [Proc] Block to process each tar entry. + # @return [void] + def tar_each(&block) + # In case of extreme weirdness where this happens twice. + close_file! + open_file! + @tar_reader.each(&block) + ensure + close_file! + end + + # Open a file handle of the correct flavor. + # + # @return [void] + def open_file! + @raw_file = ::File.open(new_resource.absolute_path, 'rb') + @file = case new_resource.absolute_path + when /\.tar$/ + nil # So it uses @raw_file instead. + when /\.t?gz/ + Zlib::GzipReader.wrap(@raw_file) + when /\.t?bz/ + # This can't take a block, hence the gross non-block forms for everything. + PoiseArchive::Bzip2::Decompressor.new(@raw_file) + else + raise RuntimeError.new("Unknown or unsupported file extension for #{new_resource.path}") + end + @tar_reader = Gem::Package::TarReader.new(@file || @raw_file) + end + + # Close all the various file handles. + # + # @return [void] + def close_file! + if @tar_reader + @tar_reader.close + @tar_reader = nil + end + if @file + @file.close + @file = nil + end + if @raw_file + @raw_file.close unless @raw_file.closed? + @raw_file = nil + end + end + + def chown_entries + paths = @tar_entry_paths + notifying_block do + paths.each do |type, path| + send(type, path) do + group new_resource.group + owner new_resource.user + end + end + end + end + + end + end +end diff --git a/cookbooks/poise-archive/files/halite_gem/poise_archive/archive_providers/zip.rb b/cookbooks/poise-archive/files/halite_gem/poise_archive/archive_providers/zip.rb new file mode 100644 index 0000000..2dba06d --- /dev/null +++ b/cookbooks/poise-archive/files/halite_gem/poise_archive/archive_providers/zip.rb @@ -0,0 +1,97 @@ +# +# Copyright 2016-2017, Noah Kantrowitz +# +# 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 'poise_archive/archive_providers/base' + + +module PoiseArchive + module ArchiveProviders + # The `zip` provider class for `poise_archive` to install from ZIP archives. + # + # @see PoiseArchive::Resources::PoiseArchive::Resource + # @provides poise_archive + class Zip < Base + provides_extension(/\.zip$/) + + private + + def unpack_archive + check_rubyzip + unpack_zip + chown_entries if new_resource.user || new_resource.group + end + + def check_rubyzip + require 'zip' + rescue LoadError + notifying_block do + install_rubyzip + end + require 'zip' + end + + def install_rubyzip + chef_gem 'rubyzip' + end + + def unpack_zip + @zip_entry_paths = [] + ::Zip::File.open(new_resource.absolute_path) do |zip_file| + zip_file.each do |entry| + entry_name = entry.name.split(/\//).drop(new_resource.strip_components).join('/') + # If strip_components wiped out the name, don't process this entry. + next if entry_name.empty? + entry_path = ::File.join(new_resource.destination, entry_name) + # Ensure parent directories exist because some ZIP files don't + # include those for some reason. + ensure_directory(entry_path) + entry.extract(entry_path) + # Make sure we restore file permissions. RubyZip won't do this + # unless we also turn on UID/GID restoration, which we don't want. + # Mask filters out setuid and setgid bits because no. + ::File.chmod(entry.unix_perms & 01777, entry_path) if !node.platform_family?('windows') && entry.unix_perms + @zip_entry_paths << [entry.directory? ? :directory : entry.file? ? :file : :link, entry_path] + end + end + end + + # Make sure all enclosing directories exist before writing a path. + # + # @param oath [String] Path to check. + def ensure_directory(path) + base = ::File.dirname(path) + unless ::File.exist?(base) + ensure_directory(base) + Dir.mkdir(base) + @zip_entry_paths << [:directory, base] + end + end + + def chown_entries + paths = @zip_entry_paths + notifying_block do + paths.each do |type, path| + send(type, path) do + group new_resource.group + owner new_resource.user + end + end + end + end + + end + end +end diff --git a/cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2.rb b/cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2.rb new file mode 100644 index 0000000..4e1ecfc --- /dev/null +++ b/cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2.rb @@ -0,0 +1,16 @@ +# This code is free software; you can redistribute it and/or modify it under +# the terms of the new BSD License. +# +# Copyright (c) 2013, Sebastian Staudt + + +module PoiseArchive::Bzip2 + + autoload :CRC, 'poise_archive/bzip2/crc' + autoload :Constants, 'poise_archive/bzip2/constants' + autoload :Decompressor, 'poise_archive/bzip2/decompressor' + autoload :IO, 'poise_archive/bzip2/io' + autoload :InputData, 'poise_archive/bzip2/input_data' + autoload :OutputData, 'poise_archive/bzip2/output_data' + +end diff --git a/cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/LICENSE b/cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/LICENSE new file mode 100644 index 0000000..ba9a1a4 --- /dev/null +++ b/cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/LICENSE @@ -0,0 +1,25 @@ +Copyright (c) 2011, Sebastian Staudt +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 the author 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" AND +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 OWNER 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. diff --git a/cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/constants.rb b/cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/constants.rb new file mode 100644 index 0000000..102c620 --- /dev/null +++ b/cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/constants.rb @@ -0,0 +1,83 @@ +# This code is free software; you can redistribute it and/or modify it under +# the terms of the new BSD License. +# +# Copyright (c) 2011-2013, Sebastian Staudt + + +module PoiseArchive::Bzip2::Constants + + BASEBLOCKSIZE = 100000 + MAX_ALPHA_SIZE = 258 + MAX_CODE_LEN = 23 + RUNA = 0 + RUNB = 1 + N_GROUPS = 6 + G_SIZE = 50 + N_ITERS = 4 + MAX_SELECTORS = (2 + (900000 / G_SIZE)) + NUM_OVERSHOOT_BYTES = 20 + + EOF = 0 + START_BLOCK_STATE = 1 + RAND_PART_A_STATE = 2 + RAND_PART_B_STATE = 3 + RAND_PART_C_STATE = 4 + NO_RAND_PART_A_STATE = 5 + NO_RAND_PART_B_STATE = 6 + NO_RAND_PART_C_STATE = 7 + + RNUMS = [ + 619, 720, 127, 481, 931, 816, 813, 233, 566, 247, 985, 724, 205, 454, 863, + 491, 741, 242, 949, 214, 733, 859, 335, 708, 621, 574, 73, 654, 730, 472, + 419, 436, 278, 496, 867, 210, 399, 680, 480, 51, 878, 465, 811, 169, 869, + 675, 611, 697, 867, 561, 862, 687, 507, 283, 482, 129, 807, 591, 733, 623, + 150, 238, 59, 379, 684, 877, 625, 169, 643, 105, 170, 607, 520, 932, 727, + 476, 693, 425, 174, 647, 73, 122, 335, 530, 442, 853, 695, 249, 445, 515, + 909, 545, 703, 919, 874, 474, 882, 500, 594, 612, 641, 801, 220, 162, 819, + 984, 589, 513, 495, 799, 161, 604, 958, 533, 221, 400, 386, 867, 600, 782, + 382, 596, 414, 171, 516, 375, 682, 485, 911, 276, 98, 553, 163, 354, 666, + 933, 424, 341, 533, 870, 227, 730, 475, 186, 263, 647, 537, 686, 600, 224, + 469, 68, 770, 919, 190, 373, 294, 822, 808, 206, 184, 943, 795, 384, 383, + 461, 404, 758, 839, 887, 715, 67, 618, 276, 204, 918, 873, 777, 604, 560, + 951, 160, 578, 722, 79, 804, 96, 409, 713, 940, 652, 934, 970, 447, 318, + 353, 859, 672, 112, 785, 645, 863, 803, 350, 139, 93, 354, 99, 820, 908, + 609, 772, 154, 274, 580, 184, 79, 626, 630, 742, 653, 282, 762, 623, 680, + 81, 927, 626, 789, 125, 411, 521, 938, 300, 821, 78, 343, 175, 128, 250, + 170, 774, 972, 275, 999, 639, 495, 78, 352, 126, 857, 956, 358, 619, 580, + 124, 737, 594, 701, 612, 669, 112, 134, 694, 363, 992, 809, 743, 168, 974, + 944, 375, 748, 52, 600, 747, 642, 182, 862, 81, 344, 805, 988, 739, 511, + 655, 814, 334, 249, 515, 897, 955, 664, 981, 649, 113, 974, 459, 893, 228, + 433, 837, 553, 268, 926, 240, 102, 654, 459, 51, 686, 754, 806, 760, 493, + 403, 415, 394, 687, 700, 946, 670, 656, 610, 738, 392, 760, 799, 887, 653, + 978, 321, 576, 617, 626, 502, 894, 679, 243, 440, 680, 879, 194, 572, 640, + 724, 926, 56, 204, 700, 707, 151, 457, 449, 797, 195, 791, 558, 945, 679, + 297, 59, 87, 824, 713, 663, 412, 693, 342, 606, 134, 108, 571, 364, 631, + 212, 174, 643, 304, 329, 343, 97, 430, 751, 497, 314, 983, 374, 822, 928, + 140, 206, 73, 263, 980, 736, 876, 478, 430, 305, 170, 514, 364, 692, 829, + 82, 855, 953, 676, 246, 369, 970, 294, 750, 807, 827, 150, 790, 288, 923, + 804, 378, 215, 828, 592, 281, 565, 555, 710, 82, 896, 831, 547, 261, 524, + 462, 293, 465, 502, 56, 661, 821, 976, 991, 658, 869, 905, 758, 745, 193, + 768, 550, 608, 933, 378, 286, 215, 979, 792, 961, 61, 688, 793, 644, 986, + 403, 106, 366, 905, 644, 372, 567, 466, 434, 645, 210, 389, 550, 919, 135, + 780, 773, 635, 389, 707, 100, 626, 958, 165, 504, 920, 176, 193, 713, 857, + 265, 203, 50, 668, 108, 645, 990, 626, 197, 510, 357, 358, 850, 858, 364, + 936, 638 + ] + + MIN_BLOCK_SIZE = 1 + MAX_BLOCK_SIZE = 9 + SETMASK = (1 << 21) + CLEARMASK = (~SETMASK) + GREATER_ICOST = 15 + LESSER_ICOST = 0 + SMALL_THRESH = 20 + DEPTH_THRESH = 10 + WORK_FACTOR = 30 + QSORT_STACK_SIZE = 1000 + + INCS = [ + 1, 4, 13, 40, 121, 364, 1093, 3280, 9841, 29524, 88573, 265720, 797161, + 2391484 + ] + +end diff --git a/cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/crc.rb b/cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/crc.rb new file mode 100644 index 0000000..c09f71d --- /dev/null +++ b/cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/crc.rb @@ -0,0 +1,73 @@ +# This code is free software; you can redistribute it and/or modify it under +# the terms of the new BSD License. +# +# Copyright (c) 2011-2013, Sebastian Staudt + + +class PoiseArchive::Bzip2::CRC + + CRC32_TABLE = [ + 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, + 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, + 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7, + 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, + 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, + 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, + 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef, + 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, + 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, + 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, + 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, + 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, + 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, + 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, + 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, + 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, + 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, + 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, + 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050, + 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, + 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, + 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, + 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1, + 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, + 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, + 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, + 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9, + 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, + 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, + 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, + 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, + 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, + 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, + 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, + 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, + 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, + 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, + 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, + 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676, + 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, + 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, + 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, + 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 + ] + + attr_accessor :global_crc + + def initialize + initialize_crc + end + + def initialize_crc + @global_crc = 0xffffffff + end + + def final_crc + @global_crc ^ 0xffffffff + end + + def update_crc(in_ch) + @global_crc = ((@global_crc << 8) & 0xffffffff) ^ CRC32_TABLE[(@global_crc >> 24) ^ in_ch] + end + +end diff --git a/cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/decompressor.rb b/cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/decompressor.rb new file mode 100644 index 0000000..201fa3e --- /dev/null +++ b/cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/decompressor.rb @@ -0,0 +1,704 @@ +# This code is free software; you can redistribute it and/or modify it under +# the terms of the new BSD License. +# +# Copyright (c) 2011-2013, Sebastian Staudt + + +class PoiseArchive::Bzip2::Decompressor + + include PoiseArchive::Bzip2::Constants + + def initialize(io) + @buff = 0 + @bytes_read = 0 + @computed_combined_crc = 0 + @crc = PoiseArchive::Bzip2::CRC.new + @current_char = -1 + @io = io + @live = 0 + @stored_combined_crc = 0 + @su_t_pos = 0 + init + end + + def count(read) + @bytes_read += read if read != -1 + end + + # ADDED METHODS + def pos + @bytes_read + end + + def eof? + @current_state == EOF + end + # /ADDED METHODS + + def read(length = nil) + raise 'stream closed' if @io.nil? + + if length == 1 + r = read0 + count (r < 0 ? -1 : 1) + r + else + r = '' + if length == nil + while true do + b = read0 + break if b < 0 + r << b.chr + end + count r.size # ADDED LINE + elsif length > 0 + length.times do + b = read0 + break if b < 0 + r << b.chr + end + count r.size + end + r + end + end + + def read0 + ret_char = @current_char + + if @current_state == RAND_PART_B_STATE + setup_rand_part_b + elsif @current_state == NO_RAND_PART_B_STATE + setup_no_rand_part_b + elsif @current_state == RAND_PART_C_STATE + setup_rand_part_c + elsif @current_state == NO_RAND_PART_C_STATE + setup_no_rand_part_c + elsif @current_state == EOF + return -1 + else + raise 'illegal state' + end + + ret_char + end + + def make_maps + in_use = @data.in_use + seq_to_unseq = @data.seq_to_unseq + + n_in_use_shadow = 0 + + 256.times do |i| + if in_use[i] + seq_to_unseq[n_in_use_shadow] = i + n_in_use_shadow += 1 + end + end + + @n_in_use = n_in_use_shadow + end + + def init + check_magic + + block_size = @io.read(1).to_i + raise 'Illegal block size.' if block_size < 1 || block_size > 9 + @block_size = block_size + + init_block + setup_block + end + + def check_magic + raise 'Magic number does not match "BZh".' unless @io.read(3) == 'BZh' + end + + def init_block + magic = [ubyte, ubyte, ubyte, ubyte, ubyte, ubyte] + + if magic == [0x17, 0x72, 0x45, 0x38, 0x50, 0x90] + complete + elsif magic != [0x31, 0x41, 0x59, 0x26, 0x53, 0x59] + @current_state = EOF + + raise 'Bad block header.' + else + @stored_block_crc = int + @block_randomised = bit + + @data = PoiseArchive::Bzip2::InputData.new @block_size if @data.nil? + + get_and_move_to_front_decode + + @crc.initialize_crc + @current_state = START_BLOCK_STATE + end + end + + def end_block + @computed_block_crc = @crc.final_crc + + if @stored_block_crc != @computed_block_crc + @computed_combined_crc = (@stored_combined_crc << 1) | (@stored_combined_crc >> 31) + @computed_combined_crc ^= @stored_block_crc + + raise 'BZip2 CRC error' + end + + @computed_combined_crc = (@computed_combined_crc << 1) | (@computed_combined_crc >> 31) + @computed_combined_crc ^= @computed_block_crc + end + + def complete + @stored_combined_crc = int + @current_state = EOF + @data = nil + + raise 'BZip2 CRC error' if @stored_combined_crc != @computed_combined_crc + end + + def close + if @io != $stdin + @io = nil + @data = nil + end + end + + def r(n) + live_shadow = @live + buff_shadow = @buff + + if live_shadow < n + begin + thech = @io.readbyte + + raise 'unexpected end of stream' if thech < 0 + + buff_shadow = (buff_shadow << 8) | thech + live_shadow += 8 + end while live_shadow < n + + @buff = buff_shadow + end + + @live = live_shadow - n + + (buff_shadow >> (live_shadow - n)) & ((1 << n) - 1) + end + + def bit + r(1) != 0 + end + + def ubyte + r 8 + end + + def int + (((((r(8) << 8) | r(8)) << 8) | r(8)) << 8) | r(8) + end + + def create_decode_tables(limit, base, perm, length, min_len, max_len, alpha_size) + pp = 0 + (min_len..max_len).each do |i| + alpha_size.times do |j| + if length[j] == i + perm[pp] = j + pp += 1 + end + end + end + + MAX_CODE_LEN.downto 1 do |i| + base[i] = 0 + limit[i] = 0 + end + + alpha_size.times do |i| + base[length[i] + 1] += 1 + end + + b = 0 + 1.upto(MAX_CODE_LEN - 1) do |i| + b += base[i] + base[i] = b + end + + vec = 0 + min_len.upto(max_len) do |i| + b = base[i] + nb = base[i + 1] + vec += nb - b + b = nb + limit[i] = vec - 1 + vec = vec << 1 + end + + (min_len + 1).upto(max_len) do |i| + base[i] = ((limit[i - 1] + 1) << 1) - base[i] + end + end + + def receive_decoding_tables + in_use = @data.in_use + pos = @data.receive_decoding_tables_pos + selector = @data.selector + selector_mtf = @data.selector_mtf + + in_use16 = 0 + + 16.times do |i| + in_use16 |= 1 << i if bit + end + + 255.downto(0) do |i| + in_use[i] = false + end + + 16.times do |i| + if (in_use16 & (1 << i)) != 0 + i16 = i << 4 + 16.times do |j| + in_use[i16 + j] = true if bit + end + end + end + + make_maps + alpha_size = @n_in_use + 2 + + groups = r 3 + selectors = r 15 + + selectors.times do |i| + j = 0 + while bit + j += 1 + end + selector_mtf[i] = j + end + + groups.downto(0) do |v| + pos[v] = v + end + + selectors.times do |i| + v = selector_mtf[i] & 0xff + tmp = pos[v] + + while v > 0 do + pos[v] = pos[v -= 1] + end + + pos[0] = tmp + selector[i] = tmp + end + + len = @data.temp_char_array_2d + + groups.times do |t| + curr = r 5 + len_t = len[t] + alpha_size.times do |i| + while bit + curr += bit ? -1 : 1 + end + len_t[i] = curr + end + @data.temp_char_array_2d[t] = len_t + end + + create_huffman_decoding_tables alpha_size, groups + end + + def create_huffman_decoding_tables(alpha_size, groups) + len = @data.temp_char_array_2d + min_lens = @data.min_lens + limit = @data.limit + base = @data.base + perm = @data.perm + + groups.times do |t| + min_len = 32 + max_len = 0 + len_t = len[t] + + (alpha_size - 1).downto 0 do |i| + lent = len_t[i] + max_len = lent if lent > max_len + min_len = lent if lent < min_len + end + + create_decode_tables limit[t], base[t], perm[t], len[t], min_len, max_len, alpha_size + min_lens[t] = min_len + end + end + + def get_and_move_to_front_decode + @orig_ptr = r 24 + receive_decoding_tables + + ll8 = @data.ll8 + unzftab = @data.unzftab + selector = @data.selector + seq_to_unseq = @data.seq_to_unseq + yy = @data.get_and_move_to_front_decode_yy + min_lens = @data.min_lens + limit = @data.limit + base = @data.base + perm = @data.perm + limit_last = @block_size * BASEBLOCKSIZE + + 256.downto(0) do |i| + yy[i] = i + unzftab[i] = 0 + end + + group_no = 0 + group_pos = G_SIZE - 1 + eob = @n_in_use + 1 + next_sym = get_and_move_to_front_decode0 0 + buff_shadow = @buff + live_shadow = @live + last_shadow = -1 + zt = selector[group_no] & 0xff + base_zt = base[zt] + limit_zt = limit[zt] + perm_zt = perm[zt] + min_lens_zt = min_lens[zt] + + while next_sym != eob + if (next_sym == RUNA) || (next_sym == RUNB) + s = -1 + + n = 1 + while true do + if next_sym == RUNA + s += n + elsif next_sym == RUNB + s += n << 1 + else + break + end + + if group_pos == 0 + group_pos = G_SIZE - 1 + group_no += 1 + zt = selector[group_no] & 0xff + base_zt = base[zt] + limit_zt = limit[zt] + perm_zt = perm[zt] + min_lens_zt = min_lens[zt] + else + group_pos -= 1 + end + + zn = min_lens_zt + + while live_shadow < zn + thech = @io.readbyte + + raise 'unexpected end of stream' if thech < 0 + + buff_shadow = ((buff_shadow << 8) & 0xffffffff) | thech + live_shadow += 8 + end + + zvec = ((buff_shadow >> (live_shadow - zn)) & 0xffffffff) & ((1 << zn) - 1) + live_shadow -= zn + + while zvec > limit_zt[zn] + zn += 1 + + while live_shadow < 1 + thech = @io.readbyte + + raise 'unexpected end of stream' if thech < 0 + + buff_shadow = ((buff_shadow << 8) & 0xffffffff) | thech + live_shadow += 8 + end + + live_shadow -= 1 + zvec = (zvec << 1) | ((buff_shadow >> live_shadow) & 1) + end + + next_sym = perm_zt[zvec - base_zt[zn]] + + n = n << 1 + end + + ch = seq_to_unseq[yy[0]] + unzftab[ch & 0xff] += s + 1 + + while s >= 0 + last_shadow += 1 + ll8[last_shadow] = ch + s -= 1 + end + + raise 'block overrun' if last_shadow >= limit_last + else + last_shadow += 1 + raise 'block overrun' if last_shadow >= limit_last + + tmp = yy[next_sym - 1] + unzftab[seq_to_unseq[tmp] & 0xff] += 1 + ll8[last_shadow] = seq_to_unseq[tmp] + + yy[1, next_sym - 1] = yy[0, next_sym - 1] + yy[0] = tmp + + if group_pos == 0 + group_pos = G_SIZE - 1 + group_no += 1 + zt = selector[group_no] & 0xff + base_zt = base[zt] + limit_zt = limit[zt] + perm_zt = perm[zt] + min_lens_zt = min_lens[zt] + else + group_pos -= 1 + end + + zn = min_lens_zt + + while live_shadow < zn + thech = @io.readbyte + + raise 'unexpected end of stream' if thech < 0 + + buff_shadow = ((buff_shadow << 8) & 0xffffffff) | thech + live_shadow += 8 + end + zvec = (buff_shadow >> (live_shadow - zn)) & ((1 << zn) - 1) + live_shadow -= zn + + while zvec > limit_zt[zn] + zn += 1 + while live_shadow < 1 + thech = @io.readbyte + + raise 'unexpected end of stream' if thech < 0 + + buff_shadow = ((buff_shadow << 8) & 0xffffffff) | thech + live_shadow += 8 + end + live_shadow -= 1 + zvec = (zvec << 1) | ((buff_shadow >> live_shadow) & 1) + end + + next_sym = perm_zt[zvec - base_zt[zn]] + end + end + + @last = last_shadow + @live = live_shadow + @buff = buff_shadow + end + + def get_and_move_to_front_decode0(group_no) + zt = @data.selector[group_no] & 0xff + limit_zt = @data.limit[zt] + zn = @data.min_lens[zt] + zvec = r zn + live_shadow = @live + buff_shadow = @buff + + while zvec > limit_zt[zn] + zn += 1 + + while live_shadow < 1 + thech = @io.readbyte + + raise 'unexpected end of stream' if thech < 0 + + buff_shadow = ((buff_shadow << 8) & 0xffffffff) | thech + live_shadow += 8 + end + + live_shadow -=1 + zvec = (zvec << 1) | ((buff_shadow >> live_shadow) & 1) + end + + @live = live_shadow + @buff = buff_shadow + + @data.perm[zt][zvec - @data.base[zt][zn]] + end + + def setup_block + return if @data.nil? + + cftab = @data.cftab + tt = @data.init_tt @last + 1 + ll8 = @data.ll8 + cftab[0] = 0 + cftab[1, 256] = @data.unzftab[0, 256] + + c = cftab[0] + 1.upto(256) do |i| + c += cftab[i] + cftab[i] = c + end + + last_shadow = @last + (last_shadow + 1).times do |i| + cftab_i = ll8[i] & 0xff + tt[cftab[cftab_i]] = i + cftab[cftab_i] += 1 + end + + raise 'stream corrupted' if @orig_ptr < 0 || @orig_ptr >= tt.size + + @su_t_pos = tt[@orig_ptr] + @su_count = 0 + @su_i2 = 0 + @su_ch2 = 256 + + if @block_randomised + @su_r_n_to_go = 0 + @su_r_t_pos = 0 + + setup_rand_part_a + else + setup_no_rand_part_a + end + end + + def setup_rand_part_a + if @su_i2 <= @last + @su_ch_prev = @su_ch2 + su_ch2_shadow = @data.ll8[@su_t_pos] & 0xff + @su_t_pos = @data.tt[@su_t_pos] + + if @su_r_n_to_go == 0 + @su_r_n_to_go = RNUMS[@su_r_t_pos] - 1 + @su_r_t_pos += 1 + @su_r_t_pos = 0 if @su_r_t_pos == 512 + else + @su_r_n_to_go -= 1 + end + + @su_ch2 = su_ch2_shadow ^= (@su_r_n_to_go == 1) ? 1 : 0 + @su_i2 += 1 + @current_char = su_ch2_shadow + @current_state = RAND_PART_B_STATE + @crc.update_crc su_ch2_shadow + else + end_block + init_block + setup_block + end + end + + def setup_no_rand_part_a + if @su_i2 <= @last + @su_ch_prev = @su_ch2 + su_ch2_shadow = @data.ll8[@su_t_pos] & 0xff + @su_ch2 = su_ch2_shadow + @su_t_pos = @data.tt[@su_t_pos] + @su_i2 += 1 + @current_char = su_ch2_shadow + @current_state = NO_RAND_PART_B_STATE + @crc.update_crc su_ch2_shadow + else + @current_state = NO_RAND_PART_A_STATE + end_block + init_block + setup_block + end + end + + def setup_rand_part_b + if @su_ch2 != @su_ch_prev + @current_state = RAND_PART_A_STATE + @su_count = 1 + setup_rand_part_a + else + @su_count += 1 + if @su_count >= 4 + @su_z = @data.ll8[@su_t_pos] & 0xff + @su_t_pos = @data.tt[@su_t_pos] + + if @su_r_n_to_go == 0 + @su_r_n_to_go = RNUMS[@su_r_t_pos] - 1 + @su_r_t_pos += 1 + @su_r_t_pos = 0 if @su_r_t_pos == 512 + else + @su_r_n_to_go -= 1 + end + + @su_j2 = 0 + @current_state = RAND_PART_C_STATE + @su_z ^= 1 if @su_r_n_to_go == 1 + setup_rand_part_c + else + @current_state = RAND_PART_A_STATE + setup_rand_part_a + end + end + end + + def setup_rand_part_c + if @su_j2 < @su_z + @current_char = @su_ch2 + @crc.update_crc @su_ch2 + @su_j2 += 1 + else + @current_state = RAND_PART_A_STATE + @su_i2 += 1 + @su_count = 0 + setup_rand_part_a + end + end + + def setup_no_rand_part_b + if @su_ch2 != @su_ch_prev + @su_count = 1 + setup_no_rand_part_a + else + @su_count += 1 + if @su_count >= 4 + @su_z = @data.ll8[@su_t_pos] & 0xff + @su_t_pos = @data.tt[@su_t_pos] + @su_j2 = 0 + setup_no_rand_part_c + else + setup_no_rand_part_a + end + end + end + + def setup_no_rand_part_c + if @su_j2 < @su_z + su_ch2_shadow = @su_ch2 + @current_char = su_ch2_shadow + @crc.update_crc su_ch2_shadow + @su_j2 += 1 + @current_state = NO_RAND_PART_C_STATE + else + @su_i2 += 1 + @su_count = 0 + setup_no_rand_part_a + end + end + + def size + if @io.is_a? StringIO + @io.size + elsif @io.is_a? File + @io.stat.size + end + end + + def uncompressed + @last + 1 + end + + def inspect + "#<#{self.class}: @io=#{@io.inspect} size=#{size} uncompressed=#{uncompressed}>" + end + +end diff --git a/cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/input_data.rb b/cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/input_data.rb new file mode 100644 index 0000000..a3ef7d2 --- /dev/null +++ b/cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/input_data.rb @@ -0,0 +1,43 @@ +# This code is free software; you can redistribute it and/or modify it under +# the terms of the new BSD License. +# +# Copyright (c) 2011-2013, Sebastian Staudt + + +class PoiseArchive::Bzip2::InputData + + include PoiseArchive::Bzip2::Constants + + attr_reader :base, :cftab, :get_and_move_to_front_decode_yy, :in_use, + :limit, :ll8, :min_lens, :perm, :receive_decoding_tables_pos, + :selector, :selector_mtf, :seq_to_unseq, :temp_char_array_2d, + :unzftab, :tt + + def initialize(block_size) + @in_use = Array.new 256, false + + @seq_to_unseq = Array.new 256, 0 + @selector = Array.new MAX_SELECTORS, 0 + @selector_mtf = Array.new MAX_SELECTORS, 0 + + @unzftab = Array.new 256, 0 + + @base = Array.new(N_GROUPS) { Array.new(MAX_ALPHA_SIZE, 0) } + @limit = Array.new(N_GROUPS) { Array.new(MAX_ALPHA_SIZE, 0) } + @perm = Array.new(N_GROUPS) { Array.new(MAX_ALPHA_SIZE, 0) } + @min_lens = Array.new N_GROUPS, 0 + + @cftab = Array.new 257, 0 + @get_and_move_to_front_decode_yy = Array.new 256 + @temp_char_array_2d = Array.new(N_GROUPS) { Array.new(MAX_ALPHA_SIZE, 0) } + @receive_decoding_tables_pos = Array.new N_GROUPS, 0 + + @ll8 = Array.new block_size * BASEBLOCKSIZE + end + + def init_tt(size) + @tt = Array.new(size) if @tt.nil? || @tt.size < size + @tt + end + +end diff --git a/cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/output_data.rb b/cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/output_data.rb new file mode 100644 index 0000000..20f890f --- /dev/null +++ b/cookbooks/poise-archive/files/halite_gem/poise_archive/bzip2/output_data.rb @@ -0,0 +1,57 @@ +# This code is free software; you can redistribute it and/or modify it under +# the terms of the new BSD License. +# +# Copyright (c) 2011-2013, Sebastian Staudt + + +class PoiseArchive::Bzip2::OutputData + + include PoiseArchive::Bzip2::Constants + + attr_reader :block, :ftab, :fmap, :generate_mtf_values_yy, :heap, :in_use, + :main_sort_big_done, :main_sort_copy, :main_sort_running_order, + :mtf_freq, :parent, :quadrant, :selector, :selector_mtf, + :send_mtf_values_code, :send_mtf_values_cost, + :send_mtf_values_fave, :send_mtf_values_len, + :send_mtf_values_rfreq, :send_mtf_values2_pos, + :send_mtf_values4_in_use_16, :sfmap, :stack_dd, :stack_hh, + :stack_ll, :unseq_to_seq, :weight + + def initialize(block_size) + n = block_size * BASEBLOCKSIZE + @block = Array.new n + 1 + NUM_OVERSHOOT_BYTES, 0 + @fmap = Array.new n, 0 + @selector = Array.new MAX_SELECTORS + @selector_mtf = Array.new MAX_SELECTORS + @sfmap = Array.new 2 * n + @quadrant = @sfmap + + @in_use = Array.new 256 + @mtf_freq = Array.new MAX_ALPHA_SIZE, 0 + @unseq_to_seq = Array.new 256 + + @generate_mtf_values_yy = Array.new 256 + @send_mtf_values_code = Array.new(N_GROUPS) { Array.new MAX_ALPHA_SIZE } + @send_mtf_values_cost = Array.new N_GROUPS + @send_mtf_values_fave = Array.new N_GROUPS + @send_mtf_values_len = Array.new(N_GROUPS) { Array.new MAX_ALPHA_SIZE } + @send_mtf_values_rfreq = Array.new(N_GROUPS) { Array.new MAX_ALPHA_SIZE } + @send_mtf_values2_pos = Array.new N_GROUPS + @send_mtf_values4_in_use_16 = Array.new 16 + + @stack_dd = Array.new QSORT_STACK_SIZE + @stack_hh = Array.new QSORT_STACK_SIZE + @stack_ll = Array.new QSORT_STACK_SIZE + + @main_sort_big_done = Array.new 256 + @main_sort_copy = Array.new 256 + @main_sort_running_order = Array.new 256 + + @heap = Array.new MAX_ALPHA_SIZE + 2 + @parent = Array.new MAX_ALPHA_SIZE + 2 + @weight = Array.new MAX_ALPHA_SIZE + 2 + + @ftab = Array.new 65537 + end + +end diff --git a/cookbooks/poise-archive/files/halite_gem/poise_archive/cheftie.rb b/cookbooks/poise-archive/files/halite_gem/poise_archive/cheftie.rb new file mode 100644 index 0000000..cb3be2d --- /dev/null +++ b/cookbooks/poise-archive/files/halite_gem/poise_archive/cheftie.rb @@ -0,0 +1,18 @@ +# +# Copyright 2016-2017, Noah Kantrowitz +# +# 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 'poise_archive/resources' +require 'poise_archive/archive_providers' diff --git a/cookbooks/poise-archive/files/halite_gem/poise_archive/resources.rb b/cookbooks/poise-archive/files/halite_gem/poise_archive/resources.rb new file mode 100644 index 0000000..d9ebb4a --- /dev/null +++ b/cookbooks/poise-archive/files/halite_gem/poise_archive/resources.rb @@ -0,0 +1,26 @@ +# +# Copyright 2016-2017, Noah Kantrowitz +# +# 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 'poise_archive/resources/poise_archive' + + +module PoiseArchive + # Chef resources and providers for poise-archive. + # + # @since 1.0.0 + module Resources + end +end diff --git a/cookbooks/poise-archive/files/halite_gem/poise_archive/resources/poise_archive.rb b/cookbooks/poise-archive/files/halite_gem/poise_archive/resources/poise_archive.rb new file mode 100644 index 0000000..7186d6c --- /dev/null +++ b/cookbooks/poise-archive/files/halite_gem/poise_archive/resources/poise_archive.rb @@ -0,0 +1,151 @@ +# +# Copyright 2016-2017, Noah Kantrowitz +# +# 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 'base64' +require 'uri' + +require 'chef/resource' +require 'poise' + + +module PoiseArchive + module Resources + # (see PoiseArchive::Resource) + # @since 1.0.0 + module PoiseArchive + # A `poise_archive` resource to unpack archives. + # + # @provides poise_archive + # @action unpack + # @example + # poise_archive '/opt/myapp.tgz' + # @example Downloading from a URL with options + # poise_archive ['http://example.com/myapp.zip', {headers: {'Authentication' => '...'}}] do + # destination '/opt/myapp' + # end + class Resource < Chef::Resource + include Poise + provides(:poise_archive) + actions(:unpack) + + # @!attribute path + # Path to the archive. If relative, it is taken as a file inside + # `Chef::Config[:file_cache_path]`. Can also be a URL to download the + # archive from. + # @return [String, Array] + attribute(:path, kind_of: String, default: lazy { @raw_name.is_a?(Array) ? @raw_name[0] : name }, required: true) + # @!attribute destination + # Path to unpack the archive to. If not specified, the path of the + # archive without the file extension is used. + # @return [String, nil, false] + attribute(:destination, kind_of: [String, NilClass, FalseClass], default: lazy { default_destination }) + # @!attribute group + # Group to run the unpack as. + # @return [String, Integer, nil, false] + attribute(:group, kind_of: [String, Integer, NilClass, FalseClass]) + # @!attribute keep_existing + # Keep existing files in the destination directory when unpacking. + # @return [Boolean] + attribute(:keep_existing, equal_to: [true, false], default: false) + # @!attribute source_properties + # Properties to pass through to the underlying download resource if + # using one. Merged with the array form of {#name}. + # @return [Hash] + attribute(:source_properties, option_collector: true, forced_keys: %i{retries}) + # @!attribute strip_components + # Number of intermediary directories to skip when unpacking. Works + # like GNU tar's --strip-components. + # @return [Integer] + attribute(:strip_components, kind_of: Integer, default: 1) + # @!attribute user + # User to run the unpack as. + # @return [String, Integer, nil, false] + attribute(:user, kind_of: [String, Integer, NilClass, FalseClass]) + + # Alias for the forgetful. + # @api private + alias_method :owner, :user + + def initialize(name, run_context) + @raw_name = name # Capture this before it gets coerced to a string. + super + end + + # Regexp for URL-like paths. + # @api private + URL_PATHS = %r{^(\w+:)?//} + + # Check if the source path is a URL. + # + # @api private + # @return [Boolean] + def is_url? + path =~ URL_PATHS + end + + # Expand a relative file path against `Chef::Config[:file_cache_path]`. + # For URLs it returns the cache file path. + # + # @api private + # @return [String] + def absolute_path + if is_url? + # Use the last path component without the query string plus the name + # of the resource in Base64. This should be both mildly readable and + # also unique per invocation. + url_part = URI(path).path.split(/\//).last + base64_name = Base64.strict_encode64(name).gsub(/\=/, '') + ::File.join(Chef::Config[:file_cache_path], "#{base64_name}_#{url_part}") + else + ::File.expand_path(path, Chef::Config[:file_cache_path]) + end + end + + # Merge the explicit source properties with the array form of the name. + # + # @api private + # @return [Hash] + def merged_source_properties + if @raw_name.is_a?(Array) && @raw_name[1] + source_properties.merge(@raw_name[1]) + else + source_properties + end + end + + private + + # Filename components to ignore. + # @api private + BASENAME_IGNORE = /(\.(t?(ar|gz|bz2?|xz)|zip))+$/ + + # Default value for the {#destination} property + # + # @api private + # @return [String] + def default_destination + if is_url? + raise ValueError.new("Destination for URL-based archive #{self} must be specified explicitly") + else + ::File.join(::File.dirname(absolute_path), ::File.basename(path).gsub(BASENAME_IGNORE, '')) + end + end + end + + # Providers can be found in archive_providers/. + end + end +end diff --git a/cookbooks/poise-archive/files/halite_gem/poise_archive/version.rb b/cookbooks/poise-archive/files/halite_gem/poise_archive/version.rb new file mode 100644 index 0000000..252b210 --- /dev/null +++ b/cookbooks/poise-archive/files/halite_gem/poise_archive/version.rb @@ -0,0 +1,20 @@ +# +# Copyright 2016-2017, Noah Kantrowitz +# +# 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 PoiseArchive + VERSION = '1.4.0' +end diff --git a/cookbooks/poise-archive/libraries/default.rb b/cookbooks/poise-archive/libraries/default.rb new file mode 100644 index 0000000..01175df --- /dev/null +++ b/cookbooks/poise-archive/libraries/default.rb @@ -0,0 +1,19 @@ +# +# Copyright 2016-2017, Noah Kantrowitz +# +# 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. +# + +raise 'Halite is not compatible with no_lazy_load false, please set no_lazy_load true in your Chef configuration file.' unless Chef::Config[:no_lazy_load] +$LOAD_PATH << File.expand_path('../../files/halite_gem', __FILE__) +require "poise_archive/cheftie" diff --git a/cookbooks/poise-archive/metadata.json b/cookbooks/poise-archive/metadata.json new file mode 100644 index 0000000..151d5e8 --- /dev/null +++ b/cookbooks/poise-archive/metadata.json @@ -0,0 +1 @@ +{"name":"poise-archive","version":"1.4.0","description":"A Chef cookbook for unpacking file archives like tar and zip.","long_description":"# Poise-Archive Cookbook\n\n[![Build Status](https://img.shields.io/travis/poise/poise-archive.svg)](https://travis-ci.org/poise/poise-archive)\n[![Gem Version](https://img.shields.io/gem/v/poise-archive.svg)](https://rubygems.org/gems/poise-archive)\n[![Cookbook Version](https://img.shields.io/cookbook/v/poise-archive.svg)](https://supermarket.chef.io/cookbooks/poise-archive)\n[![Coverage](https://img.shields.io/codecov/c/github/poise/poise-archive.svg)](https://codecov.io/github/poise/poise-archive)\n[![Gemnasium](https://img.shields.io/gemnasium/poise/poise-archive.svg)](https://gemnasium.com/poise/poise-archive)\n[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)\n\nA [Chef](https://www.chef.io/) cookbook to unpack file archives.\n\nIt supports `.tar`, `.tar.gz`, `.tar.bz2`, and `.zip` archive files.\n\n## Quick Start\n\nTo download an unpack and archive:\n\n```ruby\npoise_archive 'https://example.com/myapp.tgz' do\n destination '/opt/myapp'\nend\n```\n\n## Requirements\n\nChef 12.1 or newer is required.\n\n## Platforms\n\nThis cookbook supports all platforms (including Windows) but some Unix platforms\n(Solaris, AIX) may see very slow tar file unpacking when using the pure-Ruby fallback\nimplementation.\n\n## Resources\n\n### `poise_archive`\n\nThe `poise_archive` resource unpacks file archives.\n\n```ruby\npoise_archive '/tmp/myapp-1.2.0.tar' do\n destination '/srv/myapp-1.2.0'\nend\n```\n\nA URL can also be passed as the source path, optionally with extra properties to\nbe merged with `source_properties`.\n\n```ruby\npoise_archive 'http://example.com/myapp-1.2.0.zip' do\n destination '/srv/myapp-1.2.0'\nend\n\npoise_archive ['http://example.com/myapp-1.2.0.zip', {headers: {'Authentication' => '...'}}] do\n destination '/srv/myapp-1.2.0'\nend\n```\n\n#### Actions\n\n* `:unpack` – Unpack the archive. *(default)*\n\n#### Properties\n\n* `path` – Path to the archive. If relative, it is taken as a file inside\n `Chef::Config[:file_cache_path]`. If a URL, it is downloaded to a cache file\n first. *(name attribute)*\n* `destination` – Path to unpack the archive to. If not specified, the path of\n the archive without the file extension is used. Required when unpacking from\n a URL. *(default: auto)*\n* `group` – Group to run the unpack as.\n* `keep_existing` – Keep existing files in the destination directory when\n unpacking. *(default: false)*\n* `source_properties` – Property key/value pairs to be applied to the\n `remote_file` file resource when downloading a URL. *(default: {retries: 5})*\n* `strip_components` – Number of intermediary directories to skip when\n unpacking. Works like GNU tar's `--strip-components`. *(default: 1)*\n* `user` – User to run the unpack as.\n\n## Sponsors\n\nDevelopment sponsored by [Bloomberg](http://www.bloomberg.com/company/technology/).\n\nThe Poise test server infrastructure is sponsored by [Rackspace](https://rackspace.com/).\n\n## License\n\nCopyright 2016-2017, Noah Kantrowitz\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\nBZip2 implementation is based on RBzip2. Copyright Sebastian Staudt, Brian Lopez.\nRBzip2 code used under the terms of the new BSD license.\n","maintainer":"Noah Kantrowitz","maintainer_email":"noah@coderanger.net","license":"Apache 2.0","platforms":{},"dependencies":{"poise":"~> 2.6"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{},"source_url":"https://github.com/poise/poise-archive","issues_url":"https://github.com/poise/poise-archive/issues","chef_version":"~> 12","ohai_version":{}} \ No newline at end of file diff --git a/cookbooks/poise-javascript/CHANGELOG.md b/cookbooks/poise-javascript/CHANGELOG.md new file mode 100644 index 0000000..0756dd1 --- /dev/null +++ b/cookbooks/poise-javascript/CHANGELOG.md @@ -0,0 +1,16 @@ +# Poise-Javascript Changelog + +## v1.1.0 + +* New version list for Node.js. +* Support new SCL structure and packages. + +## v1.0.1 + +* Update for Chef 12.6 compatibility. +* Update version list for `nodejs` provider. + +## v1.0.0 + +* Initial release! + diff --git a/cookbooks/poise-javascript/README.md b/cookbooks/poise-javascript/README.md new file mode 100644 index 0000000..ed7122f --- /dev/null +++ b/cookbooks/poise-javascript/README.md @@ -0,0 +1,332 @@ +# Poise-Javascript Cookbook + +[![Build Status](https://img.shields.io/travis/poise/poise-javascript.svg)](https://travis-ci.org/poise/poise-javascript) +[![Gem Version](https://img.shields.io/gem/v/poise-javascript.svg)](https://rubygems.org/gems/poise-javascript) +[![Cookbook Version](https://img.shields.io/cookbook/v/poise-javascript.svg)](https://supermarket.chef.io/cookbooks/poise-javascript) +[![Coverage](https://img.shields.io/codecov/c/github/poise/poise-javascript.svg)](https://codecov.io/github/poise/poise-javascript) +[![Gemnasium](https://img.shields.io/gemnasium/poise/poise-javascript.svg)](https://gemnasium.com/poise/poise-javascript) +[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) + +A [Chef](https://www.chef.io/) cookbook to provide a unified interface for +installing server-side JavaScript runtimes like Node.js and io.js. + +## Quick Start + +To install the latest available version of Node.js 0.12: + +```ruby +javascript_runtime '0.12' +``` + +## Supported JavaScript Runtimes + +This cookbook can install Node.js and io.js on Linux and OS X. + +## Requirements + +Chef 12.1 or newer is required. + +## Attributes + +Attributes are used to configure the default recipe. + +* `node['poise-javascript']['install_nodejs']` – Install a Node.js runtime. *(default: true)* +* `node['poise-javascript']['install_iojs']` – Install an io.js runtime. *(default: false)* + +## Recipes + +### `default` + +The default recipe installs Node.js or io.js based on the node attributes. It is +entirely optional and can be ignored in favor of direct use of the +`javascript_runtime` resource. + +## Resources + +### `javascript_runtime` + +The `javascript_runtime` resource installs a JavaScript interpreter. + +```ruby +javascript_runtime '0.12' +``` + +#### Actions + +* `:install` – Install the JavaScript interpreter. *(default)* +* `:uninstall` – Uninstall the JavaScript interpreter. + +#### Properties + +* `version` – Version of the runtime to install. If a partial version is given, + use the latest available version matching that prefix. *(name property)* + +#### Provider Options + +The `poise-javascript` library offers an additional way to pass configuration +information to the final provider called "options". Options are key/value pairs +that are passed down to the `javascript_runtime` provider and can be used to control how it +installs JavaScript. These can be set in the `javascript_runtime` +resource using the `options` method, in node attributes or via the +`javascript_runtime_options` resource. The options from all sources are merged +together in to a single hash. + +When setting options in the resource you can either set them for all providers: + +```ruby +javascript_runtime 'myapp' do + version '0.10' + options dev_package: false +end +``` + +or for a single provider: + +```ruby +javascript_runtime 'myapp' do + version '0.10' + options :system, dev_package: false +end +``` + +Setting via node attributes is generally how an end-user or application cookbook +will set options to customize installations in the library cookbooks they are using. +You can set options for all installations or for a single runtime: + +```ruby +# Global, for all installations. +override['poise-javascript']['options']['version'] = '0.10' +# Single installation. +override['poise-javascript']['myapp']['version'] = 'iojs' +``` + +The `javascript_runtime_options` resource is also available to set node attributes +for a specific installation in a DSL-friendly way: + +```ruby +javascript_runtime_options 'myapp' do + version 'iojs' +end +``` + +Unlike resource attributes, provider options can be different for each provider. +Not all providers support the same options so make sure to the check the +documentation for each provider to see what options the use. + +### `javascript_runtime_options` + +The `javascript_runtime_options` resource allows setting provider options in a +DSL-friendly way. See [the Provider Options](#provider-options) section for more +information about provider options overall. + +```ruby +javascript_runtime_options 'myapp' do + version 'iojs' +end +``` + +#### Actions + +* `:run` – Apply the provider options. *(default)* + +#### Properties + +* `resource` – Name of the `javascript_runtime` resource. *(name property)* +* `for_provider` – Provider to set options for. + +All other attribute keys will be used as options data. + +### `javascript_execute` + +The `javascript_execute` resource executes a JavaScript script using the configured runtime. + +```ruby +javascript_execute 'myapp.js' do + user 'myuser' +end +``` + +This uses the built-in `execute` resource and supports all the same properties. + +#### Actions + +* `:run` – Execute the script. *(default)* + +#### Properties + +* `command` – Script and arguments to run. Must not include the `node`. *(name attribute)* +* `javascript` – Name of the `javascript_runtime` resource to use. If not specified, the + most recently declared `javascript_runtime` will be used. Can also be set to the + full path to a `node` binary. + +For other properties see the [Chef documentation](https://docs.chef.io/resource_execute.html#attributes). + +### `node_package` + +The `node_package` resource installs Node.js packages using +[NPM](https://www.npmjs.com/). + +```ruby +node_package 'express' do + version '4.13.3' +end +``` + +This uses the built-in `package` resource and supports the same actions and +properties. Multi-package installs are supported using the standard syntax. + +#### Actions + +* `:install` – Install the package. *(default)* +* `:upgrade` – Upgrade the package. +* `:remove` – Uninstall the package. + +The `:purge` and `:reconfigure` actions are not supported. + +#### Properties + +* `group` – System group to install the package. +* `package_name` – Package or packages to install. *(name property)* +* `path` – Path to install the package in to. If unset install using `--global`. + *(default: nil)* +* `version` – Version or versions to install. +* `javascript` – Name of the `javascript_runtime` resource to use. If not specified, the + most recently declared `javascript_runtime` will be used. Can also be set to the + full path to a `node` binary. +* `unsafe_perm` – Enable `--unsafe-perm`. *(default: true)* +* `user` – System user to install the package. + +For other properties see the [Chef documentation](https://docs.chef.io/resource_package.html#attributes). +The `response_file`, `response_file_variables`, and `source` properties are not +supported. + +### `npm_install` + +The `npm_install` resource runs `npm install` for a package. + +```ruby +npm_install '/opt/myapp' +``` + +The underlying `npm install` command will run on every converge, but notifications +will only be triggered if a package is actually installed. + +#### Actions + +* `:install` – Run `npm install`. *(default)* + +#### Properties + +* `path` – Path to the package folder containing a `package.json`. *(name attribute)* +* `group` – System group to install the packages. +* `javascript` – Name of the `javascript_runtime` resource to use. If not specified, the + most recently declared `javascript_runtime` will be used. Can also be set to the + full path to a `node` binary. +* `production` – Enable production install mode. *(default: true)* +* `unsafe_perm` – Enable `--unsafe-perm`. *(default: true)* +* `user` – System user to install the packages. + +## Javascript Providers + +### Common Options + +These provider options are supported by all providers. + +* `version` – Override the runtime version. + +### `system` + +The `system` provider installs Node.js using system packages. This is currently +only tested on platforms using `apt-get` and `yum` (Debian, Ubuntu, RHEL, CentOS +Amazon Linux, and Fedora). It may work on other platforms but is untested. + +```ruby +javascript_runtime 'myapp' do + provider :system + version '0.10' +end +``` + +#### Options + +* `dev_package` – Install the package with the headers and other development + files. Can be set to a string to select the dev package specifically. + *(default: true)* +* `package_name` – Override auto-detection of the package name. +* `package_upgrade` – Install using action `:upgrade`. *(default: false)* +* `package_version` – Override auto-detection of the package version. + +### `scl` + +The `scl` provider installs Node.js using the [Software Collections](https://www.softwarecollections.org/) +packages. This is only available on RHEL and CentOS. SCL offers more +recent versions of Node.js than the system packages for the most part. If an SCL +package exists for the requests version, it will be used in preference to the +`system` provider. + +```ruby +javascript_runtime 'myapp' do + provider :scl + version '0.10' +end +``` + +### `nodejs` + +The `nodejs` provider installs Node.js from the static binaries on nodejs.org. +Support is included for Linux and OS X. + +```ruby +javascript_runtime 'myapp' do + provider :nodejs + version '0.12' +end +``` + +#### Options + +* `path` – Folder to install Node.js to. *(default: /opt/nodejs-)* +* `static_version` – Specific version number to use for computing the URL and + path. *(default: automatic from `version`)* +* `strip_components` – Value to pass to tar --strip-components. *(automatic)* +* `url` – URL template to download the archive from. *(default: automatic)* + +### `iojs` + +The `iojs` provider installs io.js from the static binaries on iojs.org. +Support is included for Linux and OS X. + +```ruby +javascript_runtime 'myapp' do + provider :iojs + version '3' +end +``` + +#### Options + +* `path` – Folder to install io.js to. *(default: /opt/iojs-)* +* `static_version` – Specific version number to use for computing the URL and + path. *(default: automatic from `version`)* +* `strip_components` – Value to pass to tar --strip-components. *(automatic)* +* `url` – URL template to download the archive from. *(default: automatic)* + +## Sponsors + +The Poise test server infrastructure is sponsored by [Rackspace](https://rackspace.com/). + +## License + +Copyright 2015-2016, Noah Kantrowitz + +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/poise-javascript/attributes/default.rb b/cookbooks/poise-javascript/attributes/default.rb new file mode 100644 index 0000000..a72ea0f --- /dev/null +++ b/cookbooks/poise-javascript/attributes/default.rb @@ -0,0 +1,23 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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. +# + +# Default inversion options. +default['poise-javascript']['provider'] = 'auto' +default['poise-javascript']['options'] = {} + +# Used for the default recipe. +default['poise-javascript']['install_nodejs'] = true +default['poise-javascript']['install_iojs'] = false diff --git a/cookbooks/poise-javascript/files/halite_gem/poise_javascript.rb b/cookbooks/poise-javascript/files/halite_gem/poise_javascript.rb new file mode 100644 index 0000000..b91e3e7 --- /dev/null +++ b/cookbooks/poise-javascript/files/halite_gem/poise_javascript.rb @@ -0,0 +1,24 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 PoiseJavascript + autoload :Error, 'poise_javascript/error' + autoload :Resources, 'poise_javascript/resources' + autoload :JavascriptCommandMixin, 'poise_javascript/javascript_command_mixin' + autoload :JavascriptProviders, 'poise_javascript/javascript_providers' + autoload :VERSION, 'poise_javascript/version' +end diff --git a/cookbooks/poise-javascript/files/halite_gem/poise_javascript/cheftie.rb b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/cheftie.rb new file mode 100644 index 0000000..d76a171 --- /dev/null +++ b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/cheftie.rb @@ -0,0 +1,18 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 'poise_javascript/resources' +require 'poise_javascript/javascript_providers' diff --git a/cookbooks/poise-javascript/files/halite_gem/poise_javascript/error.rb b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/error.rb new file mode 100644 index 0000000..d8c6eb2 --- /dev/null +++ b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/error.rb @@ -0,0 +1,23 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 'poise_languages' + + +module PoiseJavascript + class Error < PoiseLanguages::Error + end +end diff --git a/cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_command_mixin.rb b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_command_mixin.rb new file mode 100644 index 0000000..cd7297d --- /dev/null +++ b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_command_mixin.rb @@ -0,0 +1,56 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 'poise/utils' +require 'poise_languages' + + +module PoiseJavascript + # Mixin for resources and providers which run Javascript commands. + # + # @since 1.0.0 + module JavascriptCommandMixin + include Poise::Utils::ResourceProviderMixin + + # Mixin for resources which run Javascript commands. + module Resource + include PoiseLanguages::Command::Mixin::Resource(:javascript, default_binary: 'node') + + # @!attribute npm_binary + # Path to the npm binary. + # @return [String] + attribute(:npm_binary, kind_of: String, default: lazy { default_npm_binary }) + + private + + # Find the default gem binary. If there is a parent use that, otherwise + # use the same logic as {PoiseRuby::RubyProviders::Base#npm_binary}. + # + # @return [String] + def default_npm_binary + if parent_javascript + parent_javascript.npm_binary + else + ::File.expand_path('../npm', javascript) + end + end + end + + module Provider + include PoiseLanguages::Command::Mixin::Provider(:javascript) + end + end +end diff --git a/cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_providers.rb b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_providers.rb new file mode 100644 index 0000000..6855d6a --- /dev/null +++ b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_providers.rb @@ -0,0 +1,40 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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/platform/provider_priority_map' + +require 'poise_javascript/javascript_providers/dummy' +require 'poise_javascript/javascript_providers/iojs' +require 'poise_javascript/javascript_providers/nodejs' +require 'poise_javascript/javascript_providers/scl' +require 'poise_javascript/javascript_providers/system' + + +module PoiseJavascript + # Inversion providers for the javascript_runtime resource. + # + # @since 1.0.0 + module JavascriptProviders + autoload :Base, 'poise_javascript/javascript_providers/base' + + Chef::Platform::ProviderPriorityMap.instance.priority(:javascript_runtime, [ + PoiseJavascript::JavascriptProviders::IOJS, + PoiseJavascript::JavascriptProviders::NodeJS, + PoiseJavascript::JavascriptProviders::Scl, + PoiseJavascript::JavascriptProviders::System, + ]) + end +end diff --git a/cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_providers/base.rb b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_providers/base.rb new file mode 100644 index 0000000..ddd261e --- /dev/null +++ b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_providers/base.rb @@ -0,0 +1,97 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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/provider' +require 'poise' + + +module PoiseJavascript + module JavascriptProviders + class Base < Chef::Provider + include Poise(inversion: :javascript_runtime) + + # Set default inversion options. + # + # @api private + def self.default_inversion_options(node, new_resource) + super.merge({ + version: new_resource.version, + }) + end + + # The `install` action for the `javascript_runtime` resource. + # + # @return [void] + def action_install + notifying_block do + install_javascript + end + end + + # The `uninstall` action for the `javascript_runtime` resource. + # + # @abstract + # @return [void] + def action_uninstall + notifying_block do + uninstall_javascript + end + end + + # The path to the `javascript` binary. This is an output property. + # + # @abstract + # @return [String] + def javascript_binary + raise NotImplementedError + end + + # The environment variables for this Javascript. This is an output property. + # + # @return [Hash] + def javascript_environment + {} + end + + # The path to the `npm` binary. This is an output property. + # + # @abstract + # @return [String] + def npm_binary + ::File.expand_path(::File.join('..', 'npm'), javascript_binary) + end + + private + + # Install the Javascript runtime. Must be implemented by subclass. + # + # @abstract + # @return [void] + def install_javascript + raise NotImplementedError + end + + # Uninstall the Javascript runtime. Must be implemented by subclass. + # + # @abstract + # @return [void] + def uninstall_javascript + raise NotImplementedError + end + + end + end +end diff --git a/cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_providers/dummy.rb b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_providers/dummy.rb new file mode 100644 index 0000000..6dcbd50 --- /dev/null +++ b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_providers/dummy.rb @@ -0,0 +1,77 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 'poise_javascript/javascript_providers/base' + + +module PoiseJavascript + module JavascriptProviders + # Inversion provider for the `javascript_runtime` resource to use a fake Javascript, + # for use in unit tests. + # + # @since 1.0.0 + # @provides dummy + class Dummy < Base + provides(:dummy) + + def self.default_inversion_options(node, resource) + super.merge({ + # Manual overrides for dummy data. + javascript_binary: ::File.join('', 'node'), + javascript_environment: nil, + npm_binary: nil, + }) + end + + # The `install` action for the `javascript_runtime` resource. + # + # @return [void] + def action_install + # This space left intentionally blank. + end + + # The `uninstall` action for the `javascript_runtime` resource. + # + # @return [void] + def action_uninstall + # This space left intentionally blank. + end + + # Path to the non-existent Javascript. + # + # @return [String] + def javascript_binary + options['javascript_binary'] + end + + # Environment for the non-existent Javascript. + # + # @return [String] + def javascript_environment + options['javascript_environment'] || super + end + + # Path to the non-existent npm. + # + # @return [String] + def npm_binary + options['npm_binary'] || super + end + + end + end +end + diff --git a/cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_providers/iojs.rb b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_providers/iojs.rb new file mode 100644 index 0000000..236679c --- /dev/null +++ b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_providers/iojs.rb @@ -0,0 +1,64 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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' +require 'poise_languages/static' + +require 'poise_javascript/error' +require 'poise_javascript/javascript_providers/base' + + +module PoiseJavascript + module JavascriptProviders + class IOJS < Base + provides(:iojs) + include PoiseLanguages::Static( + versions: %w{3.3.1 3.2.0 3.1.0 3.0.0 2.5.0 2.4.0 2.3.4 2.2.1 2.1.0 2.0.2 1.8.4 1.7.1 1.6.4 1.5.1 1.4.3 1.3.0 1.2.0 1.1.0 1.0.4}, + machines: %w{linux-i686 linux-x86_64 darwin-x86_64}, + url: 'https://iojs.org/dist/v%{version}/iojs-v%{version}-%{kernel}-%{machine}.tar.gz', + ) + + def self.provides_auto?(node, resource) + # Also work if we have a version starting with 1. 2. or 3. since that has + # to be io.js and no other mechanism supports that. + super || (resource.version.to_s =~ /^[123](\.|$)/ && static_machines.include?(static_machine_label(node))) + end + + MACHINE_LABELS = {'i386' => 'x86', 'i686' => 'x86', 'x86_64' => 'x64'} + + def static_url_variables + machine = node['kernel']['machine'] + super.merge(machine: MACHINE_LABELS[machine] || machine) + end + + def javascript_binary + ::File.join(static_folder, 'bin', 'iojs') + end + + private + + def install_javascript + install_static + end + + def uninstall_javascript + uninstall_static + end + + end + end +end + diff --git a/cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_providers/nodejs.rb b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_providers/nodejs.rb new file mode 100644 index 0000000..06dd54d --- /dev/null +++ b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_providers/nodejs.rb @@ -0,0 +1,65 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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' +require 'poise_languages/static' + +require 'poise_javascript/error' +require 'poise_javascript/javascript_providers/base' + + +module PoiseJavascript + module JavascriptProviders + class NodeJS < Base + provides(:nodejs) + include PoiseLanguages::Static( + # 4.x is still first here because that is what NodeJS recommends. + versions: %w{4.5.0 6.4.0 6.3.1 6.2.2 6.1.0 6.0.0 5.11.0 5.10.1 5.9.1 5.8.0 5.7.1 5.6.0 5.5.0 5.4.1 5.3.0 5.2.0 5.1.1 5.0.0 4.4.3 4.3.2 4.2.6 4.1.1 4.0.0 0.12.7 0.11.16 0.10.40 0.9.12 0.8.28 0.7.12 0.6.21 0.5.10}, + machines: %w{linux-i686 linux-x86_64 linux-armv6l linux-armv7l linux-arm64 darwin-x86_64}, + url: 'https://nodejs.org/dist/v%{version}/node-v%{version}-%{kernel}-%{machine}.tar.gz', + ) + + def self.provides_auto?(node, resource) + # Also work if we have a blank or numeric-y version. This should make + # it the default provider on supported platforms. + super || (resource.version.to_s =~ /^(\d|$)/ && static_machines.include?(static_machine_label(node))) + end + + MACHINE_LABELS = {'i386' => 'x86', 'i686' => 'x86', 'x86_64' => 'x64'} + + def static_url_variables + machine = node['kernel']['machine'] + super.merge(machine: MACHINE_LABELS[machine] || machine) + end + + def javascript_binary + ::File.join(static_folder, 'bin', 'node') + end + + private + + def install_javascript + install_static + end + + def uninstall_javascript + uninstall_static + end + + end + end +end + diff --git a/cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_providers/scl.rb b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_providers/scl.rb new file mode 100644 index 0000000..268df48 --- /dev/null +++ b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_providers/scl.rb @@ -0,0 +1,53 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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' +require 'poise_languages' + +require 'poise_javascript/error' +require 'poise_javascript/javascript_providers/base' + + +module PoiseJavascript + module JavascriptProviders + class Scl < Base + include PoiseLanguages::Scl::Mixin + provides(:scl) + scl_package('4.4.2', 'rh-nodejs4', 'rh-nodejs4-nodejs-devel', '>= 7.0') + scl_package('0.10.35', 'nodejs010', 'nodejs010-nodejs-devel') + + def javascript_binary + ::File.join(scl_folder, 'root', 'usr', 'bin', 'node') + end + + def javascript_environment + scl_environment + end + + private + + def install_javascript + install_scl_package + end + + def uninstall_javascript + uninstall_scl_package + end + + end + end +end + diff --git a/cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_providers/system.rb b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_providers/system.rb new file mode 100644 index 0000000..e0eca2f --- /dev/null +++ b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/javascript_providers/system.rb @@ -0,0 +1,71 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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' +require 'poise_languages' + +require 'poise_javascript/error' +require 'poise_javascript/javascript_providers/base' + + +module PoiseJavascript + module JavascriptProviders + class System < Base + include PoiseLanguages::System::Mixin + provides(:system) + packages('nodejs', { + debian: {default: %w{nodejs}}, + ubuntu: {default: %w{nodejs}}, + # Empty arrays because no package in the base OS. + redhat: {default: %w{}}, + centos: {default: %w{}}, + fedora: {default: %w{nodejs}}, + amazon: {default: %w{}}, + }) + + def self.provides_auto?(node, resource) + # Don't auto on platforms I know have no system package by default. Kind + # of pointless since the nodejs provider will hit on these platforms + # anyway so this shouldn't ever happen. + super && !node.platform_family?('rhel') && !node.platform?('amazon') + end + + def javascript_binary + # Debian and Ubuntu after 12.04 changed the binary name ಠ_ಠ. + binary_name = node.value_for_platform(debian: {default: 'nodejs'}, ubuntu: {'12.04' => 'node', default: 'nodejs'}, default: 'node') + ::File.join('', 'usr', 'bin', binary_name) + end + + private + + def install_javascript + install_system_packages + package %w{npm nodejs-legacy} if node.platform_family?('debian') + end + + def uninstall_javascript + uninstall_system_packages + package(%w{npm nodejs-legacy}) { action :purge } if node.platform_family?('debian') + end + + def system_package_candidates(version) + # Boring :-(. + %w{nodejs nodejs-legacy node} + end + + end + end +end diff --git a/cookbooks/poise-javascript/files/halite_gem/poise_javascript/resources.rb b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/resources.rb new file mode 100644 index 0000000..609e164 --- /dev/null +++ b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/resources.rb @@ -0,0 +1,29 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 'poise_javascript/resources/javascript_execute' +require 'poise_javascript/resources/javascript_runtime' +require 'poise_javascript/resources/node_package' +require 'poise_javascript/resources/npm_install' + + +module PoiseJavascript + # Chef resources and providers for poise-javascript. + # + # @since 1.0.0 + module Resources + end +end diff --git a/cookbooks/poise-javascript/files/halite_gem/poise_javascript/resources/javascript_execute.rb b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/resources/javascript_execute.rb new file mode 100644 index 0000000..143b085 --- /dev/null +++ b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/resources/javascript_execute.rb @@ -0,0 +1,83 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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/mixin/which' +require 'chef/provider/execute' +require 'chef/resource/execute' +require 'poise' + +require 'poise_javascript/javascript_command_mixin' + + +module PoiseJavascript + module Resources + # (see JavascriptExecute::Resource) + # @since 1.0.0 + module JavascriptExecute + # A `javascript_execute` resource to run Javascript scripts and commands. + # + # @provides javascript_execute + # @action run + # @example + # javascript_execute 'myapp.js' do + # user 'myuser' + # end + class Resource < Chef::Resource::Execute + include PoiseJavascript::JavascriptCommandMixin + provides(:javascript_execute) + actions(:run) + end + + # The default provider for `javascript_execute`. + # + # @see Resource + # @provides javascript_execute + class Provider < Chef::Provider::Execute + include Chef::Mixin::Which + provides(:javascript_execute) + + private + + # Command to pass to shell_out. + # + # @return [String, Array] + def command + if new_resource.command.is_a?(Array) + [new_resource.javascript] + new_resource.command + else + "#{new_resource.javascript} #{new_resource.command}" + end + end + + # Environment variables to pass to shell_out. + # + # @return [Hash] + def environment + if new_resource.parent_javascript + environment = new_resource.parent_javascript.javascript_environment + if new_resource.environment + environment = environment.merge(new_resource.environment) + end + environment + else + new_resource.environment + end + end + + end + end + end +end diff --git a/cookbooks/poise-javascript/files/halite_gem/poise_javascript/resources/javascript_runtime.rb b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/resources/javascript_runtime.rb new file mode 100644 index 0000000..ff5183a --- /dev/null +++ b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/resources/javascript_runtime.rb @@ -0,0 +1,85 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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' +require 'poise' + + +module PoiseJavascript + module Resources + # (see JavascriptRuntime::Resource) + # @since 1.0.0 + module JavascriptRuntime + # A `javascript_runtime` resource to manage Javascript installations. + # + # @provides javascript_runtime + # @action install + # @action uninstall + # @example + # javascript_runtime '2.7' + class Resource < Chef::Resource + include Poise(inversion: true, container: true) + provides(:javascript_runtime) + actions(:install, :uninstall) + + # @!attribute version + # Version of Javascript to install. This is generally a NodeJS version + # but because of io.js there are shenanigans. + # @return [String] + # @example Install any version + # javascript_runtime 'any' do + # version '' + # end + attribute(:version, kind_of: String, name_attribute: true) + + # The path to the `node` binary for this Javascript installation. This is + # an output property. + # + # @return [String] + # @example + # execute "#{resources('javascript_runtime[nodejs]').javascript_binary} myapp.js" + def javascript_binary + provider_for_action(:javascript_binary).javascript_binary + end + + # The environment variables for this Javascript installation. This is an + # output property. + # + # @return [Hash] + # @example + # execute '/opt/myapp.js' do + # environment resources('javascript_runtime[nodejs]').javascript_environment + # end + def javascript_environment + provider_for_action(:javascript_environment).javascript_environment + end + + # The path to the `npm` binary for this Javascript installation. This is + # an output property. Can raise an exception if NPM is not supported for + # this runtime. + # + # @return [String] + # @example + # execute "#{resources('javascript_runtime[nodejs]').npm_binary} install" + def npm_binary + provider_for_action(:npm_binary).npm_binary + end + end + + # Providers can be found under lib/poise_javascript/javascript_providers/ + end + end +end diff --git a/cookbooks/poise-javascript/files/halite_gem/poise_javascript/resources/javascript_runtime_test.rb b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/resources/javascript_runtime_test.rb new file mode 100644 index 0000000..aac4ecd --- /dev/null +++ b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/resources/javascript_runtime_test.rb @@ -0,0 +1,226 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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/provider' +require 'chef/resource' +require 'poise' + + +module PoiseJavascript + module Resources + # (see JavascriptRuntimeTest::Resource) + # @since 1.0.0 + # @api private + module JavascriptRuntimeTest + # A `javascript_runtime_test` resource for integration testing of this + # cookbook. This is an internal API and can change at any time. + # + # @provides javascript_runtime_test + # @action run + class Resource < Chef::Resource + include Poise + provides(:javascript_runtime_test) + actions(:run) + + attribute(:version, kind_of: String, name_attribute: true) + attribute(:runtime_provider, kind_of: Symbol) + attribute(:path, kind_of: String, default: lazy { default_path }) + attribute(:test_yo, equal_to: [true, false], default: true) + + def default_path + ::File.join('', 'root', "javascript_test_#{name}") + end + end + + # The default provider for `javascript_runtime_test`. + # + # @see Resource + # @provides javascript_runtime_test + class Provider < Chef::Provider + include Poise + provides(:javascript_runtime_test) + + # The `run` action for the `javascript_runtime_test` resource. + # + # @return [void] + def action_run + notifying_block do + # Top level directory for this test. + directory new_resource.path + + # Install and log the version. + javascript_runtime new_resource.name do + provider new_resource.runtime_provider if new_resource.runtime_provider + version new_resource.version + end + test_version + + # Create a package and test npm_install. + pkg_path = ::File.join(new_resource.path, 'pkg') + directory pkg_path + file ::File.join(pkg_path, 'package.json') do + content <<-EOH +{ + "name": "mypkg", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \\"Error: no test specified\\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "express": "4.13.3" + }, + "devDependencies": { + "handlebars": "4.0.2" + } +} +EOH + end + npm_install pkg_path do + notifies :create, sentinel_file('npm_install_one'), :immediately + end + npm_install pkg_path+'2' do + path pkg_path + notifies :create, sentinel_file('npm_install_two'), :immediately + end + test_require('express', pkg_path) + test_require('handlebars', pkg_path) + + # Test node_package. + test1_path = ::File.join(new_resource.path, 'test1') + directory test1_path + node_package 'express' do + path test1_path + notifies :create, sentinel_file('test1_express_one'), :immediately + end + node_package 'express two' do + package_name 'express' + path test1_path + notifies :create, sentinel_file('test1_express_two'), :immediately + end + node_package %w{gulp less} do + path test1_path + notifies :create, sentinel_file('test1_multi'), :immediately + end + node_package %w{express bower} do + path test1_path + notifies :create, sentinel_file('test1_multi_overlap'), :immediately + end + node_package 'bower' do + path test1_path + notifies :create, sentinel_file('test1_bower'), :immediately + end + node_package 'yo' do + path test1_path + version '1.4.5' + end if new_resource.test_yo + node_package 'forever' do + path test1_path + version '0.13.0' + end + test_require('express', test1_path, 'node_package_express') + test_require('gulp', test1_path) + test_require('less', test1_path) + test_require('bower', test1_path) + if new_resource.test_yo + test_require('yo', test1_path) + else + file ::File.join(new_resource.path, 'no_yo') + end + test_require('forever', test1_path) + + # Check we don't get cross talk between paths. + test2_path = ::File.join(new_resource.path, 'test2') + directory test2_path + node_package 'express' do + path test2_path + notifies :create, sentinel_file('test2_express'), :immediately + end + + # Test global installs. + node_package 'grunt-cli' do + notifies :create, sentinel_file('grunt_one'), :immediately + end + node_package 'grunt-cli two' do + package_name 'grunt-cli' + notifies :create, sentinel_file('grunt_two'), :immediately + end + test_require('grunt-cli', new_resource.path) + javascript_execute 'grunt-cli --version' do + command lazy { + # Check local/bin first and then just bin/. + grunt_path = ::File.expand_path('../../local/bin/grunt', javascript) + grunt_path = ::File.expand_path('../grunt', javascript) unless ::File.exist?(grunt_path) + "#{grunt_path} --version > #{::File.join(new_resource.path, 'grunt_version')}" + } + end + + end + end + + def sentinel_file(name) + file ::File.join(new_resource.path, "sentinel_#{name}") do + action :nothing + end + end + + private + + def test_version(javascript: new_resource.name) + # Only queue up this resource once, the ivar is just for tracking. + @javascript_version_test ||= file ::File.join(new_resource.path, 'javascript_version.js') do + user 'root' + group 'root' + mode '644' + content <<-EOH +var fs = require('fs'); +fs.writeFileSync(process.argv[2], process.version); +EOH + end + + javascript_execute "#{@javascript_version_test.path} #{::File.join(new_resource.path, 'version')}" do + javascript javascript if javascript + end + end + + def test_require(name, cwd, path=name, javascript: new_resource.name) + javascript_require_test = file ::File.join(cwd, 'javascript_require.js') do + user 'root' + group 'root' + mode '644' + content <<-EOH +var fs = require('fs'); +try { + var version = require(process.argv[2] + '/package.json').version; + fs.writeFileSync(process.argv[3], version); +} catch(e) { +} +EOH + end + + javascript_execute "#{javascript_require_test.path} #{name} #{::File.join(new_resource.path, "require_#{path}")}" do + javascript javascript if javascript + cwd cwd + end + end + + end + end + end +end diff --git a/cookbooks/poise-javascript/files/halite_gem/poise_javascript/resources/node_package.rb b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/resources/node_package.rb new file mode 100644 index 0000000..ecc75f8 --- /dev/null +++ b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/resources/node_package.rb @@ -0,0 +1,254 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require 'chef/json_compat' +require 'chef/provider/package' +require 'chef/resource/package' +require 'poise' + +require 'poise_javascript/error' +require 'poise_javascript/javascript_command_mixin' + + +module PoiseJavascript + module Resources + # (see NodePackage::Resource) + # @since 1.0.0 + module NodePackage + # A `node_package` resource to manage Node.js packages using npm. + # + # @provides node_package + # @action install + # @action upgrade + # @action uninstall + # @example + # node_package 'express' do + # javascript '0.10' + # version '1.8.3' + # end + class Resource < Chef::Resource::Package + include PoiseJavascript::JavascriptCommandMixin + provides(:node_package) + # Manually create matchers because #actions is unreliable. + %i{install upgrade remove}.each do |action| + Poise::Helpers::ChefspecMatchers.create_matcher(:node_package, action) + end + + # @!attribute group + # System group to install the package. + # @return [String, Integer, nil] + attribute(:group, kind_of: [String, Integer, NilClass]) + # @!attribute path + # Path to install the package in to. If unset install using --global. + # @return [String, nil, false] + attribute(:path, kind_of: [String, NilClass, FalseClass]) + # @!attribute unsafe_perm + # Enable --unsafe-perm. + # @return [Boolean, nil] + attribute(:unsafe_perm, equal_to: [true, false, nil], default: true) + # @!attribute user + # System user to install the package. + # @return [String, Integer, nil] + attribute(:user, kind_of: [String, Integer, NilClass]) + + def initialize(*args) + super + # For older Chef. + @resource_name = :node_package + # We don't have these actions. + @allowed_actions.delete(:purge) + @allowed_actions.delete(:reconfig) + end + + # Upstream attribute we don't support. Sets are an error and gets always + # return nil. + # + # @api private + # @param arg [Object] Ignored + # @return [nil] + def response_file(arg=nil) + raise NoMethodError if arg + end + + # (see #response_file) + def response_file_variables(arg=nil) + raise NoMethodError if arg && arg != {} + end + end + + # The default provider for the `node_package` resource. + # + # @see Resource + class Provider < Chef::Provider::Package + include PoiseJavascript::JavascriptCommandMixin + provides(:node_package) + + # Load current and candidate versions for all needed packages. + # + # @api private + # @return [Chef::Resource] + def load_current_resource + @current_resource = new_resource.class.new(new_resource.name, run_context) + current_resource.package_name(new_resource.package_name) + check_package_versions(current_resource) + current_resource + end + + # Populate current and candidate versions for all needed packages. + # + # @api private + # @param resource [PoiseJavascript::Resources::NodePackage::Resource] + # Resource to load for. + # @return [void] + def check_package_versions(resource) + version_data = Hash.new {|hash, key| hash[key] = {current: nil, candidate: nil} } + # Get the version for everything currently installed. + list_args = npm_version?('>= 1.4.16') ? %w{--depth 0} : [] + npm_shell_out!('list', list_args).fetch('dependencies', {}).each do |pkg_name, pkg_data| + version_data[pkg_name][:current] = pkg_data['version'] + end + # If any requested packages are currently installed, run npm outdated + # to look for candidate versions. Older npm doesn't support --json + # here so you get slow behavior, sorry. + requested_packages = Set.new(Array(resource.package_name)) + if npm_version?('>= 1.3.16') && version_data.any? {|pkg_name, _pkg_vers| requested_packages.include?(pkg_name) } + outdated = npm_shell_out!('outdated') || {} + version_data.each do |pkg_name, pkg_vers| + pkg_vers[:candidate] = if outdated.include?(pkg_name) + outdated[pkg_name]['wanted'] + else + # If it was already installed and not listed in outdated, it + # must have been up to date already. + pkg_vers[:current] + end + end + end + # Check for candidates for anything else we didn't get from outdated. + requested_packages.each do |pkg_name| + version_data[pkg_name][:candidate] ||= npm_shell_out!('show', [pkg_name])['version'] + end + # Populate the current resource and candidate versions. Youch this is + # a gross mix of data flow. + if(resource.package_name.is_a?(Array)) + @candidate_version = [] + versions = [] + [resource.package_name].flatten.each do |name| + ver = version_data[name.downcase] + versions << ver[:current] + @candidate_version << ver[:candidate] + end + resource.version(versions) + else + ver = version_data[resource.package_name.downcase] + resource.version(ver[:current]) + @candidate_version = ver[:candidate] + end + end + + # Install package(s) using npm. + # + # @param name [String, Array] Name(s) of package(s). + # @param version [String, Array] Version(s) of package(s). + # @return [void] + def install_package(name, version) + args = [] + # Set --unsafe-perm unless the property is nil. + unless new_resource.unsafe_perm.nil? + args << '--unsafe-perm' + args << new_resource.unsafe_perm.to_s + end + # Build up the actual package install args. + if new_resource.source + args << new_resource.source + else + Array(name).zip(Array(version)) do |pkg_name, pkg_ver| + args << "#{pkg_name}@#{pkg_ver}" + end + end + npm_shell_out!('install', args, parse_json: false) + end + + # Upgrade and install are the same for NPM. + alias_method :upgrade_package, :install_package + + # Uninstall package(s) using npm. + # + # @param name [String, Array] Name(s) of package(s). + # @param version [String, Array] Version(s) of package(s). + # @return [void] + def remove_package(name, version) + npm_shell_out!('uninstall', [name].flatten, parse_json: false) + end + + private + + # Run an npm command. + # + # @param subcmd [String] Subcommand to run. + # @param args [Array] Command arguments. + # @param parse_json [Boolean] Parse the JSON on stdout. + # @return [Hash] + def npm_shell_out!(subcmd, args=[], parse_json: true) + cmd = [new_resource.npm_binary, subcmd, '--json'] + # If path is nil, we are in global mode. + cmd << '--global' unless new_resource.path + # Add the rest. + cmd.concat(args) + # If we are in global mode, cwd will be nil so probably just fine. Add + # the directory for the node binary to $PATH for post-install stuffs. + new_path = [::File.dirname(new_resource.javascript), ENV['PATH'].to_s].join(::File::PATH_SEPARATOR) + out = javascript_shell_out!(cmd, cwd: new_resource.path, group: new_resource.group, user: new_resource.user, environment: {'PATH' => new_path}) + if parse_json + # Parse the JSON. + if out.stdout.strip.empty? + {} + else + Chef::JSONCompat.parse(out.stdout) + end + else + out + end + end + + # Find the version of the current npm binary. + # + # @return [Gem::Version] + def npm_version + @npm_version ||= begin + out = javascript_shell_out!([new_resource.npm_binary, 'version']) + # Older NPM doesn't support --json here we get to regex! + # The line we want looks like: + # npm: '2.12.1' + if out.stdout =~ /npm: '([^']+)'/ + Gem::Version.new($1) + else + raise PoiseJavascript::Error.new("Unable to parse NPM version from #{out.stdout.inspect}") + end + end + end + + # Check the NPM version against a requirement. + # + # @param req [String] Requirement string in Gem::Requirement format. + # @return [Boolean] + def npm_version?(req) + Gem::Requirement.new(req).satisfied_by?(npm_version) + end + + end + end + end +end diff --git a/cookbooks/poise-javascript/files/halite_gem/poise_javascript/resources/npm_install.rb b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/resources/npm_install.rb new file mode 100644 index 0000000..df8af23 --- /dev/null +++ b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/resources/npm_install.rb @@ -0,0 +1,98 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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/provider' +require 'chef/resource' +require 'poise' + +require 'poise_javascript/javascript_command_mixin' + + +module PoiseJavascript + module Resources + # (see NpmInstall::Resource) + # @since 1.0.0 + module NpmInstall + # A `npm_install` resource to install NPM packages based on a package.json. + # + # @provides npm_install + # @action install + # @example + # npm_install '/opt/myapp' + class Resource < Chef::Resource + include PoiseJavascript::JavascriptCommandMixin + provides(:npm_install) + actions(:install) + + # @!attribute path + # Directory to run `npm install` from. + # @return [String] + attribute(:path, kind_of: String, name_attribute: true) + # @!attribute group + # System group to install the packages. + # @return [String, Integer, nil] + attribute(:group, kind_of: [String, Integer, NilClass]) + # @!attribute production + # Enable production install mode. + # @return [Boolean] + attribute(:production, equal_to: [true, false], default: true) + # @!attribute timeout + # Command execution timeout. + # @return [Integer] + attribute(:timeout, kind_of: Integer, default: 900) + # @!attribute unsafe_perm + # Enable --unsafe-perm. + # @return [Boolean, nil] + attribute(:unsafe_perm, equal_to: [true, false, nil], default: true) + # @!attribute user + # System user to install the packages. + # @return [String, Integer, nil] + attribute(:user, kind_of: [String, Integer, NilClass]) + end + + # The default provider for `npm_install`. + # + # @see Resource + # @provides npm_install + class Provider < Chef::Provider + include Poise + include PoiseJavascript::JavascriptCommandMixin + provides(:npm_install) + + # The `install` action for the `npm_install` resource. + # + # @return [void] + def action_install + cmd = [new_resource.npm_binary, 'install'] + cmd << '--production' if new_resource.production + # Set --unsafe-perm unless the property is nil. + unless new_resource.unsafe_perm.nil? + cmd << '--unsafe-perm' + cmd << new_resource.unsafe_perm.to_s + end + # Add the directory for the node binary to $PATH for post-install stuffs. + new_path = [::File.dirname(new_resource.javascript), ENV['PATH'].to_s].join(::File::PATH_SEPARATOR) + output = javascript_shell_out!(cmd, cwd: new_resource.path, user: new_resource.user, group: new_resource.group, environment: {'PATH' => new_path}, timeout: new_resource.timeout).stdout + unless output.strip.empty? + # Any output means it did something. + new_resource.updated_by_last_action(true) + end + end + + end + end + end +end diff --git a/cookbooks/poise-javascript/files/halite_gem/poise_javascript/version.rb b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/version.rb new file mode 100644 index 0000000..f882cf4 --- /dev/null +++ b/cookbooks/poise-javascript/files/halite_gem/poise_javascript/version.rb @@ -0,0 +1,20 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 PoiseJavascript + VERSION = '1.1.0' +end diff --git a/cookbooks/poise-javascript/libraries/default.rb b/cookbooks/poise-javascript/libraries/default.rb new file mode 100644 index 0000000..6286990 --- /dev/null +++ b/cookbooks/poise-javascript/libraries/default.rb @@ -0,0 +1,19 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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. +# + +raise 'Halite is not compatible with no_lazy_load false, please set no_lazy_load true in your Chef configuration file.' unless Chef::Config[:no_lazy_load] +$LOAD_PATH << File.expand_path('../../files/halite_gem', __FILE__) +require "poise_javascript/cheftie" diff --git a/cookbooks/poise-javascript/metadata.json b/cookbooks/poise-javascript/metadata.json new file mode 100644 index 0000000..6c5c746 --- /dev/null +++ b/cookbooks/poise-javascript/metadata.json @@ -0,0 +1 @@ +{"name":"poise-javascript","version":"1.1.0","description":"A Chef cookbook for managing Node.js and io.js installations.","long_description":"# Poise-Javascript Cookbook\n\n[![Build Status](https://img.shields.io/travis/poise/poise-javascript.svg)](https://travis-ci.org/poise/poise-javascript)\n[![Gem Version](https://img.shields.io/gem/v/poise-javascript.svg)](https://rubygems.org/gems/poise-javascript)\n[![Cookbook Version](https://img.shields.io/cookbook/v/poise-javascript.svg)](https://supermarket.chef.io/cookbooks/poise-javascript)\n[![Coverage](https://img.shields.io/codecov/c/github/poise/poise-javascript.svg)](https://codecov.io/github/poise/poise-javascript)\n[![Gemnasium](https://img.shields.io/gemnasium/poise/poise-javascript.svg)](https://gemnasium.com/poise/poise-javascript)\n[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)\n\nA [Chef](https://www.chef.io/) cookbook to provide a unified interface for\ninstalling server-side JavaScript runtimes like Node.js and io.js.\n\n## Quick Start\n\nTo install the latest available version of Node.js 0.12:\n\n```ruby\njavascript_runtime '0.12'\n```\n\n## Supported JavaScript Runtimes\n\nThis cookbook can install Node.js and io.js on Linux and OS X.\n\n## Requirements\n\nChef 12.1 or newer is required.\n\n## Attributes\n\nAttributes are used to configure the default recipe.\n\n* `node['poise-javascript']['install_nodejs']` – Install a Node.js runtime. *(default: true)*\n* `node['poise-javascript']['install_iojs']` – Install an io.js runtime. *(default: false)*\n\n## Recipes\n\n### `default`\n\nThe default recipe installs Node.js or io.js based on the node attributes. It is\nentirely optional and can be ignored in favor of direct use of the\n`javascript_runtime` resource.\n\n## Resources\n\n### `javascript_runtime`\n\nThe `javascript_runtime` resource installs a JavaScript interpreter.\n\n```ruby\njavascript_runtime '0.12'\n```\n\n#### Actions\n\n* `:install` – Install the JavaScript interpreter. *(default)*\n* `:uninstall` – Uninstall the JavaScript interpreter.\n\n#### Properties\n\n* `version` – Version of the runtime to install. If a partial version is given,\n use the latest available version matching that prefix. *(name property)*\n\n#### Provider Options\n\nThe `poise-javascript` library offers an additional way to pass configuration\ninformation to the final provider called \"options\". Options are key/value pairs\nthat are passed down to the `javascript_runtime` provider and can be used to control how it\ninstalls JavaScript. These can be set in the `javascript_runtime`\nresource using the `options` method, in node attributes or via the\n`javascript_runtime_options` resource. The options from all sources are merged\ntogether in to a single hash.\n\nWhen setting options in the resource you can either set them for all providers:\n\n```ruby\njavascript_runtime 'myapp' do\n version '0.10'\n options dev_package: false\nend\n```\n\nor for a single provider:\n\n```ruby\njavascript_runtime 'myapp' do\n version '0.10'\n options :system, dev_package: false\nend\n```\n\nSetting via node attributes is generally how an end-user or application cookbook\nwill set options to customize installations in the library cookbooks they are using.\nYou can set options for all installations or for a single runtime:\n\n```ruby\n# Global, for all installations.\noverride['poise-javascript']['options']['version'] = '0.10'\n# Single installation.\noverride['poise-javascript']['myapp']['version'] = 'iojs'\n```\n\nThe `javascript_runtime_options` resource is also available to set node attributes\nfor a specific installation in a DSL-friendly way:\n\n```ruby\njavascript_runtime_options 'myapp' do\n version 'iojs'\nend\n```\n\nUnlike resource attributes, provider options can be different for each provider.\nNot all providers support the same options so make sure to the check the\ndocumentation for each provider to see what options the use.\n\n### `javascript_runtime_options`\n\nThe `javascript_runtime_options` resource allows setting provider options in a\nDSL-friendly way. See [the Provider Options](#provider-options) section for more\ninformation about provider options overall.\n\n```ruby\njavascript_runtime_options 'myapp' do\n version 'iojs'\nend\n```\n\n#### Actions\n\n* `:run` – Apply the provider options. *(default)*\n\n#### Properties\n\n* `resource` – Name of the `javascript_runtime` resource. *(name property)*\n* `for_provider` – Provider to set options for.\n\nAll other attribute keys will be used as options data.\n\n### `javascript_execute`\n\nThe `javascript_execute` resource executes a JavaScript script using the configured runtime.\n\n```ruby\njavascript_execute 'myapp.js' do\n user 'myuser'\nend\n```\n\nThis uses the built-in `execute` resource and supports all the same properties.\n\n#### Actions\n\n* `:run` – Execute the script. *(default)*\n\n#### Properties\n\n* `command` – Script and arguments to run. Must not include the `node`. *(name attribute)*\n* `javascript` – Name of the `javascript_runtime` resource to use. If not specified, the\n most recently declared `javascript_runtime` will be used. Can also be set to the\n full path to a `node` binary.\n\nFor other properties see the [Chef documentation](https://docs.chef.io/resource_execute.html#attributes).\n\n### `node_package`\n\nThe `node_package` resource installs Node.js packages using\n[NPM](https://www.npmjs.com/).\n\n```ruby\nnode_package 'express' do\n version '4.13.3'\nend\n```\n\nThis uses the built-in `package` resource and supports the same actions and\nproperties. Multi-package installs are supported using the standard syntax.\n\n#### Actions\n\n* `:install` – Install the package. *(default)*\n* `:upgrade` – Upgrade the package.\n* `:remove` – Uninstall the package.\n\nThe `:purge` and `:reconfigure` actions are not supported.\n\n#### Properties\n\n* `group` – System group to install the package.\n* `package_name` – Package or packages to install. *(name property)*\n* `path` – Path to install the package in to. If unset install using `--global`.\n *(default: nil)*\n* `version` – Version or versions to install.\n* `javascript` – Name of the `javascript_runtime` resource to use. If not specified, the\n most recently declared `javascript_runtime` will be used. Can also be set to the\n full path to a `node` binary.\n* `unsafe_perm` – Enable `--unsafe-perm`. *(default: true)*\n* `user` – System user to install the package.\n\nFor other properties see the [Chef documentation](https://docs.chef.io/resource_package.html#attributes).\nThe `response_file`, `response_file_variables`, and `source` properties are not\nsupported.\n\n### `npm_install`\n\nThe `npm_install` resource runs `npm install` for a package.\n\n```ruby\nnpm_install '/opt/myapp'\n```\n\nThe underlying `npm install` command will run on every converge, but notifications\nwill only be triggered if a package is actually installed.\n\n#### Actions\n\n* `:install` – Run `npm install`. *(default)*\n\n#### Properties\n\n* `path` – Path to the package folder containing a `package.json`. *(name attribute)*\n* `group` – System group to install the packages.\n* `javascript` – Name of the `javascript_runtime` resource to use. If not specified, the\n most recently declared `javascript_runtime` will be used. Can also be set to the\n full path to a `node` binary.\n* `production` – Enable production install mode. *(default: true)*\n* `unsafe_perm` – Enable `--unsafe-perm`. *(default: true)*\n* `user` – System user to install the packages.\n\n## Javascript Providers\n\n### Common Options\n\nThese provider options are supported by all providers.\n\n* `version` – Override the runtime version.\n\n### `system`\n\nThe `system` provider installs Node.js using system packages. This is currently\nonly tested on platforms using `apt-get` and `yum` (Debian, Ubuntu, RHEL, CentOS\nAmazon Linux, and Fedora). It may work on other platforms but is untested.\n\n```ruby\njavascript_runtime 'myapp' do\n provider :system\n version '0.10'\nend\n```\n\n#### Options\n\n* `dev_package` – Install the package with the headers and other development\n files. Can be set to a string to select the dev package specifically.\n *(default: true)*\n* `package_name` – Override auto-detection of the package name.\n* `package_upgrade` – Install using action `:upgrade`. *(default: false)*\n* `package_version` – Override auto-detection of the package version.\n\n### `scl`\n\nThe `scl` provider installs Node.js using the [Software Collections](https://www.softwarecollections.org/)\npackages. This is only available on RHEL and CentOS. SCL offers more\nrecent versions of Node.js than the system packages for the most part. If an SCL\npackage exists for the requests version, it will be used in preference to the\n`system` provider.\n\n```ruby\njavascript_runtime 'myapp' do\n provider :scl\n version '0.10'\nend\n```\n\n### `nodejs`\n\nThe `nodejs` provider installs Node.js from the static binaries on nodejs.org.\nSupport is included for Linux and OS X.\n\n```ruby\njavascript_runtime 'myapp' do\n provider :nodejs\n version '0.12'\nend\n```\n\n#### Options\n\n* `path` – Folder to install Node.js to. *(default: /opt/nodejs-)*\n* `static_version` – Specific version number to use for computing the URL and\n path. *(default: automatic from `version`)*\n* `strip_components` – Value to pass to tar --strip-components. *(automatic)*\n* `url` – URL template to download the archive from. *(default: automatic)*\n\n### `iojs`\n\nThe `iojs` provider installs io.js from the static binaries on iojs.org.\nSupport is included for Linux and OS X.\n\n```ruby\njavascript_runtime 'myapp' do\n provider :iojs\n version '3'\nend\n```\n\n#### Options\n\n* `path` – Folder to install io.js to. *(default: /opt/iojs-)*\n* `static_version` – Specific version number to use for computing the URL and\n path. *(default: automatic from `version`)*\n* `strip_components` – Value to pass to tar --strip-components. *(automatic)*\n* `url` – URL template to download the archive from. *(default: automatic)*\n\n## Sponsors\n\nThe Poise test server infrastructure is sponsored by [Rackspace](https://rackspace.com/).\n\n## License\n\nCopyright 2015-2016, Noah Kantrowitz\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","maintainer":"Noah Kantrowitz","maintainer_email":"noah@coderanger.net","license":"Apache 2.0","platforms":{},"dependencies":{"poise":"~> 2.0","poise-languages":"~> 2.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{},"source_url":"https://github.com/poise/poise-javascript","issues_url":"https://github.com/poise/poise-javascript/issues","chef_version":"~> 12","ohai_version":{}} \ No newline at end of file diff --git a/cookbooks/poise-javascript/recipes/default.rb b/cookbooks/poise-javascript/recipes/default.rb new file mode 100644 index 0000000..eb8b5c7 --- /dev/null +++ b/cookbooks/poise-javascript/recipes/default.rb @@ -0,0 +1,19 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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. +# + +# Default runtimes, last one will be the default. +javascript_runtime 'iojs' if node['poise-javascript']['install_iojs'] +javascript_runtime 'nodejs' if node['poise-javascript']['install_nodejs'] diff --git a/cookbooks/poise-languages/CHANGELOG.md b/cookbooks/poise-languages/CHANGELOG.md new file mode 100644 index 0000000..0a00a35 --- /dev/null +++ b/cookbooks/poise-languages/CHANGELOG.md @@ -0,0 +1,79 @@ +# Changelog + +## v2.1.0 + +* Allow customizing properties on the system package install resource via a block + +## v2.0.5 + +* Fixes to work with the latest Chef (again). + +## v2.0.4 + +* Fixes to work with the latest Chef. + +## v2.0.3 + +* Correct the subscription repository name used for SCLs on RedHat. + +## v2.0.2 + +* Don't try to use SCL providers on Amazon Linux. + +## v2.0.1 + +* Don't error on `Chef::Decorator::Lazy` proxy objects for `candidate_version`. +* Retry system and SCL package installs because transient network failures. + +## v2.0.0 + +* Backwards-incompatible change to SCL management to comply with their new repo + packages and layout. Uses `centos-release-scl-rh` repo package or the + `rhel-variant-rhscl` RedHat subscription. + +## v1.4.0 + +* Use `poise-archive` to unpack static binary archives. This should work better + on AIX and Solaris, as well as making it easier to add more archive formats in + the future. + +## v1.3.3 + +* [#3](https://github.com/poise/poise-languages/pull/3) Fix `static` binary + installation on AIX and Solaris. +* Only run the candidate version check for `system` installs when we aren't + passing in package_version. + +## v1.3.2 + +* Handle static archive unpacking correctly when a single download is shared + between two paths. + +## v1.3.1 + +* Fix system package installs on OS X. + +## v1.3.0 + +* `%{machine_label}` is available in URL template for static download. +* Automatically retry `remote_file` downloads to handle transient HTTP failures. +* All `*_shell_out` language command helpers use `poise_shell_out` to set `$HOME` + and other environment variables by default. + +## v1.2.0 + +* Support for installing development headers with SCL providers. +* Add `PoiseLanguages::Utils.shelljoin` for encoding command arrays with some + bash metadata characters allowed. +* [#1](https://github.com/poise/poise-languages/pull/1) Fix typo in gemspec. + +## v1.1.0 + +* Add helpers for installing from static archives. +* Improve auto-selection rules for system and SCL providers. +* Support SCL packages that depend on other SCL packages. +* Support Ruby 2.0 again. + +## v1.0.0 + +* Initial release! diff --git a/cookbooks/poise-languages/README.md b/cookbooks/poise-languages/README.md new file mode 100644 index 0000000..30bc6da --- /dev/null +++ b/cookbooks/poise-languages/README.md @@ -0,0 +1,27 @@ +# Poise-Languages Cookbook + +[![Build Status](https://img.shields.io/travis/poise/poise-languages.svg)](https://travis-ci.org/poise/poise-languages) +[![Gem Version](https://img.shields.io/gem/v/poise-languages.svg)](https://rubygems.org/gems/poise-languages) +[![Cookbook Version](https://img.shields.io/cookbook/v/poise-languages.svg)](https://supermarket.chef.io/cookbooks/poise-languages) +[![Coverage](https://img.shields.io/codecov/c/github/poise/poise-languages.svg)](https://codecov.io/github/poise/poise-languages) +[![Gemnasium](https://img.shields.io/gemnasium/poise/poise-languages.svg)](https://gemnasium.com/poise/poise-languages) +[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) + +Shared support code for Poise's language cookbooks like poise-ruby and +poise-python. + +## License + +Copyright 2015-2017, Noah Kantrowitz + +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/poise-languages/files/halite_gem/poise_languages.rb b/cookbooks/poise-languages/files/halite_gem/poise_languages.rb new file mode 100644 index 0000000..9952907 --- /dev/null +++ b/cookbooks/poise-languages/files/halite_gem/poise_languages.rb @@ -0,0 +1,26 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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 PoiseLanguages + autoload :Command, 'poise_languages/command' + autoload :Error, 'poise_languages/error' + autoload :Scl, 'poise_languages/scl' + autoload :Static, 'poise_languages/static' + autoload :System, 'poise_languages/system' + autoload :Utils, 'poise_languages/utils' + autoload :VERSION, 'poise_languages/version' +end diff --git a/cookbooks/poise-languages/files/halite_gem/poise_languages/command.rb b/cookbooks/poise-languages/files/halite_gem/poise_languages/command.rb new file mode 100644 index 0000000..bd46621 --- /dev/null +++ b/cookbooks/poise-languages/files/halite_gem/poise_languages/command.rb @@ -0,0 +1,25 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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 PoiseLanguages + # A namespace for language-command-related stuff. + # + # @since 1.0.0 + module Command + autoload :Mixin, 'poise_languages/command/mixin' + end +end diff --git a/cookbooks/poise-languages/files/halite_gem/poise_languages/command/mixin.rb b/cookbooks/poise-languages/files/halite_gem/poise_languages/command/mixin.rb new file mode 100644 index 0000000..15e2c7d --- /dev/null +++ b/cookbooks/poise-languages/files/halite_gem/poise_languages/command/mixin.rb @@ -0,0 +1,241 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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' + +require 'poise' + +require 'poise_languages/error' +require 'poise_languages/utils' + + +module PoiseLanguages + module Command + # A mixin for resources and providers that run language commands. + # + # @since 1.0.0 + module Mixin + include Poise::Utils::ResourceProviderMixin + + # A mixin for resources that run language commands. Also available as a + # parameterized mixin via `include PoiseLanguages::Command::Mixin::Resource(name)`. + # + # @example + # class MyLangThing + # include PoiseLanguages::Command::Mixin::Resource(:mylang) + # # ... + # end + module Resource + include Poise::Resource + poise_subresource(true) + + private + + # Implementation of the $name accessor. + # + # @api private + # @param name [Symbol] Language name. + # @param runtime [Symbol] Language runtime resource name. + # @param val [String, Chef::Resource, Poise::NOT_PASSED, nil] Accessor value. + # @return [String] + def language_command_runtime(name, runtime, default_binary, val=Poise::NOT_PASSED) + unless val == Poise::NOT_PASSED + path_arg = parent_arg = nil + # Figure out which property we are setting. + if val.is_a?(String) + # Check if it is a runtime resource. + begin + parent_arg = run_context.resource_collection.find("#{runtime}[#{val}]") + rescue Chef::Exceptions::ResourceNotFound + # Check if something looks like a path, defined as containing + # either / or \. While a single word could be a path, I think the + # UX win of better error messages should take priority. + might_be_path = val =~ %r{/|\\} + if might_be_path + Chef::Log.debug("[#{self}] #{runtime}[#{val}] not found, treating it as a path") + path_arg = val + else + # Surface the error up to the user. + raise + end + end + else + parent_arg = val + end + # Set both attributes. + send(:"parent_#{name}", parent_arg) + set_or_return(name, path_arg, kind_of: [String, NilClass]) + else + # Getter behavior. Using the ivar directly is kind of gross but oh well. + instance_variable_get(:"@#{name}") || default_language_command_runtime(name, default_binary) + end + end + + # Compute the path to the default runtime binary. + # + # @api private + # @param name [Symbol] Language name. + # @return [String] + def default_language_command_runtime(name, default_binary) + parent = send(:"parent_#{name}") + if parent + parent.send(:"#{name}_binary") + else + PoiseLanguages::Utils.which(default_binary || name.to_s) + end + end + + # Inherit language parent from another resource. + # + # @api private + # @param name [Symbol] Language name. + # @param resource [Chef::Resource] Resource to inherit from. + # @return [void] + def language_command_runtime_from_parent(name, resource) + parent = resource.send(:"parent_#{name}") + if parent + send(:"parent_#{name}", parent) + else + path = resource.send(name) + if path + send(name, path) + end + end + end + + module ClassMethods + # Configure this module or class for a specific language. + # + # @param name [Symbol] Language name. + # @param runtime [Symbol] Language runtime resource name. + # @param timeout [Boolean] Enable the timeout attribute. + # @param default_binary [String] Name of the default language binary. + # @return [void] + def language_command_mixin(name, runtime: :"#{name}_runtime", timeout: true, default_binary: nil) + # Create the parent attribute. + parent_attribute(name, type: runtime, optional: true) + + # Timeout attribute for the shell_out wrappers in the provider. + attribute(:timeout, kind_of: Integer, default: 900) if timeout + + # Create the main accessor for the parent/path. + define_method(name) do |val=Poise::NOT_PASSED| + language_command_runtime(name, runtime, default_binary, val) + end + + # Create the method to inherit settings from another resource. + define_method(:"#{name}_from_parent") do |resource| + language_command_runtime_from_parent(name, resource) + end + private :"#{name}_from_parent" + end + + def language_command_default_binary(val=Poise::NOT_PASSED) + @language_command_default_binary = val if val != Poise::NOT_PASSED + @language_command_default_binary + end + + # @api private + def included(klass) + super + klass.extend(ClassMethods) + end + end + + extend ClassMethods + Poise::Utils.parameterized_module(self) {|*args| language_command_mixin(*args) } + end # /module Resource + + # A mixin for providers that run language commands. + module Provider + include Poise::Utils::ShellOut + + private + + # Run a command using the configured language via `shell_out`. + # + # @api private + # @param name [Symbol] Language name. + # @param command_args [Array] Arguments to `shell_out`. + # @return [Mixlib::ShellOut] + def language_command_shell_out(name, *command_args, **options) + # Inject our environment variables if needed. + options[:environment] ||= {} + parent = new_resource.send(:"parent_#{name}") + if parent + options[:environment].update(parent.send(:"#{name}_environment")) + end + # Inject other options. + options[:timeout] ||= new_resource.timeout + # Find the actual binary to use. Raise an exception if we see false + # which happens if no parent resource is found, no explicit default + # binary was given, and which() fails to find a thing. + binary = new_resource.send(name) + raise Error.new("Unable to find a #{name} binary for command: #{command_args.is_a?(Array) ? Shellwords.shelljoin(command_args) : command_args}") unless binary + command = if command_args.length == 1 && command_args.first.is_a?(String) + # String mode, sigh. + "#{Shellwords.escape(binary)} #{command_args.first}" + else + # Array mode. Handle both ('one', 'two') and (['one', 'two']). + [binary] + command_args.flatten + end + Chef::Log.debug("[#{new_resource}] Running #{name} command: #{command.is_a?(Array) ? Shellwords.shelljoin(command) : command}") + # Run the command + poise_shell_out(command, options) + end + + # Run a command using the configured language via `shell_out!`. + # + # @api private + # @param name [Symbol] Language name. + # @param command_args [Array] Arguments to `shell_out!`. + # @return [Mixlib::ShellOut] + def language_command_shell_out!(name, *command_args) + send(:"#{name}_shell_out", *command_args).tap(&:error!) + end + + module ClassMethods + # Configure this module or class for a specific language. + # + # @param name [Symbol] Language name. + # @return [void] + def language_command_mixin(name) + define_method(:"#{name}_shell_out") do |*command_args| + language_command_shell_out(name, *command_args) + end + private :"#{name}_shell_out" + + define_method(:"#{name}_shell_out!") do |*command_args| + language_command_shell_out!(name, *command_args) + end + private :"#{name}_shell_out!" + end + + # @api private + def included(klass) + super + klass.extend(ClassMethods) + end + end + + extend ClassMethods + Poise::Utils.parameterized_module(self) {|*args| language_command_mixin(*args) } + end # /module Provider + + Poise::Utils.parameterized_module(self) {|*args| language_command_mixin(*args) } + end # /module Mixin + end +end diff --git a/cookbooks/poise-languages/files/halite_gem/poise_languages/error.rb b/cookbooks/poise-languages/files/halite_gem/poise_languages/error.rb new file mode 100644 index 0000000..ddfadee --- /dev/null +++ b/cookbooks/poise-languages/files/halite_gem/poise_languages/error.rb @@ -0,0 +1,21 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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 PoiseLanguages + class Error < ::Exception + end +end diff --git a/cookbooks/poise-languages/files/halite_gem/poise_languages/scl.rb b/cookbooks/poise-languages/files/halite_gem/poise_languages/scl.rb new file mode 100644 index 0000000..b0b5771 --- /dev/null +++ b/cookbooks/poise-languages/files/halite_gem/poise_languages/scl.rb @@ -0,0 +1,24 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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 PoiseLanguages + module Scl + autoload :Mixin, 'poise_languages/scl/mixin' + autoload :Resource, 'poise_languages/scl/resource' + autoload :Provider, 'poise_languages/scl/resource' + end +end diff --git a/cookbooks/poise-languages/files/halite_gem/poise_languages/scl/mixin.rb b/cookbooks/poise-languages/files/halite_gem/poise_languages/scl/mixin.rb new file mode 100644 index 0000000..63f6cd0 --- /dev/null +++ b/cookbooks/poise-languages/files/halite_gem/poise_languages/scl/mixin.rb @@ -0,0 +1,134 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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 'poise_languages/scl/resource' + + +module PoiseLanguages + module Scl + module Mixin + private + + def install_scl_package + pkg = scl_package + poise_languages_scl options[:package_name] || pkg[:name] do + action :upgrade if options[:package_upgrade] + dev_package options[:dev_package] == true ? pkg[:devel_name] : options[:dev_package] + parent new_resource + version options[:package_version] + end + end + + def uninstall_scl_package + install_scl_package.tap do |r| + r.action(:uninstall) + end + end + + def scl_package + @scl_package ||= self.class.find_scl_package(node, options['version']).tap do |p| + raise PoiseLanguages::Error.new("No SCL repoistory package for #{node['platform']} #{node['platform_version']}") unless p + end + end + + def scl_folder + ::File.join('', 'opt', 'rh', scl_package[:name]) + end + + def scl_environment + parse_enable_file(::File.join(scl_folder, 'enable')) + end + + # Parse an SCL enable file to extract the environment variables set in it. + # + # @param path [String] Path to the enable file. + # @return [Hash] + def parse_enable_file(path, env={}) + # Doesn't exist yet, so running Python will fail anyway. Just make sure + # it fails in the expected way. + return {} unless File.exist?(path) + # Yes, this is a bash parser in regex. Feel free to be mad at me. + IO.readlines(path).inject(env) do |memo, line| + if match = line.match(/^export (\w+)=(.*)$/) + memo[match[1]] = match[2].gsub(/\$(?:\{(\w+)(:\+:\$\{\w+\})?\}|(\w+))/) do + key = $1 || $3 + value = (memo[key] || ENV[key]).to_s + value = ":#{value}" if $2 && !value.empty? + value + end + elsif match = line.match(/^\. scl_source enable (\w+)$/) + # Parse another file. + memo.update(parse_enable_file(::File.join('', 'opt', 'rh', match[1], 'enable'), memo)) + end + memo + end + end + + module ClassMethods + def provides_auto?(node, resource) + # They don't build 32-bit versions for these and only for RHEL/CentOS. + # TODO: What do I do about Fedora and/or Amazon? + return false unless node['kernel']['machine'] == 'x86_64' && node.platform?('redhat', 'centos') + version = inversion_options(node, resource)['version'] + !!find_scl_package(node, version) + end + + # Set some default inversion provider options. Package name can't get + # a default value here because that would complicate the handling of + # {system_package_candidates}. + # + # @api private + def default_inversion_options(node, resource) + super.merge({ + # Install dev headers? + dev_package: true, + # Manual overrides for package name and/or version. + package_name: nil, + package_version: nil, + # Set to true to use action :upgrade on system packages. + package_upgrade: false, + }) + end + + def find_scl_package(node, version) + platform_version = ::Gem::Version.create(node['platform_version']) + # Filter out anything that doesn't match this EL version. + candidate_packages = scl_packages.select {|p| p[:platform_version].satisfied_by?(platform_version) } + # Find something with a prefix match on the Python version. + candidate_packages.find {|p| p[:version].start_with?(version) } + end + + private + + def scl_packages + @scl_packages ||= [] + end + + def scl_package(version, name, devel_name=nil, platform_version='>= 6.0') + scl_packages << {version: version, name: name, devel_name: devel_name, platform_version: ::Gem::Requirement.create(platform_version)} + end + + def included(klass) + super + klass.extend(ClassMethods) + end + end + + extend ClassMethods + + end + end +end diff --git a/cookbooks/poise-languages/files/halite_gem/poise_languages/scl/resource.rb b/cookbooks/poise-languages/files/halite_gem/poise_languages/scl/resource.rb new file mode 100644 index 0000000..1e92c2e --- /dev/null +++ b/cookbooks/poise-languages/files/halite_gem/poise_languages/scl/resource.rb @@ -0,0 +1,159 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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' +require 'chef/provider' +require 'poise' + + +module PoiseLanguages + module Scl + # A `poise_language_scl` resource to manage installing a language from + # SCL packages. This is an internal implementation detail of + # poise-languages. + # + # @api private + # @since 1.0 + # @provides poise_languages_scl + # @action install + # @action uninstall + class Resource < Chef::Resource + include Poise + provides(:poise_languages_scl) + actions(:install, :upgrade, :uninstall) + + # @!attribute package_name + # Name of the SCL package for the language. + # @return [String] + attribute(:package_name, kind_of: String, name_attribute: true) + # @!attribute dev_package + # Name of the -devel package with headers and whatnot. + # @return [String, nil] + attribute(:dev_package, kind_of: [String, NilClass]) + # @!attribute version + # Version of the SCL package(s) to install. If unset, follows the same + # semantics as the core `package` resource. + # @return [String, nil] + attribute(:version, kind_of: [String, NilClass]) + # @!attribute parent + # Resource for the language runtime. Used only for messages. + # @return [Chef::Resource] + attribute(:parent, kind_of: Chef::Resource, required: true) + end + + # The default provider for `poise_languages_scl`. + # + # @api private + # @since 1.0 + # @see Resource + # @provides poise_languages_scl + class Provider < Chef::Provider + include Poise + provides(:poise_languages_scl) + + # The `install` action for the `poise_languages_scl` resource. + # + # @return [void] + def action_install + notifying_block do + install_scl_repo + flush_yum_cache + install_scl_package(:install) + install_scl_devel_package(:install) if new_resource.dev_package + end + end + + # The `upgrade` action for the `poise_languages_scl` resource. + # + # @return [void] + def action_upgrade + notifying_block do + install_scl_repo + flush_yum_cache + install_scl_package(:upgrade) + install_scl_devel_package(:upgrade) if new_resource.dev_package + end + end + + # The `uninstall` action for the `poise_languages_scl` resource. + # + # @return [void] + def action_uninstall + notifying_block do + uninstall_scl_devel_package if new_resource.dev_package + uninstall_scl_package + end + end + + private + + def install_scl_repo + if node.platform?('redhat') + # Set up the real RHSCL subscription. + # NOTE: THIS IS NOT TESTED BECAUSE REDHAT DOESN'T OFFER ANY WAY TO DO + # AUTOMATED TESTING. IF YOU USE REDHAT AND THIS BREAKS, PLEASE LET ME + # KNOW BY FILING A GITHUB ISSUE AT http://github.com/poise/poise-languages/issues/new. + repo_name = "rhel-server-rhscl-#{node['platform_version'][0]}-rpms" + execute "subscription-manager repos --enable #{repo_name}" do + not_if { shell_out!('subscription-manager repos --list').stdout.include?(repo_name) } + end + else + package 'centos-release-scl-rh' do + # Using upgrade here because changes very very rare and always + # important when they happen. If this breaks your prod infra, I'm + # sorry :-( + action :upgrade + retries 5 + end + end + end + + def flush_yum_cache + ruby_block 'flush_yum_cache' do + block do + # Equivalent to flush_cache after: true + Chef::Provider::Package::Yum::YumCache.instance.reload + end + end + end + + def install_scl_package(action) + package new_resource.package_name do + action action + retries 5 + version new_resource.version + end + end + + def install_scl_devel_package(action) + package new_resource.dev_package do + action action + retries 5 + version new_resource.version + end + end + + def uninstall_scl_package + install_scl_package(:remove) + end + + def uninstall_scl_devel_package + install_scl_devel_package(:remove) + end + + end + end +end diff --git a/cookbooks/poise-languages/files/halite_gem/poise_languages/static.rb b/cookbooks/poise-languages/files/halite_gem/poise_languages/static.rb new file mode 100644 index 0000000..efdbe10 --- /dev/null +++ b/cookbooks/poise-languages/files/halite_gem/poise_languages/static.rb @@ -0,0 +1,34 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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 'poise/utils' + + +module PoiseLanguages + # Helpers for installing languages from static archives. + # + # @since 1.1.0 + module Static + autoload :Mixin, 'poise_languages/static/mixin' + autoload :Resource, 'poise_languages/static/resource' + autoload :Provider, 'poise_languages/static/resource' + + Poise::Utils.parameterized_module(self) do |opts| + require 'poise_languages/static/mixin' + include PoiseLanguages::Static::Mixin(opts) + end + end +end diff --git a/cookbooks/poise-languages/files/halite_gem/poise_languages/static/mixin.rb b/cookbooks/poise-languages/files/halite_gem/poise_languages/static/mixin.rb new file mode 100644 index 0000000..d189331 --- /dev/null +++ b/cookbooks/poise-languages/files/halite_gem/poise_languages/static/mixin.rb @@ -0,0 +1,144 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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 'poise_languages/static/resource' + + +module PoiseLanguages + module Static + # Mixin for language providers to install from static archives. + # + # @since 1.1.0 + module Mixin + private + + def install_static + url = static_url + poise_languages_static static_folder do + source url + strip_components options['strip_components'] + end + end + + def uninstall_static + install_static.tap do |r| + r.action(:uninstall) + end + end + + def static_folder + options['path'] || ::File.join('', 'opt', "#{self.class.static_name}-#{options['static_version']}") + end + + def static_url + options['url'] % static_url_variables + end + + def static_url_variables + { + version: options['static_version'], + kernel: node['kernel']['name'].downcase, + machine: node['kernel']['machine'], + machine_label: self.class.static_machine_label_wrapper(node, new_resource), + } + end + + module ClassMethods + attr_accessor :static_name + attr_accessor :static_versions + attr_accessor :static_machines + attr_accessor :static_url + attr_accessor :static_strip_components + attr_accessor :static_retries + + def provides_auto?(node, resource) + # Check that the version starts with our project name and the machine + # we are on is supported. + resource.version.to_s =~ /^#{static_name}(-|$)/ && static_machines.include?(static_machine_label_wrapper(node, resource)) + end + + # Set some default inversion provider options. Package name can't get + # a default value here because that would complicate the handling of + # {system_package_candidates}. + # + # @api private + def default_inversion_options(node, resource) + super.merge({ + # Path to install the package. Defaults to /opt/name-version. + path: nil, + # Number of times to retry failed downloads. + retries: static_retries, + # Full version number for use in interpolation. + static_version: static_version(node, resource), + # Value to pass to tar --strip-components. + strip_components: static_strip_components, + # URL template to download from. + url: static_url, + }) + end + + def static_options(name: nil, versions: [], machines: %w{linux-i686 linux-x86_64}, url: nil, strip_components: 1, retries: 5) + raise PoiseLanguages::Error.new("Static archive URL is required, on #{self}") unless url + self.static_name = name || provides.to_s + self.static_versions = versions + self.static_machines = Set.new(machines) + self.static_url = url + self.static_strip_components = strip_components + self.static_retries = retries + end + + def static_version(node, resource) + raw_version = resource.version.to_s.gsub(/^#{static_name}(-|$)/, '') + if static_versions.include?(raw_version) + raw_version + else + # Prefix match or just use the given version number if not found. + # This allow mild future proofing in some cases. + static_versions.find {|v| v.start_with?(raw_version) } || raw_version + end + end + + def static_machine_label(node, _resource=nil) + "#{node['kernel']['name'].downcase}-#{node['kernel']['machine']}" + end + + # Wrapper for {#static_machine_label} because I need to add an argument. + # This preserves backwards compat. + # + # @api private + def static_machine_label_wrapper(node, resource) + args = [node] + arity = method(:static_machine_label).arity + args << resource if arity > 1 || arity < 0 + static_machine_label(*args) + end + + def included(klass) + super + klass.extend ClassMethods + end + + end + + extend ClassMethods + + Poise::Utils.parameterized_module(self) do |opts| + static_options(opts) + end + + end + end +end diff --git a/cookbooks/poise-languages/files/halite_gem/poise_languages/static/resource.rb b/cookbooks/poise-languages/files/halite_gem/poise_languages/static/resource.rb new file mode 100644 index 0000000..150eb44 --- /dev/null +++ b/cookbooks/poise-languages/files/halite_gem/poise_languages/static/resource.rb @@ -0,0 +1,139 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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' +require 'chef/provider' +require 'poise' + + +module PoiseLanguages + module Static + # A `poise_languages_static` resource to manage installing a language from + # static binary archives. This is an internal implementation detail of + # poise-languages. + # + # @api private + # @since 1.1.0 + # @provides poise_languages_static + # @action install + # @action uninstall + class Resource < Chef::Resource + include Poise + provides(:poise_languages_static) + actions(:install, :uninstall) + + # @!attribute path + # Directory to install to. + # @return [String] + attribute(:path, kind_of: String, name_attribute: true) + # @!attribute download_retries + # Number of times to retry failed downloads. Defaults to 5. + # @return [Integer] + attribute(:download_retries, kind_of: Integer, default: 5) + # @!attribute source + # URL to download from. + # @return [String] + attribute(:source, kind_of: String, required: true) + # @!attribute strip_components + # Value to pass to tar --strip-components. + # @return [String, Integer, nil] + attribute(:strip_components, kind_of: [String, Integer, NilClass], default: 1) + + def cache_path + @cache_path ||= ::File.join(Chef::Config[:file_cache_path], source.split(/\//).last) + end + end + + # The default provider for `poise_languages_static`. + # + # @api private + # @since 1.0 + # @see Resource + # @provides poise_languages_static + class Provider < Chef::Provider + include Poise + provides(:poise_languages_static) + + # The `install` action for the `poise_languages_static` resource. + # + # @return [void] + def action_install + notifying_block do + download_archive + create_directory + # Unpack is handled as a notification from download_archive. + end + end + + # The `uninstall` action for the `poise_languages_static` resource. + # + # @return [void] + def action_uninstall + notifying_block do + delete_archive + delete_directory + end + end + + private + + def create_directory + unpack_resource = unpack_archive + directory new_resource.path do + user 0 + group 0 + mode '755' + notifies :unpack, unpack_resource, :immediately + end + end + + def download_archive + unpack_resource = unpack_archive + remote_file new_resource.cache_path do + source new_resource.source + owner 0 + group 0 + mode '644' + notifies :unpack, unpack_resource, :immediately if ::File.exist?(new_resource.path) + retries new_resource.download_retries + end + end + + def unpack_archive + @unpack_archive ||= poise_archive new_resource.cache_path do + # Run via notification from #download_archive and #create_directory. + action :nothing + destination new_resource.path + strip_components new_resource.strip_components + end + end + + def delete_archive + file new_resource.cache_path do + action :delete + end + end + + def delete_directory + directory new_resource.path do + action :delete + recursive true + end + end + + end + end +end diff --git a/cookbooks/poise-languages/files/halite_gem/poise_languages/system.rb b/cookbooks/poise-languages/files/halite_gem/poise_languages/system.rb new file mode 100644 index 0000000..5ece43c --- /dev/null +++ b/cookbooks/poise-languages/files/halite_gem/poise_languages/system.rb @@ -0,0 +1,24 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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 PoiseLanguages + module System + autoload :Mixin, 'poise_languages/system/mixin' + autoload :Resource, 'poise_languages/system/resource' + autoload :Provider, 'poise_languages/system/resource' + end +end diff --git a/cookbooks/poise-languages/files/halite_gem/poise_languages/system/mixin.rb b/cookbooks/poise-languages/files/halite_gem/poise_languages/system/mixin.rb new file mode 100644 index 0000000..8b1764e --- /dev/null +++ b/cookbooks/poise-languages/files/halite_gem/poise_languages/system/mixin.rb @@ -0,0 +1,170 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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 'poise_languages/system/resource' + + +module PoiseLanguages + module System + module Mixin + + private + + # Install a language using system packages. + # + # @api public + # @return [PoiseLanguages::System::Resource] + def install_system_packages(&block) + dev_package_overrides = system_dev_package_overrides + poise_languages_system system_package_name do + # Otherwise use the default install action. + action(:upgrade) if options['package_upgrade'] + parent new_resource + # Don't pass true because we want the default computed behavior for that. + dev_package options['dev_package'] unless options['dev_package'] == true + dev_package_overrides dev_package_overrides + package_version options['package_version'] if options['package_version'] + version options['version'] + instance_exec(&block) if block + end + end + + # Uninstall a language using system packages. + # + # @api public + # @return [PoiseLanguages::System::Resource] + def uninstall_system_packages(&block) + install_system_packages.tap do |r| + r.action(:uninstall) + r.instance_exec(&block) if block + end + end + + # Compute all possible package names for a given language version. Must be + # implemented by mixin users. Versions are expressed as prefixes so '' + # matches all versions, '2' matches 2.x. + # + # @abstract + # @api public + # @param version [String] Language version prefix. + # @return [Array] + def system_package_candidates(version) + raise NotImplementedError + end + + # Compute the default package name for the base package for this language. + # + # @api public + # @return [String] + def system_package_name + # If we have an override, just use that. + return options['package_name'] if options['package_name'] + # Look up all packages for this language on this platform. + system_packages = self.class.packages && node.value_for_platform(self.class.packages) + if !system_packages && self.class.default_package + Chef::Log.debug("[#{new_resource}] No known packages for #{node['platform']} #{node['platform_version']}, defaulting to '#{self.class.default_package}'.") if self.class.packages + system_packages = Array(self.class.default_package) + end + + # Find the first value on system_package_candidates that is in system_packages. + system_package_candidates(options['version'].to_s).each do |name| + return name if system_packages.include?(name) + end + # No valid candidate. Sad trombone. + raise PoiseLanguages::Error.new("Unable to find a candidate package for version #{options['version'].to_s.inspect}. Please set package_name provider option for #{new_resource}.") + end + + # A hash mapping package names to their override dev package name. + # + # @api public + # @return [Hash] + def system_dev_package_overrides + {} + end + + module ClassMethods + # Install this as a default provider if nothing else matched. Might not + # work, but worth a try at least for unknown platforms. Windows is a + # whole different story, and OS X might work sometimes so at least try. + # + # @api private + def provides_auto?(node, resource) + !node.platform_family?('windows') + end + + # Set some default inversion provider options. Package name can't get + # a default value here because that would complicate the handling of + # {system_package_candidates}. + # + # @api private + def default_inversion_options(node, resource) + super.merge({ + # Install dev headers? + dev_package: true, + # Manual overrides for package name and/or version. + package_name: nil, + package_version: nil, + # Set to true to use action :upgrade on system packages. + package_upgrade: false, + }) + end + + # @overload packages() + # Return a hash formatted for value_for_platform returning an Array + # of package names. + # @return [Hash] + # @overload packages(default_package, packages) + # Define what system packages are available for this language on each + # platform. + # @param default_package [String] Default package name for platforms + # not otherwise defined. + # @param [Hash] Hash formatted for value_for_platform returning an + # Array of package names. + # @return [Hash] + def packages(default_package=nil, packages=nil) + self.default_package(default_package) if default_package + if packages + @packages = packages + end + @packages + end + + # @overload default_package() + # Return the default package name for platforms not otherwise defined. + # @return [String] + # @overload default_package(name) + # Set the default package name for platforms not defined in {packages}. + # @param name [String] Package name. + # @return [String] + def default_package(name=nil) + if name + @default_package = name + end + @default_package + end + + # @api private + def included(klass) + super + klass.extend(ClassMethods) + end + end + + extend ClassMethods + + end + end +end diff --git a/cookbooks/poise-languages/files/halite_gem/poise_languages/system/resource.rb b/cookbooks/poise-languages/files/halite_gem/poise_languages/system/resource.rb new file mode 100644 index 0000000..3e40f52 --- /dev/null +++ b/cookbooks/poise-languages/files/halite_gem/poise_languages/system/resource.rb @@ -0,0 +1,215 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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' +require 'chef/provider' +require 'poise' + + +module PoiseLanguages + module System + # A `poise_language_system` resource to manage installing a language from + # system packages. This is an internal implementation detail of + # poise-languages. + # + # @api private + # @since 1.0 + # @provides poise_languages_system + # @action install + # @action upgrade + # @action uninstall + class Resource < Chef::Resource + include Poise + provides(:poise_languages_system) + actions(:install, :upgrade, :uninstall) + + # @!attribute package_name + # Name of the main package for the language. + # @return [String] + attribute(:package_name, kind_of: String, name_attribute: true) + # @!attribute dev_package + # Name of the development headers package, or false to disable + # installing headers. By default computed from {package_name}. + # @return [String, false] + attribute(:dev_package, kind_of: [String, FalseClass], default: lazy { default_dev_package }) + # @!attribute dev_package_overrides + # A hash of override names for dev packages that don't match the normal + # naming scheme. + # @return [Hash] + attribute(:dev_package_overrides, kind_of: Hash, default: lazy { {} }) + # @!attribute package_version + # Version of the package(s) to install. This is distinct from {version}, + # and is the specific version package version, not the language version. + # By default this is unset meaning the latest version will be used. + # @return [String, nil] + attribute(:package_version, kind_of: [String, NilClass]) + # @!attribute parent + # Resource for the language runtime. Used only for messages. + # @return [Chef::Resource] + attribute(:parent, kind_of: Chef::Resource, required: true) + # @!attributes version + # Language version prefix. This prefix determines which version of the + # language to install, following prefix matching rules. + # @return [String] + attribute(:version, kind_of: String, default: '') + + # Compute the default package name for the development headers. + # + # @return [String] + def default_dev_package + # Check for an override. + return dev_package_overrides[package_name] if dev_package_overrides.include?(package_name) + suffix = node.value_for_platform_family(debian: '-dev', rhel: '-devel', fedora: '-devel') + # Platforms like Arch and Gentoo don't need this anyway. I've got no + # clue how Amazon Linux does this. + if suffix + package_name + suffix + else + nil + end + end + end + + # The default provider for `poise_languages_system`. + # + # @api private + # @since 1.0 + # @see Resource + # @provides poise_languages_system + class Provider < Chef::Provider + include Poise + provides(:poise_languages_system) + + # The `install` action for the `poise_languages_system` resource. + # + # @return [void] + def action_install + run_package_action(:install) + end + + # The `upgrade` action for the `poise_languages_system` resource. + # + # @return [void] + def action_upgrade + run_package_action(:upgrade) + end + + # The `uninstall` action for the `poise_languages_system` resource. + # + # @return [void] + def action_uninstall + action = node.platform_family?('debian') ? :purge : :remove + package_resources(action).each do |resource| + resource.run_action(action) + new_resource.updated_by_last_action(true) if resource.updated_by_last_action? + end + end + + private + + # Create package resource objects for all needed packages. These are created + # directly and not added to the resource collection. + # + # @return [Array] + def package_resources(action) + packages = {new_resource.package_name => new_resource.package_version} + # If we are supposed to install the dev package, grab it using the same + # version as the main package. + if new_resource.dev_package + packages[new_resource.dev_package] = new_resource.package_version + end + + Chef::Log.debug("[#{new_resource.parent}] Building package resource using #{packages.inspect}.") + package_resource_class = Chef::Resource.resource_for_node(:package, node) + @package_resource ||= if node.platform_family?('rhel', 'fedora', 'amazon', 'mac_os_x') + # @todo Can't use multi-package mode with yum pending https://github.com/chef/chef/issues/3476. + packages.map do |name, version| + package_resource_class.new(name, run_context).tap do |r| + r.version(version) + r.action(action) + r.declared_type = :package + r.retries(5) + end + end + else + [package_resource_class.new(packages.keys, run_context).tap do |r| + r.version(packages.values) + r.action(action) + r.declared_type = :package + r.retries(5) + end] + end + end + + # Run the requested action for all package resources. This exists because + # we inject our version check in to the provider directly and I want to + # only run the provider action once for performance. It is otherwise + # mostly a stripped down version of Chef::Resource#run_action. + # + # @param action [Symbol] Action to run on all package resources. + # @return [void] + def run_package_action(action) + package_resources(action).each do |resource| + # Reset it so we have a clean baseline. + resource.updated_by_last_action(false) + # Grab the provider. + provider = resource.provider_for_action(action) + provider.action = action + # Check the candidate version if needed. With a manual package_version + # you get whatever you asked for. + patch_load_current_resource!(provider, new_resource.version) unless new_resource.package_version + # Run our action. + Chef::Log.debug("[#{new_resource.parent}] Running #{provider} with #{action}") + provider.run_action(action) + # Check updated flag. + new_resource.updated_by_last_action(true) if resource.updated_by_last_action? + end + end + + # Hack a provider object to run our verification code. + # + # @param provider [Chef::Provider] Provider object to patch. + # @param version [String] Language version prefix to check for. + # @return [void] + def patch_load_current_resource!(provider, version) + # Create a closure module and inject it. + provider.extend Module.new { + # Patch load_current_resource to run our verification logic after + # the normal code. + define_method(:load_current_resource) do + super().tap do |_| + each_package do |package_name, new_version, current_version, candidate_version| + # In Chef 12.14+, candidate_version is a Chef::Decorator::Lazy object + # so we need the nil? check to see if the object being proxied is + # nil (i.e. there is no version). + unless candidate_version && (!candidate_version.nil?) && (!candidate_version.empty?) && candidate_version.start_with?(version) + # Don't display a wonky error message if there is no candidate. + candidate_label = if candidate_version && (!candidate_version.nil?) && (!candidate_version.empty?) + candidate_version + else + candidate_version.inspect + end + raise PoiseLanguages::Error.new("Package #{package_name} would install #{candidate_label}, which does not match #{version.empty? ? version.inspect : version}. Please set the package_name or package_version provider options.") + end + end + end + end + } + end + + end + end +end diff --git a/cookbooks/poise-languages/files/halite_gem/poise_languages/utils.rb b/cookbooks/poise-languages/files/halite_gem/poise_languages/utils.rb new file mode 100644 index 0000000..84ff73d --- /dev/null +++ b/cookbooks/poise-languages/files/halite_gem/poise_languages/utils.rb @@ -0,0 +1,68 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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' + +require 'poise_languages/utils/which' + + +module PoiseLanguages + module Utils + include Which + extend self + + # Default whitelist for {#shelljoin}. + SHELLJOIN_WHITELIST = [/^2?[><]/] + + # An improved version of Shellwords.shelljoin that doesn't escape a few + # things. + # + # @param cmd [Array] Command array to join. + # @param whitelist [Array] Array of patterns to whitelist. + # @return [String] + def shelljoin(cmd, whitelist: SHELLJOIN_WHITELIST) + cmd.map do |str| + if whitelist.any? {|pat| str =~ pat } + str + else + Shellwords.shellescape(str) + end + end.join(' ') + end + + # Convert the executable in a string or array command to an absolute path. + # + # @param cmd [String, Array] Command to fix up. + # @param path [String, nil] Replacement $PATH for executable lookup. + # @return [String, Array] + def absolute_command(cmd, path: nil) + was_array = cmd.is_a?(Array) + cmd = if was_array + cmd.dup + else + Shellwords.split(cmd) + end + # Don't try to touch anything if the first value looks like a flag or a path. + if cmd.first && !cmd.first.start_with?('-') && !cmd.first.include?(::File::SEPARATOR) + # If which returns false, just leave it I guess. + cmd[0] = which(cmd.first, path: path) || cmd.first + end + cmd = shelljoin(cmd) unless was_array + cmd + end + + end +end diff --git a/cookbooks/poise-languages/files/halite_gem/poise_languages/utils/which.rb b/cookbooks/poise-languages/files/halite_gem/poise_languages/utils/which.rb new file mode 100644 index 0000000..8661c57 --- /dev/null +++ b/cookbooks/poise-languages/files/halite_gem/poise_languages/utils/which.rb @@ -0,0 +1,51 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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 PoiseLanguages + module Utils + # Replacement module for Chef::Mixin::Which with a slight improvement. + # + # @since 1.0.0 + # @see Which#which + module Which + extend self + + # A replacement for Chef::Mixin::Which#which that allows using something + # other than an environment variable if needed. + # + # @param cmd [String] Executable to search for. + # @param extra_path [Array] Extra directories to always search. + # @param path [String, nil] Replacement $PATH value. + # @return [String, false] + def which(cmd, extra_path: %w{/bin /usr/bin /sbin /usr/sbin}, path: nil) + # If it was already absolute, just return that. + return cmd if cmd =~ /^(\/|([a-z]:)?\\)/i + # Allow passing something other than the real env var. + path ||= ENV['PATH'] + # Based on Chef::Mixin::Which#which + # Copyright 2010-2017, Chef Softare, Inc. + paths = path.split(File::PATH_SEPARATOR) + extra_path + paths.each do |candidate_path| + filename = ::File.join(candidate_path, cmd) + return filename if ::File.executable?(filename) + end + false + end + + end + end +end diff --git a/cookbooks/poise-languages/files/halite_gem/poise_languages/version.rb b/cookbooks/poise-languages/files/halite_gem/poise_languages/version.rb new file mode 100644 index 0000000..916a6c0 --- /dev/null +++ b/cookbooks/poise-languages/files/halite_gem/poise_languages/version.rb @@ -0,0 +1,20 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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 PoiseLanguages + VERSION = '2.1.0' +end diff --git a/cookbooks/poise-languages/libraries/default.rb b/cookbooks/poise-languages/libraries/default.rb new file mode 100644 index 0000000..8b2a908 --- /dev/null +++ b/cookbooks/poise-languages/libraries/default.rb @@ -0,0 +1,18 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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. +# + +raise 'Halite is not compatible with no_lazy_load false, please set no_lazy_load true in your Chef configuration file.' unless Chef::Config[:no_lazy_load] +$LOAD_PATH << File.expand_path('../../files/halite_gem', __FILE__) diff --git a/cookbooks/poise-languages/metadata.json b/cookbooks/poise-languages/metadata.json new file mode 100644 index 0000000..7d99ddf --- /dev/null +++ b/cookbooks/poise-languages/metadata.json @@ -0,0 +1 @@ +{"name":"poise-languages","version":"2.1.0","description":"A Chef cookbook to help writing language cookbooks.","long_description":"# Poise-Languages Cookbook\n\n[![Build Status](https://img.shields.io/travis/poise/poise-languages.svg)](https://travis-ci.org/poise/poise-languages)\n[![Gem Version](https://img.shields.io/gem/v/poise-languages.svg)](https://rubygems.org/gems/poise-languages)\n[![Cookbook Version](https://img.shields.io/cookbook/v/poise-languages.svg)](https://supermarket.chef.io/cookbooks/poise-languages)\n[![Coverage](https://img.shields.io/codecov/c/github/poise/poise-languages.svg)](https://codecov.io/github/poise/poise-languages)\n[![Gemnasium](https://img.shields.io/gemnasium/poise/poise-languages.svg)](https://gemnasium.com/poise/poise-languages)\n[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)\n\nShared support code for Poise's language cookbooks like poise-ruby and\npoise-python.\n\n## License\n\nCopyright 2015-2017, Noah Kantrowitz\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","maintainer":"Noah Kantrowitz","maintainer_email":"noah@coderanger.net","license":"Apache 2.0","platforms":{},"dependencies":{"poise":"~> 2.5","poise-archive":"~> 1.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{},"source_url":"https://github.com/poise/poise-languages","issues_url":"https://github.com/poise/poise-languages/issues","chef_version":[["< 14",">= 12.1"],[]],"ohai_version":[[]]} \ No newline at end of file diff --git a/cookbooks/poise-ruby/CHANGELOG.md b/cookbooks/poise-ruby/CHANGELOG.md new file mode 100644 index 0000000..7145774 --- /dev/null +++ b/cookbooks/poise-ruby/CHANGELOG.md @@ -0,0 +1,25 @@ +# Changelog + +## v2.2.0 + +* Add support for Ubuntu 16.04 system packages. +* Support new SCL structure and packages. + +## v2.1.1 + +* Create ChefSpec matchers for the `ruby_gem` resource. + +## v2.1.0 + +* Fix version field for default Ruby runtime. +* Add a `:dummy` provider for `ruby_runtime` for unit testing or complex overrides. +* Improved handling for `bundle exec` in `ruby_execute`. +* New integration test harness. + +## v2.0.0 + +* Initial release (again)! + +## v1.0.0 + +* Pre-history, we do not speak of these times. diff --git a/cookbooks/poise-ruby/README.md b/cookbooks/poise-ruby/README.md new file mode 100644 index 0000000..efc01a6 --- /dev/null +++ b/cookbooks/poise-ruby/README.md @@ -0,0 +1,305 @@ +# Poise-Ruby Cookbook + +[![Build Status](https://img.shields.io/travis/poise/poise-ruby.svg)](https://travis-ci.org/poise/poise-ruby) +[![Gem Version](https://img.shields.io/gem/v/poise-ruby.svg)](https://rubygems.org/gems/poise-ruby) +[![Cookbook Version](https://img.shields.io/cookbook/v/poise-ruby.svg)](https://supermarket.chef.io/cookbooks/poise-ruby) +[![Coverage](https://img.shields.io/codecov/c/github/poise/poise-ruby.svg)](https://codecov.io/github/poise/poise-ruby) +[![Gemnasium](https://img.shields.io/gemnasium/poise/poise-ruby.svg)](https://gemnasium.com/poise/poise-ruby) +[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) + +A [Chef](https://www.chef.io/) cookbook to provide a unified interface for +installing Ruby and running things with it. This README covers the 2.x version +of the cookbook, the 1.x version is very different and no longer supported. + +## Quick Start + +To install the latest available version of Ruby 2.x and then use it to install +some gems: + +```ruby +ruby_runtime '2' + +ruby_gem 'rake' + +bundle_install '/path/to/Gemfile' do + without 'development' + deployment true +end +``` + +## Requirements + +Chef 12.1 or newer is required. + +## Attributes + +Attributes are used to configure the default recipe. + +* `node['poise-ruby']['install_ruby']` – Install a Ruby runtime. *(default: true)* +* `node['poise-ruby']['install_chef_ruby']` – Create a `ruby_runtime` using + the `:chef` provider. Doesn't actually install anything. *(default: true)* + +## Recipes + +### `default` + +The default recipe installs Ruby based on the node attributes. It is entirely +optional and can be ignored in favor of direct use of the `ruby_runtime` +resource. + +## Resources + +### `ruby_runtime` + +The `ruby_runtime` resource installs a Ruby interpreter. + +```ruby +ruby_runtime 'any' do + version '' +end +``` + +#### Actions + +* `:install` – Install the Ruby interpreter. *(default)* +* `:uninstall` – Uninstall the Ruby interpreter. + +#### Properties + +* `version` – Version of Ruby to install. If a partial version is given, use the + latest available version matching that prefix. *(name properties)* + +#### Provider Options + +The `poise-ruby` library offers an additional way to pass configuration +information to the final provider called "options". Options are key/value pairs +that are passed down to the ruby_runtime provider and can be used to control how it +installs Ruby. These can be set in the `ruby_runtime` +resource using the `options` method, in node attributes or via the +`ruby_runtime_options` resource. The options from all sources are merged +together in to a single hash. + +When setting options in the resource you can either set them for all providers: + +```ruby +ruby_runtime 'myapp' do + version '2.1' + options dev_package: false +end +``` + +or for a single provider: + +```ruby +ruby_runtime 'myapp' do + version '2.1' + options :system, dev_package: false +end +``` + +Setting via node attributes is generally how an end-user or application cookbook +will set options to customize installations in the library cookbooks they are using. +You can set options for all installations or for a single runtime: + +```ruby +# Global, for all installations. +override['poise-ruby']['options']['dev_package'] = false +# Single installation. +override['poise-ruby']['myapp']['version'] = '2.2' +``` + +The `ruby_runtime_options` resource is also available to set node attributes +for a specific installation in a DSL-friendly way: + +```ruby +ruby_runtime_options 'myapp' do + version '2.2' +end +``` + +Unlike resource attributes, provider options can be different for each provider. +Not all providers support the same options so make sure to the check the +documentation for each provider to see what options the use. + +### `ruby_runtime_options` + +The `ruby_runtime_options` resource allows setting provider options in a +DSL-friendly way. See [the Provider Options](#provider-options) section for more +information about provider options overall. + +```ruby +ruby_runtime_options 'myapp' do + version '2.2' +end +``` + +#### Actions + +* `:run` – Apply the provider options. *(default)* + +#### Properties + +* `resource` – Name of the `ruby_runtime` resource. *(name property)* +* `for_provider` – Provider to set options for. + +All other property keys will be used as options data. + +### `ruby_execute` + +The `ruby_execute` resource executes a Ruby script using the configured runtime. + +```ruby +ruby_execute 'myapp.rb' do + user 'myuser' +end +``` + +This uses the built-in `execute` resource and supports all the same properties. + +#### Actions + +* `:run` – Execute the script. *(default)* + +#### Properties + +* `command` – Script and arguments to run. Must not include the `ruby`. *(name property)* +* `ruby` – Name of the `ruby_runtime` resource to use. If not specified, the + most recently declared `ruby_runtime` will be used. + +For other properties see the [Chef documentation](https://docs.chef.io/resource_execute.html#attributes). + +### `ruby_gem` + +The `ruby_gem` resource is a subclass of the standard `gem_package` resource to +install the gem with the configured runtime. + +```ruby +ruby_gem 'rake' do + version ' 10.4.2' +end +``` + +All actions and attributes match the standard `gem_package` resource with the +addition of a `ruby` attribute matching `ruby_execute`. + +### `bundle_install` + +The `bundle_install` resource installs gems based on a Gemfile using +[bundler](http://bundler.io/). + +```ruby +bundle_install '/path/to/Gemfile' do + deployment true + jobs 3 +end +``` + +The underlying `bundle` command will run on every converge, but notifications +will only be triggered if a gem is actually installed. + +#### Actions + +* `:install` – Run `bundle install`. *(default)* +* `:update` – Run `bundle update`. + +#### Properties + +* `path` – Path to a Gemfile or a directory containing a Gemfile. *(name property)* +* `binstubs` – Enable binstubs. If set to a string it is the path to generate + stubs in. +* `bundler_version` – Version of bundler to install. If unset the latest version is used. +* `deployment` – Enable deployment mode. +* `gem_binary` – Path to the gem binary. If unset this uses the `ruby_runtime` parent. +* `jobs` – Number of parallel installations to run. +* `retry` – Number of times to retry failed installations. +* `ruby` – Name of the `ruby_runtime` resource to execute against. +* `user` – User to run bundler as. +* `vendor` – Enable local vendoring. This maps to the `--path` option in bundler, + but that attribute name is already used. +* `without` – Group or groups to not install. + +## Ruby Providers + +### `system` + +The `system` provider installs Ruby using system packages. This is currently +only tested on platforms using `apt-get` and `yum` (Debian, Ubuntu, RHEL, CentOS +Amazon Linux, and Fedora) and is the default provider on those platforms. It +may work on other platforms but is untested. + +```ruby +ruby_runtime 'myapp' do + provider :system + version '2.1' +end +``` + +#### Options + +* `dev_package` – Install the package with the headers and other development + files. *(default: true)* +* `rubygems_package` – Install rubygems from a package. This is only needed for + Ruby 1.8. *(default: true on RHEL 6)* +* `package_name` – Override auto-detection of the package name. +* `package_upgrade` – Install using action `:upgrade`. *(default: false)* +* `package_version` – Override auto-detection of the package version. +* `version` – Override the Ruby version. + +### `scl` + +The `scl` provider installs Ruby using the [Software Collections](https://www.softwarecollections.org/) +packages. This is only available on RHEL and CentOS. SCL offers more +recent versions of Ruby than the system packages for the most part. If an SCL +package exists for the requested version, it will be used in preference to the +`system` provider. + +```ruby +ruby_runtime 'myapp' do + provider :scl + version '2.2' +end +``` + +### `chef` + +The `chef` provider uses the Ruby environment included in the Omnibus packages. +Great care should be taken when using this provider. + +```ruby +ruby_runtime 'myapp' do + provider :chef + version '2.1' +end +``` + +#### Options + +* `version` – Override the Ruby version. + +### `ruby_build` + +The `ruby_build` provider uses [ruby-build](https://github.com/sstephenson/ruby-build) +to compile and install Ruby. It can be found in the +[poise-ruby-build cookbook](https://github.com/poise/poise-ruby-build). + +## Sponsors + +Development sponsored by [Bloomberg](http://www.bloomberg.com/company/technology/). + +The Poise test server infrastructure is sponsored by [Rackspace](https://rackspace.com/). + +## License + +Copyright 2015-2016, Noah Kantrowitz + +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/poise-ruby/attributes/default.rb b/cookbooks/poise-ruby/attributes/default.rb new file mode 100644 index 0000000..2d66e51 --- /dev/null +++ b/cookbooks/poise-ruby/attributes/default.rb @@ -0,0 +1,23 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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. +# + +# Default inversion options. +default['poise-ruby']['provider'] = 'auto' +default['poise-ruby']['options'] = {} + +# Used for the default recipe. +default['poise-ruby']['install_ruby'] = true +default['poise-ruby']['install_chef_ruby'] = true diff --git a/cookbooks/poise-ruby/files/halite_gem/poise_ruby.rb b/cookbooks/poise-ruby/files/halite_gem/poise_ruby.rb new file mode 100644 index 0000000..3e258ee --- /dev/null +++ b/cookbooks/poise-ruby/files/halite_gem/poise_ruby.rb @@ -0,0 +1,25 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 PoiseRuby + autoload :BundlerMixin, 'poise_ruby/bundler_mixin' + autoload :Error, 'poise_ruby/error' + autoload :Resources, 'poise_ruby/resources' + autoload :RubyCommandMixin, 'poise_ruby/ruby_command_mixin' + autoload :RubyProviders, 'poise_ruby/ruby_providers' + autoload :VERSION, 'poise_ruby/version' +end diff --git a/cookbooks/poise-ruby/files/halite_gem/poise_ruby/bundler_mixin.rb b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/bundler_mixin.rb new file mode 100644 index 0000000..4dcc712 --- /dev/null +++ b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/bundler_mixin.rb @@ -0,0 +1,84 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 'poise_ruby/error' + + +module PoiseRuby + # Mixin for creating bundle exec commands. + # + # @since 2.1.0 + module BundlerMixin + # Transform a command to run under `bundle exec` with the same semantics as + # Ruby execution elsewhere in this system. That means you should end up with + # something like `/bin/ruby /bin/bundle exec /bin/ruby /bin/cmd args`. + # + # @param cmd [String, Array] Command to transform. + # @param path [String] Optional input path for command resolution. + # @return [String, Array] + def bundle_exec_command(cmd, path: nil) + bundle = new_resource.parent_bundle + return cmd unless bundle + is_array = cmd.is_a?(Array) + cmd = Shellwords.split(cmd) unless is_array + root_path = ::File.expand_path('..', bundle.gemfile_path) + # Grab this once in case I need it for the extra path. + bundler_binary = bundle.bundler_binary + # This doesn't account for the potential of a .bundle/config created with + # settings that Chef doesn't know about. (╯°□°)╯︵ ┻━┻ + extra_path = if bundle.binstubs + bundle.binstubs == true ? 'bin' : bundle.binstubs + elsif bundle.vendor || bundle.deployment + # Find the relative path to start searching from. + vendor_base_path = if bundle.vendor && bundle.vendor != true + bundle.vendor + else + 'vendor/bundle' + end + # Add the ruby/. + vendor_base_path = ::File.join(File.expand_path(vendor_base_path, root_path), 'ruby') + # Find the version number folder inside that. + candidates = Dir.entries(vendor_base_path) + ruby_abi_folder = candidates.find {|name| name =~ /^\d\./ } + vendor_sub_path = if ruby_abi_folder + ::File.join(ruby_abi_folder, 'bin') + elsif candidates.include?('bin') + 'bin' + else + raise PoiseRuby::Error.new("Unable to find the vendor bin folder for #{vendor_base_path}: #{candidates.join(', ')}") + end + # Make the final path. + ::File.join(vendor_base_path, vendor_sub_path) + else + # The folder the bundler binary is in was the global gem executable dir. + ::File.dirname(bundler_binary) + end + # Resolve relative paths against Bundler.root. + extra_path = ::File.expand_path(extra_path, root_path) + # Create the full $PATH. + path ||= ENV['PATH'] + bundle_exec_path = extra_path + ::File::PATH_SEPARATOR + path + # Resolve the command + abs_cmd = PoiseLanguages::Utils.absolute_command(cmd, path: bundle_exec_path) + bundle_exec = [new_resource.ruby, bundler_binary, 'exec', new_resource.ruby] + abs_cmd + if is_array + bundle_exec + else + PoiseLanguages::Utils.shelljoin(bundle_exec) + end + end + end +end diff --git a/cookbooks/poise-ruby/files/halite_gem/poise_ruby/cheftie.rb b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/cheftie.rb new file mode 100644 index 0000000..474a2f4 --- /dev/null +++ b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/cheftie.rb @@ -0,0 +1,18 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 'poise_ruby/resources' +require 'poise_ruby/ruby_providers' diff --git a/cookbooks/poise-ruby/files/halite_gem/poise_ruby/error.rb b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/error.rb new file mode 100644 index 0000000..34835c7 --- /dev/null +++ b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/error.rb @@ -0,0 +1,21 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 PoiseRuby + class Error < ::Exception + end +end diff --git a/cookbooks/poise-ruby/files/halite_gem/poise_ruby/resources.rb b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/resources.rb new file mode 100644 index 0000000..11b5710 --- /dev/null +++ b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/resources.rb @@ -0,0 +1,29 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 'poise_ruby/resources/bundle_install' +require 'poise_ruby/resources/ruby_execute' +require 'poise_ruby/resources/ruby_gem' +require 'poise_ruby/resources/ruby_runtime' + + +module PoiseRuby + # Chef resources and providers for poise-ruby. + # + # @since 2.0.0 + module Resources + end +end diff --git a/cookbooks/poise-ruby/files/halite_gem/poise_ruby/resources/bundle_install.rb b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/resources/bundle_install.rb new file mode 100644 index 0000000..52b6fe8 --- /dev/null +++ b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/resources/bundle_install.rb @@ -0,0 +1,221 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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/mixin/shell_out' +require 'chef/mixin/which' +require 'chef/provider' +require 'chef/resource' +require 'poise' + +require 'poise_ruby/error' +require 'poise_ruby/ruby_command_mixin' + + +module PoiseRuby + module Resources + # (see BundleInstall::Resource) + # @since 2.0.0 + module BundleInstall + # A `bundle_install` resource to install a [Bundler](http://bundler.io/) + # Gemfile. + # + # @provides bundle_install + # @action install + # @action update + # @note + # This resource is not idempotent itself, it will always run `bundle + # install`. + # @example + # bundle_install '/opt/my_app' do + # gem_path '/usr/local/bin/gem' + # end + class Resource < Chef::Resource + include Poise + provides(:bundle_install) + actions(:install, :update) + include PoiseRuby::RubyCommandMixin + + # @!attribute path + # Path to the Gemfile or to a directory that contains a Gemfile. + # @return [String] + attribute(:path, kind_of: String, name_attribute: true) + # @!attribute binstubs + # Enable binstubs. If set to a string it is the path to generate + # stubs in. + # @return [Boolean, String] + attribute(:binstubs, kind_of: [TrueClass, String]) + # @!attribute deployment + # Enable deployment mode. + # @return [Boolean] + attribute(:deployment, equal_to: [true, false], default: false) + # @!attribute jobs + # Number of parallel installations to run. + # @return [String, Integer] + attribute(:jobs, kind_of: [String, Integer]) + # @!attribute retry + # Number of times to retry failed installations. + # @return [String, Integer] + attribute(:retry, kind_of: [String, Integer]) + # @!attribute user + # User to run bundler as. + # @return [String, Integery, nil] + attribute(:user, kind_of: [String, Integer, NilClass]) + # @!attribute vendor + # Enable local vendoring. This maps to the `--path` option in bundler, + # but that attribute name is already used. + # @return [Boolean, String] + attribute(:vendor, kind_of: [TrueClass, String]) + # @!attribute without + # Group or groups to not install. + # @return [String, Array] + attribute(:without, kind_of: [Array, String]) + + # The path to the `bundle` binary for this installation. This is an + # output property. + # + # @return [String] + # @example + # execute "#{resources('bundle_install[/opt/myapp]').bundler_binary} vendor" + def bundler_binary + @bundler_binary ||= provider_for_action(:bundler_binary).bundler_binary + end + + # The path to the Gemfile for this installation. This is an output + # property. + # + # @return [String] + # @example + # file resources('bundle_install[/opt/myapp]').gemfile_path do + # owner 'root' + # end + def gemfile_path + @gemfile_path ||= provider_for_action(:gemfile_path).gemfile_path + end + end + + # The default provider for the `bundle_install` resource. + # + # @see Resource + class Provider < Chef::Provider + include Poise + provides(:bundle_install) + include PoiseRuby::RubyCommandMixin + + # Install bundler and the gems in the Gemfile. + def action_install + run_bundler('install') + end + + # Install bundler and update the gems in the Gemfile. + def action_update + run_bundler('update') + end + + # Return the absolute path to the correct bundle binary to run. + # + # @return [String] + def bundler_binary + @bundler_binary ||= ::File.join(gem_bindir, 'bundle') + end + + # Find the absolute path to the Gemfile. This mirrors bundler's internal + # search logic by scanning up to parent folder as needed. + # + # @return [String] + def gemfile_path + @gemfile_path ||= begin + path = ::File.expand_path(new_resource.path) + if ::File.file?(path) + # We got a path to a real file, use that. + path + else + # Walk back until path==dirname(path) meaning we are at the root + while path != (next_path = ::File.dirname(path)) + possible_path = ::File.join(path, 'Gemfile') + return possible_path if ::File.file?(possible_path) + path = next_path + end + end + end + end + + private + + # Install the gems in the Gemfile. + def run_bundler(command) + return converge_by "Run bundle #{command}" if whyrun_mode? + cmd = ruby_shell_out!(bundler_command(command), environment: {'BUNDLE_GEMFILE' => gemfile_path}, user: new_resource.user) + # Look for a line like 'Installing $gemname $version' to know if we did anything. + if cmd.stdout.include?('Installing') + new_resource.updated_by_last_action(true) + end + end + + # Parse out the value for Gem.bindir. This is so complicated to minimize + # the required configuration on the resource combined with gem having + # terrible output formats. + # + # @return [String] + def gem_bindir + cmd = ruby_shell_out!(new_resource.gem_binary, 'environment') + # Parse a line like: + # - EXECUTABLE DIRECTORY: /usr/local/bin + matches = cmd.stdout.scan(/EXECUTABLE DIRECTORY: (.*)$/).first + if matches + matches.first + else + raise PoiseRuby::Error.new("Cannot find EXECUTABLE DIRECTORY: #{cmd.stdout}") + end + end + + # Command line options for the bundle install. + # + # @return [Array] + def bundler_options + [].tap do |opts| + if new_resource.binstubs + opts << "--binstubs" + (new_resource.binstubs.is_a?(String) ? "=#{new_resource.binstubs}" : '') + end + if new_resource.vendor + opts << "--path=" + (new_resource.vendor.is_a?(String) ? new_resource.vendor : 'vendor/bundle') + end + if new_resource.deployment + opts << '--deployment' + end + if new_resource.jobs + opts << "--jobs=#{new_resource.jobs}" + end + if new_resource.retry + opts << "--retry=#{new_resource.retry}" + end + if new_resource.without + opts << '--without' + opts.insert(-1, *new_resource.without) + end + end + end + + # Command array to run when installing the Gemfile. + # + # @return [Array] + def bundler_command(command) + [bundler_binary, command] + bundler_options + end + + end + end + end +end diff --git a/cookbooks/poise-ruby/files/halite_gem/poise_ruby/resources/ruby_execute.rb b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/resources/ruby_execute.rb new file mode 100644 index 0000000..47ce0e0 --- /dev/null +++ b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/resources/ruby_execute.rb @@ -0,0 +1,90 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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/mash' +require 'chef/provider/execute' +require 'chef/resource/execute' +require 'poise' + +require 'poise_ruby/bundler_mixin' +require 'poise_ruby/ruby_command_mixin' + + +module PoiseRuby + module Resources + # (see RubyExecute::Resource) + # @since 2.0.0 + module RubyExecute + # A `ruby_execute` resource to run Ruby scripts and commands. + # + # @provides ruby_execute + # @action run + # @example + # ruby_execute 'myapp.rb' do + # user 'myuser' + # end + class Resource < Chef::Resource::Execute + include Poise + provides(:ruby_execute) + actions(:run) + include PoiseRuby::RubyCommandMixin + + # @!attribute parent_bundle + # Optional bundle_install resource to run `bundle exec` against. + # @return [PoiseRuby::Resources::BundleInstall::Resource] + parent_attribute(:bundle, type: :bundle_install, optional: true, auto: false) + end + + # The default provider for `ruby_execute`. + # + # @see Resource + # @provides ruby_execute + class Provider < Chef::Provider::Execute + include PoiseRuby::BundlerMixin + provides(:ruby_execute) + + private + + # Command to pass to shell_out. + # + # @return [String, Array] + def command + if new_resource.parent_bundle + bundle_exec_command(new_resource.command, path: environment['PATH']) + else + if new_resource.command.is_a?(Array) + [new_resource.ruby] + new_resource.command + else + "#{new_resource.ruby} #{new_resource.command}" + end + end + end + + # Environment variables to pass to shell_out. + # + # @return [Hash] + def environment + Mash.new.tap do |environment| + environment.update(new_resource.parent_ruby.ruby_environment) if new_resource.parent_ruby + environment['BUNDLE_GEMFILE'] = new_resource.parent_bundle.gemfile_path if new_resource.parent_bundle + environment.update(new_resource.environment) if new_resource.environment + end + end + + end + end + end +end diff --git a/cookbooks/poise-ruby/files/halite_gem/poise_ruby/resources/ruby_gem.rb b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/resources/ruby_gem.rb new file mode 100644 index 0000000..26ac898 --- /dev/null +++ b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/resources/ruby_gem.rb @@ -0,0 +1,125 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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/provider/package/rubygems' +require 'chef/resource/gem_package' +require 'poise' + +require 'poise_ruby/ruby_command_mixin' + + +module PoiseRuby + module Resources + # (see RubyGem::Resource) + # @since 2.0.0 + module RubyGem + # A `ruby_gem` resource to install Ruby gems. + # + # @provides ruby_gem + # @action install + # @action upgrade + # @action remove + # @action purge + # @action reconfig + # @example + # ruby_gem 'rack' + class Resource < Chef::Resource::GemPackage + include Poise + provides(:ruby_gem) + actions(:install, :upgrade, :remove, :purge, :reconfig) + include PoiseRuby::RubyCommandMixin + + # @api private + def initialize(name, run_context=nil) + super + @resource_name = :ruby_gem if @resource_name + # Remove when all useful versions are using provider resolver. + @provider = PoiseRuby::Resources::RubyGem::Provider if @provider + end + end + + # The default provider for `ruby_gem`. + # + # @see Resource + # @provides ruby_gem + class Provider < Chef::Provider::Package::Rubygems + include Poise + provides(:ruby_gem) + + def load_current_resource + patch_environment { super } + end + + def define_resource_requirements + patch_environment { super } + end + + def action_install + patch_environment { super } + end + + def action_upgrade + patch_environment { super } + end + + def action_remove + patch_environment { super } + end + + def action_purge + patch_environment { super } + end + + def action_reconfig + patch_environment { super } + end + + private + + def patch_environment(&block) + environment_to_add = if new_resource.parent_ruby + new_resource.parent_ruby.ruby_environment + else + {} + end + + begin + if ENV['GEM_HOME'] && !ENV['GEM_HOME'].empty? + Chef::Log.warn("[#{new_resource}] $GEM_HOME is set in Chef's environment, this will likely interfere with gem installation") + end + if ENV['GEM_PATH'] && !ENV['GEM_PATH'].empty? + Chef::Log.warn("[#{new_resource}] $GEM_PATH is set in Chef's environment, this will likely interfere with gem installation") + end + old_vars = environment_to_add.inject({}) do |memo, (key, value)| + memo[key] = ENV[key] + ENV[key] = value + memo + end + block.call + ensure + old_vars.each do |key, value| + if value.nil? + ENV.delete(key) + else + ENV[key] = value + end + end + end + end + end + end + end +end diff --git a/cookbooks/poise-ruby/files/halite_gem/poise_ruby/resources/ruby_runtime.rb b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/resources/ruby_runtime.rb new file mode 100644 index 0000000..e0b0292 --- /dev/null +++ b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/resources/ruby_runtime.rb @@ -0,0 +1,87 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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' +require 'poise' + + +module PoiseRuby + module Resources + # (see RubyRuntime::Resource) + # @since 2.0.0 + module RubyRuntime + # A `ruby_runtime` resource to manage Ruby installations. + # + # @provides ruby_runtime + # @action install + # @action uninstall + # @example + # ruby_runtime '2.1.2' + class Resource < Chef::Resource + include Poise(inversion: true, container: true) + provides(:ruby_runtime) + actions(:install, :uninstall) + + # @!attribute version + # Version of Ruby to install. + # @return [String] + attribute(:version, kind_of: String, name_attribute: true) + # @!attribute bundler_version + # Version of Bundler to install. It set to `true`, the latest + # available version will be used. If set to `false`, Bundler will + # not be installed. + # @note Disabling the Bundler install may result in other resources + # being non-functional. + # @return [String, Boolean] + attribute(:bundler_version, kind_of: [String, TrueClass, FalseClass], default: true) + + # The path to the `ruby` binary for this Ruby installation. This is an + # output property. + # + # @return [String] + # @example + # execute "#{resources('ruby_runtime[2.2.2]').ruby_binary} myapp.rb" + def ruby_binary + @ruby_binary ||= provider_for_action(:ruby_binary).ruby_binary + end + + # The environment variables for this Ruby installation. This is an + # output property. + # + # @return [Hash] + # @example + # execute '/opt/myapp.py' do + # environment resources('ruby_runtime[2.2.2]').ruby_environment + # end + def ruby_environment + @ruby_environment ||= provider_for_action(:ruby_environment).ruby_environment + end + + # The path to the `gem` binary for this Ruby installation. This is an + # output property. + # + # @return [String] + # @example + # execute "#{resources('ruby_runtime[2.2.2]').gem_binary} install myapp" + def gem_binary + @gem_binary ||= provider_for_action(:gem_binary).gem_binary + end + end + + # Providers can be found under lib/poise_ruby/ruby_providers/ + end + end +end diff --git a/cookbooks/poise-ruby/files/halite_gem/poise_ruby/resources/ruby_runtime_test.rb b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/resources/ruby_runtime_test.rb new file mode 100644 index 0000000..34ae7da --- /dev/null +++ b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/resources/ruby_runtime_test.rb @@ -0,0 +1,213 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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/mixin/convert_to_class_name' +require 'chef/provider' +require 'chef/resource' +require 'poise' + + +module PoiseRuby + module Resources + # (see RubyRuntimeTest::Resource) + # @since 2.1.0 + # @api private + module RubyRuntimeTest + # A `ruby_runtime_test` resource for integration testing of this + # cookbook. This is an internal API and can change at any time. + # + # @provides ruby_runtime_test + # @action run + class Resource < Chef::Resource + include Poise + provides(:ruby_runtime_test) + actions(:run) + + attribute(:version, kind_of: String, name_attribute: true) + attribute(:runtime_provider, kind_of: Symbol) + attribute(:path, kind_of: String, default: lazy { default_path }) + + def default_path + ::File.join('', 'root', "ruby_test_#{name}") + end + end + + # The default provider for `ruby_runtime_test`. + # + # @see Resource + # @provides ruby_runtime_test + class Provider < Chef::Provider + include Poise + provides(:ruby_runtime_test) + + # The `run` action for the `ruby_runtime_test` resource. + # + # @return [void] + def action_run + notifying_block do + # Top level directory for this test. + directory new_resource.path + + # Install and log the version. + ruby_runtime new_resource.name do + provider new_resource.runtime_provider if new_resource.runtime_provider + version new_resource.version + end + test_version + + # Test ruby_gem. + ruby_gem 'thor remove before' do + action :remove + package_name 'thor' + ruby new_resource.name + end + test_require('thor', 'thor_before') + ruby_gem 'thor' do + ruby new_resource.name + notifies :create, sentinel_file('thor'), :immediately + end + test_require('thor', 'thor_mid') + ruby_gem 'thor again' do + package_name 'thor' + ruby new_resource.name + notifies :create, sentinel_file('thor2'), :immediately + end + ruby_gem 'thor remove after' do + action :remove + package_name 'thor' + ruby new_resource.name + end + test_require('thor', 'thor_after') + + # Use bundler to test something that should always be installed. + ruby_gem 'bundler' do + ruby new_resource.name + notifies :create, sentinel_file('bundler'), :immediately + end + + # Create and install a Gemfile. + bundle1_path = ::File.join(new_resource.path, 'bundle1') + directory bundle1_path + file ::File.join(bundle1_path, 'Gemfile') do + content <<-EOH +source 'https://rubygems.org/' +gem 'hashie' +gem 'tomlrb', '1.1.0' +EOH + end + bundle1 = bundle_install bundle1_path do + ruby new_resource.name + end + test_require('hashie', bundle: bundle1) + test_require('tomlrb', bundle: bundle1) + test_require('thor', 'thor_bundle', bundle: bundle1) + + # Test for bundle exec shebang issues. + bundle2_path = ::File.join(new_resource.path, 'bundle2') + directory bundle2_path + file ::File.join(bundle2_path, 'Gemfile') do + content <<-EOH +source 'https://rubygems.org/' +gem 'unicorn' +EOH + end + file ::File.join(bundle2_path, 'Gemfile.lock') do + content <<-EOH +GEM + remote: https://rubygems.org/ + specs: + kgio (2.10.0) + rack (1.6.4) + raindrops (0.15.0) + unicorn (4.9.0) + kgio (~> 2.6) + rack + raindrops (~> 0.7) + +PLATFORMS + ruby + +DEPENDENCIES + unicorn + +BUNDLED WITH + 1.10.6 +EOH + end + bundle2 = bundle_install bundle2_path do + ruby new_resource.name + deployment true + end + # test_require('unicorn', bundle: bundle2) + ruby_execute "unicorn --version > #{::File.join(new_resource.path, "unicorn_version")}" do + ruby new_resource.name + parent_bundle bundle2 + end + end + end + + def sentinel_file(name) + file ::File.join(new_resource.path, "sentinel_#{name}") do + action :nothing + end + end + + private + + def test_version(ruby: new_resource.name) + # Only queue up this resource once, the ivar is just for tracking. + @ruby_version_test ||= file ::File.join(new_resource.path, 'ruby_version.rb') do + user 'root' + group 'root' + mode '644' + content <<-EOH +File.new(ARGV[0], 'w').write(RUBY_VERSION) +EOH + end + + ruby_execute "#{@ruby_version_test.path} #{::File.join(new_resource.path, 'version')}" do + ruby ruby if ruby + end + end + + def test_require(name, path=name, ruby: new_resource.name, bundle: nil, class_name: nil) + # Only queue up this resource once, the ivar is just for tracking. + @ruby_require_test ||= file ::File.join(new_resource.path, 'require_version.rb') do + user 'root' + group 'root' + mode '644' + content <<-EOH +require 'rubygems' +begin + require "\#{ARGV[0]}/version" + klass = ARGV[1].split('::').inject(Object) {|memo, name| memo.const_get(name) } + File.new(ARGV[2], 'w').write(klass::VERSION) +rescue LoadError +end +EOH + end + + class_name ||= Chef::Mixin::ConvertToClassName.convert_to_class_name(name) + ruby_execute "#{@ruby_require_test.path} #{name} #{class_name} #{::File.join(new_resource.path, "require_#{path}")}" do + ruby ruby if ruby + parent_bundle bundle if bundle + end + end + + end + end + end +end diff --git a/cookbooks/poise-ruby/files/halite_gem/poise_ruby/ruby_command_mixin.rb b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/ruby_command_mixin.rb new file mode 100644 index 0000000..01a15b3 --- /dev/null +++ b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/ruby_command_mixin.rb @@ -0,0 +1,59 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 'poise/utils' +require 'poise_languages' + + +module PoiseRuby + # Mixin for resources and providers which run Ruby commands. + # + # @since 2.0.0 + module RubyCommandMixin + include Poise::Utils::ResourceProviderMixin + + module Resource + include PoiseLanguages::Command::Mixin::Resource(:ruby) + + # @!attribute gem_binary + # Path to the gem binary. + # @return [String] + attribute(:gem_binary, kind_of: String, default: lazy { default_gem_binary }) + + private + + # Find the default gem binary. If there is a parent use that, otherwise + # use the same logic as {PoiseRuby::RubyProviders::Base#gem_binary}. + # + # @return [String] + def default_gem_binary + if parent_ruby + parent_ruby.gem_binary + else + dir, base = ::File.split(ruby) + # If this ruby is called something weird, bail out. + raise NotImplementedError unless base.start_with?('ruby') + # Allow for names like "ruby2.0" -> "gem2.0". + ::File.join(dir, base.sub(/^ruby/, 'gem')) + end + end + end + + module Provider + include PoiseLanguages::Command::Mixin::Provider(:ruby) + end + end +end diff --git a/cookbooks/poise-ruby/files/halite_gem/poise_ruby/ruby_providers.rb b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/ruby_providers.rb new file mode 100644 index 0000000..7d742b5 --- /dev/null +++ b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/ruby_providers.rb @@ -0,0 +1,35 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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/platform/provider_priority_map' + +require 'poise_ruby/ruby_providers/chef' +require 'poise_ruby/ruby_providers/dummy' +require 'poise_ruby/ruby_providers/scl' +require 'poise_ruby/ruby_providers/system' + + +module PoiseRuby + # Inversion providers for the ruby_runtime resource. + # + # @since 2.0.0 + module RubyProviders + Chef::Platform::ProviderPriorityMap.instance.priority(:ruby_runtime, [ + PoiseRuby::RubyProviders::Scl, + PoiseRuby::RubyProviders::System, + ]) + end +end diff --git a/cookbooks/poise-ruby/files/halite_gem/poise_ruby/ruby_providers/base.rb b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/ruby_providers/base.rb new file mode 100644 index 0000000..ac7b3a9 --- /dev/null +++ b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/ruby_providers/base.rb @@ -0,0 +1,117 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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/provider' +require 'poise' + +require 'poise_ruby/resources/ruby_gem' +require 'poise_ruby/resources/ruby_runtime' + + +module PoiseRuby + module RubyProviders + class Base < Chef::Provider + include Poise(inversion: :ruby_runtime) + + # Set default inversion options. + # + # @api private + def self.default_inversion_options(node, new_resource) + super.merge({ + bundler_version: new_resource.bundler_version, + version: new_resource.version, + }) + end + + # The `install` action for the `ruby_runtime` resource. + # + # @return [void] + def action_install + notifying_block do + install_ruby + install_bundler + end + end + + # The `uninstall` action for the `ruby_runtime` resource. + # + # @return [void] + def action_uninstall + notifying_block do + uninstall_ruby + end + end + + # The path to the `ruby` binary. + # + # @abstract + # @return [String] + def ruby_binary + raise NotImplementedError + end + + # Output property for environment variables. + # + # @return [Hash] + def ruby_environment + # No environment variables needed. Rejoice. + {} + end + + # The path to the `gem` binary. Look relative to the + # `ruby` binary for a default implementation. + # + # @return [String] + def gem_binary + dir, base = ::File.split(ruby_binary) + # If this ruby is called something weird, bail out. + raise NotImplementedError unless base.start_with?('ruby') + # Allow for names like "ruby2.0" -> "gem2.0". + ::File.join(dir, base.sub(/^ruby/, 'gem')) + end + + private + + # Install the Ruby runtime. Must be implemented by subclass. + # + # @abstract + # @return [void] + def install_ruby + end + + # Uninstall the Ruby runtime. Must be implemented by subclass. + # + # @abstract + # @return [void] + def uninstall_ruby + end + + # Install Bundler in to the Ruby runtime. + # + # @return [void] + def install_bundler + # Captured because #options conflicts with Chef::Resource::Package#options. + bundler_version = options[:bundler_version] + return unless bundler_version + ruby_gem 'bundler' do + action :upgrade if bundler_version == true + parent_ruby new_resource + version bundler_version if bundler_version.is_a?(String) + end + end + end + end +end diff --git a/cookbooks/poise-ruby/files/halite_gem/poise_ruby/ruby_providers/chef.rb b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/ruby_providers/chef.rb new file mode 100644 index 0000000..259a0b8 --- /dev/null +++ b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/ruby_providers/chef.rb @@ -0,0 +1,53 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 'poise_ruby/error' +require 'poise_ruby/ruby_providers/base' + + +module PoiseRuby + module RubyProviders + # Inversion provider for the `ruby_runtime` resource to use whatever Ruby is + # currently running, generally Chef's omnibus-d Ruby. + # + # @since 2.0.0 + # @provides chef + class ChefRuby < Base + provides(:chef) + + # The `install` action for the `ruby_runtime` resource. + # + # @return [void] + def action_install + # No-op, already installed! + end + + # The `uninstall` action for the `ruby_runtime` resource. + # + # @return [void] + def action_uninstall + raise PoiseRuby::Error.new("You cannot uninstall Chef's Ruby.") + end + + # The path to the running Ruby binary as determined via RbConfig. + # + # @return [String] + def ruby_binary + Gem.ruby + end + end + end +end diff --git a/cookbooks/poise-ruby/files/halite_gem/poise_ruby/ruby_providers/dummy.rb b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/ruby_providers/dummy.rb new file mode 100644 index 0000000..3e8663f --- /dev/null +++ b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/ruby_providers/dummy.rb @@ -0,0 +1,77 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 'poise_ruby/ruby_providers/base' + + +module PoiseRuby + module RubyProviders + # Inversion provider for the `ruby_runtime` resource to use a fake Ruby, + # for use in unit tests. + # + # @since 2.1.0 + # @provides dummy + class Dummy < Base + provides(:dummy) + + def self.default_inversion_options(node, resource) + super.merge({ + # Manual overrides for dummy data. + ruby_binary: ::File.join('', 'ruby'), + ruby_environment: nil, + gem_binary: nil, + }) + end + + # The `install` action for the `ruby_runtime` resource. + # + # @return [void] + def action_install + # This space left intentionally blank. + end + + # The `uninstall` action for the `ruby_runtime` resource. + # + # @return [void] + def action_uninstall + # This space left intentionally blank. + end + + # Path to the non-existent ruby. + # + # @return [String] + def ruby_binary + options['ruby_binary'] + end + + # Environment for the non-existent Ruby. + # + # @return [String] + def ruby_environment + options['ruby_environment'] || super + end + + # Path to the non-existent gem. + # + # @return [String] + def gem_binary + options['gem_binary'] || super + end + + end + end +end + diff --git a/cookbooks/poise-ruby/files/halite_gem/poise_ruby/ruby_providers/scl.rb b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/ruby_providers/scl.rb new file mode 100644 index 0000000..6d5b7d3 --- /dev/null +++ b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/ruby_providers/scl.rb @@ -0,0 +1,55 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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' +require 'poise_languages' + +require 'poise_ruby/ruby_providers/base' + + +module PoiseRuby + module RubyProviders + class Scl < Base + include PoiseLanguages::Scl::Mixin + provides(:scl) + scl_package('2.3.0', 'rh-ruby23', 'rh-ruby23-ruby-devel', '>= 7.0') + scl_package('2.2.2', 'rh-ruby22', 'rh-ruby22-ruby-devel') + # On EL7, the system package is Ruby 2.0.0 and is newer than the SCL build. + scl_package('2.0.0', 'ruby200', 'ruby200-ruby-devel', '~> 6.0') + scl_package('1.9.3', 'ruby193', 'ruby193-ruby-devel') + + def ruby_binary + ::File.join(scl_folder, 'root', 'usr', 'bin', 'ruby') + end + + def ruby_environment + scl_environment + end + + private + + def install_ruby + install_scl_package + end + + def uninstall_ruby + uninstall_scl_package + end + + end + end +end + diff --git a/cookbooks/poise-ruby/files/halite_gem/poise_ruby/ruby_providers/system.rb b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/ruby_providers/system.rb new file mode 100644 index 0000000..945acf9 --- /dev/null +++ b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/ruby_providers/system.rb @@ -0,0 +1,116 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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' +require 'poise_languages' + +require 'poise_ruby/error' +require 'poise_ruby/ruby_providers/base' + + +module PoiseRuby + module RubyProviders + class System < Base + include PoiseLanguages::System::Mixin + provides(:system) + packages('ruby', { + debian: { + '8' => %w{ruby2.1}, + '7' => %w{ruby1.9.3 ruby1.9.1 ruby1.8}, + # Debian 6 has a ruby1.9.1 package that installs 1.9.2, ignoring it for now. + '6' => %w{ruby1.8}, + }, + ubuntu: { + '16.04' => %w{ruby2.3}, + '14.04' => %w{ruby2.0 ruby1.9.3}, + '12.04' => %w{ruby1.9.3 ruby1.8}, + '10.04' => %w{ruby1.9.1 ruby1.8}, + }, + rhel: {default: %w{ruby}}, + centos: {default: %w{ruby}}, + fedora: {default: %w{ruby}}, + # Amazon Linux does actually have packages ruby18, ruby19, ruby20, ruby21. + # Ignoring for now because wooooo non-standard formatting. + amazon: {default: %w{ruby}}, + }) + + def self.default_inversion_options(node, resource) + super.merge({ + # Install a separate rubygems package? Only needed for 1.8. + rubygems_package: node['platform_family'] == 'rhel' && node['platform_version'].start_with?('6'), + }) + end + + # Output value for the Python binary we are installing. Seems to match + # package name on all platforms I've checked. + def ruby_binary + ::File.join('', 'usr', 'bin', system_package_name) + end + + private + + def install_ruby + install_system_packages + install_rubygems_package if options['rubygems_package'] + end + + def uninstall_ruby + uninstall_system_packages + end + + # Ubuntu has no ruby1.9.3-dev package. + def system_dev_package_overrides + super.tap do |overrides| + # WTF Ubuntu, seriously. + overrides['ruby1.9.3'] = 'ruby1.9.1-dev' if node.platform_family?('debian') + end + end + + # Install the configured rubygems package. + def install_rubygems_package + package (options['rubygems_package'].is_a?(String) ? options['rubygems_package'] : 'rubygems') + end + + def system_package_candidates(version) + [].tap do |names| + # Might as well try it. + names << "ruby#{version}" if version && !['', '1', '2'].include?(version) + # On debian, 1.9.1 and 1.9.3 have special packages. + if match = version.match(/^(\d+\.\d+\.\d+)/) + names << "ruby#{match[1]}" + end + # Normal debian package like ruby2.0. + if match = version.match(/^(\d+\.\d+)/) + names << "ruby#{match[1]}" + end + # Aliases for ruby1 and ruby2 + if version == '2' || version == '' + # 2.3 is on there for future proofing. Well, at least giving me a + # buffer zone. + names.concat(%w{ruby2.3 ruby2.2 ruby2.1 ruby2.0}) + end + if version == '1' || version == '' + names.concat(%w{ruby1.9.3 ruby1.9 ruby1.8}) + end + # For RHEL and friends. + names << 'ruby' + names.uniq! + end + end + + end + end +end diff --git a/cookbooks/poise-ruby/files/halite_gem/poise_ruby/version.rb b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/version.rb new file mode 100644 index 0000000..41f6040 --- /dev/null +++ b/cookbooks/poise-ruby/files/halite_gem/poise_ruby/version.rb @@ -0,0 +1,20 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 PoiseRuby + VERSION = '2.2.0' +end diff --git a/cookbooks/poise-ruby/libraries/default.rb b/cookbooks/poise-ruby/libraries/default.rb new file mode 100644 index 0000000..2865254 --- /dev/null +++ b/cookbooks/poise-ruby/libraries/default.rb @@ -0,0 +1,19 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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. +# + +raise 'Halite is not compatible with no_lazy_load false, please set no_lazy_load true in your Chef configuration file.' unless Chef::Config[:no_lazy_load] +$LOAD_PATH << File.expand_path('../../files/halite_gem', __FILE__) +require "poise_ruby/cheftie" diff --git a/cookbooks/poise-ruby/metadata.json b/cookbooks/poise-ruby/metadata.json new file mode 100644 index 0000000..d929224 --- /dev/null +++ b/cookbooks/poise-ruby/metadata.json @@ -0,0 +1 @@ +{"name":"poise-ruby","version":"2.2.0","description":"A Chef cookbook for managing Ruby installations.","long_description":"# Poise-Ruby Cookbook\n\n[![Build Status](https://img.shields.io/travis/poise/poise-ruby.svg)](https://travis-ci.org/poise/poise-ruby)\n[![Gem Version](https://img.shields.io/gem/v/poise-ruby.svg)](https://rubygems.org/gems/poise-ruby)\n[![Cookbook Version](https://img.shields.io/cookbook/v/poise-ruby.svg)](https://supermarket.chef.io/cookbooks/poise-ruby)\n[![Coverage](https://img.shields.io/codecov/c/github/poise/poise-ruby.svg)](https://codecov.io/github/poise/poise-ruby)\n[![Gemnasium](https://img.shields.io/gemnasium/poise/poise-ruby.svg)](https://gemnasium.com/poise/poise-ruby)\n[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)\n\nA [Chef](https://www.chef.io/) cookbook to provide a unified interface for\ninstalling Ruby and running things with it. This README covers the 2.x version\nof the cookbook, the 1.x version is very different and no longer supported.\n\n## Quick Start\n\nTo install the latest available version of Ruby 2.x and then use it to install\nsome gems:\n\n```ruby\nruby_runtime '2'\n\nruby_gem 'rake'\n\nbundle_install '/path/to/Gemfile' do\n without 'development'\n deployment true\nend\n```\n\n## Requirements\n\nChef 12.1 or newer is required.\n\n## Attributes\n\nAttributes are used to configure the default recipe.\n\n* `node['poise-ruby']['install_ruby']` – Install a Ruby runtime. *(default: true)*\n* `node['poise-ruby']['install_chef_ruby']` – Create a `ruby_runtime` using\n the `:chef` provider. Doesn't actually install anything. *(default: true)*\n\n## Recipes\n\n### `default`\n\nThe default recipe installs Ruby based on the node attributes. It is entirely\noptional and can be ignored in favor of direct use of the `ruby_runtime`\nresource.\n\n## Resources\n\n### `ruby_runtime`\n\nThe `ruby_runtime` resource installs a Ruby interpreter.\n\n```ruby\nruby_runtime 'any' do\n version ''\nend\n```\n\n#### Actions\n\n* `:install` – Install the Ruby interpreter. *(default)*\n* `:uninstall` – Uninstall the Ruby interpreter.\n\n#### Properties\n\n* `version` – Version of Ruby to install. If a partial version is given, use the\n latest available version matching that prefix. *(name properties)*\n\n#### Provider Options\n\nThe `poise-ruby` library offers an additional way to pass configuration\ninformation to the final provider called \"options\". Options are key/value pairs\nthat are passed down to the ruby_runtime provider and can be used to control how it\ninstalls Ruby. These can be set in the `ruby_runtime`\nresource using the `options` method, in node attributes or via the\n`ruby_runtime_options` resource. The options from all sources are merged\ntogether in to a single hash.\n\nWhen setting options in the resource you can either set them for all providers:\n\n```ruby\nruby_runtime 'myapp' do\n version '2.1'\n options dev_package: false\nend\n```\n\nor for a single provider:\n\n```ruby\nruby_runtime 'myapp' do\n version '2.1'\n options :system, dev_package: false\nend\n```\n\nSetting via node attributes is generally how an end-user or application cookbook\nwill set options to customize installations in the library cookbooks they are using.\nYou can set options for all installations or for a single runtime:\n\n```ruby\n# Global, for all installations.\noverride['poise-ruby']['options']['dev_package'] = false\n# Single installation.\noverride['poise-ruby']['myapp']['version'] = '2.2'\n```\n\nThe `ruby_runtime_options` resource is also available to set node attributes\nfor a specific installation in a DSL-friendly way:\n\n```ruby\nruby_runtime_options 'myapp' do\n version '2.2'\nend\n```\n\nUnlike resource attributes, provider options can be different for each provider.\nNot all providers support the same options so make sure to the check the\ndocumentation for each provider to see what options the use.\n\n### `ruby_runtime_options`\n\nThe `ruby_runtime_options` resource allows setting provider options in a\nDSL-friendly way. See [the Provider Options](#provider-options) section for more\ninformation about provider options overall.\n\n```ruby\nruby_runtime_options 'myapp' do\n version '2.2'\nend\n```\n\n#### Actions\n\n* `:run` – Apply the provider options. *(default)*\n\n#### Properties\n\n* `resource` – Name of the `ruby_runtime` resource. *(name property)*\n* `for_provider` – Provider to set options for.\n\nAll other property keys will be used as options data.\n\n### `ruby_execute`\n\nThe `ruby_execute` resource executes a Ruby script using the configured runtime.\n\n```ruby\nruby_execute 'myapp.rb' do\n user 'myuser'\nend\n```\n\nThis uses the built-in `execute` resource and supports all the same properties.\n\n#### Actions\n\n* `:run` – Execute the script. *(default)*\n\n#### Properties\n\n* `command` – Script and arguments to run. Must not include the `ruby`. *(name property)*\n* `ruby` – Name of the `ruby_runtime` resource to use. If not specified, the\n most recently declared `ruby_runtime` will be used.\n\nFor other properties see the [Chef documentation](https://docs.chef.io/resource_execute.html#attributes).\n\n### `ruby_gem`\n\nThe `ruby_gem` resource is a subclass of the standard `gem_package` resource to\ninstall the gem with the configured runtime.\n\n```ruby\nruby_gem 'rake' do\n version ' 10.4.2'\nend\n```\n\nAll actions and attributes match the standard `gem_package` resource with the\naddition of a `ruby` attribute matching `ruby_execute`.\n\n### `bundle_install`\n\nThe `bundle_install` resource installs gems based on a Gemfile using\n[bundler](http://bundler.io/).\n\n```ruby\nbundle_install '/path/to/Gemfile' do\n deployment true\n jobs 3\nend\n```\n\nThe underlying `bundle` command will run on every converge, but notifications\nwill only be triggered if a gem is actually installed.\n\n#### Actions\n\n* `:install` – Run `bundle install`. *(default)*\n* `:update` – Run `bundle update`.\n\n#### Properties\n\n* `path` – Path to a Gemfile or a directory containing a Gemfile. *(name property)*\n* `binstubs` – Enable binstubs. If set to a string it is the path to generate\n stubs in.\n* `bundler_version` – Version of bundler to install. If unset the latest version is used.\n* `deployment` – Enable deployment mode.\n* `gem_binary` – Path to the gem binary. If unset this uses the `ruby_runtime` parent.\n* `jobs` – Number of parallel installations to run.\n* `retry` – Number of times to retry failed installations.\n* `ruby` – Name of the `ruby_runtime` resource to execute against.\n* `user` – User to run bundler as.\n* `vendor` – Enable local vendoring. This maps to the `--path` option in bundler,\n but that attribute name is already used.\n* `without` – Group or groups to not install.\n\n## Ruby Providers\n\n### `system`\n\nThe `system` provider installs Ruby using system packages. This is currently\nonly tested on platforms using `apt-get` and `yum` (Debian, Ubuntu, RHEL, CentOS\nAmazon Linux, and Fedora) and is the default provider on those platforms. It\nmay work on other platforms but is untested.\n\n```ruby\nruby_runtime 'myapp' do\n provider :system\n version '2.1'\nend\n```\n\n#### Options\n\n* `dev_package` – Install the package with the headers and other development\n files. *(default: true)*\n* `rubygems_package` – Install rubygems from a package. This is only needed for\n Ruby 1.8. *(default: true on RHEL 6)*\n* `package_name` – Override auto-detection of the package name.\n* `package_upgrade` – Install using action `:upgrade`. *(default: false)*\n* `package_version` – Override auto-detection of the package version.\n* `version` – Override the Ruby version.\n\n### `scl`\n\nThe `scl` provider installs Ruby using the [Software Collections](https://www.softwarecollections.org/)\npackages. This is only available on RHEL and CentOS. SCL offers more\nrecent versions of Ruby than the system packages for the most part. If an SCL\npackage exists for the requested version, it will be used in preference to the\n`system` provider.\n\n```ruby\nruby_runtime 'myapp' do\n provider :scl\n version '2.2'\nend\n```\n\n### `chef`\n\nThe `chef` provider uses the Ruby environment included in the Omnibus packages.\nGreat care should be taken when using this provider.\n\n```ruby\nruby_runtime 'myapp' do\n provider :chef\n version '2.1'\nend\n```\n\n#### Options\n\n* `version` – Override the Ruby version.\n\n### `ruby_build`\n\nThe `ruby_build` provider uses [ruby-build](https://github.com/sstephenson/ruby-build)\nto compile and install Ruby. It can be found in the\n[poise-ruby-build cookbook](https://github.com/poise/poise-ruby-build).\n\n## Sponsors\n\nDevelopment sponsored by [Bloomberg](http://www.bloomberg.com/company/technology/).\n\nThe Poise test server infrastructure is sponsored by [Rackspace](https://rackspace.com/).\n\n## License\n\nCopyright 2015-2016, Noah Kantrowitz\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","maintainer":"Noah Kantrowitz","maintainer_email":"noah@coderanger.net","license":"Apache 2.0","platforms":{},"dependencies":{"poise":"~> 2.0","poise-languages":"~> 2.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{},"source_url":"https://github.com/poise/poise-ruby","issues_url":"https://github.com/poise/poise-ruby/issues","chef_version":"~> 12","ohai_version":{}} \ No newline at end of file diff --git a/cookbooks/poise-ruby/recipes/default.rb b/cookbooks/poise-ruby/recipes/default.rb new file mode 100644 index 0000000..f5b8080 --- /dev/null +++ b/cookbooks/poise-ruby/recipes/default.rb @@ -0,0 +1,19 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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. +# + +# Default runtimes, last one will be the default. +ruby_runtime('chef') { provider :chef } if node['poise-ruby']['install_chef_ruby'] +ruby_runtime('ruby') { version '' } if node['poise-ruby']['install_ruby'] diff --git a/cookbooks/poise-service/CHANGELOG.md b/cookbooks/poise-service/CHANGELOG.md new file mode 100644 index 0000000..8364cfe --- /dev/null +++ b/cookbooks/poise-service/CHANGELOG.md @@ -0,0 +1,74 @@ +# Poise-Service Changelog + +## v1.4.2 + +* Fix the `noterm` test service to work on Ruby 2.3. + +## v1.4.1 + +* Fix `poise_service_user` on Solaris and make it closer to being usable on Windows. + +## v1.4.0 + +* [#31](https://github.com/poise/poise-service/pull/31) Add `shell` property to + `poise_service_user` resource. + +## v1.3.1 + +* [#25](https://github.com/poise/poise-service/pull/25) Cope with a service user + with an invalid home directory. +* Use the correct default cookbook for `service_template` when used with additional plugins. + +## v1.3.0 + +* Allow setting `pid_file_external false` as a provider option for the `sysvinit` + provider to have non-standard path but keep the internal handling. +* Improved quoting for environment variables in the `inittab` provider. + +## v1.2.1 + +* [#23](https://github.com/poise/poise-service/pull/23) Fix service templates on AIX and FreeBSD to use the correct root group. + +## v1.2.0 + +* The `Restart` mode for systemd services can now be controlled via provider + option and defaults to `on-failure` to match other providers. + +## v1.1.2 + +* [#22](https://github.com/poise/poise-service/pull/22) Set all script commands + for the `sysvinit` provider. This should fix compatibility with EL5. + +## v1.1.1 + +* Fix an incorrect value in `poise_service_test`. This is not relevant to + end-users of `poise-service`. + +## v1.1.0 + +* Added `inittab` provider to manage services using old-fashioned `/etc/inittab`. + +## v1.0.4 + +* Set GID correctly in all service providers. +* Allow overriding the path to the generated sysvinit script. + +## v1.0.3 + +* [#10](https://github.com/poise/poise-service/pull/10) Fixes for ensuring services are restarted when their command or user changes. +* [#11](https://github.com/poise/poise-service/pull/11) Revamp the `sysvinit` provider for non-Debian platforms to be more stable. +* [#12](https://github.com/poise/poise-service/pull/12) Improve the `dummy` provider to handle dropping privs correctly. + +## v1.0.2 + +* Fix a potential infinite loop when starting a service with the dummy provider. +* [#2](https://github.com/poise/poise-service/pull/2) Remove usage of root + default files so uploading with Berkshelf works (for now). + +## v1.0.1 + +* Don't use a shared, mutable default value for `#environment`. + +## v1.0.0 + +* Initial release! diff --git a/cookbooks/poise-service/README.md b/cookbooks/poise-service/README.md new file mode 100644 index 0000000..922b8dd --- /dev/null +++ b/cookbooks/poise-service/README.md @@ -0,0 +1,414 @@ +# Poise-Service Cookbook + +[![Build Status](https://img.shields.io/travis/poise/poise-service.svg)](https://travis-ci.org/poise/poise-service) +[![Gem Version](https://img.shields.io/gem/v/poise-service.svg)](https://rubygems.org/gems/poise-service) +[![Cookbook Version](https://img.shields.io/cookbook/v/poise-service.svg)](https://supermarket.chef.io/cookbooks/poise-service) +[![Coverage](https://img.shields.io/codecov/c/github/poise/poise-service.svg)](https://codecov.io/github/poise/poise-service) +[![Gemnasium](https://img.shields.io/gemnasium/poise/poise-service.svg)](https://gemnasium.com/poise/poise-service) +[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) + +A [Chef](https://www.chef.io/) cookbook to provide a unified interface for +services. + +### What is poise-service? + +Poise-service is a tool for developers of "library cookbooks" to define a +service without forcing the end-user of the library to adhere to their choice of +service management framework. The `poise_service` resource represents an +abstract service to be run, which can then be customized by node attributes and +the `poise_service_options` resource. This is a technique called [dependency +injection](https://en.wikipedia.org/wiki/Dependency_injection), and allows a +measure of decoupling between the library and application cookbooks. + +### Why would I use poise-service? + +Poise-service is most useful for authors of library-style cookbooks, for example +the `apache2`, `mysql`, or `application` cookbooks. When using other service +management options with Chef, the author of the library cookbook has to add +specific code for each service management framework they want to support, often +resulting in a cookbook only supporting the favorite framework of the author or +depending on distribution packages for their init scripts. The `poise_service` +resource allows library cookbook authors a way to write generic code for all +service management frameworks while still allowing users of that cookbook to +choose which service management framework best fits their needs. + +### How is this different from the built-in service resource? + +Chef includes a `service` resource which allows interacting with certain +service management frameworks such as SysV, Upstart, and systemd. +`poise-service` goes further in that it actually generates the configuration +files needed for the requested service management framework, as well as offering +a dependency injection system for application cookbooks to customize which +framework is used. + +### What service management frameworks are supported? + +* [SysV (aka /etc/init.d)](#sysvinit) +* [Upstart](#upstart) +* [systemd](#systemd) +* [Inittab](#inittab) +* [Runit](https://github.com/poise/poise-service-runit) +* [Monit](https://github.com/poise/poise-monit#service-provider) +* [Solaris](https://github.com/sh9189/poise-service-solaris) +* [AIX](https://github.com/johnbellone/poise-service-aix) +* *Supervisor (coming soon!)* + + +## Quick Start + +To create a service user and a service to run Apache2: + +```ruby +poise_service_user 'www-data' + +poise_service 'apache2' do + command '/usr/sbin/apache2 -f /etc/apache2/apache2.conf -DFOREGROUND' + stop_signal 'WINCH' + reload_signal 'USR1' +end +``` + +or for a hypothetical Rails web application: + +```ruby +poise_service_user 'myapp' + +poise_service 'myapp-web' do + command 'bundle exec unicorn -p 8080' + user 'myapp' + directory '/srv/myapp' + environment RAILS_ENV: 'production' +end +``` + +## Resources + +### `poise_service` + +The `poise_service` resource is the abstract definition of a service. + +```ruby +poise_service 'myapp' do + command 'myapp --serve' + environment RAILS_ENV: 'production' +end +``` + +#### Actions + +* `:enable` – Create, enable and start the service. *(default)* +* `:disable` – Stop, disable, and destroy the service. +* `:start` – Start the service. +* `:stop` – Stop the service. +* `:restart` – Stop and then start the service. +* `:reload` – Send the configured reload signal to the service. + +#### Attributes + +* `service_name` – Name of the service. *(name attribute)* +* `command` – Command to run for the service. This command must stay in the + foreground and not daemonize itself. *(required)* +* `user` – User to run the service as. See + [`poise_service_user`](#poise_service_user) for any easy way to create service + users. *(default: root)* +* `directory` – Working directory for the service. *(default: home directory for + user, or / if not found)* +* `environment` – Environment variables for the service. +* `stop_signal` – Signal to use to stop the service. Some systems will fall back + to SIGKILL if this signal fails to stop the process. *(default: TERM)* +* `reload_signal` – Signal to use to reload the service. *(default: HUP)* +* `restart_on_update` – If true, the service will be restarted if the service + definition or configuration changes. If `'immediately'`, the notification will + happen in immediate mode. *(default: true)* + +#### Service Options + +The `poise-service` library offers an additional way to pass configuration +information to the final service called "options". Options are key/value pairs +that are passed down to the service provider and can be used to control how it +creates and manages the service. These can be set in the `poise_service` +resource using the `options` method, in node attributes or via the +`poise_service_options` resource. The options from all sources are merged +together in to a single hash. + +When setting options in the resource you can either set them for all providers: + +```ruby +poise_service 'myapp' do + command 'myapp --serve' + options status_port: 8000 +end +``` + +or for a single provider: + +```ruby +poise_service 'myapp' do + command 'myapp --serve' + options :systemd, after_target: 'network' +end +``` + +Setting via node attributes is generally how an end-user or application cookbook +will set options to customize services in the library cookbooks they are using. +You can set options for all services or for a single service, by service name +or by resource name: + +```ruby +# Global, for all services. +override['poise-service']['options']['after_target'] = 'network' +# Single service. +override['poise-service']['myapp']['template'] = 'myapp.erb' +``` + +The `poise_service_options` resource is also available to set node attributes +for a specific service in a DSL-friendly way: + +```ruby +poise_service_options 'myapp' do + template 'myapp.erb' + restart_on_update false +end +``` + +Unlike resource attributes, service options can be different for each provider. +Not all providers support the same options so make sure to check the +documentation for each provider to see what options are available. + +### `poise_service_options` + +The `poise_service_options` resource allows setting per-service options in a +DSL-friendly way. See [the Service Options](#service-options) section for more +information about service options overall. + +```ruby +poise_service_options 'myapp' do + template 'myapp.erb' + restart_on_update false +end +``` + +#### Actions + +* `:run` – Apply the service options. *(default)* + +#### Attributes + +* `resource` – Name of the service. *(name attribute)* +* `for_provider` – Provider to set options for. + +All other attribute keys will be used as options data. + +### `poise_service_user` + +The `poise_service_user` resource is an easy way to create service users. It is +not required to use `poise_service`, it is only a helper. + +```ruby +poise_service_user 'myapp' do + home '/srv/myapp' +end +``` + +#### Actions + +* `:create` – Create the user and group. *(default)* +* `:remove` – Remove the user and group. + +#### Attributes + +* `user` – Name of the user. *(name attribute)* +* `group` – Name of the group. Set to `false` to disable group creation. *(name attribute)* +* `uid` – UID of the user. *(default: automatic)* +* `gid` – GID of the group. *(default: automatic)* +* `home` – Home directory of the user. +* `shell` – Shell of the user. *(default: /bin/nologin if present or /bin/false)* + +## Providers + +### `sysvinit` + +The `sysvinit` provider supports SystemV-style init systems on Debian-family and +RHEL-family platforms. It will create the `/etc/init.d/` script +and enable/disable the service using the platform-specific service resource. + +```ruby +poise_service 'myapp' do + provider :sysvinit + command 'myapp --serve' +end +``` + +By default a PID file will be created in `/var/run/service_name.pid`. You can +use the `pid_file` option detailed below to override this and rely on your +process creating a PID file in the given path. + +#### Options + +* `pid_file` – Path to PID file that the service command will create. +* `pid_file_external` – If true, assume the service will create the PID file + itself. *(default: true if `pid_file` option is set)* +* `template` – Override the default script template. If you want to use a + template in a different cookbook use `'cookbook:template'`. +* `command` – Override the service command. +* `directory` – Override the service directory. +* `environment` – Override the service environment variables. +* `reload_signal` – Override the service reload signal. +* `stop_signal` – Override the service stop signal. +* `user` – Override the service user. +* `never_restart` – Never try to restart the service. +* `never_reload` – Never try to reload the service. +* `script_path` – Override the path to the generated service script. + +### `upstart` + +The `upstart` provider supports [Upstart](http://upstart.ubuntu.com/). It will +create the `/etc/init/service_name.conf` configuration. + +```ruby +poise_service 'myapp' do + provider :upstart + command 'myapp --serve' +end +``` + +As a wide variety of versions of Upstart are in use in various Linux +distributions, the provider does its best to identify which features are +available and provide shims as appropriate. Most of these should be invisible +however Upstart older than 1.10 does not support setting a `reload signal` so +only SIGHUP can be used. You can set a `reload_shim` option to enable an +internal implementaion of reloading to be used for signals other than SIGHUP, +however as this is implemented inside Chef code, running `initctl reload` would +still result in SIGHUP being sent. For this reason, the feature is disabled by +default and will throw an error if a reload signal other than SIGHUP is used. + +#### Options + +* `reload_shim` – Enable the reload signal shim. See above for a warning about + this feature. +* `template` – Override the default configuration template. If you want to use a + template in a different cookbook use `'cookbook:template'`. +* `command` – Override the service command. +* `directory` – Override the service directory. +* `environment` – Override the service environment variables. +* `reload_signal` – Override the service reload signal. +* `stop_signal` – Override the service stop signal. +* `user` – Override the service user. +* `never_restart` – Never try to restart the service. +* `never_reload` – Never try to reload the service. + +### `systemd` + +The `systemd` provider supports [systemd](http://www.freedesktop.org/wiki/Software/systemd/). +It will create the `/etc/systemd/system/service_name.service` configuration. + + +```ruby +poise_service 'myapp' do + provider :systemd + command 'myapp --serve' +end +``` + +#### Options + +* `template` – Override the default configuration template. If you want to use a + template in a different cookbook use `'cookbook:template'`. +* `command` – Override the service command. +* `directory` – Override the service directory. +* `environment` – Override the service environment variables. +* `reload_signal` – Override the service reload signal. +* `stop_signal` – Override the service stop signal. +* `user` – Override the service user. +* `never_restart` – Never try to restart the service. +* `never_reload` – Never try to reload the service. +* `auto_reload` – Run `systemctl daemon-reload` after changes to the unit file. *(default: true)* +* `restart_mode` – Restart mode for the generated service unit. *(default: on-failure)* + +### `inittab` + +The `inittab` provider supports managing services via `/etc/inittab` using +[SystemV Init](http://www.nongnu.org/sysvinit/). This can provide basic +process supervision even on very old *nix machines. + +```ruby +poise_service 'myapp' do + provider :inittab + command 'myapp --serve' +end +``` + +**NOTE:** Inittab does not allow stopping services, and they are started as soon +as they are enabled. + +#### Options + +* `never_restart` – Never try to restart the service. +* `never_reload` – Never try to reload the service. +* `pid_file` – Path to PID file that the service command will create. +* `service_id` – Unique 1-4 character tag for the service. Defaults to an + auto-generated hash based on the service name. If these collide, bad things + happen. Don't do that. + +## ServiceMixin + +For the common case of a resource (LWRP or plain Ruby) that roughly maps to +"some config files and a service" poise-service provides a mixin module, +`PoiseService::ServiceMixin`. This mixin adds the standard service actions +(`enable`, `disable`, `start`, `stop`, `restart`, and `reload`) with basic +implementations that call those actions on a `poise_service` resource for you. +You customize the service by defining a `service_options` method on your +provider class: + +```ruby +def service_options(service) + # service is the PoiseService::Resource object instance. + service.command "/usr/sbin/#{new_resource.name} -f /etc/#{new_resource.name}/conf/httpd.conf -DFOREGROUND" + service.stop_signal 'WINCH' + service.reload_signal 'USR1' +end +``` + +You will generally want to override the `enable` action to install things +related to the service like packages, users and configuration files: + +```ruby +def action_enable + notifying_block do + package 'apache2' + poise_service_user 'www-data' + template "/etc/#{new_resource.name}/conf/httpd.conf" do + # ... + end + end + # This super call will run the normal service enable, + # creating the service and starting it. + super +end +``` + +See [the poise_service_test_mixin resource](test/cookbooks/poise-service_test/resources/mixin.rb) +and [provider](test/cookbooks/poise-service_test/providers/mixin.rb) for +examples of using `ServiceMixin` in an LWRP. + +## Sponsors + +Development sponsored by [Bloomberg](http://www.bloomberg.com/company/technology/). + +The Poise test server infrastructure is sponsored by [Rackspace](https://rackspace.com/). + +## License + +Copyright 2015-2016, Noah Kantrowitz + +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/poise-service/attributes/default.rb b/cookbooks/poise-service/attributes/default.rb new file mode 100644 index 0000000..2e8490d --- /dev/null +++ b/cookbooks/poise-service/attributes/default.rb @@ -0,0 +1,19 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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. +# + +default['poise-service']['provider'] = 'auto' + +default['poise-service']['options'] = {} diff --git a/cookbooks/poise-service/files/halite_gem/poise_service.rb b/cookbooks/poise-service/files/halite_gem/poise_service.rb new file mode 100644 index 0000000..ad2ec60 --- /dev/null +++ b/cookbooks/poise-service/files/halite_gem/poise_service.rb @@ -0,0 +1,25 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 PoiseService + autoload :Error, 'poise_service/error' + autoload :Resources, 'poise_service/resources' + autoload :ServiceMixin, 'poise_service/service_mixin' + autoload :ServiceProviders, 'poise_service/service_providers' + autoload :Utils, 'poise_service/utils' + autoload :VERSION, 'poise_service/version' +end diff --git a/cookbooks/poise-service/files/halite_gem/poise_service/cheftie.rb b/cookbooks/poise-service/files/halite_gem/poise_service/cheftie.rb new file mode 100644 index 0000000..31d59db --- /dev/null +++ b/cookbooks/poise-service/files/halite_gem/poise_service/cheftie.rb @@ -0,0 +1,18 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 'poise_service/resources' +require 'poise_service/service_providers' diff --git a/cookbooks/poise-service/files/halite_gem/poise_service/error.rb b/cookbooks/poise-service/files/halite_gem/poise_service/error.rb new file mode 100644 index 0000000..5029795 --- /dev/null +++ b/cookbooks/poise-service/files/halite_gem/poise_service/error.rb @@ -0,0 +1,20 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 PoiseService + class Error < ::Exception + end +end diff --git a/cookbooks/poise-service/files/halite_gem/poise_service/resources.rb b/cookbooks/poise-service/files/halite_gem/poise_service/resources.rb new file mode 100644 index 0000000..b0e1ddb --- /dev/null +++ b/cookbooks/poise-service/files/halite_gem/poise_service/resources.rb @@ -0,0 +1,27 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 'poise_service/resources/poise_service' +require 'poise_service/resources/poise_service_user' + + +module PoiseService + # Chef resources and providers for poise-service. + # + # @since 1.0.0 + module Resources + end +end diff --git a/cookbooks/poise-service/files/halite_gem/poise_service/resources/poise_service.rb b/cookbooks/poise-service/files/halite_gem/poise_service/resources/poise_service.rb new file mode 100644 index 0000000..157a584 --- /dev/null +++ b/cookbooks/poise-service/files/halite_gem/poise_service/resources/poise_service.rb @@ -0,0 +1,165 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 'etc' + +require 'chef/mash' +require 'chef/resource' +require 'poise' + +require 'poise_service/error' + + +module PoiseService + module Resources + # (see PoiseService::Resource) + module PoiseService + # `poise_service` resource. Provides a unified service interface with a + # dependency injection framework. + # + # @since 1.0.0 + # @provides poise_service + # @action enable + # @action disable + # @action start + # @action stop + # @action restart + # @action reload + # @example + # poise_service 'myapp' do + # command 'myapp --serve' + # user 'myuser' + # directory '/home/myapp' + # end + class Resource < Chef::Resource + include Poise(inversion: true) + provides(:poise_service) + actions(:enable, :disable, :start, :stop, :restart, :reload) + + # @!attribute service_name + # Name of the service to the underlying init system. Defaults to the name + # of the resource. + # @return [String] + attribute(:service_name, kind_of: String, name_attribute: true) + # @!attribute command + # Command to run inside the service. This command must remain in the + # foreground and not daemoinize itself. + # @return [String] + attribute(:command, kind_of: String, required: true) + # @!attribute user + # User to run the service as. See {UserResource} for an easy way to + # create service users. Defaults to root. + # @return [String] + attribute(:user, kind_of: String, default: 'root') + # @!attribute directory + # Working directory for the service. Defaults to the home directory of + # the configured user or / if not found. + # @return [String] + attribute(:directory, kind_of: String, default: lazy { default_directory }) + # @!attribute environment + # Environment variables for the service. + # @return [Hash] + attribute(:environment, kind_of: Hash, default: lazy { Mash.new }) + # @!attribute stop_signal + # Signal to use to stop the service. Some systems will fall back to + # KILL if this signal fails to stop the process. Defaults to TERM. + # @return [String, Symbol, Integer] + attribute(:stop_signal, kind_of: [String, Symbol, Integer], default: 'TERM') + # @!attribute reload_signal + # Signal to use to reload the service. Defaults to HUP. + # @return [String, Symbol, Integer] + attribute(:reload_signal, kind_of: [String, Symbol, Integer], default: 'HUP') + # @!attribute restart_on_update + # If true, the service will be restarted if the service definition or + # configuration changes. If 'immediately', the notification will happen + # in immediate mode. + # @return [Boolean, String] + attribute(:restart_on_update, equal_to: [true, false, 'immediately', :immediately], default: true) + + # Resource DSL callback. + # + # @api private + def after_created + # Set signals to clean values. + stop_signal(clean_signal(stop_signal)) + reload_signal(clean_signal(reload_signal)) + end + + # Return the PID of the main process for this service or nil if the service + # isn't running or the PID cannot be found. + # + # @return [Integer, nil] + # @example + # execute "kill -WINCH #{resources('poise_test[myapp]').pid}" + def pid + # :pid isn't a real action, but this should still work. + provider_for_action(:pid).pid + end + + private + + # Try to find the home diretory for the configured user. This will fail if + # nsswitch.conf was changed during this run such as with LDAP. Defaults to + # the system root directory. + # + # @see #directory + # @return [String] + def default_directory + # Default fallback. + sysroot = case node['platform_family'] + when 'windows' + ENV.fetch('SystemRoot', 'C:\\') + else + '/' + end + # For root we always want the system root path. + return sysroot if user == 'root' + # Force a reload in case any users were created earlier in the run. + Etc.endpwent + # ArgumentError means we can't find the user, possibly nsswitch caching? + home = begin + Dir.home(user) + rescue ArgumentError + sysroot + end + # If the home doesn't exist or is empty, use sysroot. + home = sysroot if home.empty? || !::File.directory?(home) + home + end + + # Clean up a signal string/integer. Ints are mapped to the signal name, + # and strings are reformatted to upper case and without the SIG. + # + # @see #stop_signal + # @param signal [String, Symbol, Integer] Signal value to clean. + # @return [String] + def clean_signal(signal) + if signal.is_a?(Integer) + raise Error.new("Unknown signal #{signal}") unless (0..31).include?(signal) + Signal.signame(signal) + else + short_sig = signal.to_s.upcase + short_sig = short_sig[3..-1] if short_sig.start_with?('SIG') + raise Error.new("Unknown signal #{signal}") unless Signal.list.include?(short_sig) + short_sig + end + end + + # Providers can be found under service_providers/. + end + end + end +end diff --git a/cookbooks/poise-service/files/halite_gem/poise_service/resources/poise_service_test.rb b/cookbooks/poise-service/files/halite_gem/poise_service/resources/poise_service_test.rb new file mode 100644 index 0000000..393ae21 --- /dev/null +++ b/cookbooks/poise-service/files/halite_gem/poise_service/resources/poise_service_test.rb @@ -0,0 +1,240 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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' +require 'chef/provider' +require 'poise' + + +module PoiseService + module Resources + # (see PoiseServiceTest::Resource) + module PoiseServiceTest + # A `poise_service_test` resource for integration testing service providers. + # This is used in Test-Kitchen tests to ensure all providers behave + # similarly. + # + # @since 1.0.0 + # @provides poise_service_test + # @action run + # @example + # poise_service_test 'upstart' do + # service_provider :upstart + # base_port 5000 + # end + class Resource < Chef::Resource + include Poise + provides(:poise_service_test) + actions(:run) + + # @!attribute service_provider + # Service provider to set for the test group. + # @return [Symbol] + attribute(:service_provider, kind_of: Symbol) + # @!attribute service_options + # Service options to set for the test group. + # @return [Hash, nil] + attribute(:service_options, kind_of: [Hash, NilClass]) + # @!attribute base_port + # Port number to start from for the test group. + # @return [Integer] + attribute(:base_port, kind_of: Integer) + end + + # Provider for `poise_service_test`. + # + # @see Resource + # @provides poise_service_test + class Provider < Chef::Provider + include Poise + provides(:poise_service_test) + + SERVICE_SCRIPT = <<-EOH +require 'webrick' +require 'json' +require 'etc' +FILE_DATA = '' +server = WEBrick::HTTPServer.new(Port: ARGV[0].to_i) +server.mount_proc '/' do |req, res| + res.body = { + directory: Dir.getwd, + user: Etc.getpwuid(Process.uid).name, + euser: Etc.getpwuid(Process.euid).name, + group: Etc.getgrgid(Process.gid).name, + egroup: Etc.getgrgid(Process.egid).name, + environment: ENV.to_hash, + file_data: FILE_DATA, + pid: Process.pid, + }.to_json +end +EOH + + # `run` action for `poise_service_test`. Create all test services. + # + # @return [void] + def action_run + notifying_block do + create_script + create_noterm_script + create_user + create_tests + end + end + + private + + def create_script + file '/usr/bin/poise_test' do + owner 'root' + group 'root' + mode '755' + content <<-EOH +#!/opt/chef/embedded/bin/ruby +#{SERVICE_SCRIPT} +def load_file + FILE_DATA.replace(IO.read(ARGV[1])) +end +if ARGV[1] + load_file + trap('HUP') do + load_file + end +end +server.start +EOH + end + end + + def create_noterm_script + file '/usr/bin/poise_test_noterm' do + owner 'root' + group 'root' + mode '755' + content <<-EOH +#!/opt/chef/embedded/bin/ruby +trap('HUP', 'IGNORE') +trap('TERM', 'IGNORE') +#{SERVICE_SCRIPT} +while true + begin + server.start + rescue Exception + rescue StandardError + end +end +EOH + end + end + + def create_user + poise_service_user 'poise' do + home '/tmp' + end + end + + def create_tests + poise_service "poise_test_#{new_resource.name}" do + if new_resource.service_provider + provider new_resource.service_provider + options new_resource.service_provider, new_resource.service_options if new_resource.service_options + end + command "/usr/bin/poise_test #{new_resource.base_port}" + end + + poise_service "poise_test_#{new_resource.name}_params" do + if new_resource.service_provider + provider new_resource.service_provider + options new_resource.service_provider, new_resource.service_options if new_resource.service_options + end + command "/usr/bin/poise_test #{new_resource.base_port + 1}" + environment POISE_ENV: new_resource.name + user 'poise' + end + + poise_service "poise_test_#{new_resource.name}_noterm" do + if new_resource.service_provider + provider new_resource.service_provider + options new_resource.service_provider, new_resource.service_options if new_resource.service_options + end + action [:enable, :disable] + command "/usr/bin/poise_test_noterm #{new_resource.base_port + 2}" + stop_signal 'kill' + end + + {'restart' => 3, 'reload' => 4}.each do |action, port| + # Stop it before writing the file so we always start with first. + poise_service "poise_test_#{new_resource.name}_#{action} stop" do + if new_resource.service_provider + provider new_resource.service_provider + options new_resource.service_provider, new_resource.service_options if new_resource.service_options + end + action(:disable) + service_name "poise_test_#{new_resource.name}_#{action}" + end + + # Write the content to the read on service launch. + file "/etc/poise_test_#{new_resource.name}_#{action}" do + content 'first' + end + + # Launch the service, reading in first. + poise_service "poise_test_#{new_resource.name}_#{action}" do + if new_resource.service_provider + provider new_resource.service_provider + options new_resource.service_provider, new_resource.service_options if new_resource.service_options + end + command "/usr/bin/poise_test #{new_resource.base_port + port} /etc/poise_test_#{new_resource.name}_#{action}" + end + + # Rewrite the file to second, restart/reload to trigger an update. + file "/etc/poise_test_#{new_resource.name}_#{action} again" do + path "/etc/poise_test_#{new_resource.name}_#{action}" + content 'second' + notifies action.to_sym, "poise_service[poise_test_#{new_resource.name}_#{action}]" + end + end + + # Test the #pid accessor. + ruby_block "/tmp/poise_test_#{new_resource.name}_pid" do + block do + pid = resources("poise_service[poise_test_#{new_resource.name}]").pid + IO.write("/tmp/poise_test_#{new_resource.name}_pid", pid.to_s) + end + end + + # Test changing the service definition itself. + poise_service "poise_test_#{new_resource.name}_change" do + if new_resource.service_provider + provider new_resource.service_provider + options new_resource.service_provider, new_resource.service_options if new_resource.service_options + end + command "/usr/bin/poise_test #{new_resource.base_port + 5}" + end + + poise_service "poise_test_#{new_resource.name}_change_second" do + service_name "poise_test_#{new_resource.name}_change" + if new_resource.service_provider + provider new_resource.service_provider + options new_resource.service_provider, new_resource.service_options if new_resource.service_options + end + command "/usr/bin/poise_test #{new_resource.base_port + 6}" + end + + end + end + end + end +end diff --git a/cookbooks/poise-service/files/halite_gem/poise_service/resources/poise_service_user.rb b/cookbooks/poise-service/files/halite_gem/poise_service/resources/poise_service_user.rb new file mode 100644 index 0000000..6d4eac4 --- /dev/null +++ b/cookbooks/poise-service/files/halite_gem/poise_service/resources/poise_service_user.rb @@ -0,0 +1,186 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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' +require 'chef/provider' +require 'poise' + + +module PoiseService + module Resources + # (see PoiseServiceUser::Resource) + # @since 1.0.0 + module PoiseServiceUser + # Shells to look for in order. + # @api private + DEFAULT_SHELLS = %w{/bin/nologin /usr/bin/nologin /bin/false} + + # A `poise_service_user` resource to create service users/groups. + # + # @since 1.0.0 + # @provides poise_service_user + # @action create + # @action remove + # @example + # poise_service_user 'myapp' do + # home '/var/tmp' + # group 'nogroup' + # end + class Resource < Chef::Resource + include Poise + provides(:poise_service_user) + actions(:create, :remove) + + # @!attribute user + # Name of the user to create. Defaults to the name of the resource. + # @return [String] + attribute(:user, kind_of: String, name_attribute: true) + # @!attribute group + # Name of the group to create. Defaults to the name of the user, + # except on Windows where it defaults to false. Set to false to + # disable group creation. + # @return [String, false] + attribute(:group, kind_of: [String, FalseClass], default: lazy { default_group }) + # @!attribute uid + # UID of the user to create. Optional, if not set the UID will be + # allocated automatically. + # @return [Integer] + attribute(:uid, kind_of: Integer) + # @!attribute gid + # GID of the group to create. Optional, if not set the GID will be + # allocated automatically. + # @return [Integer] + attribute(:gid, kind_of: Integer) + # @!attribute shell + # Login shell for the user. Optional, if not set the shell will be + # determined automatically. + # @return [String] + attribute(:shell, kind_of: String, default: lazy { default_shell }) + # @!attribute home + # Home directory of the user. This directory will not be created if it + # does not exist. Optional. + # @return [String] + attribute(:home, kind_of: String) + + private + + # Find a default shell for service users. Tries to use nologin, but fall + # back on false. + # + # @api private + # @return [String] + def default_shell + DEFAULT_SHELLS.find {|s| ::File.exist?(s) } || DEFAULT_SHELLS.last + end + + # Find the default group name. Returns false on Windows because service + # groups aren't needed there. Otherwise use the name of the service user. + # + # @api private + # @return [String, false] + def default_group + if node.platform_family?('windows') + false + else + user + end + end + end + + # Provider for `poise_service_user`. + # + # @since 1.0.0 + # @see Resource + # @provides poise_service_user + class Provider < Chef::Provider + include Poise + provides(:poise_service_user) + + # `create` action for `poise_service_user`. Ensure the user and group (if + # enabled) exist. + # + # @return [void] + def action_create + notifying_block do + create_group if new_resource.group + create_user + end + end + + # `remove` action for `poise_service_user`. Ensure the user and group (if + # enabled) are destroyed. + # + # @return [void] + def action_remove + notifying_block do + remove_user + remove_group if new_resource.group + end + end + + private + + # Create the system group. + # + # @api private + # @return [void] + def create_group + group new_resource.group do + gid new_resource.gid + # Solaris doesn't support the idea of system groups. + system true unless node.platform_family?('solaris2') + end + end + + # Create the system user. + # + # @api private + # @return [void] + def create_user + user new_resource.user do + comment "Service user for #{new_resource.name}" + gid new_resource.group if new_resource.group + home new_resource.home + shell new_resource.shell + # Solaris doesn't support the idea of system users. + system true unless node.platform_family?('solaris2') + uid new_resource.uid + end + end + + # Remove the system group. + # + # @api private + # @return [void] + def remove_group + create_group.tap do |r| + r.action(:remove) + end + end + + # Remove the system user. + # + # @api private + # @return [void] + def remove_user + create_user.tap do |r| + r.action(:remove) + end + end + end + end + end +end diff --git a/cookbooks/poise-service/files/halite_gem/poise_service/service_mixin.rb b/cookbooks/poise-service/files/halite_gem/poise_service/service_mixin.rb new file mode 100644 index 0000000..da88a86 --- /dev/null +++ b/cookbooks/poise-service/files/halite_gem/poise_service/service_mixin.rb @@ -0,0 +1,192 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 'poise' + +require 'poise_service/resources/poise_service' + + +module PoiseService + # Mixin for application services. This is any resource that will be part of + # an application deployment and involves running a persistent service. + # + # @since 1.0.0 + # @example + # module MyApp + # class Resource < Chef::Resource + # include Poise + # provides(:my_app) + # include PoiseService::ServiceMixin + # end + # + # class Provider < Chef::Provider + # include Poise + # provides(:my_app) + # include PoiseService::ServiceMixin + # + # def action_enable + # notifying_block do + # template '/etc/myapp.conf' do + # # ... + # end + # end + # super + # end + # + # def service_options(r) + # r.command('myapp --serve') + # end + # end + # end + module ServiceMixin + include Poise::Utils::ResourceProviderMixin + + # Mixin for service wrapper resources. + # + # @see ServiceMixin + module Resource + include Poise::Resource + + module ClassMethods + # @api private + def included(klass) + super + klass.extend(ClassMethods) + klass.class_exec do + actions(:enable, :disable, :start, :stop, :restart, :reload) + attribute(:service_name, kind_of: String, name_attribute: true) + end + end + end + + extend ClassMethods + end + + # Mixin for service wrapper providers. + # + # @see ServiceMixin + module Provider + include Poise::Provider + + # Default enable action for service wrappers. + # + # @return [void] + def action_enable + notify_if_service do + service_resource.run_action(:enable) + end + end + + # Default disable action for service wrappers. + # + # @return [void] + def action_disable + notify_if_service do + service_resource.run_action(:disable) + end + end + + # Default start action for service wrappers. + # + # @return [void] + def action_start + notify_if_service do + service_resource.run_action(:start) + end + end + + # Default stop action for service wrappers. + # + # @return [void] + def action_stop + notify_if_service do + service_resource.run_action(:stop) + end + end + + # Default restart action for service wrappers. + # + # @return [void] + def action_restart + notify_if_service do + service_resource.run_action(:restart) + end + end + + # Default reload action for service wrappers. + # + # @return [void] + def action_reload + notify_if_service do + service_resource.run_action(:reload) + end + end + + # @todo Add reload once poise-service supports it. + + private + + # Set the current resource as notified if the provided block updates the + # service resource. + # + # @api public + # @param block [Proc] Block to run. + # @return [void] + # @example + # notify_if_service do + # service_resource.run_action(:enable) + # end + def notify_if_service(&block) + service_resource.updated_by_last_action(false) + block.call if block + new_resource.updated_by_last_action(true) if service_resource.updated_by_last_action? + end + + # Service resource for this service wrapper. This returns a + # poise_service resource that will not be added to the resource + # collection. Override {#service_options} to set service resource + # parameters. + # + # @api public + # @return [Chef::Resource] + # @example + # service_resource.run_action(:restart) + def service_resource + @service_resource ||= PoiseService::Resources::PoiseService::Resource.new(new_resource.name, run_context).tap do |r| + # Set some defaults. + r.enclosing_provider = self + r.source_line = new_resource.source_line + r.service_name(new_resource.service_name) + # Call the subclass hook for more specific settings. + service_options(r) + end + end + + # Abstract hook to set parameters on {#service_resource} when it is + # created. This is required to set at least `resource.command`. + # + # @api public + # @param resource [Chef::Resource] Resource instance to set parameters on. + # @return [void] + # @example + # def service_options(resource) + # resource.command('myapp --serve') + # end + def service_options(resource) + end + end + end +end diff --git a/cookbooks/poise-service/files/halite_gem/poise_service/service_providers.rb b/cookbooks/poise-service/files/halite_gem/poise_service/service_providers.rb new file mode 100644 index 0000000..6cee1ae --- /dev/null +++ b/cookbooks/poise-service/files/halite_gem/poise_service/service_providers.rb @@ -0,0 +1,38 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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/platform/provider_priority_map' + +require 'poise_service/service_providers/dummy' +require 'poise_service/service_providers/inittab' +require 'poise_service/service_providers/systemd' +require 'poise_service/service_providers/sysvinit' +require 'poise_service/service_providers/upstart' + + +module PoiseService + # Inversion providers for the poise_service resource. + # + # @since 1.0.0 + module ServiceProviders + # Set up priority maps + Chef::Platform::ProviderPriorityMap.instance.priority(:poise_service, [ + PoiseService::ServiceProviders::Systemd, + PoiseService::ServiceProviders::Upstart, + PoiseService::ServiceProviders::Sysvinit, + ]) + end +end diff --git a/cookbooks/poise-service/files/halite_gem/poise_service/service_providers/base.rb b/cookbooks/poise-service/files/halite_gem/poise_service/service_providers/base.rb new file mode 100644 index 0000000..f5e2408 --- /dev/null +++ b/cookbooks/poise-service/files/halite_gem/poise_service/service_providers/base.rb @@ -0,0 +1,193 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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/provider' +require 'poise' + + +module PoiseService + module ServiceProviders + class Base < Chef::Provider + include Poise(inversion: :poise_service) + + # Extend the default lookup behavior to check for service_name too. + # + # @api private + def self.resolve_inversion_provider(node, resource) + attrs = resolve_inversion_attribute(node) + (attrs[resource.service_name] && attrs[resource.service_name]['provider']) || super + end + + # Extend the default options to check for service_name too. + # + # @api private + def self.inversion_options(node, resource) + super.tap do |opts| + attrs = resolve_inversion_attribute(node) + opts.update(attrs[resource.service_name]) if attrs[resource.service_name] + run_state = Mash.new(node.run_state.fetch('poise_inversion', {}).fetch(inversion_resource, {}))[resource.service_name] || {} + opts.update(run_state['*']) if run_state['*'] + opts.update(run_state[provides]) if run_state[provides] + end + end + + # Cache the service hints to improve performance. This is called from the + # provides_auto? on most service providers and hits the filesystem a lot. + # + # @return [Array] + def self.service_resource_hints + @@service_resource_hints ||= Chef::Platform::ServiceHelpers.service_resource_providers + end + + def action_enable + include_recipe(*Array(recipes)) if recipes + notifying_block do + create_service + end + enable_service + action_start + end + + def action_disable + action_stop + disable_service + notifying_block do + destroy_service + end + end + + def action_start + notify_if_service do + service_resource.run_action(:start) + end + end + + def action_stop + notify_if_service do + service_resource.run_action(:stop) + end + end + + def action_restart + return if options['never_restart'] + notify_if_service do + service_resource.run_action(:restart) + end + end + + def action_reload + return if options['never_reload'] + notify_if_service do + service_resource.run_action(:reload) + end + end + + def pid + raise NotImplementedError + end + + private + + # Recipes to include for this provider to work. Subclasses can override. + # + # @return [String, Array] + def recipes + end + + # Subclass hook to create the required files et al for the service. + def create_service + raise NotImplementedError + end + + # Subclass hook to remove the required files et al for the service. + def destroy_service + raise NotImplementedError + end + + def enable_service + notify_if_service do + service_resource.run_action(:enable) + end + end + + def disable_service + notify_if_service do + service_resource.run_action(:disable) + end + end + + def notify_if_service(&block) + service_resource.updated_by_last_action(false) + block.call + new_resource.updated_by_last_action(true) if service_resource.updated_by_last_action? + end + + # Subclass hook to create the resource used to delegate start, stop, and + # restart actions. + def service_resource + @service_resource ||= Chef::Resource::Service.new(new_resource.service_name, run_context).tap do |r| + r.enclosing_provider = self + r.source_line = new_resource.source_line + r.supports(status: true, restart: true, reload: true) + end + end + + def service_template(path, default_source, &block) + # Sigh scoping. + template path do + owner 'root' + group node['root_group'] + mode '644' + if options['template'] + # If we have a template override, allow specifying a cookbook via + # "cookbook:template". + parts = options['template'].split(/:/, 2) + if parts.length == 2 + source parts[1] + cookbook parts[0] + else + source parts.first + cookbook new_resource.cookbook_name.to_s + end + else + source default_source + cookbook self.poise_defined_in_cookbook + end + variables( + command: options['command'] || new_resource.command, + directory: options['directory'] || new_resource.directory, + environment: options['environment'] || new_resource.environment, + name: new_resource.service_name, + new_resource: new_resource, + options: options, + reload_signal: options['reload_signal'] || new_resource.reload_signal, + stop_signal: options['stop_signal'] || new_resource.stop_signal, + user: options['user'] || new_resource.user, + ) + # Don't trigger a restart if the template doesn't already exist, this + # prevents restarting on the run that first creates the service. + restart_on_update = options.fetch('restart_on_update', new_resource.restart_on_update) + if restart_on_update && ::File.exist?(path) + mode = restart_on_update.to_s == 'immediately' ? :immediately : :delayed + notifies :restart, new_resource, mode + end + instance_exec(&block) if block + end + end + + end + end +end diff --git a/cookbooks/poise-service/files/halite_gem/poise_service/service_providers/dummy.rb b/cookbooks/poise-service/files/halite_gem/poise_service/service_providers/dummy.rb new file mode 100644 index 0000000..7cc6378 --- /dev/null +++ b/cookbooks/poise-service/files/halite_gem/poise_service/service_providers/dummy.rb @@ -0,0 +1,156 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 'etc' +require 'shellwords' + +require 'poise_service/service_providers/base' + + +module PoiseService + module ServiceProviders + class Dummy < Base + provides(:dummy) + + def action_start + return if pid + Chef::Log.debug("[#{new_resource}] Starting #{new_resource.command}") + # Clear the pid file if it exists. + ::File.unlink(pid_file) if ::File.exist?(pid_file) + if Process.fork + # Parent, wait for the final child to write the pid file. + now = Time.now + until ::File.exist?(pid_file) + sleep(1) + # After 30 seconds, show output at a higher level to avoid too much + # confusing on failed process launches. + if Time.now - now <= 30 + Chef::Log.debug("[#{new_resource}] Waiting for PID file") + else + Chef::Log.warning("[#{new_resource}] Waiting for PID file at #{pid_file} to be created") + end + end + else + # :nocov: + Chef::Log.debug("[#{new_resource}] Forked") + # First child, daemonize and go to town. This handles multi-fork, + # setsid, and shutting down stdin/out/err. + Process.daemon(true) + Chef::Log.debug("[#{new_resource}] Daemonized") + # Daemonized, set up process environment. + Dir.chdir(new_resource.directory) + Chef::Log.debug("[#{new_resource}] Directory changed to #{new_resource.directory}") + ENV['HOME'] = Dir.home(new_resource.user) + new_resource.environment.each do |key, val| + ENV[key.to_s] = val.to_s + end + Chef::Log.debug("[#{new_resource}] Process environment configured") + IO.write(pid_file, Process.pid) + Chef::Log.debug("[#{new_resource}] PID written to #{pid_file}") + ent = Etc.getpwnam(new_resource.user) + if Process.euid != ent.uid || Process.egid != ent.gid + Process.initgroups(ent.name, ent.gid) + Process::GID.change_privilege(ent.gid) if Process.egid != ent.gid + Process::UID.change_privilege(ent.uid) if Process.euid != ent.uid + end + Chef::Log.debug("[#{new_resource}] Changed privs to #{new_resource.user} (#{ent.uid}:#{ent.gid})") + # Split the command so we don't get an extra sh -c. + Chef::Log.debug("[#{new_resource}] Execing #{new_resource.command}") + Kernel.exec(*Shellwords.split(new_resource.command)) + # Just in case, bail out. + exit! + # :nocov: + end + Chef::Log.debug("[#{new_resource}] Started.") + end + + def action_stop + return unless pid + Chef::Log.debug("[#{new_resource}] Stopping with #{new_resource.stop_signal}. Current PID is #{pid.inspect}.") + Process.kill(new_resource.stop_signal, pid) + ::File.unlink(pid_file) + end + + def action_restart + return if options['never_restart'] + action_stop + action_start + end + + def action_reload + return if options['never_reload'] + return unless pid + Chef::Log.debug("[#{new_resource}] Reloading with #{new_resource.reload_signal}. Current PID is #{pid.inspect}.") + Process.kill(new_resource.reload_signal, pid) + end + + def pid + return nil unless ::File.exist?(pid_file) + pid = IO.read(pid_file).to_i + begin + # Check if the PID is running. + Process.kill(0, pid) + pid + rescue Errno::ESRCH + nil + end + end + + private + + def service_resource + # Intentionally not implemented. + raise NotImplementedError + end + + def enable_service + end + + # Write all major service parameters to a file so that if they change, we + # can restart the service. This also makes debuggin a bit easier so you + # can still see what it thinks it was starting without sifting through + # piles of debug output. + def create_service + service_template(run_file, 'dummy.json.erb') + end + + def disable_service + end + + # Delete the tracking file. + def destroy_service + file run_file do + action :delete + end + + file pid_file do + action :delete + end + end + + # Path to the run parameters tracking file. + def run_file + "/var/run/#{new_resource.service_name}.json" + end + + # Path to the PID file. + def pid_file + "/var/run/#{new_resource.service_name}.pid" + end + + end + end +end diff --git a/cookbooks/poise-service/files/halite_gem/poise_service/service_providers/inittab.rb b/cookbooks/poise-service/files/halite_gem/poise_service/service_providers/inittab.rb new file mode 100644 index 0000000..4758455 --- /dev/null +++ b/cookbooks/poise-service/files/halite_gem/poise_service/service_providers/inittab.rb @@ -0,0 +1,150 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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/util/file_edit' + +require 'poise_service/service_providers/base' + + +module PoiseService + module ServiceProviders + class Inittab < Base + provides(:inittab) + + def self.provides_auto?(node, resource) + ::File.exist?('/etc/inittab') + end + + def pid + IO.read(pid_file).to_i if ::File.exist?(pid_file) + end + + # Don't try to stop when disabling because we can't. + def action_disable + disable_service + notifying_block do + destroy_service + end + end + + def action_start + Chef::Log.debug("[#{new_resource}] Inittab services are always started.") + end + + def action_stop + raise NotImplementedError.new("[#{new_resource}] Inittab services cannot be stopped") + end + + def action_restart + return if options['never_restart'] + # Just kill it and let init restart it. + Process.kill(new_resource.stop_signal, pid) if pid + end + + def action_reload + return if options['never_reload'] + Process.kill(new_resource.reload_signal, pid) if pid + end + + private + + def service_resource + # Intentionally not implemented. + raise NotImplementedError + end + + def enable_service + end + + def disable_service + end + + def create_service + # Sigh scoping. + pid_file_ = pid_file + # Inittab only allows 127 characters for the command, so cram stuff in + # a file. Writing to a file is gross, but so is using inittab so ¯\_(ツ)_/¯. + service_template("/sbin/poise_service_#{new_resource.service_name}", 'inittab.sh.erb') do + mode '755' + variables.update( + pid_file: pid_file_, + ) + end + # Add to inittab. + edit_inittab do |content| + inittab_line = "#{service_id}:2345:respawn:/sbin/poise_service_#{new_resource.service_name}" + if content =~ /^# #{Regexp.escape(service_tag)}$/ + # Existing line, update in place. + content.gsub!(/^(# #{Regexp.escape(service_tag)}\n)(.*)$/, "\\1#{inittab_line}") + else + # Add to the end. + content << "# #{service_tag}\n#{inittab_line}\n" + end + end + end + + def destroy_service + # Remove from inittab. + edit_inittab do |content| + content.gsub!(/^# #{Regexp.escape(service_tag)}\n.*?\n$/, '') + end + + file "/sbin/poise_service_#{new_resource.service_name}" do + action :delete + end + + file pid_file do + action :delete + end + end + + # The shortened ID because sysvinit only allows 4 characters. + def service_id + # This is a terrible hash, but it should be good enough. + options['service_id'] || begin + sum = new_resource.service_name.sum(20).to_s(36) + if sum.length < 4 + 'p' + sum + else + sum + end + end + end + + # Tag to put in a comment in inittab for tracking. + def service_tag + "poise_service(#{new_resource.service_name})" + end + + def pid_file + options['pid_file'] || "/var/run/#{new_resource.service_name}.pid" + end + + def edit_inittab(&block) + inittab = IO.read('/etc/inittab') + original_inittab = inittab.dup + block.call(inittab) + if inittab != original_inittab + file '/etc/inittab' do + content inittab + end + + execute 'telinit q' + end + end + end + end +end diff --git a/cookbooks/poise-service/files/halite_gem/poise_service/service_providers/systemd.rb b/cookbooks/poise-service/files/halite_gem/poise_service/service_providers/systemd.rb new file mode 100644 index 0000000..1de6160 --- /dev/null +++ b/cookbooks/poise-service/files/halite_gem/poise_service/service_providers/systemd.rb @@ -0,0 +1,85 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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/mixin/shell_out' + +require 'poise_service/service_providers/base' + + +module PoiseService + module ServiceProviders + class Systemd < Base + include Chef::Mixin::ShellOut + provides(:systemd) + + # @api private + def self.provides_auto?(node, resource) + # Don't allow systemd under docker, it won't work in most cases. + return false if node['virtualization'] && %w{docker lxc}.include?(node['virtualization']['system']) + service_resource_hints.include?(:systemd) + end + + # @api private + def self.default_inversion_options(node, resource) + super.merge({ + # Automatically reload systemd on changes. + auto_reload: true, + # Service restart mode. + restart_mode: 'on-failure', + }) + end + + def pid + cmd = shell_out(%w{systemctl status} + [new_resource.service_name]) + if !cmd.error? && cmd.stdout.include?('Active: active (running)') && md = cmd.stdout.match(/Main PID: (\d+)/) + md[1].to_i + else + nil + end + end + + private + + def service_resource + super.tap do |r| + r.provider(Chef::Provider::Service::Systemd) + end + end + + def systemctl_daemon_reload + execute 'systemctl daemon-reload' do + action :nothing + user 'root' + end + end + + def create_service + reloader = systemctl_daemon_reload + service_template("/etc/systemd/system/#{new_resource.service_name}.service", 'systemd.service.erb') do + notifies :run, reloader, :immediately if options['auto_reload'] + variables.update(auto_reload: options['auto_reload'], restart_mode: options['restart_mode']) + end + end + + def destroy_service + file "/etc/systemd/system/#{new_resource.service_name}.service" do + action :delete + end + end + + end + end +end diff --git a/cookbooks/poise-service/files/halite_gem/poise_service/service_providers/sysvinit.rb b/cookbooks/poise-service/files/halite_gem/poise_service/service_providers/sysvinit.rb new file mode 100644 index 0000000..8438a41 --- /dev/null +++ b/cookbooks/poise-service/files/halite_gem/poise_service/service_providers/sysvinit.rb @@ -0,0 +1,97 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 'poise_service/service_providers/base' + + +module PoiseService + module ServiceProviders + class Sysvinit < Base + provides(:sysvinit) + + def self.provides_auto?(node, resource) + [:debian, :redhat, :invokercd].any? {|name| service_resource_hints.include?(name) } + end + + def pid + IO.read(pid_file).to_i if ::File.exist?(pid_file) + end + + private + + def service_resource + super.tap do |r| + r.provider(case node['platform_family'] + when 'debian' + Chef::Provider::Service::Debian + when 'rhel' + Chef::Provider::Service::Redhat + else + # Better than nothing I guess? Will fail on enable I think. + Chef::Provider::Service::Init + end) + r.init_command(script_path) + # Pending https://github.com/chef/chef/pull/4709. + r.start_command("#{script_path} start") + r.stop_command("#{script_path} stop") + r.status_command("#{script_path} status") + r.restart_command("#{script_path} restart") + r.reload_command("#{script_path} reload") + end + end + + def create_service + # Split the command into the binary and its arguments. This is for + # start-stop-daemon since it treats those differently. + parts = new_resource.command.split(/ /, 2) + daemon = ENV['PATH'].split(/:/) + .map {|path| ::File.absolute_path(parts[0], path) } + .find {|path| ::File.exist?(path) } || parts[0] + # Sigh scoping. + pid_file_ = pid_file + # Render the service template + service_template(script_path, 'sysvinit.sh.erb') do + mode '755' + variables.update( + daemon: daemon, + daemon_options: parts[1].to_s, + pid_file: pid_file_, + pid_file_external: options['pid_file_external'].nil? ? !!options['pid_file'] : options['pid_file_external'], + platform_family: node['platform_family'], + ) + end + end + + def destroy_service + file script_path do + action :delete + end + + file pid_file do + action :delete + end + end + + def script_path + options['script_path'] || "/etc/init.d/#{new_resource.service_name}" + end + + def pid_file + options['pid_file'] || "/var/run/#{new_resource.service_name}.pid" + end + end + end +end diff --git a/cookbooks/poise-service/files/halite_gem/poise_service/service_providers/upstart.rb b/cookbooks/poise-service/files/halite_gem/poise_service/service_providers/upstart.rb new file mode 100644 index 0000000..61b2318 --- /dev/null +++ b/cookbooks/poise-service/files/halite_gem/poise_service/service_providers/upstart.rb @@ -0,0 +1,128 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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. +# + +# Used in the template. +require 'shellwords' + +require 'chef/mixin/shell_out' + +require 'poise_service/error' +require 'poise_service/service_providers/base' + + +module PoiseService + module ServiceProviders + class Upstart < Base + include Chef::Mixin::ShellOut + provides(:upstart) + + def self.provides_auto?(node, resource) + # Don't allow upstart under docker, it won't work. + return false if node['virtualization'] && %w{docker lxc}.include?(node['virtualization']['system']) + service_resource_hints.include?(:upstart) + end + + # True restart in Upstart preserves the original config data, we want the + # more obvious behavior like everything else in the world that restart + # would re-read the updated config file. Use stop+start to get this + # behavior. http://manpages.ubuntu.com/manpages/raring/man8/initctl.8.html + def action_restart + return if options['never_restart'] + action_stop + action_start + end + + # Shim out reload if we have a version that predates reload support. + def action_reload + return if options['never_reload'] + if !upstart_features[:reload_signal] && new_resource.reload_signal != 'HUP' + if options[:reload_shim] + Process.kill(new_resource.reload_signal, pid) + else + check_reload_signal! + end + else + super + end + end + + def pid + cmd = shell_out(%w{initctl status} + [new_resource.service_name]) + if !cmd.error? && md = cmd.stdout.match(/process (\d+)/) + md[1].to_i + else + nil + end + end + + private + + def service_resource + super.tap do |r| + r.provider(Chef::Provider::Service::Upstart) + end + end + + def create_service + check_reload_signal! + # Set features so it will be a closure below. + features = upstart_features + service_template("/etc/init/#{new_resource.service_name}.conf", 'upstart.conf.erb') do + variables.update( + upstart_features: features, + ) + end + end + + def destroy_service + file "/etc/init/#{new_resource.service_name}.conf" do + action :delete + end + end + + def upstart_version + cmd = shell_out(%w{initctl --version}) + if !cmd.error? && md = cmd.stdout.match(/upstart ([^)]+)\)/) + md[1] + else + '0' + end + end + + def upstart_features + @upstart_features ||= begin + upstart_ver = Gem::Version.new(upstart_version) + versions_added = { + kill_signal: '1.3', + reload_signal: '1.10', + setuid: '1.4', + } + versions_added.inject({}) do |memo, (feature, version)| + memo[feature] = Gem::Requirement.create(">= #{version}").satisfied_by?(upstart_ver) + memo + end + end + end + + def check_reload_signal! + if !options['reload_shim'] && !upstart_features[:reload_signal] && new_resource.reload_signal != 'HUP' + raise Error.new("Upstart #{upstart_version} only supports HUP for reload, to use the shim please set the 'reload_shim' options for #{new_resource.to_s}") + end + end + + end + end +end diff --git a/cookbooks/poise-service/files/halite_gem/poise_service/utils.rb b/cookbooks/poise-service/files/halite_gem/poise_service/utils.rb new file mode 100644 index 0000000..bbf7896 --- /dev/null +++ b/cookbooks/poise-service/files/halite_gem/poise_service/utils.rb @@ -0,0 +1,45 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 'pathname' + + +module PoiseService + # Utility methods for PoiseService. + # + # @api public + # @since 1.0.0 + module Utils + # Methods are also available as module-level methods as well as a mixin. + extend self + + # Common segments to ignore + COMMON_SEGMENTS = %w{var www current etc}.inject({}) {|memo, seg| memo[seg] = true; memo } + + # Parse the service name from a path. Look at the last component of the + # path, ignoring some common names. + # + # @param path [String] Path to parse. + # @return [String] + # @example + # attribute(:service_name, kind_of: String, default: lazy { PoiseService::Utils.parse_service_name(path) }) + def parse_service_name(path) + parts = Pathname.new(path).each_filename.to_a.reverse! + # Find the last segment not in common segments, fall back to the last segment. + parts.find {|seg| !COMMON_SEGMENTS[seg] } || parts.first + end + end +end diff --git a/cookbooks/poise-service/files/halite_gem/poise_service/version.rb b/cookbooks/poise-service/files/halite_gem/poise_service/version.rb new file mode 100644 index 0000000..6859904 --- /dev/null +++ b/cookbooks/poise-service/files/halite_gem/poise_service/version.rb @@ -0,0 +1,20 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 PoiseService + VERSION = '1.4.2' +end diff --git a/cookbooks/poise-service/libraries/default.rb b/cookbooks/poise-service/libraries/default.rb new file mode 100644 index 0000000..dd4c6ca --- /dev/null +++ b/cookbooks/poise-service/libraries/default.rb @@ -0,0 +1,19 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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. +# + +raise 'Halite is not compatible with no_lazy_load false, please set no_lazy_load true in your Chef configuration file.' unless Chef::Config[:no_lazy_load] +$LOAD_PATH << File.expand_path('../../files/halite_gem', __FILE__) +require "poise_service/cheftie" diff --git a/cookbooks/poise-service/metadata.json b/cookbooks/poise-service/metadata.json new file mode 100644 index 0000000..8a3dc4c --- /dev/null +++ b/cookbooks/poise-service/metadata.json @@ -0,0 +1 @@ +{"name":"poise-service","version":"1.4.2","description":"A Chef cookbook for managing system services.","long_description":"# Poise-Service Cookbook\n\n[![Build Status](https://img.shields.io/travis/poise/poise-service.svg)](https://travis-ci.org/poise/poise-service)\n[![Gem Version](https://img.shields.io/gem/v/poise-service.svg)](https://rubygems.org/gems/poise-service)\n[![Cookbook Version](https://img.shields.io/cookbook/v/poise-service.svg)](https://supermarket.chef.io/cookbooks/poise-service)\n[![Coverage](https://img.shields.io/codecov/c/github/poise/poise-service.svg)](https://codecov.io/github/poise/poise-service)\n[![Gemnasium](https://img.shields.io/gemnasium/poise/poise-service.svg)](https://gemnasium.com/poise/poise-service)\n[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)\n\nA [Chef](https://www.chef.io/) cookbook to provide a unified interface for\nservices.\n\n### What is poise-service?\n\nPoise-service is a tool for developers of \"library cookbooks\" to define a\nservice without forcing the end-user of the library to adhere to their choice of\nservice management framework. The `poise_service` resource represents an\nabstract service to be run, which can then be customized by node attributes and\nthe `poise_service_options` resource. This is a technique called [dependency\ninjection](https://en.wikipedia.org/wiki/Dependency_injection), and allows a\nmeasure of decoupling between the library and application cookbooks.\n\n### Why would I use poise-service?\n\nPoise-service is most useful for authors of library-style cookbooks, for example\nthe `apache2`, `mysql`, or `application` cookbooks. When using other service\nmanagement options with Chef, the author of the library cookbook has to add\nspecific code for each service management framework they want to support, often\nresulting in a cookbook only supporting the favorite framework of the author or\ndepending on distribution packages for their init scripts. The `poise_service`\nresource allows library cookbook authors a way to write generic code for all\nservice management frameworks while still allowing users of that cookbook to\nchoose which service management framework best fits their needs.\n\n### How is this different from the built-in service resource?\n\nChef includes a `service` resource which allows interacting with certain\nservice management frameworks such as SysV, Upstart, and systemd.\n`poise-service` goes further in that it actually generates the configuration\nfiles needed for the requested service management framework, as well as offering\na dependency injection system for application cookbooks to customize which\nframework is used.\n\n### What service management frameworks are supported?\n\n* [SysV (aka /etc/init.d)](#sysvinit)\n* [Upstart](#upstart)\n* [systemd](#systemd)\n* [Inittab](#inittab)\n* [Runit](https://github.com/poise/poise-service-runit)\n* [Monit](https://github.com/poise/poise-monit#service-provider)\n* [Solaris](https://github.com/sh9189/poise-service-solaris)\n* [AIX](https://github.com/johnbellone/poise-service-aix)\n* *Supervisor (coming soon!)*\n\n\n## Quick Start\n\nTo create a service user and a service to run Apache2:\n\n```ruby\npoise_service_user 'www-data'\n\npoise_service 'apache2' do\n command '/usr/sbin/apache2 -f /etc/apache2/apache2.conf -DFOREGROUND'\n stop_signal 'WINCH'\n reload_signal 'USR1'\nend\n```\n\nor for a hypothetical Rails web application:\n\n```ruby\npoise_service_user 'myapp'\n\npoise_service 'myapp-web' do\n command 'bundle exec unicorn -p 8080'\n user 'myapp'\n directory '/srv/myapp'\n environment RAILS_ENV: 'production'\nend\n```\n\n## Resources\n\n### `poise_service`\n\nThe `poise_service` resource is the abstract definition of a service.\n\n```ruby\npoise_service 'myapp' do\n command 'myapp --serve'\n environment RAILS_ENV: 'production'\nend\n```\n\n#### Actions\n\n* `:enable` – Create, enable and start the service. *(default)*\n* `:disable` – Stop, disable, and destroy the service.\n* `:start` – Start the service.\n* `:stop` – Stop the service.\n* `:restart` – Stop and then start the service.\n* `:reload` – Send the configured reload signal to the service.\n\n#### Attributes\n\n* `service_name` – Name of the service. *(name attribute)*\n* `command` – Command to run for the service. This command must stay in the\n foreground and not daemonize itself. *(required)*\n* `user` – User to run the service as. See\n [`poise_service_user`](#poise_service_user) for any easy way to create service\n users. *(default: root)*\n* `directory` – Working directory for the service. *(default: home directory for\n user, or / if not found)*\n* `environment` – Environment variables for the service.\n* `stop_signal` – Signal to use to stop the service. Some systems will fall back\n to SIGKILL if this signal fails to stop the process. *(default: TERM)*\n* `reload_signal` – Signal to use to reload the service. *(default: HUP)*\n* `restart_on_update` – If true, the service will be restarted if the service\n definition or configuration changes. If `'immediately'`, the notification will\n happen in immediate mode. *(default: true)*\n\n#### Service Options\n\nThe `poise-service` library offers an additional way to pass configuration\ninformation to the final service called \"options\". Options are key/value pairs\nthat are passed down to the service provider and can be used to control how it\ncreates and manages the service. These can be set in the `poise_service`\nresource using the `options` method, in node attributes or via the\n`poise_service_options` resource. The options from all sources are merged\ntogether in to a single hash.\n\nWhen setting options in the resource you can either set them for all providers:\n\n```ruby\npoise_service 'myapp' do\n command 'myapp --serve'\n options status_port: 8000\nend\n```\n\nor for a single provider:\n\n```ruby\npoise_service 'myapp' do\n command 'myapp --serve'\n options :systemd, after_target: 'network'\nend\n```\n\nSetting via node attributes is generally how an end-user or application cookbook\nwill set options to customize services in the library cookbooks they are using.\nYou can set options for all services or for a single service, by service name\nor by resource name:\n\n```ruby\n# Global, for all services.\noverride['poise-service']['options']['after_target'] = 'network'\n# Single service.\noverride['poise-service']['myapp']['template'] = 'myapp.erb'\n```\n\nThe `poise_service_options` resource is also available to set node attributes\nfor a specific service in a DSL-friendly way:\n\n```ruby\npoise_service_options 'myapp' do\n template 'myapp.erb'\n restart_on_update false\nend\n```\n\nUnlike resource attributes, service options can be different for each provider.\nNot all providers support the same options so make sure to check the\ndocumentation for each provider to see what options are available.\n\n### `poise_service_options`\n\nThe `poise_service_options` resource allows setting per-service options in a\nDSL-friendly way. See [the Service Options](#service-options) section for more\ninformation about service options overall.\n\n```ruby\npoise_service_options 'myapp' do\n template 'myapp.erb'\n restart_on_update false\nend\n```\n\n#### Actions\n\n* `:run` – Apply the service options. *(default)*\n\n#### Attributes\n\n* `resource` – Name of the service. *(name attribute)*\n* `for_provider` – Provider to set options for.\n\nAll other attribute keys will be used as options data.\n\n### `poise_service_user`\n\nThe `poise_service_user` resource is an easy way to create service users. It is\nnot required to use `poise_service`, it is only a helper.\n\n```ruby\npoise_service_user 'myapp' do\n home '/srv/myapp'\nend\n```\n\n#### Actions\n\n* `:create` – Create the user and group. *(default)*\n* `:remove` – Remove the user and group.\n\n#### Attributes\n\n* `user` – Name of the user. *(name attribute)*\n* `group` – Name of the group. Set to `false` to disable group creation. *(name attribute)*\n* `uid` – UID of the user. *(default: automatic)*\n* `gid` – GID of the group. *(default: automatic)*\n* `home` – Home directory of the user.\n* `shell` – Shell of the user. *(default: /bin/nologin if present or /bin/false)*\n\n## Providers\n\n### `sysvinit`\n\nThe `sysvinit` provider supports SystemV-style init systems on Debian-family and\nRHEL-family platforms. It will create the `/etc/init.d/` script\nand enable/disable the service using the platform-specific service resource.\n\n```ruby\npoise_service 'myapp' do\n provider :sysvinit\n command 'myapp --serve'\nend\n```\n\nBy default a PID file will be created in `/var/run/service_name.pid`. You can\nuse the `pid_file` option detailed below to override this and rely on your\nprocess creating a PID file in the given path.\n\n#### Options\n\n* `pid_file` – Path to PID file that the service command will create.\n* `pid_file_external` – If true, assume the service will create the PID file\n itself. *(default: true if `pid_file` option is set)*\n* `template` – Override the default script template. If you want to use a\n template in a different cookbook use `'cookbook:template'`.\n* `command` – Override the service command.\n* `directory` – Override the service directory.\n* `environment` – Override the service environment variables.\n* `reload_signal` – Override the service reload signal.\n* `stop_signal` – Override the service stop signal.\n* `user` – Override the service user.\n* `never_restart` – Never try to restart the service.\n* `never_reload` – Never try to reload the service.\n* `script_path` – Override the path to the generated service script.\n\n### `upstart`\n\nThe `upstart` provider supports [Upstart](http://upstart.ubuntu.com/). It will\ncreate the `/etc/init/service_name.conf` configuration.\n\n```ruby\npoise_service 'myapp' do\n provider :upstart\n command 'myapp --serve'\nend\n```\n\nAs a wide variety of versions of Upstart are in use in various Linux\ndistributions, the provider does its best to identify which features are\navailable and provide shims as appropriate. Most of these should be invisible\nhowever Upstart older than 1.10 does not support setting a `reload signal` so\nonly SIGHUP can be used. You can set a `reload_shim` option to enable an\ninternal implementaion of reloading to be used for signals other than SIGHUP,\nhowever as this is implemented inside Chef code, running `initctl reload` would\nstill result in SIGHUP being sent. For this reason, the feature is disabled by\ndefault and will throw an error if a reload signal other than SIGHUP is used.\n\n#### Options\n\n* `reload_shim` – Enable the reload signal shim. See above for a warning about\n this feature.\n* `template` – Override the default configuration template. If you want to use a\n template in a different cookbook use `'cookbook:template'`.\n* `command` – Override the service command.\n* `directory` – Override the service directory.\n* `environment` – Override the service environment variables.\n* `reload_signal` – Override the service reload signal.\n* `stop_signal` – Override the service stop signal.\n* `user` – Override the service user.\n* `never_restart` – Never try to restart the service.\n* `never_reload` – Never try to reload the service.\n\n### `systemd`\n\nThe `systemd` provider supports [systemd](http://www.freedesktop.org/wiki/Software/systemd/).\nIt will create the `/etc/systemd/system/service_name.service` configuration.\n\n\n```ruby\npoise_service 'myapp' do\n provider :systemd\n command 'myapp --serve'\nend\n```\n\n#### Options\n\n* `template` – Override the default configuration template. If you want to use a\n template in a different cookbook use `'cookbook:template'`.\n* `command` – Override the service command.\n* `directory` – Override the service directory.\n* `environment` – Override the service environment variables.\n* `reload_signal` – Override the service reload signal.\n* `stop_signal` – Override the service stop signal.\n* `user` – Override the service user.\n* `never_restart` – Never try to restart the service.\n* `never_reload` – Never try to reload the service.\n* `auto_reload` – Run `systemctl daemon-reload` after changes to the unit file. *(default: true)*\n* `restart_mode` – Restart mode for the generated service unit. *(default: on-failure)*\n\n### `inittab`\n\nThe `inittab` provider supports managing services via `/etc/inittab` using\n[SystemV Init](http://www.nongnu.org/sysvinit/). This can provide basic\nprocess supervision even on very old *nix machines.\n\n```ruby\npoise_service 'myapp' do\n provider :inittab\n command 'myapp --serve'\nend\n```\n\n**NOTE:** Inittab does not allow stopping services, and they are started as soon\nas they are enabled.\n\n#### Options\n\n* `never_restart` – Never try to restart the service.\n* `never_reload` – Never try to reload the service.\n* `pid_file` – Path to PID file that the service command will create.\n* `service_id` – Unique 1-4 character tag for the service. Defaults to an\n auto-generated hash based on the service name. If these collide, bad things\n happen. Don't do that.\n\n## ServiceMixin\n\nFor the common case of a resource (LWRP or plain Ruby) that roughly maps to\n\"some config files and a service\" poise-service provides a mixin module,\n`PoiseService::ServiceMixin`. This mixin adds the standard service actions\n(`enable`, `disable`, `start`, `stop`, `restart`, and `reload`) with basic\nimplementations that call those actions on a `poise_service` resource for you.\nYou customize the service by defining a `service_options` method on your\nprovider class:\n\n```ruby\ndef service_options(service)\n # service is the PoiseService::Resource object instance.\n service.command \"/usr/sbin/#{new_resource.name} -f /etc/#{new_resource.name}/conf/httpd.conf -DFOREGROUND\"\n service.stop_signal 'WINCH'\n service.reload_signal 'USR1'\nend\n```\n\nYou will generally want to override the `enable` action to install things\nrelated to the service like packages, users and configuration files:\n\n```ruby\ndef action_enable\n notifying_block do\n package 'apache2'\n poise_service_user 'www-data'\n template \"/etc/#{new_resource.name}/conf/httpd.conf\" do\n # ...\n end\n end\n # This super call will run the normal service enable,\n # creating the service and starting it.\n super\nend\n```\n\nSee [the poise_service_test_mixin resource](test/cookbooks/poise-service_test/resources/mixin.rb)\nand [provider](test/cookbooks/poise-service_test/providers/mixin.rb) for\nexamples of using `ServiceMixin` in an LWRP.\n\n## Sponsors\n\nDevelopment sponsored by [Bloomberg](http://www.bloomberg.com/company/technology/).\n\nThe Poise test server infrastructure is sponsored by [Rackspace](https://rackspace.com/).\n\n## License\n\nCopyright 2015-2016, Noah Kantrowitz\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","maintainer":"Noah Kantrowitz","maintainer_email":"noah@coderanger.net","license":"Apache 2.0","platforms":{},"dependencies":{"poise":"~> 2.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{},"source_url":"https://github.com/poise/poise-service","issues_url":"https://github.com/poise/poise-service/issues","chef_version":"~> 12","ohai_version":{}} \ No newline at end of file diff --git a/cookbooks/poise-service/templates/default/dummy.json.erb b/cookbooks/poise-service/templates/default/dummy.json.erb new file mode 100644 index 0000000..ad62f40 --- /dev/null +++ b/cookbooks/poise-service/templates/default/dummy.json.erb @@ -0,0 +1,7 @@ +<%= {command: @command, + directory: @directory, + environment: @environment, + name: @name, + reload_signal: @reload_signal, + stop_signal: @stop_signal, + user: @user}.to_json %> diff --git a/cookbooks/poise-service/templates/default/inittab.sh.erb b/cookbooks/poise-service/templates/default/inittab.sh.erb new file mode 100644 index 0000000..7e19bf7 --- /dev/null +++ b/cookbooks/poise-service/templates/default/inittab.sh.erb @@ -0,0 +1,15 @@ +#!/bin/sh +exec /opt/chef/embedded/bin/ruby <", Process.pid) +Dir.chdir("<%= @directory %>") +ent = Etc.getpwnam("<%= @user %>") +if Process.euid != ent.uid || Process.egid != ent.gid + Process.initgroups(ent.name, ent.gid) + Process::GID.change_privilege(ent.gid) if Process.egid != ent.gid + Process::UID.change_privilege(ent.uid) if Process.euid != ent.uid +end +(ENV["HOME"] = Dir.home("<%= @user %>")) rescue nil +<%= @environment.map {|key, value| "ENV[#{key.to_s.inspect}] = #{value.to_s.inspect}" }.join("; ") %> +exec(*<%= Shellwords.split(@command).inspect %>) +EOH diff --git a/cookbooks/poise-service/templates/default/systemd.service.erb b/cookbooks/poise-service/templates/default/systemd.service.erb new file mode 100644 index 0000000..ebdf871 --- /dev/null +++ b/cookbooks/poise-service/templates/default/systemd.service.erb @@ -0,0 +1,14 @@ +[Unit] +Description=<%= @name %> + +[Service] +Environment=<%= @environment.map {|key, val| %Q{"#{key}=#{val}"} }.join(' ') %> +ExecStart=<%= @command %> +ExecReload=/bin/kill -<%= @reload_signal %> $MAINPID +KillSignal=<%= @stop_signal %> +User=<%= @user %> +WorkingDirectory=<%= @directory %> +Restart=<%= @restart_mode %> + +[Install] +WantedBy=multi-user.target diff --git a/cookbooks/poise-service/templates/default/sysvinit.sh.erb b/cookbooks/poise-service/templates/default/sysvinit.sh.erb new file mode 100644 index 0000000..f13d811 --- /dev/null +++ b/cookbooks/poise-service/templates/default/sysvinit.sh.erb @@ -0,0 +1,190 @@ +#!/bin/sh +# Init script for <%= @name %> generated by poise-service +# +### BEGIN INIT INFO +# Provides: <%= @name %> +# Required-Start: $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Init script for <%= @name %> +# Description: Init script for <%= @name %> +### END INIT INFO + +<%- if @platform_family == 'debian' -%> +. /lib/lsb/init-functions + +_start() { + start-stop-daemon --start --quiet --background \ + --pidfile "<%= @pid_file %>"<% unless @pid_file_external %> --make-pidfile<% end %> \ + --chuid "<%= @user %>" --chdir "<%= @directory %>" \ + --exec "<%= @daemon %>" -- <%= @daemon_options %> +} + +_stop() { + start-stop-daemon --stop --quiet --pidfile "<%= @pid_file %>" --user "<%= @user %>" --signal "<%= @stop_signal %>" +} + +_status() { + status_of_proc -p "<%= @pid_file %>" "<%= @daemon %>" "<%= @name %>" +} + +_reload() { + start-stop-daemon --stop --quiet --pidfile "<%= @pid_file %>" --user "<%= @user %>" --signal "<%= @reload_signal %>" +} + +<%- else -%> +_start() { + <%# Implementing this using RedHat's bash helpers is too painful. Sorry. %> + <%# See dummy.rb for a more commented version of this code. %> + /opt/chef/embedded/bin/ruby < +File.unlink(pid_file) if File.exist?(pid_file) +if Process.fork + sleep(1) until File.exist?(pid_file) +else + Process.daemon(true) + Dir.chdir(<%= @directory.inspect %>) + <%- unless @pid_file_external -%> + IO.write(pid_file, Process.pid) + <%- end -%> + ent = Etc.getpwnam(<%= @user.inspect %>) + if Process.euid != ent.uid || Process.egid != ent.gid + Process.initgroups(ent.name, ent.gid) + Process::GID.change_privilege(ent.gid) if Process.egid != ent.gid + Process::UID.change_privilege(ent.uid) if Process.euid != ent.uid + end + Kernel.exec(*<%= Shellwords.split(@command).inspect %>) + exit! +end +EOH +} + +_stop() { + if [ -r "<%= @pid_file %>" ]; then + kill -<%= @stop_signal%> "$(cat "<%= @pid_file %>")" + else + return 0 + fi +} + +_status() { + if [ -r "<%= @pid_file %>" ]; then + kill -0 "$(cat "<%= @pid_file %>")" + else + return 1 + fi +} + +_reload() { + if [ -r "<%= @pid_file %>" ]; then + kill -<%= @reload_signal%> "$(cat "<%= @pid_file %>")" + else + return 1 + fi +} + +<%# Some functions to match LSB %> + +log_daemon_msg() { + echo -n "$1" +} + +log_progress_msg() { + echo -n "$1" +} + +log_warning_msg() { + echo -n "$1" +} + +log_failure_msg() { + echo -n "$1" +} + +log_end_msg() { + if [ "$1" = 0 ]; then + echo " [ OK ]" + else + echo " [FAILED]" + fi +} +<%- end -%> + +set -e + +start() { + if _start + then + rc=0 + sleep 1 + if ! kill -0 "$(cat "<%= @pid_file %>")" >/dev/null 2>&1; then + log_failure_msg "<%= @name %> failed to start" + rc=1 + fi + else + rc=1 + fi + if [ "$rc" -eq 0 ]; then + log_end_msg 0 + else + log_end_msg 1 + rm -f "<%= @pid_file %>" + fi +} + +<%- @environment.each do |key, val| -%> +export <%= key %>="<%= val %>" +<%- end -%> +export PATH="${PATH:+$PATH:}/usr/sbin:/sbin" + +case "$1" in + start) + log_daemon_msg "Starting <%= @name %>" + if [ -s "<%= @pid_file %>" ] && kill -0 "$(cat "<%= @pid_file %>")" >/dev/null 2>&1; then + log_progress_msg "apparently already running" + log_end_msg 0 + exit 0 + fi + start + ;; + + stop) + log_daemon_msg "Stopping <%= @name %>" + _stop + log_end_msg "$?" + rm -f "<%= @pid_file %>" + ;; + + reload|force-reload) + log_daemon_msg "Reloading <%= @name %>" + _reload + log_end_msg "$?" + ;; + + restart) + set +e + log_daemon_msg "Restarting <%= @name %>" + if [ -s "<%= @pid_file %>" ] && kill -0 "$(cat "<%= @pid_file %>")" >/dev/null 2>&1; then + _stop || true + sleep 1 + else + log_warning_msg "<%= @name %> not running, attempting to start." + rm -f "<%= @pid_file %>" + fi + start + ;; + + status) + set +e + _status + exit $? + ;; + + *) + echo "Usage: /etc/init.d/<%= @name %> {start|stop|reload|force-reload|restart|status}" + exit 1 +esac + +exit 0 diff --git a/cookbooks/poise-service/templates/default/upstart.conf.erb b/cookbooks/poise-service/templates/default/upstart.conf.erb new file mode 100644 index 0000000..cd60ea1 --- /dev/null +++ b/cookbooks/poise-service/templates/default/upstart.conf.erb @@ -0,0 +1,49 @@ +# <%= @name %> generated by poise-service for <%= @new_resource.to_s %> + +description "<%= @name %>" + +start on runlevel [2345] +stop on runlevel [!2345] + +respawn +respawn limit 10 5 +umask 022 +chdir <%= @directory %> +<%- @environment.each do |key, val| -%> +env <%= key %>="<%= val %>" +<%- end -%> +<%- if @upstart_features[:setuid] -%> +setuid <%= @user %> +<%- end -%> +<%- if @upstart_features[:kill_signal] -%> +kill signal <%= @stop_signal %> +<%- end -%> +<%- if @upstart_features[:reload_signal] -%> +reload signal <%= @reload_signal %> +<%- end -%> + +<%- if @upstart_features[:setuid] -%> +exec <%= @command %> +<%- else -%> +script +exec /opt/chef/embedded/bin/ruby <) +if Process.euid != ent.uid || Process.egid != ent.gid + Process.initgroups(ent.name, ent.gid) + Process::GID.change_privilege(ent.gid) if Process.egid != ent.gid + Process::UID.change_privilege(ent.uid) if Process.euid != ent.uid +end +ENV["HOME"] = Dir.home(<%= @user.inspect %>) rescue nil +exec(*<%= Shellwords.split(@command).inspect %>) +EOH +end script +<%- end -%> +<%- if !@upstart_features[:kill_signal] && @stop_signal != 'TERM' -%> +pre-stop script + PID=`initctl status <%= @name %> | sed 's/^.*process \([0-9]*\)$/\1/'` + if [ -n "$PID" ]; then + kill -<%= @stop_signal %> "$PID" + fi +end script +<%- end -%> diff --git a/cookbooks/poise/CHANGELOG.md b/cookbooks/poise/CHANGELOG.md new file mode 100644 index 0000000..a856e2c --- /dev/null +++ b/cookbooks/poise/CHANGELOG.md @@ -0,0 +1,187 @@ +# Changelog + +## v2.7.2 + +* Test harness fixes for Chef. + +## v2.7.1 + +* Minor tweak for compatability with Chef master. + +## v2.7.0 + +* More compatibility improvements for Chef 12.9. +* New helper: `Poise::Helpers::Win32User` to automatically convert `'root'` + defaults for user and group properties to more platform-appropriate values. +* Enhanced `poise_shell_out` to better cope with Windows command parsing. Use + Bash-style commands and it will automatically convert. +* Overall compatibility fixes for Windows. + +## v2.6.1 + +* Compatibility with Chef master to fix issues with `defined_in!` not ignoring + stack frames from Chef code. +* Setting a provider in a inversion options resource now works as (probably) + expected. + +## v2.6.0 + +* New backwards-compatibility helper: `Poise::Backports::VERIFY_PATH`. Use it + like `verify "myapp -t #{Poise::Backports::VERIFY_PATH}" if defined?(verify)` + for backwards-compatible usage of file verifications. +* Fixed Poise's implementation of lazy defaults to more closely match Chef's + even when both are used in conjunction. Lazy defaults will no longer be + evaluated when setting a value or getting an existing non-default value. + +## v2.5.0 + +* New property for inversion resources: `provider_no_auto`. Set one or more + provider names that will be ignored for automatic resolution for that instance. +* Support `variables` as an alias for `options` in template content properties + to match the `template` resource. +* Template content properties are no longer validated after creation for + non-default actions. +* Formalize the extra-verbose logging mode for Poise and expose it via helpers. +* Extra-verbose logging mode can now be enabled by creating a `/poise_debug` file. +* New helper: `poise_shell_out`. Like normal `shell_out` but sets group and + environment variables automatically to better defaults. + +## v2.4.0 + +* Added return value to `Container#register_subresource` to track if the resource + was already added. +* Improve inspect output for subresources and containers. +* Ensure notifications work with subresources. +* Inversion providers process name equivalences. + +## v2.3.2 + +* Improve handling of deeply nested subresources. + +## v2.3.1 + +* Ensure a container with a parent link to its own type doesn't use self as the + default parent. +* Improve handling of `load_current_resource` in providers that call it via + `super`. + +## v2.3.0 + +* New helper: `ResourceSubclass`, a helper for subclassing a resource while + still using the providers as the base class. +* New feature: Non-default containers. Use `container_default: false` to mark + a container class as ineligible for default lookup. +* New feature: parent attribute defaults. You can set a `parent_default` to + provide a default value for the parent of a resource. This supports the + `lazy { }` helper as with normal default values. +* New feature: use `forced_keys: [:name]` on an option collector property to + force keys that would otherwise be clobbered by resource methods. +* Can enable verbose logging mode via a node attribute in addition to an + environment variable. + +## v2.2.3 + +* Add `ancestor_send` utility method for use in other helpers. +* Improve subresource support for use in mixins. + +## v2.2.2 + +* Fix 2.2.1 for older versions of Chef. + +## v2.2.1 + +* Fixed delayed notifications inside `notifying_block`. +* Default actions as expected within LWRPs. + +## v2.2.0 + +* Compatibility with Chef 12.4.1 and Chefspec 4.3.0. +* New helper `ResourceCloning`: Disables resource cloning between Poise-based + resources. This is enabled by default. +* Subresource parent references can be set to nil. + +## v2.1.0 + +* Compatibility with Chef 12.4. +* Add `#property` as an alias for `#attribute` in resources. This provides + forward compatibility with future versions of Chef. +* Freeze default resource attribute values. **This may break your code**, + however this is not a major release because any code broken by this change + was itself already a bug. + +## v2.0.1 + +* Make the ChefspecHelpers helper a no-op if chefspec is not already loaded. +* Fix for finding the correct cookbook for a file when using vendored gems. +* New flag for the OptionCollector helper, `parser`: + +```ruby +class Resource < Chef::Resource + include Poise + attribute(:options, option_collector: true, parser: proc {|val| parse(val) }) + + def parse(val) + {name: val} + end +end +``` + +* Fix for a possible infinite loop when using `ResourceProviderMixin` in a nested + module structure. + +## v2.0.0 + +Major overhaul! Poise is now a Halite gem/cookbook. New helpers: + +* ChefspecMatchers – Automatically create Chefspec matchers for Poise resources. +* DefinedIn – Track which file (and cookbook) a resource or provider is defined in. +* Fused – Experimental support for defining provider actions in the resource class. +* Inversion – Support for end-user dependency inversion with providers. + +All helpers are compatible with Chef >= 12.0. Chef 11 is now deprecated, if you +need to support Chef 11 please continue to use Poise 1. + +## v1.0.12 + +* Correctly propagate errors from inside notifying_block. + +## v1.0.10 + +* Fixes an issue with the LWRPPolyfill helper and false values. + + +## v1.0.8 + +* Delayed notifications from nested converges will still only run at the end of + the main converge. + +## v1.0.6 + +* The include_recipe helper now works correctly when used at compile time. + +## v1.0.4 + +* Redeclaring a template attribute with the same name as a parent class will + inherit its options. + +## v1.0.2 + +* New template attribute pattern. + +```ruby +attribute(:config, template: true) + +... + +resource 'name' do + config_source 'template.erb' +end + +... + +new_resource.config_content +``` + +## v1.0.0 + +* Initial release! diff --git a/cookbooks/poise/README.md b/cookbooks/poise/README.md new file mode 100644 index 0000000..881b5cf --- /dev/null +++ b/cookbooks/poise/README.md @@ -0,0 +1,233 @@ +# Poise + +[![Build Status](https://img.shields.io/travis/poise/poise.svg)](https://travis-ci.org/poise/poise) +[![Gem Version](https://img.shields.io/gem/v/poise.svg)](https://rubygems.org/gems/poise) +[![Cookbook Version](https://img.shields.io/cookbook/v/poise.svg)](https://supermarket.chef.io/cookbooks/poise) +[![Coverage](https://img.shields.io/codecov/c/github/poise/poise.svg)](https://codecov.io/github/poise/poise) +[![Gemnasium](https://img.shields.io/gemnasium/poise/poise.svg)](https://gemnasium.com/poise/poise) +[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) + +## What is Poise? + +The poise cookbook is a set of libraries for writing reusable cookbooks. It +provides helpers for common patterns and a standard structure to make it easier to create flexible cookbooks. + +## Writing your first resource + +Rather than LWRPs, Poise promotes the idea of using normal, or "heavy weight" +resources, while including helpers to reduce much of boilerplate needed for this. Each resource goes in its own file under `libraries/` named to match +the resource, which is in turn based on the class name. This means that the file `libraries/my_app.rb` would contain `Chef::Resource::MyApp` which maps to the resource `my_app`. + +An example of a simple shell to start from: + +```ruby +require 'poise' +require 'chef/resource' +require 'chef/provider' + +module MyApp + class Resource < Chef::Resource + include Poise + provides(:my_app) + actions(:enable) + + attribute(:path, kind_of: String) + # Other attribute definitions. + end + + class Provider < Chef::Provider + include Poise + provides(:my_app) + + def action_enable + notifying_block do + ... # Normal Chef recipe code goes here + end + end + end +end +``` + +Starting from the top, first we require the libraries we will be using. Then we +create a module to hold our resource and provider. If your cookbook declares +multiple resources and/or providers, you might want additional nesting here. +Then we declare the resource class, which inherits from `Chef::Resource`. This +is similar to the `resources/` file in an LWRP, and a similar DSL can be used. +We then include the `Poise` mixin to load our helpers, and then call +`provides(:my_app)` to tell Chef this class will implement the `my_app` +resource. Then we use the familiar DSL, though with a few additions we'll cover +later. + +Then we declare the provider class, again similar to the `providers/` file in an +LWRP. We include the `Poise` mixin again to get access to all the helpers and +call `provides()` to tell Chef what provider this is. Rather than use the +`action :enable do ... end` DSL from LWRPs, we just define the action method +directly. The implementation of action comes from a block of recipe code +wrapped with `notifying_block` to capture changes in much the same way as +`use_inline_resources`, see below for more information about all the features of +`notifying_block`. + +We can then use this resource like any other Chef resource: + +```ruby +my_app 'one' do + path '/tmp' +end +``` + +## Helpers + +While not exposed as a specific method, Poise will automatically set the +`resource_name` based on the class name. + +### Notifying Block + +As mentioned above, `notifying_block` is similar to `use_inline_resources` in LWRPs. Any Chef resource created inside the block will be converged in a sub-context and if any have updated it will trigger notifications on the current resource. Unlike `use_inline_resources`, resources inside the sub-context can still see resources outside of it, with lookups propagating up sub-contexts until a match is found. Also any delayed notifications are scheduled to run at the end of the main converge cycle, instead of the end of this inner converge. + +This can be used to write action methods using the normal Chef recipe DSL, while still offering more flexibility through subclassing and other forms of code reuse. + +### Include Recipe + +In keeping with `notifying_block` to implement action methods using the Chef DSL, Poise adds an `include_recipe` helper to match the method of the same name in recipes. This will load and converge the requested recipe. + +### Resource DSL + +To make writing resource classes easier, Poise exposes a DSL similar to LWRPs for defining actions and attributes. Both `actions` and +`default_action` are just like in LWRPs, though `default_action` is rarely needed as the first action becomes the default. `attribute` is also available just like in LWRPs, but with some enhancements noted below. + +One notable difference over the standard DSL method is that Poise attributes +can take a block argument. + +#### Template Content + +A common pattern with resources is to allow passing either a template filename or raw file content to be used in a configuration file. Poise exposes a new attribute flag to help with this behavior: + +```ruby +attribute(:name, template: true) +``` + +This creates four methods on the class, `name_source`, `name_cookbook`, +`name_content`, and `name_options`. If the name is set to `''`, no prefix is applied to the function names. The content method can be set directly, but if not set and source is set, then it will render the template and return it as a string. Default values can also be set for any of these: + +```ruby +attribute(:name, template: true, default_source: 'app.cfg.erb', + default_options: {host: 'localhost'}) +``` + +As an example, you can replace this: + +```ruby +if new_resource.source + template new_resource.path do + source new_resource.source + owner 'app' + group 'app' + variables new_resource.options + end +else + file new_resource.path do + content new_resource.content + owner 'app' + group 'app' + end +end +``` + +with simply: + +```ruby +file new_resource.path do + content new_resource.content + owner 'app' + group 'app' +end +``` + +As the content method returns the rendered template as a string, this can also +be useful within other templates to build from partials. + +#### Lazy Initializers + +One issue with Poise-style resources is that when the class definition is executed, Chef hasn't loaded very far so things like the node object are not +yet available. This means setting defaults based on node attributes does not work directly: + +```ruby +attribute(:path, default: node['myapp']['path']) +... +NameError: undefined local variable or method 'node' +``` + +To work around this, Poise extends the idea of lazy initializers from Chef recipes to work with resource definitions as well: + +```ruby +attribute(:path, default: lazy { node['myapp']['path'] }) +``` + +These initializers are run in the context of the resource object, allowing +complex default logic to be moved to a method if desired: + +```ruby +attribute(:path, default: lazy { my_default_path }) + +def my_default_path + ... +end +``` + +#### Option Collector + +Another common pattern with resources is to need a set of key/value pairs for +configuration data or options. This can done with a simple Hash, but an option collector attribute can offer a nicer syntax: + +```ruby +attribute(:mydata, option_collector: true) +... + +my_app 'name' do + mydata do + key1 'value1' + key2 'value2' + end +end +``` + +This will be converted to `{key1: 'value1', key2: 'value2'}`. You can also pass a Hash to an option collector attribute just as you would with a normal attribute. + +## Debugging Poise + +Poise has its own extra-verbose level of debug logging that can be enabled in +three different ways. You can either set the environment variable `$POISE_DEBUG`, +set a node attribute `node['POISE_DEBUG']`, or touch the file `/POISE_DEBUG`. +You will see a log message `Extra verbose logging enabled` at the start of the +run to confirm Poise debugging has been enabled. Make sure you also set Chef's +log level to `debug`, usually via `-l debug` on the command line. + +## Upgrading from Poise 1.x + +The biggest change when upgrading from Poise 1.0 is that the mixin is no longer +loaded automatically. You must add `require 'poise'` to your code is you want to +load it, as you would with normal Ruby code outside of Chef. It is also highly +recommended to add `provides(:name)` calls to your resources and providers, this +will be required in Chef 13 and will display a deprecation warning if you do +not. This also means you can move your code out of the `Chef` module namespace +and instead declare it in your own namespace. An example of this is shown above. + +## Sponsors + +The Poise test server infrastructure is generously sponsored by [Rackspace](https://rackspace.com/). Thanks Rackspace! + +## License + +Copyright 2013-2016, Noah Kantrowitz + +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/poise/files/halite_gem/poise.rb b/cookbooks/poise/files/halite_gem/poise.rb new file mode 100644 index 0000000..0c70c74 --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise.rb @@ -0,0 +1,108 @@ +# +# Copyright 2013-2016, Noah Kantrowitz +# +# 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/provider' +require 'chef/resource' +require 'chef/run_context' + +require 'poise/utils/resource_provider_mixin' + + +module Poise + include Poise::Utils::ResourceProviderMixin + autoload :Backports, 'poise/backports' + autoload :Helpers, 'poise/helpers' + autoload :NOT_PASSED, 'poise/backports/not_passed' + autoload :Provider, 'poise/provider' + autoload :Resource, 'poise/resource' + autoload :Subcontext, 'poise/subcontext' + autoload :Utils, 'poise/utils' + autoload :VERSION, 'poise/version' + + # Check if Poise's extra debugging output is enabled. This produces a *lot* + # of logging. + # + # @param node [Chef::Node, Chef::RunContext] Optional node to check for + # attributes. If not given, Chef.node is used instead. + # @return [Boolean] + def self.debug?(node=nil) + node = node.node if node.is_a?(Chef::RunContext) + node ||= Chef.node if defined?(Chef.node) + @debug_file_upper = ::File.exist?('/POISE_DEBUG') unless defined?(@debug_file_upper) + @debug_file_lower = ::File.exist?('/poise_debug') unless defined?(@debug_file_lower) + !!( + (ENV['POISE_DEBUG'] && ENV['POISE_DEBUG'] != 'false') || + (ENV['poise_debug'] && ENV['poise_debug'] != 'false') || + (node && node['POISE_DEBUG']) || + (node && node['poise_debug']) || + @debug_file_upper || + @debug_file_lower + ) + end + + # Log a message only if Poise's extra debugging output is enabled. + # + # @see #debug? + # @param msg [String] Log message. + # @return [void] + def self.debug(msg) + Chef::Log.debug(msg) if debug? + end +end + +# Callable form to allow passing in options: +# include Poise(ParentResource) +# include Poise(parent: ParentResource) +# include Poise(container: true) +def Poise(options={}) + # Allow passing a class as a shortcut + if options.is_a?(Class) + options = {parent: options} + end + + # Create a new anonymous module + mod = Module.new + + # Fake the name. + mod.define_singleton_method(:name) do + super() || 'Poise' + end + + mod.define_singleton_method(:included) do |klass| + super(klass) + # Pull in the main helper to cover most of the needed logic. + klass.class_exec { include Poise } + # Set the defined_in values as needed. + klass.poise_defined!(caller) + # Resource-specific options. + if klass < Chef::Resource + klass.poise_subresource(options[:parent], options[:parent_optional], options[:parent_auto]) if options[:parent] + klass.poise_subresource_container(options[:container_namespace], options[:container_default]) if options[:container] + klass.poise_fused if options[:fused] + klass.poise_inversion(options[:inversion_options_resource]) if options[:inversion] + end + # Provider-specific options. + if klass < Chef::Provider + klass.poise_inversion(options[:inversion], options[:inversion_attribute]) if options[:inversion] + end + end + + mod +end + +# Display a message if poise_debug is enabled. Off in ChefSpec so I don't get +# extra logging stuff that I don't care about. +Poise.debug('[Poise] Extra verbose logging enabled') unless defined?(ChefSpec) diff --git a/cookbooks/poise/files/halite_gem/poise/backports.rb b/cookbooks/poise/files/halite_gem/poise/backports.rb new file mode 100644 index 0000000..84ceed8 --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/backports.rb @@ -0,0 +1,28 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 Poise + # Backported features from Chef to be able to use them with older versions. + # + # @since 2.3.0 + module Backports + autoload :NOT_PASSED, 'poise/backports/not_passed' + autoload :VERIFY_PATH, 'poise/backports/verify_path' + end + + autoload :NOT_PASSED, 'poise/backports/not_passed' +end diff --git a/cookbooks/poise/files/halite_gem/poise/backports/not_passed.rb b/cookbooks/poise/files/halite_gem/poise/backports/not_passed.rb new file mode 100644 index 0000000..c5b3ce0 --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/backports/not_passed.rb @@ -0,0 +1,52 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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. +# + +begin + require 'chef/constants' +rescue LoadError + # This space left intentionally blank. +end + + +module Poise + module Backports + # A sentinel value for optional arguments where nil is a valid value. + # @since 2.3.0 + # @!parse NOT_PASSED = Object.new + NOT_PASSED = if defined?(Chef::NOT_PASSED) + Chef::NOT_PASSED + else + # Copyright 2015-2016, Chef Software Inc. + # Used under Apache License, Version 2.0. + Object.new.tap do |not_passed| + def not_passed.to_s + "NOT_PASSED" + end + def not_passed.inspect + to_s + end + not_passed.freeze + end + end + + end + + # An alias to {Backports::NOT_PASSED} to avoid typing so much. + # + # @since 2.3.0 + # @see Backports::NOT_PASSED + NOT_PASSED = Backports::NOT_PASSED +end diff --git a/cookbooks/poise/files/halite_gem/poise/backports/verify_path.rb b/cookbooks/poise/files/halite_gem/poise/backports/verify_path.rb new file mode 100644 index 0000000..8bd4c06 --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/backports/verify_path.rb @@ -0,0 +1,33 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 Poise + module Backports + # The correct interpolation key for any version of Chef. + # @since 2.6.0 + # @example + # file '/path' do + # content my_content + # verify "myapp -t #{Poise::Backports::VERIFY_PATH}" + # end + VERIFY_PATH = if Gem::Version.create(Chef::VERSION) < Gem::Version.create('12.5.0') + '%{file}' + else + '%{path}' + end + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/error.rb b/cookbooks/poise/files/halite_gem/poise/error.rb new file mode 100644 index 0000000..9a6a948 --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/error.rb @@ -0,0 +1,24 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 Poise + # Base exception class for Poise errors. + # + # @since 2.0.0 + class Error < Exception + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/helpers.rb b/cookbooks/poise/files/halite_gem/poise/helpers.rb new file mode 100644 index 0000000..ab2fc33 --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/helpers.rb @@ -0,0 +1,36 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 Poise + module Helpers + autoload :ChefspecMatchers, 'poise/helpers/chefspec_matchers' + autoload :DefinedIn, 'poise/helpers/defined_in' + autoload :Fused, 'poise/helpers/fused' + autoload :IncludeRecipe, 'poise/helpers/include_recipe' + autoload :Inversion, 'poise/helpers/inversion' + autoload :LazyDefault, 'poise/helpers/lazy_default' + autoload :LWRPPolyfill, 'poise/helpers/lwrp_polyfill' + autoload :NotifyingBlock, 'poise/helpers/notifying_block' + autoload :OptionCollector, 'poise/helpers/option_collector' + autoload :ResourceCloning, 'poise/helpers/resource_cloning' + autoload :ResourceName, 'poise/helpers/resource_name' + autoload :ResourceSubclass, 'poise/helpers/resource_subclass' + autoload :Subresources, 'poise/helpers/subresources' + autoload :TemplateContent, 'poise/helpers/template_content' + autoload :Win32User, 'poise/helpers/win32_user' + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/helpers/chefspec_matchers.rb b/cookbooks/poise/files/halite_gem/poise/helpers/chefspec_matchers.rb new file mode 100644 index 0000000..7417628 --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/helpers/chefspec_matchers.rb @@ -0,0 +1,92 @@ +# +# Copyright 2013-2016, Noah Kantrowitz +# +# 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. +# + +# Not requiring chefspec or rspec/expectations since this code should only +# activate if they are already loaded. + +require 'poise/helpers/lwrp_polyfill' +require 'poise/helpers/resource_name' + + +module Poise + module Helpers + # A resource mixin to register ChefSpec matchers for a resource + # automatically. + # + # If you are using the provides() form for naming resources, ensure that is + # set before declaring actions. + # + # @since 2.0.0 + # @example Define a class + # class Chef::Resource::MyResource < Chef::Resource + # include Poise::Helpers::ChefspecMatchers + # actions(:run) + # end + # @example Use a matcher + # expect(chef_run).to run_my_resource('...') + module ChefspecMatchers + include Poise::Helpers::LWRPPolyfill::Resource + include Poise::Helpers::ResourceName + + # Create a matcher for a given resource type and action. This is + # idempotent so if a matcher already exists, it will not be recreated. + # + # @api private + def self.create_matcher(resource, action) + # Check that we have everything we need. + return unless defined?(ChefSpec) && defined?(RSpec::Matchers) && resource + method = :"#{action}_#{resource}" + return if RSpec::Matchers.method_defined?(method) + RSpec::Matchers.send(:define_method, method) do |resource_name| + ChefSpec::Matchers::ResourceMatcher.new(resource, action, resource_name) + end + end + + # @!classmethods + module ClassMethods + # Create a resource-level matcher for this resource. + # + # @see Resource::ResourceName.provides + def provides(name, *args, &block) + super(name, *args, &block) + ChefSpec.define_matcher(name) if defined?(ChefSpec) + # Call #actions here to grab any actions from a parent class. + actions.each do |action| + ChefspecMatchers.create_matcher(name, action) + end + end + + # Create matchers for all declared actions. + # + # @see Resource::LWRPPolyfill.actions + def actions(*names) + super.tap do |actions| + actions.each do |action| + ChefspecMatchers.create_matcher(resource_name, action) + end if resource_name && resource_name != :resource && !names.empty? + end + end + + def included(klass) + super + klass.extend ClassMethods + end + end + + extend ClassMethods + end + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/helpers/defined_in.rb b/cookbooks/poise/files/halite_gem/poise/helpers/defined_in.rb new file mode 100644 index 0000000..43944ba --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/helpers/defined_in.rb @@ -0,0 +1,128 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 'poise/error' +require 'poise/utils' + + +module Poise + module Helpers + # A mixin to track where a resource or provider was defined. This can + # provide either the filename of the class or the cookbook it was defined in. + # + # @since 2.0.0 + # @example + # class MyProvider < Chef::provider + # include Poise::Helpers::DefinedIn + # + # def action_create + # template '...' do + # # ... + # cookbook new_resource.poise_defined_in + # end + # end + # end + module DefinedIn + # Path to the root of Poise's code. + # @see #poise_defined! + # @api private + POISE_LIB_ROOT = ::File.expand_path('../..', __FILE__) + + # Path to the root of Chef's code. + # @see #poise_defined! + # @api private + CHEF_LIB_ROOT = ::File.join(::Gem::Specification.find_by_name('chef').gem_dir, 'lib') + + # A regex used to parse Ruby's `caller` string syntax. + # @see #poise_defined! + # @api private + CALLER_REGEXP = /^(.+):\d+:in `.+'/ + + # Wrapper for {.poise_defined_in_cookbook} to pass the run context for you. + # + # @see .poise_defined_in_cookbook + # @param file [String, nil] Optional file path to check instead of the path + # this class was defined in. + # @return [String] + def poise_defined_in_cookbook(file=nil) + self.class.poise_defined_in_cookbook(run_context, file) + end + + # @!classmethods + module ClassMethods + # The file this class or module was defined in, or nil if it isn't found. + # + # @return [String] + def poise_defined_in + raise Poise::Error.new("Unable to determine location of #{self.name}") unless @poise_defined_in + @poise_defined_in + end + + # The cookbook this class or module was defined in. Can pass a file to + # check that instead. + # + # @param run_context [Chef::RunContext] Run context to check cookbooks in. + # @param file [String, nil] Optional file path to check instead of the + # path this class was defined in. + # @return [String] + def poise_defined_in_cookbook(run_context, file=nil) + file ||= poise_defined_in + Poise.debug("[#{self.name}] Checking cookbook name for #{file}") + Poise::Utils.find_cookbook_name(run_context, file).tap do |cookbook| + Poise.debug("[#{self.name}] found cookbook #{cookbook.inspect}") + end + end + + # Record that the class/module was defined. Called automatically by Ruby + # for all normal cases. + # + # @param caller_array [Array] A strack trace returned by #caller. + # @return [void] + def poise_defined!(caller_array) + # Only try to set this once. + return if @poise_defined_in + # Parse out just the filenames. + caller_paths = caller_array.map {|line| line[CALLER_REGEXP, 1] } + # Find the first non-poise, non-chef line. This assumes Halite + # transformation which I'm not thrilled about. + caller_path = caller_paths.find do |line| + line && !line.start_with?(POISE_LIB_ROOT) && !line.start_with?(CHEF_LIB_ROOT) + end + raise Poise::Error.new("Unable to find a caller path for: #{caller_array.inspect}") unless caller_path + if ::File::ALT_SEPARATOR + caller_path.gsub!(::File::ALT_SEPARATOR, ::File::SEPARATOR) + end + Chef::Log.debug("[#{self.name}] Recording poise_defined_in as #{caller_path}") + @poise_defined_in = caller_path + end + + # @api private + def inherited(klass) + super + klass.poise_defined!(caller) + end + + def included(klass) + super + klass.extend(ClassMethods) + klass.poise_defined!(caller) + end + end + + extend ClassMethods + end + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/helpers/fused.rb b/cookbooks/poise/files/halite_gem/poise/helpers/fused.rb new file mode 100644 index 0000000..8b67bea --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/helpers/fused.rb @@ -0,0 +1,127 @@ +# +# Copyright 2013-2016, Noah Kantrowitz +# +# 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/provider' + + +module Poise + module Helpers + # Resource mixin to create "fused" resources where the resource and provider + # are implemented in the same class. + # + # @since 2.0.0 + # @example + # class Chef::Resource::MyResource < Chef::Resource + # include Poise(fused: true) + # attribute(:path, kind_of: String) + # attribute(:message, kind_of: String) + # action(:run) do + # file new_resource.path do + # content new_resource.message + # end + # end + # end + module Fused + # Hack is_a? so that the DSL will consider this a Provider for the + # purposes of attaching enclosing_provider. + # + # @api private + # @param klass [Class] + # @return [Boolean] + def is_a?(klass) + if klass == Chef::Provider + # Lies, damn lies, and Ruby code. + true + else + super + end + end + + # Hack provider_for_action so that the resource is also the provider. + # + # @api private + # @param action [Symbol] + # @return [Chef::Provider] + def provider_for_action(action) + provider(self.class.fused_provider_class) unless provider + super + end + + # @!classmethods + module ClassMethods + # Define a provider action. The block should contain the usual provider + # code. + # + # @param name [Symbol] Name of the action. + # @param block [Proc] Action implementation. + # @example + # action(:run) do + # file '/temp' do + # user 'root' + # content 'temp' + # end + # end + def action(name, &block) + fused_actions[name.to_sym] = block + # Make sure this action is allowed, also sets the default if first. + if respond_to?(:actions) + actions(name.to_sym) + end + end + + # Storage accessor for fused action blocks. Maps action name to proc. + # + # @api private + # @return [Hash] + def fused_actions + (@fused_actions ||= {}) + end + + # Create a provider class for the fused actions in this resource. + # Inherits from the fused provider class of the resource's superclass if + # present. + # + # @api private + # @return [Class] + def fused_provider_class + @fused_provider_class ||= begin + provider_superclass = begin + self.superclass.fused_provider_class + rescue NoMethodError + Chef::Provider + end + actions = fused_actions + class_name = self.name + Class.new(provider_superclass) do + include Poise + define_singleton_method(:name) { class_name + ' (fused)' } + actions.each do |action, block| + define_method(:"action_#{action}", &block) + end + end + end + end + + def included(klass) + super + klass.extend(ClassMethods) + end + end + + extend ClassMethods + end + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/helpers/include_recipe.rb b/cookbooks/poise/files/halite_gem/poise/helpers/include_recipe.rb new file mode 100644 index 0000000..2b84e30 --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/helpers/include_recipe.rb @@ -0,0 +1,62 @@ +# +# Copyright 2013-2016, Noah Kantrowitz +# +# 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 'poise/helpers/subcontext_block' +require 'poise/subcontext/runner' + + +module Poise + module Helpers + # A provider mixin to add #include_recipe that can be called from action + # methods. + # + # @since 2.0.0 + module IncludeRecipe + include Poise::Helpers::SubcontextBlock + + def include_recipe(*recipes) + loaded_recipes = [] + subcontext = subcontext_block do + recipes.flatten.each do |recipe| + case recipe + when String + # Process normally + Chef::Log.debug("Loading recipe #{recipe} via include_recipe (poise)") + loaded_recipes += run_context.include_recipe(recipe) + when Proc + # Pretend its a block of recipe code + fake_recipe = Chef::Recipe.new(cookbook_name, new_resource.recipe_name, run_context) + fake_recipe.instance_eval(&recipe) + loaded_recipes << fake_recipe + end + end + end + # Converge the new context. + Poise::Subcontext::Runner.new(new_resource, subcontext).converge + collection = global_resource_collection + subcontext.resource_collection.each do |r| + Chef::Log.debug("Poise::IncludeRecipe: Adding #{r} to global collection #{collection.object_id}") + # Insert the local resource into the global context + collection.insert(r) + # Skip the iterator forward so we don't double-execute the inserted resource + # If running at compile time, the iterator is nil + collection.iterator.skip_forward if collection.iterator + end + loaded_recipes + end + end + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/helpers/inversion.rb b/cookbooks/poise/files/halite_gem/poise/helpers/inversion.rb new file mode 100644 index 0000000..76b64ba --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/helpers/inversion.rb @@ -0,0 +1,414 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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/node' +require 'chef/node_map' +require 'chef/provider' +require 'chef/resource' + +require 'poise/backports' +require 'poise/helpers/defined_in' +require 'poise/error' +require 'poise/helpers/inversion/options_resource' +require 'poise/utils/resource_provider_mixin' + + +module Poise + module Helpers + # A mixin for dependency inversion in Chef. + # + # @since 2.0.0 + module Inversion + autoload :OptionsResource, 'poise/helpers/inversion/options_resource' + autoload :OptionsProvider, 'poise/helpers/inversion/options_provider' + + include Poise::Utils::ResourceProviderMixin + + # Resource implementation for {Poise::Helpers::Inversion}. + # @see Poise::Helpers::Inversion + module Resource + # @overload options(val=nil) + # Set or return provider options for all providers. + # @param val [Hash] Provider options to set. + # @return [Hash] + # @example + # my_resource 'thing_one' do + # options depends: 'thing_two' + # end + # @overload options(provider, val=nil) + # Set or return provider options for a specific provider. + # @param provider [Symbol] Provider to set for. + # @param val [Hash] Provider options to set. + # @return [Hash] + # @example + # my_resource 'thing_one' do + # options :my_provider, depends: 'thing_two' + # end + def options(provider=nil, val=nil) + key = :options + if !val && provider.is_a?(Hash) + val = provider + elsif provider + key = :"options_#{provider}" + end + set_or_return(key, val ? Mash.new(val) : val, kind_of: Hash, default: lazy { Mash.new }) + end + + # Allow setting the provider directly using the same names as the attribute + # settings. + # + # @param val [String, Symbol, Class, nil] Value to set the provider to. + # @return [Class] + # @example + # my_resource 'thing_one' do + # provider :my_provider + # end + def provider(val=nil) + if val && !val.is_a?(Class) + resource_names = [resource_name] + # If subclass_providers! might be in play, check for those names too. + resource_names.concat(self.class.subclass_resource_equivalents) if self.class.respond_to?(:subclass_resource_equivalents) + # Silly ruby tricks to find the first provider that exists and no more. + provider_class = resource_names.lazy.map {|name| Poise::Helpers::Inversion.provider_for(name, node, val) }.select {|x| x }.first + Poise.debug("[#{self}] Checking for an inversion provider for #{val}: #{provider_class && provider_class.name}") + val = provider_class if provider_class + end + super + end + + # Set or return the array of provider names to be blocked from + # auto-resolution. + # + # @param val [String, Array] Value to set. + # @return [Array] + def provider_no_auto(val=nil) + # Coerce to an array. + val = Array(val).map(&:to_s) if val + set_or_return(:provider_no_auto, val, kind_of: Array, default: []) + end + + # @!classmethods + module ClassMethods + # Options resource class. + attr_reader :inversion_options_resource_class + # Options provider class. + attr_reader :inversion_options_provider_class + + # @overload inversion_options_resource() + # Return the options resource mode for this class. + # @return [Boolean] + # @overload inversion_options_resource(val) + # Set the options resource mode for this class. Set to true to + # automatically create an options resource. Defaults to true. + # @param val [Boolean] Enable/disable setting. + # @return [Boolean] + def inversion_options_resource(val=nil) + @poise_inversion_options_resource = val unless val.nil? + @poise_inversion_options_resource + end + + # Create resource and provider classes for an options resource. + # + # @param name [String, Symbol] DSL name for the base resource. + # @return [void] + def create_inversion_options_resource!(name) + enclosing_class = self + options_resource_name = :"#{name}_options" + # Create the resource class. + @inversion_options_resource_class = Class.new(Chef::Resource) do + include Poise::Helpers::Inversion::OptionsResource + define_singleton_method(:name) do + "#{enclosing_class}::OptionsResource" + end + define_singleton_method(:inversion_resource_class) do + enclosing_class + end + provides(options_resource_name) + inversion_resource(name) + end + # Create the provider class. + @inversion_options_provider_class = Class.new(Chef::Provider) do + include Poise::Helpers::Inversion::OptionsProvider + define_singleton_method(:name) do + "#{enclosing_class}::OptionsProvider" + end + define_singleton_method(:inversion_resource_class) do + enclosing_class + end + provides(options_resource_name) + end + end + + # Wrap #provides() to create an options resource if desired. + # + # @param name [Symbol] Resource name + # return [void] + def provides(name, *args, &block) + create_inversion_options_resource!(name) if inversion_options_resource + super(name, *args, &block) if defined?(super) + end + + def included(klass) + super + klass.extend(ClassMethods) + end + end + + extend ClassMethods + end + + # Provider implementation for {Poise::Helpers::Inversion}. + # @see Poise::Helpers::Inversion + module Provider + include DefinedIn + + # Compile all the different levels of inversion options together. + # + # @return [Hash] + # @example + # def action_run + # if options['depends'] + # # ... + # end + # end + def options + @options ||= self.class.inversion_options(node, new_resource) + end + + # @!classmethods + module ClassMethods + # @overload inversion_resource() + # Return the inversion resource name for this class. + # @return [Symbo, nill] + # @overload inversion_resource(val) + # Set the inversion resource name for this class. You can pass either + # a symbol in DSL format or a resource class that uses Poise. This + # name is used to determine which resources the inversion provider is + # a candidate for. + # @param val [Symbol, Class] Name to set. + # @return [Symbol, nil] + def inversion_resource(val=Poise::NOT_PASSED) + if val != Poise::NOT_PASSED + val = val.resource_name if val.is_a?(Class) + Chef::Log.debug("[#{self.name}] Setting inversion resource to #{val}") + @poise_inversion_resource = val.to_sym + end + if defined?(@poise_inversion_resource) + @poise_inversion_resource + else + Poise::Utils.ancestor_send(self, :inversion_resource, default: nil) + end + end + + # @overload inversion_attribute() + # Return the inversion attribute name(s) for this class. + # @return [Array, nil] + # @overload inversion_attribute(val) + # Set the inversion attribute name(s) for this class. This is + # used by {.resolve_inversion_attribute} to load configuration data + # from node attributes. To specify a nested attribute pass an array + # of strings corresponding to the keys. + # @param val [String, Array] Attribute path. + # @return [Array, nil] + def inversion_attribute(val=Poise::NOT_PASSED) + if val != Poise::NOT_PASSED + # Coerce to an array of strings. + val = Array(val).map {|name| name.to_s } + @poise_inversion_attribute = val + end + if defined?(@poise_inversion_attribute) + @poise_inversion_attribute + else + Poise::Utils.ancestor_send(self, :inversion_attribute, default: nil) + end + end + + # Default attribute paths to check for inversion options. Based on + # the cookbook this class and its superclasses are defined in. + # + # @param node [Chef::Node] Node to load from. + # @return [Array>] + def default_inversion_attributes(node) + klass = self + tried = [] + while klass.respond_to?(:poise_defined_in_cookbook) + cookbook = klass.poise_defined_in_cookbook(node.run_context) + if node[cookbook] + return [cookbook] + end + tried << cookbook + klass = klass.superclass + end + raise Poise::Error.new("Unable to find inversion attributes, tried: #{tried.join(', ')}") + end + + # Resolve the node attribute used as the base for inversion options + # for this class. This can be set explicitly with {.inversion_attribute} + # or the default is to use the name of the cookbook the provider is + # defined in. + # + # @param node [Chef::Node] Node to load from. + # @return [Chef::Node::Attribute] + def resolve_inversion_attribute(node) + # Default to using just the name of the cookbook. + attribute_names = inversion_attribute || default_inversion_attributes(node) + return {} if attribute_names.empty? + attribute_names.inject(node) do |memo, key| + memo[key] || begin + raise Poise::Error.new("Attribute #{key} not set when expanding inversion attribute for #{self.name}: #{memo}") + end + end + end + + # Compile all the different levels of inversion options together. + # + # @param node [Chef::Node] Node to load from. + # @param resource [Chef::Resource] Resource to load from. + # @return [Hash] + def inversion_options(node, resource) + Mash.new.tap do |opts| + attrs = resolve_inversion_attribute(node) + # Cast the run state to a Mash because string vs. symbol keys. I can + # at least promise poise_inversion will be a str so cut down on the + # amount of data to convert. + run_state = Mash.new(node.run_state.fetch('poise_inversion', {}).fetch(inversion_resource, {}))[resource.name] || {} + # Class-level defaults. + opts.update(default_inversion_options(node, resource)) + # Resource options for all providers. + opts.update(resource.options) if resource.respond_to?(:options) + # Global provider from node attributes. + opts.update(provider: attrs['provider']) if attrs['provider'] + # Attribute options for all providers. + opts.update(attrs['options']) if attrs['options'] + # Resource options for this provider. + opts.update(resource.options(provides)) if resource.respond_to?(:options) + # Attribute options for this resource name. + opts.update(attrs[resource.name]) if attrs[resource.name] + # Options resource options for all providers. + opts.update(run_state['*']) if run_state['*'] + # Options resource options for this provider. + opts.update(run_state[provides]) if run_state[provides] + # Vomitdebug output for tracking down weirdness. + Poise.debug("[#{resource}] Resolved inversion options: #{opts.inspect}") + end + end + + # Default options data for this provider class. + # + # @param node [Chef::Node] Node to load from. + # @param resource [Chef::Resource] Resource to load from. + # @return [Hash] + def default_inversion_options(node, resource) + {} + end + + # Resolve which provider name should be used for a resource. + # + # @param node [Chef::Node] Node to load from. + # @param resource [Chef::Resource] Resource to query. + # @return [String] + def resolve_inversion_provider(node, resource) + inversion_options(node, resource)['provider'] || 'auto' + end + + # Override the normal #provides to set the inversion provider name + # instead of adding to the normal provider map. + # + # @overload provides() + # Return the inversion provider name for the class. + # @return [Symbol] + # @overload provides(name, opts={}, &block) + # Set the inversion provider name for the class. + # @param name [Symbol] Provider name. + # @param opts [Hash] NodeMap filter options. + # @param block [Proc] NodeMap filter proc. + # @return [Symbol] + def provides(name=nil, opts={}, &block) + if name + raise Poise::Error.new("Inversion resource name not set for #{self.name}") unless inversion_resource + @poise_inversion_provider = name + Chef::Log.debug("[#{self.name}] Setting inversion provider name to #{name}") + Poise::Helpers::Inversion.provider_map(inversion_resource).set(name.to_sym, self, opts, &block) + # Set the actual Chef-level provides name for DSL dispatch. + super(inversion_resource) + end + @poise_inversion_provider + end + + # Override the default #provides? to check for our inverted providers. + # + # @api private + # @param node [Chef::Node] Node to use for attribute checks. + # @param resource [Chef::Resource] Resource instance to match. + # @return [Boolean] + def provides?(node, resource) + raise Poise::Error.new("Inversion resource name not set for #{self.name}") unless inversion_resource + resource_name_equivalents = {resource.resource_name => true} + # If subclass_providers! might be in play, check for those names too. + if resource.class.respond_to?(:subclass_resource_equivalents) + resource.class.subclass_resource_equivalents.each do |name| + resource_name_equivalents[name] = true + end + end + return false unless resource_name_equivalents[inversion_resource] + provider_name = resolve_inversion_provider(node, resource).to_s + Poise.debug("[#{resource}] Checking provides? on #{self.name}. Got provider_name #{provider_name.inspect}") + provider_name == provides.to_s || ( provider_name == 'auto' && !resource.provider_no_auto.include?(provides.to_s) && provides_auto?(node, resource) ) + end + + # Subclass hook to provide auto-detection for providers. + # + # @param node [Chef::Node] Node to check against. + # @param resource [Chef::Resource] Resource to check against. + # @return [Boolean] + def provides_auto?(node, resource) + false + end + + def included(klass) + super + klass.extend(ClassMethods) + end + end + + extend ClassMethods + end + + # The provider map for a given resource type. + # + # @param resource_type [Symbol] Resource type in DSL format. + # @return [Chef::NodeMap] + # @example + # Poise::Helpers::Inversion.provider_map(:my_resource) + def self.provider_map(resource_type) + @provider_maps ||= {} + @provider_maps[resource_type.to_sym] ||= Chef::NodeMap.new + end + + # Find a specific provider class for a resource. + # + # @param resource_type [Symbol] Resource type in DSL format. + # @param node [Chef::Node] Node to use for the lookup. + # @param provider_type [Symbol] Provider type in DSL format. + # @return [Class] + # @example + # Poise::Helpers::Inversion.provider_for(:my_resource, node, :my_provider) + def self.provider_for(resource_type, node, provider_type) + provider_map(resource_type).get(node, provider_type.to_sym) + end + end + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/helpers/inversion/options_provider.rb b/cookbooks/poise/files/halite_gem/poise/helpers/inversion/options_provider.rb new file mode 100644 index 0000000..9ea5f94 --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/helpers/inversion/options_provider.rb @@ -0,0 +1,41 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 Poise + module Helpers + module Inversion + # A mixin for inversion options providers. + # + # @api private + # @since 2.0.0 + # @see Poise::Helper::Inversion + module OptionsProvider + # @api private + def self.included(klass) + klass.class_exec { include Poise } + end + + # A blank run action. + # + # @return [void] + def action_run + # This space left intentionally blank. + end + end + end + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/helpers/inversion/options_resource.rb b/cookbooks/poise/files/halite_gem/poise/helpers/inversion/options_resource.rb new file mode 100644 index 0000000..9ff47a7 --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/helpers/inversion/options_resource.rb @@ -0,0 +1,115 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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/mash' + +require 'poise/backports' +require 'poise/error' + + +module Poise + module Helpers + module Inversion + # A mixin for inversion options resources. + # + # @api private + # @since 2.0.0 + # @see Poise::Helpers::Inversion + module OptionsResource + include Poise + + # Method missing delegation to allow DSL-style options. + # + # @example + # my_app_options 'app' do + # key1 'value1' + # key2 'value2' + # end + def method_missing(method_sym, *args, &block) + super(method_sym, *args, &block) + rescue NoMethodError + # First time we've seen this key and using it as an rvalue, NOPE.GIF. + raise unless !args.empty? || block || _options[method_sym] + if !args.empty? || block + _options[method_sym] = block || args.first + end + _options[method_sym] + end + + # Capture setting the provider and make it Do What I Mean. This does + # mean you can't set the actual provider for the options resource, which + # is fine because the provider is a no-op. + # + # @api private + def provider(val=Poise::NOT_PASSED) + if val == Poise::NOT_PASSED + super() + else + _options[:provider] = val + end + end + + # Insert the options data in to the run state. This has to match the + # layout used in {Poise::Helpers::Inversion::Provider.inversion_options}. + # + # @api private + def after_created + raise Poise::Error.new("Inversion resource name not set for #{self.class.name}") unless self.class.inversion_resource + node.run_state['poise_inversion'] ||= {} + node.run_state['poise_inversion'][self.class.inversion_resource] ||= {} + node.run_state['poise_inversion'][self.class.inversion_resource][resource] ||= {} + node.run_state['poise_inversion'][self.class.inversion_resource][resource][for_provider] ||= {} + node.run_state['poise_inversion'][self.class.inversion_resource][resource][for_provider].update(_options) + end + + module ClassMethods + # @overload inversion_resource() + # Return the inversion resource name for this class. + # @return [Symbol] + # @overload inversion_resource(val) + # Set the inversion resource name for this class. You can pass either + # a symbol in DSL format or a resource class that uses Poise. This + # name is used to determine which resources the inversion provider is + # a candidate for. + # @param val [Symbol, Class] Name to set. + # @return [Symbol] + def inversion_resource(val=nil) + if val + val = val.resource_name if val.is_a?(Class) + Chef::Log.debug("[#{self.name}] Setting inversion resource to #{val}") + @poise_inversion_resource = val.to_sym + end + @poise_inversion_resource || (superclass.respond_to?(:inversion_resource) ? superclass.inversion_resource : nil) + end + + # @api private + def included(klass) + super + klass.extend(ClassMethods) + klass.class_exec do + actions(:run) + attribute(:resource, kind_of: String, name_attribute: true) + attribute(:for_provider, kind_of: [String, Symbol], default: '*') + attribute(:_options, kind_of: Hash, default: lazy { Mash.new }) + end + end + end + + extend ClassMethods + end + end + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/helpers/lazy_default.rb b/cookbooks/poise/files/halite_gem/poise/helpers/lazy_default.rb new file mode 100644 index 0000000..59a04c9 --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/helpers/lazy_default.rb @@ -0,0 +1,79 @@ +# +# Copyright 2013-2016, Noah Kantrowitz +# +# 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/version' + + +module Poise + module Helpers + # Resource mixin to allow lazyily-evaluated defaults in resource attributes. + # This is designed to be used with {LWRPPolyfill} or a similar #attributes + # method. + # + # @since 1.0.0 + # @example + # class MyResource < Chef::Resource + # include Poise::Helpers::LWRPPolyfill + # include Poise::Helpers::LazyDefault + # attribute(:path, default: lazy { name + '_temp' }) + # end + module LazyDefault + # Check if this version of Chef already supports lazy defaults. This is + # true for Chef 12.5+. + # + # @since 2.0.3 + # @api private + # @return [Boolean] + def self.needs_polyfill? + @needs_polyfill ||= Gem::Requirement.new('< 12.5.pre').satisfied_by?(Gem::Version.new(Chef::VERSION)) + end + + # Override the default set_or_return to support lazy evaluation of the + # default value. This only actually matters when it is called from a class + # level context via #attributes. + def set_or_return(symbol, arg, validation) + if LazyDefault.needs_polyfill? && validation && validation[:default].is_a?(Chef::DelayedEvaluator) + validation = validation.dup + if (arg.nil? || arg == Poise::NOT_PASSED) && (!instance_variable_defined?(:"@#{symbol}") || instance_variable_get(:"@#{symbol}").nil?) + validation[:default] = instance_eval(&validation[:default]) + else + # Clear the default. + validation.delete(:default) + end + end + super(symbol, arg, validation) + end + + # @!classmethods + module ClassMethods + # Create a lazyily-evaluated block. + # + # @param block [Proc] Callable to return the default value. + # @return [Chef::DelayedEvaluator] + def lazy(&block) + Chef::DelayedEvaluator.new(&block) + end + + def included(klass) + super + klass.extend(ClassMethods) + end + end + + extend ClassMethods + end + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/helpers/lwrp_polyfill.rb b/cookbooks/poise/files/halite_gem/poise/helpers/lwrp_polyfill.rb new file mode 100644 index 0000000..a8c2541 --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/helpers/lwrp_polyfill.rb @@ -0,0 +1,163 @@ +# +# Copyright 2013-2016, Noah Kantrowitz +# +# 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' + +require 'poise/utils/resource_provider_mixin' + + +module Poise + module Helpers + # A resource and provider mixin to add back some compatability with Chef's + # LWRPBase classes. + # + # @since 1.0.0 + module LWRPPolyfill + include Poise::Utils::ResourceProviderMixin + + # Provide default_action and actions like LWRPBase but better equipped for subclassing. + module Resource + def initialize(*args) + super + # Try to not stomp on stuff if already set in a parent. Coerce @action + # to an array because this behavior may change in the future in Chef. + @action = self.class.default_action if Array(@action) == [:nothing] + (@allowed_actions << self.class.actions).flatten!.uniq! + end + + module ClassMethods + # @overload default_action() + # Get the default action for this resource class. If no explicit + # default is set, the first action in the list will be used. + # @see #actions + # @return [Array] + # @overload default_action(name) + # Set the default action for this resource class. If this action is + # not already allowed, it will be added. + # @note It is idiomatic to use {#actions} instead, with the first + # action specified being the default. + # @param name [Symbol, Array] Name of the action(s). + # @return [Array] + # @example + # class MyApp < Chef::Resource + # include Poise + # default_action(:install) + # end + def default_action(name=nil) + if name + name = Array(name).flatten.map(&:to_sym) + @default_action = name + actions(*name) + end + if @default_action + @default_action + elsif respond_to?(:superclass) && superclass != Chef::Resource && superclass.respond_to?(:default_action) && superclass.default_action && Array(superclass.default_action) != %i{nothing} + superclass.default_action + elsif first_non_nothing = actions.find {|action| action != :nothing } + [first_non_nothing] + else + %i{nothing} + end + end + + # @overload actions() + # Get all actions allowed for this resource class. This includes + # any actions allowed on parent classes. + # @return [Array] + # @overload actions(*names) + # Set actions as allowed for this resource class. These must + # correspond with action methods in the provider class(es). + # @param names [Array] One or more actions to set. + # @return [Array] + # @example + # class MyApp < Chef::Resource + # include Poise + # actions(:install, :uninstall) + # end + def actions(*names) + @actions ||= ( respond_to?(:superclass) && superclass.respond_to?(:actions) && superclass.actions.dup ) || ( respond_to?(:superclass) && superclass != Chef::Resource && superclass.respond_to?(:allowed_actions) && superclass.allowed_actions.dup ) || [] + (@actions << names).tap {|actions| actions.flatten!; actions.uniq! } + end + + # Create a resource property (née attribute) on this resource class. + # This follows the same usage as the helper of the same name in Chef + # LWRPs. + # + # @param name [Symbol] Name of the property. + # @param opts [Hash] Validation options and flags. + # @return [void] + # @example + # class MyApp < Chef::Resource + # include Poise + # attribute(:path, name_attribute: true) + # attribute(:port, kind_of: Integer, default: 8080) + # end + def attribute(name, opts={}) + # Freeze the default value. This is done upstream too in Chef 12.5+. + opts[:default].freeze if opts && opts[:default] + # Ruby 1.8 can go to hell. + define_method(name) do |arg=nil, &block| + arg = block if arg.nil? # Try to allow passing either. + set_or_return(name, arg, opts) + end + end + + # For forward compat with Chef 12.5+. + alias_method :property, :attribute + + def included(klass) + super + klass.extend(ClassMethods) + end + end + + extend ClassMethods + end + + # Helper to handle load_current_resource for direct subclasses of Provider + module Provider + module LoadCurrentResource + def load_current_resource + @current_resource = if new_resource + new_resource.class.new(new_resource.name, run_context) + else + # Better than nothing, subclass can overwrite anyway. + Chef::Resource.new(nil, run_context) + end + end + end + + # @!classmethods + module ClassMethods + def included(klass) + super + klass.extend(ClassMethods) + + # Mask Chef::Provider#load_current_resource because it throws NotImplementedError. + if klass.is_a?(Class) && klass.superclass == Chef::Provider + klass.send(:include, LoadCurrentResource) + end + + # Reinstate the Chef DSL, removed in Chef 12. + klass.send(:include, Chef::DSL::Recipe) + end + end + + extend ClassMethods + end + end + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/helpers/notifying_block.rb b/cookbooks/poise/files/halite_gem/poise/helpers/notifying_block.rb new file mode 100644 index 0000000..72708c9 --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/helpers/notifying_block.rb @@ -0,0 +1,78 @@ +# +# Copyright 2013-2016, Noah Kantrowitz +# +# 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 'poise/helpers/subcontext_block' +require 'poise/subcontext/runner' + + +module Poise + module Helpers + # A provider mixin to provide #notifying_block, a scoped form of Chef's + # use_inline_resources. + # + # @since 1.0.0 + # @example + # class MyProvider < Chef::Provider + # include Chef::Helpers::NotifyingBlock + # + # def action_run + # notifying_block do + # template '/etc/myapp.conf' do + # # ... + # end + # end + # end + # end + module NotifyingBlock + include Poise::Helpers::SubcontextBlock + + private + + # Create and converge a subcontext for the recipe DSL. This is similar to + # Chef's use_inline_resources but is scoped to a block. All DSL resources + # declared inside the block will be converged when the block returns, and + # the updated_by_last_action flag will be set if any of the inner + # resources are updated. + # + # @api public + # @param block [Proc] Block to run in the subcontext. + # @return [void] + # @example + # def action_run + # notifying_block do + # template '/etc/myapp.conf' do + # # ... + # end + # end + # end + def notifying_block(&block) + # Make sure to mark the resource as updated-by-last-action if + # any sub-run-context resources were updated (any actual + # actions taken against the system) during the + # sub-run-context convergence. + begin + subcontext = subcontext_block(&block) + # Converge the new context. + Poise::Subcontext::Runner.new(new_resource, subcontext).converge + ensure + new_resource.updated_by_last_action( + subcontext && subcontext.resource_collection.any?(&:updated?) + ) + end + end + end + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/helpers/option_collector.rb b/cookbooks/poise/files/halite_gem/poise/helpers/option_collector.rb new file mode 100644 index 0000000..ef48a42 --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/helpers/option_collector.rb @@ -0,0 +1,142 @@ +# +# Copyright 2013-2016, Noah Kantrowitz +# +# 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/mash' + +require 'poise/error' + + +module Poise + module Helpers + # A resource mixin to add a new kind of attribute, an option collector. + # These attributes can act as mini-DSLs for things which would otherwise be + # key/value pairs. + # + # @since 1.0.0 + # @example Defining an option collector + # class MyResource < Chef::Resource + # include Poise::Helpers::OptionCollector + # attribute(:my_options, option_collector: true) + # end + # @example Using an option collector + # my_resource 'name' do + # my_options do + # key1 'value1' + # key2 'value2' + # end + # end + module OptionCollector + # Instance context used to eval option blocks. + # @api private + class OptionEvalContext + attr_reader :_options + + def initialize(parent, forced_keys) + @parent = parent + @forced_keys = forced_keys + @_options = {} + end + + def method_missing(method_sym, *args, &block) + # Deal with forced keys. + if @forced_keys.include?(method_sym) + @_options[method_sym] = args.first || block if !args.empty? || block + return @_options[method_sym] + end + # Try the resource context. + @parent.send(method_sym, *args, &block) + rescue NameError + # Even though method= in the block will set a variable instead of + # calling method_missing, still try to cope in case of self.method=. + method_sym = method_sym.to_s.chomp('=').to_sym + if !args.empty? || block + @_options[method_sym] = args.first || block + elsif !@_options.include?(method_sym) + # We haven't seen this name before, re-raise the NameError. + raise + end + @_options[method_sym] + end + end + + # @!classmethods + module ClassMethods + # Override the normal #attribute() method to support defining option + # collectors too. + def attribute(name, options={}) + # If present but false-y, make sure it is removed anyway so it + # doesn't confuse ParamsValidate. + if options.delete(:option_collector) + option_collector_attribute(name, options) + else + super + end + end + + # Define an option collector attribute. Normally used via {.attribute}. + # + # @param name [String, Symbol] Name of the attribute to define. + # @param default [Hash] Default value for the options. + # @param parser [Proc, Symbol] Optional parser method. If a symbol it is + # called as a method on self. Takes a non-hash value and returns a + # hash of its parsed representation. + # @param forced_keys [Array, Set] Method names that will be forced + # to be options rather than calls to the parent resource. + def option_collector_attribute(name, default: {}, parser: nil, forced_keys: Set.new) + raise Poise::Error.new("Parser must be a Proc or Symbol: #{parser.inspect}") if parser && !(parser.is_a?(Proc) || parser.is_a?(Symbol)) + # Cast to a set at definition time. + forced_keys = Set.new(forced_keys) unless forced_keys.is_a?(Set) + # Unlike LWRPBase.attribute, I don't care about Ruby 1.8. Worlds tiniest violin. + define_method(name.to_sym) do |arg=nil, &block| + iv_sym = :"@#{name}" + + value = instance_variable_get(iv_sym) || begin + default = instance_eval(&default) if default.is_a?(Chef::DelayedEvaluator) # Handle lazy{} + Mash.new(default) # Wrap in a mash because fuck str vs sym. + end + if arg + if !arg.is_a?(Hash) && parser + arg = case parser + when Proc + instance_exec(arg, &parser) + when Symbol + send(parser, arg) + end + end + raise Exceptions::ValidationFailed, "Option #{name} must be a Hash" if !arg.is_a?(Hash) + # Should this and the update below be a deep merge? + value.update(arg) + end + if block + ctx = OptionEvalContext.new(self, forced_keys) + ctx.instance_exec(&block) + value.update(ctx._options) + end + instance_variable_set(iv_sym, value) + value + end + end + + def included(klass) + super + klass.extend(ClassMethods) + end + end + + extend ClassMethods + end + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/helpers/resource_cloning.rb b/cookbooks/poise/files/halite_gem/poise/helpers/resource_cloning.rb new file mode 100644 index 0000000..54c259c --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/helpers/resource_cloning.rb @@ -0,0 +1,72 @@ +# +# Copyright 2013-2016, Noah Kantrowitz +# +# 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 Poise + module Helpers + # A resource mixin to disable resource cloning. + # + # @since 2.2.0 + # @example + # class MyResource < Chef::Resource + # include Poise::Helpers::ResourceCloning + # end + module ResourceCloning + # Override to disable resource cloning on Chef 12.0. + # + # @api private + def load_prior_resource(*args) + # Do nothing. + end + + # Override to disable resource cloning on Chef 12.1+. + # + # @api private + def load_from(*args) + # Do nothing. + end + + # Monkeypatch for Chef::ResourceBuilder to silence the warning if needed. + # + # @api private + module ResourceBuilderPatch + # @api private + def self.install! + begin + require 'chef/resource_builder' + Chef::ResourceBuilder.send(:prepend, ResourceBuilderPatch) + rescue LoadError + # For 12.0, this is already taken care of. + end + end + + # @api private + def emit_cloned_resource_warning + super unless resource.is_a?(ResourceCloning) + end + + # @api private + def emit_harmless_cloning_debug + super unless resource.is_a?(ResourceCloning) + end + end + + # Install the patch. + ResourceBuilderPatch.install! + + end + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/helpers/resource_name.rb b/cookbooks/poise/files/halite_gem/poise/helpers/resource_name.rb new file mode 100644 index 0000000..c5d40e0 --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/helpers/resource_name.rb @@ -0,0 +1,107 @@ +# +# Copyright 2013-2016, Noah Kantrowitz +# +# 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/mixin/convert_to_class_name' + + +module Poise + module Helpers + # A resource mixin to automatically set @resource_name. + # + # @since 1.0.0 + # @example + # class MyResource < Chef::Resource + # include Poise::Helpers::ResourceName + # provides(:my_resource) + # end + module ResourceName + def initialize(*args) + super + # If provides() was explicitly set, unconditionally set @resource_name. + # This helps when subclassing core Chef resources which set it + # themselves in #initialize. + if self.class.resource_name(false) + @resource_name = self.class.resource_name + else + @resource_name ||= self.class.resource_name + end + end + + # @!classmethods + module ClassMethods + # Set the DSL name for the the resource class. + # + # @param name [Symbol] Name of the resource. + # @return [void] + # @example + # class MyResource < Chef::Resource + # include Poise::Resource::ResourceName + # provides(:my_resource) + # end + def provides(name, *args, &block) + # Patch self.constantize so this can cope with anonymous classes. + # This does require that the anonymous class define self.name though. + if self.name && respond_to?(:constantize) + old_constantize = instance_method(:constantize) + define_singleton_method(:constantize) do |const_name| + ( const_name == self.name ) ? self : old_constantize.bind(self).call(const_name) + end + end + # Store the name for later. + @provides_name ||= name + # Call the original if present. The defined? is for old Chef. + super(name, *args, &block) if defined?(super) + end + + # Retreive the DSL name for the resource class. If not set explicitly + # via {provides} this will try to auto-detect based on the class name. + # + # @param auto [Boolean] Try to auto-detect based on class name. + # @return [Symbol] + def resource_name(auto=true) + # In 12.4+ we need to proxy through the super class for setting. + return super(auto) if defined?(super) && (auto.is_a?(Symbol) || auto.is_a?(String)) + return @provides_name unless auto + @provides_name || if name + mode = if name.start_with?('Chef::Resource') + [name, 'Chef::Resource'] + else + [name.split('::').last] + end + Chef::Mixin::ConvertToClassName.convert_to_snake_case(*mode).to_sym + elsif defined?(super) + # No name on 12.4+ probably means this is an LWRP, use super(). + super() + end + end + + # Used by Resource#to_text to find the human name for the resource. + # + # @api private + def dsl_name + resource_name.to_s + end + + def included(klass) + super + klass.extend(ClassMethods) + end + end + + extend ClassMethods + end + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/helpers/resource_subclass.rb b/cookbooks/poise/files/halite_gem/poise/helpers/resource_subclass.rb new file mode 100644 index 0000000..416d30d --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/helpers/resource_subclass.rb @@ -0,0 +1,82 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 'poise/error' +require 'poise/helpers/resource_name' + + +module Poise + module Helpers + # A resource mixin to help subclass existing resources. + # + # @since 2.3.0 + module ResourceSubclass + include ResourceName + + module ClassMethods + def subclass_providers!(superclass_resource_name=nil, resource_name: nil) + resource_name ||= self.resource_name + superclass_resource_name ||= if superclass.respond_to?(:resource_name) + superclass.resource_name + elsif superclass.respond_to?(:dsl_name) + superclass.dsl_name + else + raise Poise::Error.new("Unable to determine superclass resource name for #{superclass}. Please specify name manually via subclass_providers!('name').") + end.to_sym + # Deal with the node maps. + node_maps = {} + node_maps['handler map'] = Chef.provider_handler_map if defined?(Chef.provider_handler_map) + node_maps['priority map'] = Chef.provider_priority_map if defined?(Chef.provider_priority_map) + # Patch anything in the descendants tracker. + Chef::Provider.descendants.each do |provider| + node_maps["#{provider} node map"] = provider.node_map if defined?(provider.node_map) + end if defined?(Chef::Provider.descendants) + node_maps.each do |map_name, node_map| + map = node_map.respond_to?(:map, true) ? node_map.send(:map) : node_map.instance_variable_get(:@map) + if map.include?(superclass_resource_name) + Chef::Log.debug("[#{self}] Copying provider mapping in #{map_name} from #{superclass_resource_name} to #{resource_name}") + map[resource_name] = map[superclass_resource_name].dup + end + end + # Add any needed equivalent names. + if superclass.respond_to?(:subclass_resource_equivalents) + subclass_resource_equivalents.concat(superclass.subclass_resource_equivalents) + else + subclass_resource_equivalents << superclass_resource_name + end + subclass_resource_equivalents.uniq! + end + + # An array of names for the resources this class is equivalent to for + # the purposes of provider resolution. + # + # @return [Array] + def subclass_resource_equivalents + @subclass_resource_names ||= [resource_name.to_sym] + end + + # @api private + def included(klass) + super + klass.extend(ClassMethods) + end + end + + extend ClassMethods + end + + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/helpers/subcontext_block.rb b/cookbooks/poise/files/halite_gem/poise/helpers/subcontext_block.rb new file mode 100644 index 0000000..facdda9 --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/helpers/subcontext_block.rb @@ -0,0 +1,72 @@ +# +# Copyright 2013-2016, Noah Kantrowitz +# +# 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 'poise/subcontext/resource_collection' + + +module Poise + module Helpers + # A provider mixin to help with creating subcontexts. Mostly for internal + # use within Poise. + # + # @since 1.0.0 + module SubcontextBlock + private + + def subcontext_block(parent_context=nil, &block) + # Setup a subcontext. + parent_context ||= @run_context + sub_run_context = parent_context.dup + # Reset state for the subcontext. In 12.4+ this uses the built-in + # support, otherwise do it manually. + if defined?(sub_run_context.initialize_child_state) + sub_run_context.initialize_child_state + else + # Audits was added in 12.1 I think. + sub_run_context.audits = {} if defined?(sub_run_context.audits) + # Dup and clear to preserve the default behavior without copy-pasta. + sub_run_context.immediate_notification_collection = parent_context.immediate_notification_collection.dup.clear + sub_run_context.delayed_notification_collection = parent_context.delayed_notification_collection.dup.clear + end + # Create the subcollection. + sub_run_context.resource_collection = Poise::Subcontext::ResourceCollection.new(parent_context.resource_collection) + # Create an accessor for the parent run context. + sub_run_context.define_singleton_method(:parent_run_context) { parent_context } + + # Declare sub-resources within the sub-run-context. Since they + # are declared here, they do not pollute the parent run-context. + begin + outer_run_context = @run_context + @run_context = sub_run_context + instance_eval(&block) + ensure + @run_context = outer_run_context + end + + # Return the inner context to do other things with + sub_run_context + end + + def global_resource_collection + collection = @run_context.resource_collection + while collection.respond_to?(:parent) && collection.parent + collection = collection.parent + end + collection + end + end + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/helpers/subresources.rb b/cookbooks/poise/files/halite_gem/poise/helpers/subresources.rb new file mode 100644 index 0000000..ce0f199 --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/helpers/subresources.rb @@ -0,0 +1,29 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 Poise + module Helpers + # Mixins and helpers for managing subresources, resources with a + # parent/child relationship. + # + # @since 2.0.0 + module Subresources + autoload :Child, 'poise/helpers/subresources/child' + autoload :Container, 'poise/helpers/subresources/container' + end + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/helpers/subresources/child.rb b/cookbooks/poise/files/halite_gem/poise/helpers/subresources/child.rb new file mode 100644 index 0000000..ef6a24a --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/helpers/subresources/child.rb @@ -0,0 +1,276 @@ +# +# Copyright 2013-2016, Noah Kantrowitz +# +# 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' + +require 'poise/error' +require 'poise/helpers/subresources/default_containers' + + +module Poise + module Helpers + module Subresources + # A resource mixin for child subresources. + # + # @since 1.0.0 + module Child + # Little class used to fix up the display of subresources in #to_text. + # Without this you get the full parent resource shown for @parent et al. + # @api private + class ParentRef + attr_accessor :resource + + def initialize(resource) + @resource = resource + end + + def inspect + to_text + end + + def to_text + if @resource.nil? + 'nil' + else + @resource.to_s + end + end + end + + # @overload parent() + # Get the parent resource for this child. This may be nil if the + # resource is set to parent_optional = true. + # @return [Chef::Resource, nil] + # @overload parent(val) + # Set the parent resource. The parent can be set as resource + # object, a string (either a bare resource name or a type[name] + # string), or a type:name hash. + # @param val [String, Hash, Chef::Resource] Parent resource to set. + # @return [Chef::Resource, nil] + def parent(*args) + # Lie about this method if the parent type is true. + if self.class.parent_type == true + raise NoMethodError.new("undefined method `parent' for #{self}") + end + _parent(:parent, self.class.parent_type, self.class.parent_optional, self.class.parent_auto, self.class.parent_default, *args) + end + + # Register ourself with parents in case this is not a nested resource. + # + # @api private + def after_created + super + self.class.parent_attributes.each_key do |name| + parent = self.send(name) + parent.register_subresource(self) if parent && parent.respond_to?(:register_subresource) + end + end + + private + + # Generic form of the parent getter/setter. + # + # @since 2.0.0 + # @see #parent + def _parent(name, parent_type, parent_optional, parent_auto, parent_default, *args) + # Allow using a DSL symbol as the parent type. + if parent_type.is_a?(Symbol) + parent_type = Chef::Resource.resource_for_node(parent_type, node) + end + # Grab the ivar for local use. + parent_ref = instance_variable_get(:"@#{name}") + if !args.empty? + val = args.first + if val.nil? + # Unsetting the parent. + parent = parent_ref = nil + else + if val.is_a?(String) && !val.include?('[') + raise Poise::Error.new("Cannot use a string #{name} without defining a parent type") if parent_type == Chef::Resource + # Try to find the most recent instance of parent_type with a + # matching name. This takes subclassing parent_type into account. + found_val = nil + iterator = run_context.resource_collection.respond_to?(:recursive_each) ? :recursive_each : :each + # This will find the last matching value due to overwriting + # found_val as it goes. Will be the nearest match. + run_context.resource_collection.public_send(iterator) do |res| + found_val = res if res.is_a?(parent_type) && res.name == val + end + # If found_val is nil, fall back to using lookup even though + # it won't work with subclassing, better than nothing? + val = found_val || "#{parent_type.resource_name}[#{val}]" + end + if val.is_a?(String) || val.is_a?(Hash) + parent = @run_context.resource_collection.find(val) + else + parent = val + end + if !parent.is_a?(parent_type) + raise Poise::Error.new("Parent resource is not an instance of #{parent_type.name}: #{val.inspect}") + end + parent_ref = ParentRef.new(parent) + end + elsif !parent_ref || !parent_ref.resource + if parent_default + parent = if parent_default.is_a?(Chef::DelayedEvaluator) + instance_eval(&parent_default) + else + parent_default + end + end + # The @parent_ref means we won't run this if we previously set + # ParentRef.new(nil). This means auto-lookup only happens during + # after_created. + if !parent && !parent_ref && parent_auto + # Automatic sibling lookup for sequential composition. + # Find the last instance of the parent class as the default parent. + # This is super flaky and should only be a last resort. + parent = Poise::Helpers::Subresources::DefaultContainers.find(parent_type, run_context, self_resource: self) + end + # Can't find a valid parent, if it wasn't optional raise an error. + raise Poise::Error.new("No #{name} found for #{self}") unless parent || parent_optional + parent_ref = ParentRef.new(parent) + else + parent = parent_ref.resource + end + raise Poise::Error.new("Cannot set the #{name} of #{self} to itself") if parent.equal?(self) + # Store the ivar back. + instance_variable_set(:"@#{name}", parent_ref) + # Return the actual resource. + parent + end + + module ClassMethods + # @overload parent_type() + # Get the class of the default parent link on this resource. + # @return [Class, Symbol] + # @overload parent_type(type) + # Set the class of the default parent link on this resource. + # @param type [Class, Symbol] Class to set. + # @return [Class, Symbol] + def parent_type(type=nil) + if type + raise Poise::Error.new("Parent type must be a class, symbol, or true, got #{type.inspect}") unless type.is_a?(Class) || type.is_a?(Symbol) || type == true + # Setting to true shouldn't actually do anything if a type was already set. + @parent_type = type unless type == true && !@parent_type.nil? + end + # First ancestor_send looks for a non-true && non-default value, + # second one is to check for default vs true if no real value is found. + @parent_type || Poise::Utils.ancestor_send(self, :parent_type, ignore: [Chef::Resource, true]) || Poise::Utils.ancestor_send(self, :parent_type, default: Chef::Resource) + end + + # @overload parent_optional() + # Get the optional mode for the default parent link on this resource. + # @return [Boolean] + # @overload parent_optional(val) + # Set the optional mode for the default parent link on this resource. + # @param val [Boolean] Mode to set. + # @return [Boolean] + def parent_optional(val=nil) + unless val.nil? + @parent_optional = val + end + if @parent_optional.nil? + Poise::Utils.ancestor_send(self, :parent_optional, default: false) + else + @parent_optional + end + end + + # @overload parent_auto() + # Get the auto-detect mode for the default parent link on this resource. + # @return [Boolean] + # @overload parent_auto(val) + # Set the auto-detect mode for the default parent link on this resource. + # @param val [Boolean] Mode to set. + # @return [Boolean] + def parent_auto(val=nil) + unless val.nil? + @parent_auto = val + end + if @parent_auto.nil? + Poise::Utils.ancestor_send(self, :parent_auto, default: true) + else + @parent_auto + end + end + + # @overload parent_default() + # Get the default value for the default parent link on this resource. + # @since 2.3.0 + # @return [Object, Chef::DelayedEvaluator] + # @overload parent_default(val) + # Set the default value for the default parent link on this resource. + # @since 2.3.0 + # @param val [Object, Chef::DelayedEvaluator] Default value to set. + # @return [Object, Chef::DelayedEvaluator] + def parent_default(*args) + unless args.empty? + @parent_default = args.first + end + if defined?(@parent_default) + @parent_default + else + Poise::Utils.ancestor_send(self, :parent_default) + end + end + + # Create a new kind of parent link. + # + # @since 2.0.0 + # @param name [Symbol] Name of the relationship. This becomes a method + # name on the resource instance. + # @param type [Class] Class of the parent. + # @param optional [Boolean] If the parent is optional. + # @param auto [Boolean] If the parent is auto-detected. + # @return [void] + def parent_attribute(name, type: Chef::Resource, optional: false, auto: true, default: nil) + name = :"parent_#{name}" + (@parent_attributes ||= {})[name] = type + define_method(name) do |*args| + _parent(name, type, optional, auto, default, *args) + end + end + + # Return the name of all parent relationships on this class. + # + # @since 2.0.0 + # @return [Hash] + def parent_attributes + {}.tap do |attrs| + # Grab superclass's attributes if possible. + attrs.update(Poise::Utils.ancestor_send(self, :parent_attributes, default: {})) + # Local default parent. + attrs[:parent] = parent_type + # Extra locally defined parents. + attrs.update(@parent_attributes) if @parent_attributes + # Remove anything with the type set to true. + attrs.reject! {|name, type| type == true } + end + end + + # @api private + def included(klass) + super + klass.extend(ClassMethods) + end + end + + extend ClassMethods + end + end + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/helpers/subresources/container.rb b/cookbooks/poise/files/halite_gem/poise/helpers/subresources/container.rb new file mode 100644 index 0000000..7d107f8 --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/helpers/subresources/container.rb @@ -0,0 +1,229 @@ +# +# Copyright 2013-2016, Noah Kantrowitz +# +# 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 'poise/helpers/subcontext_block' +require 'poise/helpers/subresources/default_containers' + + +module Poise + module Helpers + module Subresources + # A resource mixin for subresource containers. + # + # @since 1.0.0 + module Container + # A resource collection that has much more condensed text output. This + # is used to show the value of @subresources during Chef's error formatting. + # @api private + class NoPrintingResourceCollection < Chef::ResourceCollection + def inspect + to_text + end + + def to_text + "[#{all_resources.map(&:to_s).join(', ')}]" + end + end + + include SubcontextBlock + include Chef::DSL::Recipe + + attr_reader :subresources + attr_reader :subcontexts + + def initialize(*args) + super + @subresources = NoPrintingResourceCollection.new + @subcontexts = [] + end + + def after_created + super + # Register as a default container if needed. + Poise::Helpers::Subresources::DefaultContainers.register!(self, run_context) if self.class.container_default + # Add all internal subresources to the resource collection. + unless @subresources.empty? + Chef::Log.debug("[#{self}] Adding subresources to collection:") + # Because after_create is run before adding the container to the resource collection + # we need to jump through some hoops to get it swapped into place. + self_ = self + order_fixer = Chef::Resource::RubyBlock.new('subresource_order_fixer', @run_context) + # respond_to? is for <= 12.0.2, remove some day when I stop caring. + order_fixer.declared_type = 'ruby_block' if order_fixer.respond_to?(:declared_type=) + order_fixer.block do + Chef::Log.debug("[#{self_}] Running order fixer") + collection = self_.run_context.resource_collection + # Delete the current container resource from its current position. + collection.all_resources.delete(self_) + # Replace the order fixer with the container so it runs before all + # subresources. + collection.all_resources[collection.iterator.position] = self_ + # Hack for Chef 11 to reset the resources_by_name position too. + # @todo Remove this when I drop support for Chef 11. + if resources_by_name = collection.instance_variable_get(:@resources_by_name) + resources_by_name[self_.to_s] = collection.iterator.position + end + # Step back so we re-run the "current" resource, which is now the + # container. + collection.iterator.skip_back + Chef::Log.debug("Collection: #{@run_context.resource_collection.map(&:to_s).join(', ')}") + end + @run_context.resource_collection.insert(order_fixer) + @subcontexts.each do |ctx| + # Copy all resources to the outer context. + ctx.resource_collection.each do |r| + Chef::Log.debug(" * #{r}") + # Fix the subresource to use the outer run context. + r.run_context = @run_context + @run_context.resource_collection.insert(r) + end + # Copy all notifications to the outer context. + %w{immediate delayed}.each do |notification_type| + ctx.send(:"#{notification_type}_notification_collection").each do |key, notifications| + notifications.each do |notification| + parent_notifications = @run_context.send(:"#{notification_type}_notification_collection")[key] + unless parent_notifications.any? { |existing_notification| existing_notification.duplicates?(notification) } + parent_notifications << notification + end + end + end + end + end + Chef::Log.debug("Collection: #{@run_context.resource_collection.map(&:to_s).join(', ')}") + end + end + + def declare_resource(type, name, created_at=nil, &block) + Chef::Log.debug("[#{self}] Creating subresource from #{type}(#{name})") + self_ = self + # Used to break block context, non-local return from subcontext_block. + resource = [] + # Grab the caller so we can make the subresource look like it comes from + # correct place. + created_at ||= caller[0] + # Run this inside a subcontext to avoid adding to the current resource collection. + # It will end up added later, indirected via @subresources to ensure ordering. + @subcontexts << subcontext_block do + namespace = if self.class.container_namespace == true + # If the value is true, use the name of the container resource. + self.name + elsif self.class.container_namespace.is_a?(Proc) + instance_eval(&self.class.container_namespace) + else + self.class.container_namespace + end + sub_name = if name && !name.empty? + if namespace + "#{namespace}::#{name}" + else + name + end + else + # If you pass in nil or '', you just get the namespace or parent name. + namespace || self.name + end + resource << super(type, sub_name, created_at) do + # Apply the correct parent before anything else so it is available + # in after_created for the subresource. It might raise + # NoMethodError is there isn't a real parent. + begin + parent(self_) if respond_to?(:parent) + rescue NoMethodError + # This space left intentionally blank. + end + # Run the resource block. + instance_exec(&block) if block + end + end + # Try and add to subresources. For normal subresources this is handled + # in the after_created. + register_subresource(resource.first) if resource.first + # Return whatever we have + resource.first + end + + # Register a resource as part of this container. Returns true if the + # resource was added to the collection and false if it was already + # known. + # + # @note Return value added in 2.4.0. + # @return [Boolean] + def register_subresource(resource) + subresources.lookup(resource) + false + rescue Chef::Exceptions::ResourceNotFound + Chef::Log.debug("[#{self}] Adding #{resource} to subresources") + subresources.insert(resource) + true + end + + private + + # Thanks Array.flatten, big help you are. Specifically the + # method_missing in the recipe DSL will make a flatten on an array of + # resources fail, so make this safe. + def to_ary + nil + end + + # @!classmethods + module ClassMethods + def container_namespace(val=nil) + @container_namespace = val unless val.nil? + if @container_namespace.nil? + # Not set here, look at the superclass or true by default for backwards compat. + Poise::Utils.ancestor_send(self, :container_namespace, default: true) + else + @container_namespace + end + end + + # @overload container_default() + # Get the default mode for this resource. If false, this resource + # class will not be used for default container lookups. Defaults to + # true. + # @since 2.3.0 + # @return [Boolean] + # @overload container_default(val) + # Set the default mode for this resource. + # @since 2.3.0 + # @param val [Boolean] Default mode to set. + # @return [Boolean] + def container_default(val=nil) + @container_default = val unless val.nil? + if @container_default.nil? + # Not set here, look at the superclass or true by default for backwards compat. + Poise::Utils.ancestor_send(self, :container_default, default: true) + else + @container_default + end + end + + def included(klass) + super + klass.extend(ClassMethods) + klass.const_get(:HIDDEN_IVARS) << :@subcontexts + klass.const_get(:FORBIDDEN_IVARS) << :@subcontexts + end + end + + extend ClassMethods + end + end + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/helpers/subresources/default_containers.rb b/cookbooks/poise/files/halite_gem/poise/helpers/subresources/default_containers.rb new file mode 100644 index 0000000..2ef26e5 --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/helpers/subresources/default_containers.rb @@ -0,0 +1,75 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 Poise + module Helpers + module Subresources + # Helpers to track default container resources. This is used to find a + # default parent for a child with no parent set. It flat out violates + # encapsulation to allow for the use of default parents to act as + # system-level defaults even when created in a nested scope. + # + # @api private + # @since 2.0.0 + module DefaultContainers + # Mutex to sync access to the containers array. + # + # @see .containers + CONTAINER_MUTEX = Mutex.new + + # Add a resource to the array of default containers. + # + # @param resource [Chef::Resource] Resource to add. + # @param run_context [Chef::RunContext] Context of the current run. + # @return [void] + def self.register!(resource, run_context) + CONTAINER_MUTEX.synchronize do + containers(run_context) << resource + end + end + + # Find a default container for a resource class. + # + # @param klass [Class] Resource class to search for. + # @param run_context [Chef::RunContext] Context of the current run. + # @return [Chef::Resource] + def self.find(klass, run_context, self_resource: nil) + CONTAINER_MUTEX.synchronize do + containers(run_context).reverse_each do |resource| + return resource if resource.is_a?(klass) && (!self_resource || self_resource != resource) + end + # Nothing found. + nil + end + end + + private + + # Get the array of all default container resources. + # + # @note MUST BE CALLED FROM A LOCKED CONTEXT! + # @param run_context [Chef::RunContext] Context of the current run. + # @return [Array] + def self.containers(run_context) + # For test cases where nil gets used sometimes. + return [] unless run_context && run_context.node && run_context.node.run_state + run_context.node.run_state[:poise_default_containers] ||= [] + end + end + end + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/helpers/template_content.rb b/cookbooks/poise/files/halite_gem/poise/helpers/template_content.rb new file mode 100644 index 0000000..48d8ec9 --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/helpers/template_content.rb @@ -0,0 +1,168 @@ +# +# Copyright 2013-2016, Noah Kantrowitz +# +# 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/provider/template_finder' +require 'chef/mixin/template' + +require 'poise/helpers/lazy_default' +require 'poise/helpers/lwrp_polyfill' +require 'poise/helpers/option_collector' +require 'poise/utils' + + +module Poise + module Helpers + # A resource mixin to add a new kind of attribute, template content. TODO + # + # @since 1.0.0 + module TemplateContent + include LazyDefault + include LWRPPolyfill + include OptionCollector + + # @!classmethods + module ClassMethods + def attribute(name, options={}) + if options.delete(:template) + name_prefix = name.empty? ? '' : "#{name}_" + + # If you are reading this, I'm so sorry + # This is used for computing the default cookbook below + parent_filename = caller.first.reverse.split(':', 4).last.reverse + + # If our parent class also declared a template_content attribute on the same name, inherit its options + if superclass.respond_to?("_#{name_prefix}_template_content_options") + options = superclass.send("_#{name_prefix}_template_content_options").merge(options) + end + + # Template source path if using a template + attribute("#{name_prefix}source", kind_of: String) + define_method("_#{name_prefix}source") do + send("#{name_prefix}source") || maybe_eval(options[:default_source]) + end + + # Template cookbook name if using a template + attribute("#{name_prefix}cookbook", kind_of: [String, Symbol], default: lazy do + if send("#{name_prefix}source") + cookbook_name + elsif options[:default_cookbook] + maybe_eval(options[:default_cookbook]) + else + Poise::Utils.find_cookbook_name(run_context, parent_filename) + end + end) + + # Template variables if using a template + attribute("#{name_prefix}options", option_collector: true) + + # Make an alias for #variables to match the template resource. + alias_method("#{name_prefix}variables", "#{name_prefix}options") + + # The big one, get/set content, but if you are getting and no + # explicit content was given, try to render the template + define_method("#{name_prefix}content") do |arg=nil, no_compute=false| + ret = set_or_return("#{name_prefix}content", arg, kind_of: String) + if !ret && !arg && !no_compute + ret = send("_#{name_prefix}content") + # Cache the results for next time + set_or_return("#{name_prefix}content", ret, {}) if ret + end + ret + end + + # Validate that arguments work + define_method("_#{name_prefix}validate") do + if options[:required] && !send("_#{name_prefix}source") && !send("#{name_prefix}content", nil, true) + raise Chef::Exceptions::ValidationFailed, "#{self}: One of #{name_prefix}source or #{name_prefix}content is required" + end + if send("#{name_prefix}source") && send("#{name_prefix}content", nil, true) + raise Chef::Exceptions::ValidationFailed, "#{self}: Only one of #{name_prefix}source or #{name_prefix}content can be specified" + end + end + + # Monkey patch #after_create to run best-effort validation. Arguments + # could be changed after creation, but this gives nicer errors for + # most cases. + unless options[:no_validate_on_create] + old_after_created = instance_method(:after_created) + define_method(:after_created) do + old_after_created.bind(self).call + send("_#{name_prefix}validate") if Array(action) == Array(self.class.default_action) + end + end + + # Compile the needed content + define_method("_#{name_prefix}content") do + # Run validation again + send("_#{name_prefix}validate") + # Get all the relevant parameters + content = send("#{name_prefix}content", nil, true) + source = send("_#{name_prefix}source") + if content + content # I don't think it can ever hit this branch + elsif source + cookbook = send("#{name_prefix}cookbook") + template_options = send("#{name_prefix}options") + send("_#{name_prefix}render_template", source, cookbook, template_options) + else + maybe_eval(options[:default]) + end + end + + # Actually render a template + define_method("_#{name_prefix}render_template") do |source, cookbook, template_options| + all_template_options = {} + all_template_options.update(maybe_eval(options[:default_options])) if options[:default_options] + all_template_options.update(template_options) + all_template_options[:new_resource] = self + finder = Chef::Provider::TemplateFinder.new(run_context, cookbook, node) + context = Chef::Mixin::Template::TemplateContext.new(all_template_options) + context[:node] = node + context[:template_finder] = finder + context.render_template(finder.find(source)) + end + + # Used to check if a parent class already defined a template_content thing here + define_singleton_method("_#{name_prefix}_template_content_options") do + options + end + else + super if defined?(super) + end + end + + def included(klass) + super + klass.extend(ClassMethods) + end + end + + extend ClassMethods + + private + + # Evaluate lazy blocks if needed + def maybe_eval(val) + if val.is_a?(Chef::DelayedEvaluator) + instance_eval(&val) + else + val + end + end + + end + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/helpers/win32_user.rb b/cookbooks/poise/files/halite_gem/poise/helpers/win32_user.rb new file mode 100644 index 0000000..4588df4 --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/helpers/win32_user.rb @@ -0,0 +1,64 @@ +# +# Copyright 2013-2016, Noah Kantrowitz +# +# 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 'poise/utils/win32' + + +module Poise + module Helpers + # A resource mixin to intercept properties named `user`, `group`, or `owner`, + # if their default value is `'root'` and make it work on Windows (and + # FreeBSD, AIX). + # + # @since 2.7.0 + # @example + # class MyResource < Chef::Resource + # include Poise::Helpers::Win32User + # attribute(:user, default: 'root') + # attribute(:group, default: 'root') + # end + # @example Avoiding automatic translation + # class MyResource < Chef::Resource + # include Poise::Helpers::Win32User + # attribute(:user, default: lazy { 'root' }) + # attribute(:group, default: lazy { 'root' }) + # end + module Win32User + # User-ish property names. + # @api private + USER_PROPERTIES = ['user', :user, 'owner', :owner] + + # Group-ish property names. + # @api private + GROUP_PROPERTIES = ['group', :group] + + # Intercept property access to swap out the default value. + # @api private + def set_or_return(symbol, arg, options={}) + if options && options[:default] == 'root' + if USER_PROPERTIES.include?(symbol) && node.platform_family?('windows') + options = options.dup + options[:default] = Poise::Utils::Win32.admin_user + elsif GROUP_PROPERTIES.include?(symbol) + options = options.dup + options[:default] = node['root_group'] + end + end + super(symbol, arg, options) + end + end + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/provider.rb b/cookbooks/poise/files/halite_gem/poise/provider.rb new file mode 100644 index 0000000..953e31c --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/provider.rb @@ -0,0 +1,59 @@ +# +# Copyright 2013-2016, Noah Kantrowitz +# +# 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 'poise/helpers' +require 'poise/utils' + + +module Poise + # Master provider mixin for Poise-based providers. + # + # @since 1.0.0 + # @example Default helpers. + # class MyProvider < Chef::Provider + # include Poise::Provider + # end + # @example With optional helpers. + # class MyProvider < Chef::Provider + # include Poise::Provider + # poise_inversion(MyResource) + # end + module Provider + include Poise::Helpers::DefinedIn + include Poise::Helpers::LWRPPolyfill + # IncludeRecipe must come after LWRPPolyfill because that pulls in the + # recipe DSL which has its own #include_recipe. + include Poise::Helpers::IncludeRecipe + include Poise::Helpers::NotifyingBlock + include Poise::Utils::ShellOut + + # @!classmethods + module ClassMethods + def poise_inversion(resource, attribute=nil) + include Poise::Helpers::Inversion + inversion_resource(resource) + inversion_attribute(attribute) if attribute + end + + def included(klass) + super + klass.extend(ClassMethods) + end + end + + extend ClassMethods + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/resource.rb b/cookbooks/poise/files/halite_gem/poise/resource.rb new file mode 100644 index 0000000..ff8ad05 --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/resource.rb @@ -0,0 +1,81 @@ +# +# Copyright 2013-2016, Noah Kantrowitz +# +# 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 'poise/helpers' +require 'poise/utils' + + +module Poise + # Master resource mixin for Poise-based resources. + # + # @since 1.0.0 + # @example Default helpers. + # class MyResource < Chef::Resource + # include Poise::Resource + # end + # @example With optional helpers. + # class MyResource < Chef::Resource + # include Poise::Resource + # poise_subresource(MyParent) + # poise_fused + # end + module Resource + include Poise::Helpers::ChefspecMatchers + include Poise::Helpers::DefinedIn + include Poise::Helpers::LazyDefault if Poise::Helpers::LazyDefault.needs_polyfill? + include Poise::Helpers::LWRPPolyfill + include Poise::Helpers::OptionCollector + include Poise::Helpers::ResourceCloning + include Poise::Helpers::ResourceName + include Poise::Helpers::ResourceSubclass + include Poise::Helpers::TemplateContent + include Poise::Helpers::Win32User # Must be after LazyDefault. + include Poise::Utils::ShellOut + + # @!classmethods + module ClassMethods + def poise_subresource_container(namespace=nil, default=nil) + include Poise::Helpers::Subresources::Container + # false is a valid value. + container_namespace(namespace) unless namespace.nil? + container_default(default) unless default.nil? + end + + def poise_subresource(parent_type=nil, parent_optional=nil, parent_auto=nil) + include Poise::Helpers::Subresources::Child + parent_type(parent_type) if parent_type + parent_optional(parent_optional) unless parent_optional.nil? + parent_auto(parent_auto) unless parent_auto.nil? + end + + def poise_fused + include Poise::Helpers::Fused + end + + def poise_inversion(options_resource=nil) + include Poise::Helpers::Inversion + inversion_options_resource(true) unless options_resource == false + end + + def included(klass) + super + klass.extend(ClassMethods) + end + end + + extend ClassMethods + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/subcontext.rb b/cookbooks/poise/files/halite_gem/poise/subcontext.rb new file mode 100644 index 0000000..278d973 --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/subcontext.rb @@ -0,0 +1,27 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 Poise + # Helpers and whatnot for dealing with subcontexts. + # + # @api private + # @since 2.0.0 + module Subcontext + autoload :ResourceCollection, 'poise/subcontext/resource_collection' + autoload :Runner, 'poise/subcontext/runner' + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/subcontext/resource_collection.rb b/cookbooks/poise/files/halite_gem/poise/subcontext/resource_collection.rb new file mode 100644 index 0000000..cacd32c --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/subcontext/resource_collection.rb @@ -0,0 +1,75 @@ +# +# Copyright 2013-2016, Noah Kantrowitz +# +# 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' + + +module Poise + module Subcontext + # A subclass of the normal Chef ResourceCollection that creates a partially + # isolated set of resources. Notifications and other resources lookups can + # propagate out to parent contexts but not back in. This is used to allow + # black-box resources that are still aware of things in upper contexts. + # + # @api private + # @since 1.0.0 + class ResourceCollection < Chef::ResourceCollection + attr_accessor :parent + + def initialize(parent) + @parent = parent + super() + end + + def lookup(resource) + super + rescue Chef::Exceptions::ResourceNotFound + @parent.lookup(resource) + end + + # Iterate over all resources, expanding parent context in order. + # + # @param block [Proc] Iteration block + # @return [void] + def recursive_each(&block) + if @parent + if @parent.respond_to?(:recursive_each) + @parent.recursive_each(&block) + else + @parent.each(&block) + end + end + each(&block) + end + + # Iterate over all resources in reverse order. + # + # @since 2.3.0 + # @param block [Proc] Iteration block + # @return [void] + def reverse_recursive_each(&block) + reverse_each(&block) + if @parent + if @parent.respond_to?(:recursive_each) + @parent.reverse_recursive_each(&block) + else + @parent.reverse_each(&block) + end + end + end + end + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/subcontext/runner.rb b/cookbooks/poise/files/halite_gem/poise/subcontext/runner.rb new file mode 100644 index 0000000..aaa5e44 --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/subcontext/runner.rb @@ -0,0 +1,55 @@ +# +# Copyright 2013-2016, Noah Kantrowitz +# +# 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/runner' + + +module Poise + module Subcontext + # A subclass of the normal Chef Runner that migrates delayed notifications + # to the enclosing run_context instead of running them at the end of the + # subcontext convergence. + # + # @api private + # @since 1.0.0 + class Runner < Chef::Runner + def initialize(resource, *args) + super(*args) + @resource = resource + end + + def run_delayed_notifications(error=nil) + # If there is an error, just do the normal thing. The return shouldn't + # ever fire because the superclass re-raises if there is an error. + return super if error + delayed_actions.each do |notification| + if @resource.run_context.respond_to?(:add_delayed_action) + @resource.run_context.add_delayed_action(notification) + else + notifications = run_context.parent_run_context.delayed_notifications(@resource) + if notifications.any? { |existing_notification| existing_notification.duplicates?(notification) } + Chef::Log.info( "#{@resource} not queuing delayed action #{notification.action} on #{notification.resource}"\ + " (delayed), as it's already been queued") + else + notifications << notification + end + end + end + end + + end + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/utils.rb b/cookbooks/poise/files/halite_gem/poise/utils.rb new file mode 100644 index 0000000..9e05270 --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/utils.rb @@ -0,0 +1,181 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 'poise/error' + + +module Poise + module Utils + autoload :ResourceProviderMixin, 'poise/utils/resource_provider_mixin' + autoload :ShellOut, 'poise/utils/shell_out' + autoload :Win32, 'poise/utils/win32' + + extend self + + # Find the cookbook name for a given filename. The can used to find the + # cookbook that corresponds to a caller of a file. + # + # @param run_context [Chef::RunContext] Context to check. + # @param filename [String] Absolute filename to check for. + # @return [String] + # @example + # def my_thing + # caller_filename = caller.first.split(':').first + # cookbook = Poise::Utils.find_cookbook_name(run_context, caller_filename) + # # ... + # end + def find_cookbook_name(run_context, filename) + possibles = {} + Poise.debug("[Poise] Checking cookbook for #{filename.inspect}") + run_context.cookbook_collection.each do |name, ver| + # This special method is added by Halite::Gem#as_cookbook_version. + if ver.respond_to?(:halite_root) + # The join is there because ../poise-ruby/lib starts with ../poise so + # we want a trailing /. + if filename.start_with?(File.join(ver.halite_root, '')) + Poise.debug("[Poise] Found matching halite_root in #{name}: #{ver.halite_root.inspect}") + possibles[ver.halite_root] = name + end + else + Chef::CookbookVersion::COOKBOOK_SEGMENTS.each do |seg| + ver.segment_filenames(seg).each do |file| + if ::File::ALT_SEPARATOR + file = file.gsub(::File::ALT_SEPARATOR, ::File::SEPARATOR) + end + # Put this behind an environment variable because it is verbose + # even for normal debugging-level output. + Poise.debug("[Poise] Checking #{seg} in #{name}: #{file.inspect}") + if file == filename + Poise.debug("[Poise] Found matching #{seg} in #{name}: #{file.inspect}") + possibles[file] = name + end + end + end + end + end + raise Poise::Error.new("Unable to find cookbook for file #{filename.inspect}") if possibles.empty? + # Sort the items by matching path length, pick the name attached to the longest. + possibles.sort_by{|key, value| key.length }.last[1] + end + + # Try to find an ancestor to call a method on. + # + # @since 2.2.3 + # @since 2.3.0 + # Added ignore parameter. + # @param obj [Object] Self from the caller. + # @param msg [Symbol] Method to try to call. + # @param args [Array] Method arguments. + # @param default [Object] Default return value if no valid ancestor exists. + # @param ignore [Array] Return value to ignore when scanning ancesors. + # @return [Object] + # @example + # val = @val || Poise::Utils.ancestor_send(self, :val) + def ancestor_send(obj, msg, *args, default: nil, ignore: [default]) + # Class is a subclass of Module, if we get something else use its class. + obj = obj.class unless obj.is_a?(Module) + ancestors = [] + if obj.respond_to?(:superclass) + # Check the superclass first if present. + ancestors << obj.superclass + end + # Make sure we don't check obj itself. + ancestors.concat(obj.ancestors.drop(1)) + ancestors.each do |mod| + if mod.respond_to?(msg) + val = mod.send(msg, *args) + # If we get the default back, assume we should keep trying. + return val unless ignore.include?(val) + end + end + # Nothing valid found, use the default. + default + end + + # Create a helper to invoke a module with some parameters. + # + # @since 2.3.0 + # @param mod [Module] The module to wrap. + # @param block [Proc] The module to implement to parameterization. + # @return [void] + # @example + # module MyMixin + # def self.my_mixin_name(name) + # # ... + # end + # end + # + # Poise::Utils.parameterized_module(MyMixin) do |name| + # my_mixin_name(name) + # end + def parameterized_module(mod, &block) + raise Poise::Error.new("Cannot parameterize an anonymous module") unless mod.name && !mod.name.empty? + parent_name_parts = mod.name.split(/::/) + # Grab the last piece which will be the method name. + mod_name = parent_name_parts.pop + # Find the enclosing module or class object. + parent = parent_name_parts.inject(Object) {|memo, name| memo.const_get(name) } + # Object is a special case since we need #define_method instead. + method_type = if parent == Object + :define_method + else + :define_singleton_method + end + # Scoping hack. + self_ = self + # Construct the method. + parent.send(method_type, mod_name) do |*args| + self_.send(:check_block_arity!, block, args) + # Create a new anonymous module to be returned from the method. + Module.new do + # Fake the name. + define_singleton_method(:name) do + super() || mod.name + end + + # When the stub module gets included, activate our behaviors. + define_singleton_method(:included) do |klass| + super(klass) + klass.send(:include, mod) + klass.instance_exec(*args, &block) + end + end + end + end + + private + + # Check that the given arguments match the given block. This is needed + # because Ruby will nil-pad mismatched argspecs on blocks rather than error. + # + # @since 2.3.0 + # @param block [Proc] Block to check. + # @param args [Array] Arguments to check. + # @return [void] + def check_block_arity!(block, args) + # Convert the block to a lambda-style proc. You can't make this shit up. + obj = Object.new + obj.define_singleton_method(:block, &block) + block = obj.method(:block).to_proc + # Check + required_args = block.arity < 0 ? ~block.arity : block.arity + if args.length < required_args || (block.arity >= 0 && args.length > block.arity) + raise ArgumentError.new("wrong number of arguments (#{args.length} for #{required_args}#{block.arity < 0 ? '+' : ''})") + end + end + + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/utils/resource_provider_mixin.rb b/cookbooks/poise/files/halite_gem/poise/utils/resource_provider_mixin.rb new file mode 100644 index 0000000..fba69d4 --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/utils/resource_provider_mixin.rb @@ -0,0 +1,65 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 Poise + module Utils + # A mixin to dispatch other mixins with resource and provider + # implementations. The module this is included in must have Resource and + # Provider sub-modules. + # + # @since 2.0.0 + # @example + # module MyHelper + # include Poise::Utils::ResourceProviderMixin + # module Resource + # # ... + # end + # + # module Provider + # # ... + # end + # end + module ResourceProviderMixin + def self.included(klass) + # Warning here be dragons. + # Create a new anonymous module, klass will be the module that + # actually included ResourceProviderMixin. We want to keep a reference + # to that locked down so that we can close over it and use it in the + # "real" .included defined below to find the original relative consts. + mod = Module.new do + # Use define_method instead of def so we can close over klass and mod. + define_method(:included) do |inner_klass| + # Has to be explicit because super inside define_method. + super(inner_klass) + # Cargo this .included to things which include us. + inner_klass.extend(mod) + # Dispatch to submodules, inner_klass is the most recent includer. + if inner_klass < Chef::Resource || inner_klass.name.to_s.end_with?('::Resource') + # Use klass::Resource to look up relative to the original module. + inner_klass.class_exec { include klass::Resource } + elsif inner_klass < Chef::Provider || inner_klass.name.to_s.end_with?('::Provider') + # As above, klass::Provider. + inner_klass.class_exec { include klass::Provider } + end + end + end + # Add our .included to the original includer. + klass.extend(mod) + end + end + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/utils/shell_out.rb b/cookbooks/poise/files/halite_gem/poise/utils/shell_out.rb new file mode 100644 index 0000000..0231e14 --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/utils/shell_out.rb @@ -0,0 +1,90 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 'etc' + +require 'chef/mixin/shell_out' + + +module Poise + module Utils + # A mixin to provider a better shell_out. + # + # @since 2.5.0 + # @example + # Poise::Utils::ShellOut.poise_shell_out('ruby myapp.rb', user: 'myuser') + module ShellOut + extend self + include Chef::Mixin::ShellOut + + # An enhanced version of Chef's `shell_out` which sets some default + # parameters. If possible it will set $HOME, $USER, $LOGNAME, and the + # group to run as. + # + # @param command_args [Array] Command arguments to be passed to `shell_out`. + # @param options [Hash] Options to be passed to `shell_out`, + # with modifications. + # @return [Mixlib::ShellOut] + def poise_shell_out(*command_args, **options) + # Allow the env option shorthand. + options[:environment] ||= {} + if options[:env] + options[:environment].update(options[:env]) + options.delete(:env) + end + # Convert environment keys to strings to be safe. + options[:environment] = options[:environment].inject({}) do |memo, (key, value)| + memo[key.to_s] = value.to_s + memo + end + # Populate some standard environment variables. + ent = begin + if options[:user].is_a?(Integer) + Etc.getpwuid(options[:user]) + elsif options[:user] + Etc.getpwnam(options[:user]) + end + rescue ArgumentError + nil + end + username = ent ? ent.name : options[:name] + if username + options[:environment]['HOME'] ||= Dir.home(username) + options[:environment]['USER'] ||= username + # On the off chance they set one manually but not the other. + options[:environment]['LOGNAME'] ||= options[:environment]['USER'] + end + # Set the default group on Unix. + options[:group] ||= ent.gid if ent + # Mixlib-ShellOut doesn't support array commands on Windows and has + # super wonky escaping for cmd.exe. + if respond_to?(:node) && node.platform_family?('windows') + command_args = [Poise::Utils::Win32.reparse_command(*command_args)] + end + # Call Chef's shell_out wrapper. + shell_out(*command_args, **options) + end + + # The `error!` version of {#poise_shell_out}. + # + # @see #poise_shell_out + # @return [Mixlib::ShellOut] + def poise_shell_out!(*command_args) + poise_shell_out(*command_args).tap(&:error!) + end + end + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/utils/win32.rb b/cookbooks/poise/files/halite_gem/poise/utils/win32.rb new file mode 100644 index 0000000..0cc6f9d --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/utils/win32.rb @@ -0,0 +1,127 @@ +# +# Copyright 2016, Noah Kantrowitz +# +# 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' + + +module Poise + module Utils + # Utilities for working with Windows. + # + # @since 2.7.0 + module Win32 + extend self + + # Code borrowed from https://github.com/chef-cookbooks/chef-client/blob/master/libraries/helpers.rb + # Used under the terms of the Apache v2 license. + # Copyright 2012-2016, John Dewey + + # Run a WMI query and extracts a property. This assumes Chef has already + # loaded the win32 libraries. + # + # @api private + # @param wmi_property [Symbol] Property to extract. + # @param wmi_query [String] Query to run. + # @return [String] + def wmi_property_from_query(wmi_property, wmi_query) + @wmi = ::WIN32OLE.connect('winmgmts://') + result = @wmi.ExecQuery(wmi_query) + return nil unless result.each.count > 0 + result.each.next.send(wmi_property) + end + + # Find the name of the Administrator user, give or take localization. + # + # @return [String] + def admin_user + if defined?(::WIN32OLE) + wmi_property_from_query(:name, "select * from Win32_UserAccount where sid like 'S-1-5-21-%-500' and LocalAccount=True") + else + # Warn except under ChefSpec because it will just annoy people. + Chef::Log.warn('[Poise::Utils::Win32] Unable to query admin user, WIN32OLE not available') unless defined?(ChefSpec) + 'Administrator' + end + end + + # Escaping that is compatible with CommandLineToArgvW. Based on + # https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/everyone-quotes-command-line-arguments-the-wrong-way/ + # + # @api private + # @param string [String] String to escape. + # @return [String] + def argv_quote(string, force_quote: false) + if !force_quote && !string.empty? && string !~ /[ \t\n\v"]/ + # Nothing fancy, no escaping needed. + string + else + command_line = '"' + i = 0 + while true + number_backslashes = 0 + + while i != string.size && string[i] == '\\' + i += 1 + number_backslashes += 1 + end + + if i == string.size + # Escape all backslashes, but let the terminating + # double quotation mark we add below be interpreted + # as a metacharacter. + command_line << '\\' * (number_backslashes * 2) + break + elsif string[i] == '"' + # Escape all backslashes and the following + # double quotation mark. + command_line << '\\' * ((number_backslashes * 2) + 1) + command_line << '"' + else + # Backslashes aren't special here. + command_line << '\\' * number_backslashes + command_line << string[i] + end + i += 1 + end + command_line << '"' + command_line + end + end + + # Take a string or array command in the format used by shell_out et al and + # create something we can use on Windows. + # + # @ + def reparse_command(*args) + array_mode = !(args.length == 1 && args.first.is_a?(String)) + # At some point when mixlib-shellout groks array commands on Windows, + # we should support that here. + parsed_args = array_mode ? args.flatten : Shellwords.split(args.first) + cmd = parsed_args.map {|s| argv_quote(s) }.join(' ') + if array_mode + # This fails on non-Windows because of win32/process. + require 'mixlib/shellout/windows' + if Mixlib::ShellOut::Windows::Utils.should_run_under_cmd?(cmd) + # If we are in array mode, try to make cmd.exe keep its grubby paws + # off our metacharacters. + cmd = cmd.each_char.map {|c| '^'+c }.join('') + end + end + cmd + end + + end + end +end diff --git a/cookbooks/poise/files/halite_gem/poise/version.rb b/cookbooks/poise/files/halite_gem/poise/version.rb new file mode 100644 index 0000000..18c9006 --- /dev/null +++ b/cookbooks/poise/files/halite_gem/poise/version.rb @@ -0,0 +1,20 @@ +# +# Copyright 2013-2016, Noah Kantrowitz +# +# 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 Poise + VERSION = '2.7.2' +end diff --git a/cookbooks/poise/libraries/default.rb b/cookbooks/poise/libraries/default.rb new file mode 100644 index 0000000..9731909 --- /dev/null +++ b/cookbooks/poise/libraries/default.rb @@ -0,0 +1,18 @@ +# +# Copyright 2013-2016, Noah Kantrowitz +# +# 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. +# + +raise 'Halite is not compatible with no_lazy_load false, please set no_lazy_load true in your Chef configuration file.' unless Chef::Config[:no_lazy_load] +$LOAD_PATH << File.expand_path('../../files/halite_gem', __FILE__) diff --git a/cookbooks/poise/metadata.json b/cookbooks/poise/metadata.json new file mode 100644 index 0000000..5fb9bb6 --- /dev/null +++ b/cookbooks/poise/metadata.json @@ -0,0 +1 @@ +{"name":"poise","version":"2.7.2","description":"Helpers for writing extensible Chef cookbooks.","long_description":"# Poise\n\n[![Build Status](https://img.shields.io/travis/poise/poise.svg)](https://travis-ci.org/poise/poise)\n[![Gem Version](https://img.shields.io/gem/v/poise.svg)](https://rubygems.org/gems/poise)\n[![Cookbook Version](https://img.shields.io/cookbook/v/poise.svg)](https://supermarket.chef.io/cookbooks/poise)\n[![Coverage](https://img.shields.io/codecov/c/github/poise/poise.svg)](https://codecov.io/github/poise/poise)\n[![Gemnasium](https://img.shields.io/gemnasium/poise/poise.svg)](https://gemnasium.com/poise/poise)\n[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)\n\n## What is Poise?\n\nThe poise cookbook is a set of libraries for writing reusable cookbooks. It\nprovides helpers for common patterns and a standard structure to make it easier to create flexible cookbooks.\n\n## Writing your first resource\n\nRather than LWRPs, Poise promotes the idea of using normal, or \"heavy weight\"\nresources, while including helpers to reduce much of boilerplate needed for this. Each resource goes in its own file under `libraries/` named to match\nthe resource, which is in turn based on the class name. This means that the file `libraries/my_app.rb` would contain `Chef::Resource::MyApp` which maps to the resource `my_app`.\n\nAn example of a simple shell to start from:\n\n```ruby\nrequire 'poise'\nrequire 'chef/resource'\nrequire 'chef/provider'\n\nmodule MyApp\n class Resource < Chef::Resource\n include Poise\n provides(:my_app)\n actions(:enable)\n\n attribute(:path, kind_of: String)\n # Other attribute definitions.\n end\n\n class Provider < Chef::Provider\n include Poise\n provides(:my_app)\n\n def action_enable\n notifying_block do\n ... # Normal Chef recipe code goes here\n end\n end\n end\nend\n```\n\nStarting from the top, first we require the libraries we will be using. Then we\ncreate a module to hold our resource and provider. If your cookbook declares\nmultiple resources and/or providers, you might want additional nesting here.\nThen we declare the resource class, which inherits from `Chef::Resource`. This\nis similar to the `resources/` file in an LWRP, and a similar DSL can be used.\nWe then include the `Poise` mixin to load our helpers, and then call\n`provides(:my_app)` to tell Chef this class will implement the `my_app`\nresource. Then we use the familiar DSL, though with a few additions we'll cover\nlater.\n\nThen we declare the provider class, again similar to the `providers/` file in an\nLWRP. We include the `Poise` mixin again to get access to all the helpers and\ncall `provides()` to tell Chef what provider this is. Rather than use the\n`action :enable do ... end` DSL from LWRPs, we just define the action method\ndirectly. The implementation of action comes from a block of recipe code\nwrapped with `notifying_block` to capture changes in much the same way as\n`use_inline_resources`, see below for more information about all the features of\n`notifying_block`.\n\nWe can then use this resource like any other Chef resource:\n\n```ruby\nmy_app 'one' do\n path '/tmp'\nend\n```\n\n## Helpers\n\nWhile not exposed as a specific method, Poise will automatically set the\n`resource_name` based on the class name.\n\n### Notifying Block\n\nAs mentioned above, `notifying_block` is similar to `use_inline_resources` in LWRPs. Any Chef resource created inside the block will be converged in a sub-context and if any have updated it will trigger notifications on the current resource. Unlike `use_inline_resources`, resources inside the sub-context can still see resources outside of it, with lookups propagating up sub-contexts until a match is found. Also any delayed notifications are scheduled to run at the end of the main converge cycle, instead of the end of this inner converge.\n\nThis can be used to write action methods using the normal Chef recipe DSL, while still offering more flexibility through subclassing and other forms of code reuse.\n\n### Include Recipe\n\nIn keeping with `notifying_block` to implement action methods using the Chef DSL, Poise adds an `include_recipe` helper to match the method of the same name in recipes. This will load and converge the requested recipe.\n\n### Resource DSL\n\nTo make writing resource classes easier, Poise exposes a DSL similar to LWRPs for defining actions and attributes. Both `actions` and\n`default_action` are just like in LWRPs, though `default_action` is rarely needed as the first action becomes the default. `attribute` is also available just like in LWRPs, but with some enhancements noted below.\n\nOne notable difference over the standard DSL method is that Poise attributes\ncan take a block argument.\n\n#### Template Content\n\nA common pattern with resources is to allow passing either a template filename or raw file content to be used in a configuration file. Poise exposes a new attribute flag to help with this behavior:\n\n```ruby\nattribute(:name, template: true)\n```\n\nThis creates four methods on the class, `name_source`, `name_cookbook`,\n`name_content`, and `name_options`. If the name is set to `''`, no prefix is applied to the function names. The content method can be set directly, but if not set and source is set, then it will render the template and return it as a string. Default values can also be set for any of these:\n\n```ruby\nattribute(:name, template: true, default_source: 'app.cfg.erb',\n default_options: {host: 'localhost'})\n```\n\nAs an example, you can replace this:\n\n```ruby\nif new_resource.source\n template new_resource.path do\n source new_resource.source\n owner 'app'\n group 'app'\n variables new_resource.options\n end\nelse\n file new_resource.path do\n content new_resource.content\n owner 'app'\n group 'app'\n end\nend\n```\n\nwith simply:\n\n```ruby\nfile new_resource.path do\n content new_resource.content\n owner 'app'\n group 'app'\nend\n```\n\nAs the content method returns the rendered template as a string, this can also\nbe useful within other templates to build from partials.\n\n#### Lazy Initializers\n\nOne issue with Poise-style resources is that when the class definition is executed, Chef hasn't loaded very far so things like the node object are not\nyet available. This means setting defaults based on node attributes does not work directly:\n\n```ruby\nattribute(:path, default: node['myapp']['path'])\n...\nNameError: undefined local variable or method 'node'\n```\n\nTo work around this, Poise extends the idea of lazy initializers from Chef recipes to work with resource definitions as well:\n\n```ruby\nattribute(:path, default: lazy { node['myapp']['path'] })\n```\n\nThese initializers are run in the context of the resource object, allowing\ncomplex default logic to be moved to a method if desired:\n\n```ruby\nattribute(:path, default: lazy { my_default_path })\n\ndef my_default_path\n ...\nend\n```\n\n#### Option Collector\n\nAnother common pattern with resources is to need a set of key/value pairs for\nconfiguration data or options. This can done with a simple Hash, but an option collector attribute can offer a nicer syntax:\n\n```ruby\nattribute(:mydata, option_collector: true)\n...\n\nmy_app 'name' do\n mydata do\n key1 'value1'\n key2 'value2'\n end\nend\n```\n\nThis will be converted to `{key1: 'value1', key2: 'value2'}`. You can also pass a Hash to an option collector attribute just as you would with a normal attribute.\n\n## Debugging Poise\n\nPoise has its own extra-verbose level of debug logging that can be enabled in\nthree different ways. You can either set the environment variable `$POISE_DEBUG`,\nset a node attribute `node['POISE_DEBUG']`, or touch the file `/POISE_DEBUG`.\nYou will see a log message `Extra verbose logging enabled` at the start of the\nrun to confirm Poise debugging has been enabled. Make sure you also set Chef's\nlog level to `debug`, usually via `-l debug` on the command line.\n\n## Upgrading from Poise 1.x\n\nThe biggest change when upgrading from Poise 1.0 is that the mixin is no longer\nloaded automatically. You must add `require 'poise'` to your code is you want to\nload it, as you would with normal Ruby code outside of Chef. It is also highly\nrecommended to add `provides(:name)` calls to your resources and providers, this\nwill be required in Chef 13 and will display a deprecation warning if you do\nnot. This also means you can move your code out of the `Chef` module namespace\nand instead declare it in your own namespace. An example of this is shown above.\n\n## Sponsors\n\nThe Poise test server infrastructure is generously sponsored by [Rackspace](https://rackspace.com/). Thanks Rackspace!\n\n## License\n\nCopyright 2013-2016, Noah Kantrowitz\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","maintainer":"Noah Kantrowitz","maintainer_email":"noah@coderanger.net","license":"Apache 2.0","platforms":{},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{},"source_url":"https://github.com/poise/poise","issues_url":"https://github.com/poise/poise/issues","chef_version":"~> 12","ohai_version":{}} \ No newline at end of file diff --git a/cookbooks/postgresql/.foodcritic b/cookbooks/postgresql/.foodcritic new file mode 100644 index 0000000..41c5512 --- /dev/null +++ b/cookbooks/postgresql/.foodcritic @@ -0,0 +1,2 @@ +~FC037 +~FC016 diff --git a/cookbooks/postgresql/CHANGELOG.md b/cookbooks/postgresql/CHANGELOG.md index f794009..5c4f4fa 100644 --- a/cookbooks/postgresql/CHANGELOG.md +++ b/cookbooks/postgresql/CHANGELOG.md @@ -1,44 +1,197 @@ -postgresql Cookbook CHANGELOG -============================= +# postgresql Cookbook CHANGELOG + This file is used to list changes made in each version of the postgresql cookbook. -v4.0.0 ------ -* Potential breaking change: Restructured default attributes to avoid compile time deriving other attribute values from value of the `node[‘postgresql’][‘version’]` -(#313, #302, #295, #288, #280, #261, #260, #254, #248, #217, #214, #167, #143) -* Correct issues which caused the inability to override installation version defaults -* Correct issues which caused configuration file entries with miss matching version numbers and incorrect file system paths being defined -* Remove method pgdgrepo_rpm_info compile time use of derived attributes case many issues -* Use correct directory path and check for the correct not_if condition to determine if the database has been initialized -* Ensure that correct packages are installed in all scenarios where pg gem is compiled -* Fix errors in configuration files for unix_socket_directory and unix_socket_directories -* Updates to test-kitchen suite configuration -* Added more grey hair to my beard +## v6.1.1 (2017-03-08) -v3.4.24 -------- -* Corrections to address repositories signed with newer certificates that some distributions have in their default ca-certificates package -* Updates to more accurately determine distributions service init systems adds better support for systemd systems -* Correct how version attribute is evaluated in certain places -* test-kitchen suite configuration corrections -* Opensuse support +- Fix pg gem installation on non-omnibus chef runs +- Resolve resource cloning deprecation warnings in the ruby recipe +- Fix issues resolving the timezone on CentOS 7 and probably other distros +- Test with Delivery local instead of Rake + +## v6.1.0 (2017-02-18) + +- Fix a method name conflict that caused errors if Chef Sugar was also being used on the run list +- Revert a previous PR that added support for Postgresql 9.6 as it introduced incorrect configuration values +- Added Fedora 25 support for pgdg packages +- Added RHEL 5 support for Postgresql 9.4 pgdg packages +- Removed testing for RHEL 5 and Ubuntu 12.04 as they are scheduled for EoL in the near future +- Improvements to Test Kitchen testing to allow more extensive testing in Travis CI +- Fixed the client recipe on Fedora +- Added Inspec tests for client installs + +## v6.0.1 (2017-01-04 + +- Fix systemd unit file template + +## v6.0.0 (2017-01-03) + +- This cookbook now requires Chef 12.1 or later +- Removed the dependency on the apt cookbook as this functionality is built into modern chef client releases +- Added a new custom resource for installing extensions. This acts as a replacement for the contrib recipe with minimal backwards compatibility. You can now install / remove extensions into any database. This adds the compat_resource cookbook dependency so we can continue to support Chef 12.1-12.4, which lack custom resource support. +- The unused get_result_orig helper has been removed. If you utilized this you'll want to move it to your own wrapper cookbook +- Updates for compatibility with Postgresql 9.5 and 9.6 +- Fixed client package installation on openSUSE Leap 42.2 +- ca-certificates recipe has been deprecated. If ca-certificates package needs to be upgraded the user should do so prior to including this recipe. Package upgrades in community cookbooks are generally a bad idea as this bring in updated packages to production systems. The recipe currently warns if used and will be removed with the next major cookbook release. +- Fixed RHEL platform detection in the Ruby recipe +- systemd fixes for RHEL systems +- Fix systemd service file include when using pgdg packages +- Package installation now uses multi-package installs to speed up converge times +- Added integration testing in Travis of the client recipe using a new test cookbook. This will be expanded in the future to cover server installation as well +- Expanded the specs to test converges on multiple platforms + +## v5.2.0 (2016-12-30) + +- Updated contacts and links to point to Sous Chefs now +- Added a Code of Conduct (the Chef CoC) +- Removed duplicate platforms in the metadata +- Fix Chef runs with local mode in the server recipe +- Fix the ruby recipe to not fail when you specify enabling both the apt and yum repos for mixed distro environments +- Set the postgresql data directory to 700 permissions +- Added node['postgresql']['pg_gem']['version'] to specify the version of the pg gem to install +- Cookstyle fixes for the latest cookstyle release +- Removed test deps from the Gemfile. Rely on ChefDK for base testing deps instead + +## v5.1.0 (2016-11-01) + +- Maintenance of this cookbook has been migrated from Heavy Water to Sous Chefs - +- Add support for Chef-Zero (local mode) +- Don't hardcode the UID / GID on RHEL/Amazon/Suse platforms +- Add PGDG yum RPMs for 9.5 / 9.6 + +## v5.0.0 (2016-10-25) + +### Breaking changes + +- Switched from Librarian to Berkshelf +- Remove support for the following platforms + + - SLES < 12 + - openSUSE < 13 + - Debian < 7 + - Ubuntu < 12.04 + - RHEL < 6 + - Amazon < 2013 + - Unsupported (EOL) Fedora releases + +### Other changes + +- Added support for Ubuntu 16.04 +- Loosened cookbook dependencies to not prevent pulling in the latest community cookbooks +- Added chef_version metadata +- Switched from rubocop to cookstyle and fix all warnings +- Removed minitests and the minitest handler +- Added support for opensuse / opensuseleap +- Added support for Fedora 23/24 +- Added a chefignore file to limit the files uploaded to the chef server +- Updated Test Kitchen config to test on modern platform releases +- Added a Rakefile and updated Travis to test with ChefDK and that rakefile +- Avoid installing packages included in build-essential twice in the ruby recipe +- Require at least build-essential 2.0 +- Don't cleanup the old PPA files in the apt_pgdg_postgresql recipe anymore. These should be long gone everywhere +- Remove logic in the apt_pgdg_postgresql recipe that made Chef fail when new distro releases came out +- Avoid node.set deprecation warnings +- Avoid managed_home deprecation warnings in server_redhat recipe + +## v4.0.6 + +- Add 16.04 Xenial to the allowed list + +## v4.0.4 + +- Add leading pound symbol on pg_hba.conf template comment line +- Update gem install for compile_time to correct deprication warning +- Add support Ubuntu Wily Werewolf pgdg apt repository +- test-kitchen platforms for Centos 7.2 and Ubuntu 15.04 +- Fixes PostgreSQL version & package name defaults for EL7 distros +- Add appropriate systemd unit file overrides for EL7 distros + +## v4.0.2 + +- Add Code of Conduct +- Add Rubocop +- Clean up of syntax in many places as result of adding and evaluating Rubocop +- Updates to test-kitchen.yml +- added additional attribute for people who are importing pgdg packages for internal repositories + + - `default['postgresql']['use_pgdg_packages'] = false` + +## v4.0.0 + +**WARNING: Please read carefully through the stated changes, as they probably will break your current setup and can result in duplicate postgresql versions being installed, configuration corruption and data loss! This list might not be complete, so be careful when using the 4.x version and make sure to test it extensively before production use!** + +When in doubt, put the following in your `Berksfile` until you are ready to upgrade: + +```ruby +cookbook 'postgresql', '~> 3.4.0' +``` + +- Potential breaking change: Restructured default attributes to avoid compile time deriving other attribute values from value of the `node[‘postgresql’][‘version’]` (#313, #302, #295, #288, #280, #261, #260, #254, #248, #217, #214, #167, #143). If you specify a custom postgresql version, make sure to adapt the following attributes as well: + +```ruby +default['postgresql']['dir'] = "/etc/postgresql/#{node['postgresql']['version']}/main" +default['postgresql']['client']['packages'] = [ "postgresql-client-#{node['postgresql']['version']}", 'libpq-dev' ] +default['postgresql']['server']['packages'] = [ "postgresql-#{node['postgresql']['version']}" ] +default['postgresql']['contrib']['packages'] = [ "postgresql-contrib-#{node['postgresql']['version']}" ] +``` + +- Potential breaking change: SSL configuration parameters. Due to the new structuring, make sure you set all SSL attributes to `override` when specifying them in a cookbook: + +```ruby +override['postgresql']['config']['ssl'] = true +override['postgresql']['config']['ssl_cert_file'] = "/path/to/cert.crt" +override['postgresql']['config']['ssl_key_file'] = "/path/to/cert.key" +override['postgresql']['config']['ssl_ciphers'] = "" +``` + +- Potential breaking change: Some node attributes are now persistet in your node configuration. This affects the following attributes: + +```json +"config": { + "data_directory": "/var/lib/postgresql/9.4/main", + "hba_file": "/etc/postgresql/9.4/main/pg_hba.conf", + "ident_file": "/etc/postgresql/9.4/main/pg_ident.conf", + "external_pid_file": "/var/run/postgresql/9.4-main.pid", + "unix_socket_directories": "/var/run/postgresql", + "ssl_cert_file": "/etc/ssl/certs/ssl-cert-snakeoil.pem", + "ssl_key_file": "/etc/ssl/private/ssl-cert-snakeoil.key" +} +``` + +- Potential breaking change: Parsing of attributes from node/ environment configuration. It has been reported that setting the `node['postgresql']['client']['packages']` attribute in a cookbook might result in the default version of the postgresql client package being installed alongside the required version. This might affect the server packages as well. +- Correct issues which caused the inability to override installation version defaults +- Correct issues which caused configuration file entries with miss matching version numbers and incorrect file system paths being defined +- Remove method pgdgrepo_rpm_info compile time use of derived attributes case many issues +- Use correct directory path and check for the correct not_if condition to determine if the database has been initialized +- Ensure that correct packages are installed in all scenarios where pg gem is compiled +- Fix errors in configuration files for unix_socket_directory and unix_socket_directories +- Updates to test-kitchen suite configuration +- Added more grey hair to my beard + +## v3.4.24 + +- Corrections to address repositories signed with newer certificates that some distributions have in their default ca-certificates package +- Updates to more accurately determine distributions service init systems adds better support for systemd systems +- Correct how version attribute is evaluated in certain places +- test-kitchen suite configuration corrections +- Opensuse support + +## v3.4.23 -v3.4.23 -------- - Skipping 3.4.22 with Develop branch 3.4.23 to return to releasing cookbook from master on even numbers and develop on odd numbers. -v3.4.21 -------- +## v3.4.21 + - Use more optimistic openssl version constraint - Add Postgresql 9.4 package sources for RHEL platforms - Update testing infrastructure to address bit rot -v3.4.20 -------- -- Revert [#251](https://github.com/hw-cookbooks/postgresql/pull/251), a change which caused the postgresql service to restart every Chef run. +## v3.4.20 + +- Revert [#251](https://github.com/sous-chefs/postgresql/pull/251), a change which caused the postgresql service to restart every Chef run. + +## v3.4.19 -v3.4.19 -------- - node.save could better not be run on every chef run since it causes node.default attributes stored to the node objects to differ during a chef run and when - Missing attribute in docs for yum_pgdg_postgresql - restart postgres service immediately on config change @@ -50,46 +203,46 @@ v3.4.19 - add amazon 2015 - add rhel7 support -v3.4.18 ------- +## v3.4.18 + - Revert changes from #201 with the intention of revisiting these changes as part of the next major version release. - Specify version constraint on openssl cookbook due to an upstream release mishap -v3.4.16 ------- +## v3.4.16 + - Changed hard coded value to attribute #219 - Correction for directory creation under debian, etc. #222 - Fedora 20 yum support #223 - Define version-sensitive attributes in a recipe #201 -v3.4.14 ------- +## v3.4.14 + - Support apt repository for Ubuntu Utopic 14.10 - Do not try and set password on standby hosts -v3.4.12 ------- +## v3.4.12 + - Create configuration templates at the appropriate time - If template is updated restart service changed to default of :delayed - Fix SSL for PostgreSQL versions < 9.2 -v3.4.10 -------- +## v3.4.10 + - correct conditional error created in 3.4.8. -v3.4.8 ------- +## v3.4.8 + - Correct scenario where work_mem could be set to 0 if con is greater than mem Issue #185 - Add Centos7 suites to kitchen configuration -v3.4.6 ------- +## v3.4.6 + - Don't include the pgdg recipes on the wrong machine types - Add missing dir /etc/sysconfig/pgsl for centos7 - CentOS 7 package support -v3.4.4 ------- +## v3.4.4 + - fix packages on SLES11SP2 and higher - [COOK-4737] Add flag to control database user password behavior - add amazon platform rpm info @@ -97,117 +250,117 @@ v3.4.4 - attribute typo correction - correctly check and set max_connections to an integer -v3.4.2 ------- +## v3.4.2 + - Changed the Gem::Installer::ExtensionBuildError to a Mixlib::ShellOut::ShellCommandFailed -v3.4.1 ------- +## v3.4.1 + - Added support for Ubuntu 14.04 and Postgresql 9.3 -- Fix [COOK-3490] https://tickets.opscode.com/browse/COOK-3490 +- Fix [COOK-3490] -v3.4.0 ------- -Updated CONTRIBUTING document. -Refreshed test kitchen configuration. -Merged Pull Requests: 122, 116, 104, 102, 99, 96, 93, 90. +## v3.4.0 + +Updated CONTRIBUTING document. Refreshed test kitchen configuration. Merged Pull Requests: 122, 116, 104, 102, 99, 96, 93, 90. + +## v3.3.4 -v3.3.4 ------- Testing +## v3.3.2 -v3.3.2 ------- - Testing maintainer transfer to Heavywater with Opscode as collaborator +## v3.3.0 -v3.3.0 ------- ### Bug + - **[COOK-3851](https://tickets.opscode.com/browse/COOK-3851)** - Postgresql: reload after config change does not pick up certain configuration changes - **[COOK-3611](https://tickets.opscode.com/browse/COOK-3611)** - unix_socket_directory does not exists in 9.3 - **[COOK-2954](https://tickets.opscode.com/browse/COOK-2954)** - PostgreSQL installation ignores version attribute on CentOS >= 6 +## v3.2.0 -v3.2.0 ------- - [COOK-3717] Pgdg repositories improvements - [COOK-3756] Change postgresql.conf mode from 0600 to 0644 +## v3.1.0 -v3.1.0 ------- ### Improvement + - **[COOK-3685](https://tickets.opscode.com/browse/COOK-3685)** - Upgrade Repo Attributes for Postgresql 9.3 - **[COOK-3597](https://tickets.opscode.com/browse/COOK-3597)** - Fix implementation of `initdb_locale` attribute for RHEL - **[COOK-3566](https://tickets.opscode.com/browse/COOK-3566)** - Give the user's rules more priority than the default ones in pg_hba - **[COOK-3553](https://tickets.opscode.com/browse/COOK-3553)** - Remove automatic `apt-get update` ### Bug + - **[COOK-3611](https://tickets.opscode.com/browse/COOK-3611)** - Remove `unix_socket_directory` (it does not exists in 9.3) - **[COOK-3599](https://tickets.opscode.com/browse/COOK-3599)** - Automatically add PGDG apt repo dependency on PostgreSQL version - **[COOK-3555](https://tickets.opscode.com/browse/COOK-3555)** - Documentation Fix - **[COOK-2383](https://tickets.opscode.com/browse/COOK-2383)** - Update Postgres version in attributes +## v3.0.4 -v3.0.4 ------- ### Bug + - **[COOK-3173](https://tickets.opscode.com/browse/COOK-3173)** - Use :reload instead of :restart on conf changes - **[COOK-2939](https://tickets.opscode.com/browse/COOK-2939)** - Fix RedHat support -v3.0.2 ------- +## v3.0.2 + ### Bug + - [COOK-3076]: postgresql::ruby recipe error when using pgdg repositories -v3.0.0 ------- +## v3.0.0 + This is a backwards-incompatible release because the Pitti PPA is deprecated and the recipe removed, replaced with the PGDG apt repository. ### Bug + - [COOK-2571]: Create helper library for pg extension detection - [COOK-2797]: Contrib extension contianing '-' fails to load. ### Improvement + - [COOK-2387]: Pitti Postgresql PPA is deprecated ### Task + - [COOK-3022]: update baseboxes in .kitchen.yml -v2.4.0 ------- +## v2.4.0 + - [COOK-2163] - Dangerous "assign-postgres-password" in "recipes/server.rb" -- Can lock out dbadmin access - [COOK-2390] - Recipes to auto-generate many postgresql.conf settings, following "initdb" and "pgtune" - [COOK-2435] - Foodcritic fixes for postgresql cookbook - [COOK-2476] - Installation into database of any contrib module extensions listed in a node attribute -v2.2.2 ------- -- [COOK-2232] -Provide PGDG yum repo to install postgresql 9.x on - redhat-derived distributions +## v2.2.2 + +- [COOK-2232] -Provide PGDG yum repo to install postgresql 9.x on redhat-derived distributions + +## v2.2.0 -v2.2.0 ------- - [COOK-2230] - Careful about Debian minor version numbers - [COOK-2231] - Fix support for postgresql 9.x in server_redhat recipe - [COOK-2238] - Postgresql recipe error in password check - [COOK-2176] - PostgreSQL cookbook in Solo mode can cause "NoMethodError: undefined method `[]' for nil:NilClass" - [COOK-2233] - Provide postgresql::contrib recipe to install useful server administration tools -v2.1.0 ------- +## v2.1.0 + - [COOK-1872] - Allow latest PostgreSQL deb packages to be installed - [COOK-1961] - Postgresql config file changes with every Chef run - [COOK-2041] - Postgres cookbook no longer installs on OpenSuSE 11.4 -v2.0.2 ------- +## v2.0.2 + - [COOK-1406] - pg gem compile is unable to find libpq under Chef full stack (omnibus) installation -v2.0.0 ------- +## v2.0.0 + This version is backwards incompatible with previous versions of the cookbook due to use of `platform_family`, and the refactored configuration files using node attributes. See README.md for details on how to modify configuration of PostgreSQL. - [COOK-1508] - fix mixlib shellout error on SUSE @@ -215,11 +368,10 @@ This version is backwards incompatible with previous versions of the cookbook du - [COOK-1779] - Don't run apt-get update and others in ruby recipe if pg is installed - [COOK-1871] - Attribute driven configuration files for PostgreSQL - [COOK-1900] - don't assume ssl on all postgresql 8.4+ installs -- [COOK-1901] - fail a chef-solo run when the postgres password - attribute is not set +- [COOK-1901] - fail a chef-solo run when the postgres password attribute is not set + +## v1.0.0 -v1.0.0 ------- **Important note for this release** This version no longer installs Ruby bindings in the client recipe by default. Use the ruby recipe if you'd like the RubyGem. If you'd like packages for your distribution, use them in your application's specific cookbook/recipe, or modify the client packages attribute. @@ -235,17 +387,17 @@ The following issues are also resolved with this release. - [COOK-1224] - fix undefined variable on Debian - [COOK-1462] - Add attribute for specifying listen address -v0.99.4 ------- +## v0.99.4 + - [COOK-421] - config template is malformed - [COOK-956] - add make package on ubuntu/debian -v0.99.2 ------- +## v0.99.2 + - [COOK-916] - use < (with float) for version comparison. -v0.99.0 ------- +## v0.99.0 + - Better support for Red Hat-family platforms - Integration with database cookbook - Make sure the postgres role is updated with a (secure) password diff --git a/cookbooks/postgresql/CONTRIBUTING.md b/cookbooks/postgresql/CONTRIBUTING.md new file mode 100644 index 0000000..ae6f6df --- /dev/null +++ b/cookbooks/postgresql/CONTRIBUTING.md @@ -0,0 +1,22 @@ +# Contributing + +## Branches + +### `master` branch + +The master branch is the current comitted changes. These changes may not yet be released although we try to release often. + +## Tags + +All releases are tagged in git. To see the releases available to you see the changelog or the tags directly. + + +## Pull requests + +- + +## Issues + +Need to report an issue? Use the github issues: + +- diff --git a/cookbooks/postgresql/README.md b/cookbooks/postgresql/README.md index 847ff32..061a9b0 100644 --- a/cookbooks/postgresql/README.md +++ b/cookbooks/postgresql/README.md @@ -1,443 +1,275 @@ -Description -=========== +# postgresql cookbook + +[![Build Status](https://travis-ci.org/sous-chefs/postgresql.svg?branch=master)](https://travis-ci.org/sous-chefs/postgresql) [![Cookbook Version](https://img.shields.io/cookbook/v/postgresql.svg)](https://supermarket.chef.io/cookbooks/postgresql) Installs and configures PostgreSQL as a client or a server. -Requirements -============ +## Requirements -## Platforms +### Platforms -* Debian, Ubuntu -* Red Hat/CentOS/Scientific (6.0+ required) - "EL6-family" -* Fedora -* SUSE +- Debian 7+ +- Ubuntu 12.04+ +- Red Hat/CentOS/Scientific (6.0+ required) - "EL6-family" +- Fedora +- SLES 12+ +- openSUSE 13+ / openSUSE Leap -Tested on: +### Chef -* Ubuntu 12.04, 14.04, 14.10 -* Red Hat 6.1, Scientific 6.1, CentOS 6.3, 7.0, OpenSuse +- Chef 12.1+ -## Cookbooks +### Cookbooks -Requires Opscode's `openssl` cookbook for secure password generation. +- `compat_resource` +- `openssl` +- `build-essential` -Requires a C compiler and development headers in order to build the -`pg` RubyGem to provide Ruby bindings in the `ruby` recipe. +## Attributes -Opscode's `build-essential` cookbook provides this functionality on -Debian, Ubuntu, and EL6-family. +The following attributes are set based on the platform, see the `attributes/default.rb` file for default values. -While not required, Opscode's `database` cookbook contains resources -and providers that can interact with a PostgreSQL database. This -cookbook is a dependency of database. +- `node['postgresql']['version']` - version of postgresql to manage +- `node['postgresql']['dir']` - home directory of where postgresql data and configuration lives. +- `node['postgresql']['client']['packages']` - An array of package names that should be installed on "client" systems. +- `node['postgresql']['server']['packages']` - An array of package names that should be installed on "server" systems. +- `node['postgresql']['server']['config_change_notify']` - Type of notification triggered when a config file changes. +- `node['postgresql']['contrib']['packages']` - An array of package names that could be installed on "server" systems for useful sysadmin tools. +- `node['postgresql']['enable_pgdg_apt']` - Whether to enable the apt repo by the PostgreSQL Global Development Group, which contains newer versions of PostgreSQL. +- `node['postgresql']['enable_pgdg_yum']` - Whether to enable the yum repo by the PostgreSQL Global Development Group, which contains newer versions of PostgreSQL. +- `node['postgresql']['initdb_locale']` - Sets the default locale for the database cluster. If this attribute is not specified, the locale is inherited from the environment that initdb runs in. Sometimes you must have a system locale that is not what you want for your database cluster, and this attribute addresses that scenario. Valid only for EL-family distros (RedHat/Centos/etc.). -Attributes -========== +The following attributes are generated in `recipe[postgresql::server]`. -The following attributes are set based on the platform, see the -`attributes/default.rb` file for default values. +## Configuration -* `node['postgresql']['version']` - version of postgresql to manage -* `node['postgresql']['dir']` - home directory of where postgresql - data and configuration lives. +The `postgresql.conf` and `pg_hba.conf` files are dynamically generated from attributes. Each key in `node['postgresql']['config']` is a postgresql configuration directive, and will be rendered in the config file. For example, the attribute: -* `node['postgresql']['client']['packages']` - An array of package names - that should be installed on "client" systems. -* `node['postgresql']['server']['packages']` - An array of package names - that should be installed on "server" systems. -* `node['postgresql']['server']['config_change_notify']` - Type of - notification triggered when a config file changes. -* `node['postgresql']['contrib']['packages']` - An array of package names - that could be installed on "server" systems for useful sysadmin tools. - -* `node['postgresql']['enable_pgdg_apt']` - Whether to enable the apt repo - by the PostgreSQL Global Development Group, which contains newer versions - of PostgreSQL. - -* `node['postgresql']['enable_pgdg_yum']` - Whether to enable the yum repo - by the PostgreSQL Global Development Group, which contains newer versions - of PostgreSQL. - -* `node['postgresql']['initdb_locale']` - Sets the default locale for the - database cluster. If this attribute is not specified, the locale is - inherited from the environment that initdb runs in. Sometimes you must - have a system locale that is not what you want for your database cluster, - and this attribute addresses that scenario. Valid only for EL-family - distros (RedHat/Centos/etc.). - -The following attributes are generated in -`recipe[postgresql::server]`. - -Configuration -------------- - -The `postgresql.conf` and `pg_hba.conf` files are dynamically -generated from attributes. Each key in `node['postgresql']['config']` -is a postgresql configuration directive, and will be rendered in the -config file. For example, the attribute: - - node['postgresql']['config']['listen_addresses'] = 'localhost' +```ruby +node['postgresql']['config']['listen_addresses'] = 'localhost' +``` Will result in the following line in the `postgresql.conf` file: - listen_addresses = 'localhost' +```ruby +listen_addresses = 'localhost' +``` -The attributes file contains default values for Debian and RHEL -platform families (per the `node['platform_family']`). These defaults -have disparity between the platforms because they were originally -extracted from the postgresql.conf files in the previous version of -this cookbook, which differed in their default config. The resulting -configuration files will be the same as before, but the content will -be dynamically rendered from the attributes. The helpful commentary -will no longer be present. You should consult the PostgreSQL -documentation for specific configuration details. +The attributes file contains default values for Debian and RHEL platform families (per the `node['platform_family']`). These defaults have disparity between the platforms because they were originally extracted from the postgresql.conf files in the previous version of this cookbook, which differed in their default config. The resulting configuration files will be the same as before, but the content will be dynamically rendered from the attributes. The helpful commentary will no longer be present. You should consult the PostgreSQL documentation for specific configuration details. -See __Recipes__ `config_initdb` and `config_pgtune` below to -auto-generate many postgresql.conf settings. +See **Recipes** `config_initdb` and `config_pgtune` below to auto-generate many postgresql.conf settings. -For values that are "on" or "off", they should be specified as literal -`true` or `false`. String values will be used with single quotes. Any -configuration option set to the literal `nil` will be skipped -entirely. All other values (e.g., numeric literals) will be used as -is. So for example: +For values that are "on" or "off", they should be specified as literal `true` or `false`. String values will be used with single quotes. Any configuration option set to the literal `nil` will be skipped entirely. All other values (e.g., numeric literals) will be used as is. So for example: - node.default['postgresql']['config']['logging_collector'] = true - node.default['postgresql']['config']['datestyle'] = 'iso, mdy' - node.default['postgresql']['config']['ident_file'] = nil - node.default['postgresql']['config']['port'] = 5432 +```ruby +node.default['postgresql']['config']['logging_collector'] = true +node.default['postgresql']['config']['datestyle'] = 'iso, mdy' +node.default['postgresql']['config']['ident_file'] = nil +node.default['postgresql']['config']['port'] = 5432 +``` Will result in the following config lines: - logging_collector = 'on' - datestyle = 'iso,mdy' - port = 5432 +```ruby +logging_collector = 'on' +datestyle = 'iso,mdy' +port = 5432 +``` (no line printed for `ident_file` as it is `nil`) -Note that the `unix_socket_directory` configuration was renamed to -`unix_socket_directories` in Postgres 9.3 so make sure to use the -`node['postgresql']['unix_socket_directories']` attribute instead of -`node['postgresql']['unix_socket_directory']`. +Note that the `unix_socket_directory` configuration was renamed to `unix_socket_directories` in Postgres 9.3 so make sure to use the `node['postgresql']['unix_socket_directories']` attribute instead of `node['postgresql']['unix_socket_directory']`. -The `pg_hba.conf` file is dynamically generated from the -`node['postgresql']['pg_hba']` attribute. This attribute must be an -array of hashes, each hash containing the authorization data. As it is -an array, you can append to it in your own recipes. The hash keys in -the array must be symbols. Each hash will be written as a line in -`pg_hba.conf`. For example, this entry from -`node['postgresql']['pg_hba']`: +The `pg_hba.conf` file is dynamically generated from the `node['postgresql']['pg_hba']` attribute. This attribute must be an array of hashes, each hash containing the authorization data. As it is an array, you can append to it in your own recipes. The hash keys in the array must be symbols. Each hash will be written as a line in `pg_hba.conf`. For example, this entry from `node['postgresql']['pg_hba']`: - [{:comment => '# Optional comment', - :type => 'local', :db => 'all', :user => 'postgres', :addr => nil, :method => 'md5'}] +``` +[{:comment => '# Optional comment', +:type => 'local', :db => 'all', :user => 'postgres', :addr => nil, :method => 'md5'}] +``` Will result in the following line in `pg_hba.conf`: - # Optional comment - local all postgres md5 +``` +# Optional comment +local all postgres md5 +``` -Use `nil` if the CIDR-ADDRESS should be empty (as above). -Don't provide a comment if none is desired in the `pg_hba.conf` file. +Use `nil` if the CIDR-ADDRESS should be empty (as above). Don't provide a comment if none is desired in the `pg_hba.conf` file. -Note that the following authorization rule is supplied automatically by -the cookbook template. The cookbook needs this to execute SQL in the -PostgreSQL server without supplying the clear-text password (which isn't -known by the cookbook). Therefore, your `node['postgresql']['pg_hba']` -attributes don't need to specify this authorization rule: +Note that the following authorization rule is supplied automatically by the cookbook template. The cookbook needs this to execute SQL in the PostgreSQL server without supplying the clear-text password (which isn't known by the cookbook). Therefore, your `node['postgresql']['pg_hba']` attributes don't need to specify this authorization rule: - # "local" is for Unix domain socket connections only - local all all ident +``` +# "local" is for Unix domain socket connections only +local all all ident +``` -(By the way, the template uses `peer` instead of `ident` for PostgreSQL-9.1 -and above, which has the same effect.) +(By the way, the template uses `peer` instead of `ident` for PostgreSQL-9.1 and above, which has the same effect.) -Recipes -======= +## Recipes -default -------- +### default Includes the client recipe. -client ------- +### client -Installs the packages defined in the -`node['postgresql']['client']['packages']` attribute. +Installs the packages defined in the `node['postgresql']['client']['packages']` attribute. -ruby ----- +### ruby -Install the `pg` gem under Chef's Ruby environment so it can be used -in other recipes. The build-essential packages and postgresql client -packages will be installed during the compile phase, so that the -native extensions of `pg` can be compiled. +Install the `pg` gem under Chef's Ruby environment so it can be used in other recipes. The build-essential packages and postgresql client packages will be installed during the compile phase, so that the native extensions of `pg` can be compiled. -server ------- +### server -Includes the `server_debian` or `server_redhat` recipe to get the -appropriate server packages installed and service managed. Also -manages the configuration for the server: +Includes the `server_debian` or `server_redhat` recipe to get the appropriate server packages installed and service managed. Also manages the configuration for the server: -* generates a strong default password (via `openssl`) for `postgres` -* sets the password for postgres -* manages the `postgresql.conf` file. -* manages the `pg_hba.conf` file. +- generates a strong default password (via `openssl`) for `postgres` +- sets the password for postgres +- manages the `postgresql.conf` file. +- manages the `pg_hba.conf` file. -server\_debian --------------- +### config_initdb -Installs the postgresql server packages and sets up the service. You -should include the `postgresql::server` recipe, which will include -this on Debian platforms. +Takes locale and timezone settings from the system configuration. This recipe creates `node.default['postgresql']['config']` attributes that conform to the system's locale and timezone. In addition, this recipe creates the same error reporting and logging settings that `initdb` provided: a rotation of 7 days of log files named postgresql-Mon.log, etc. -server\_redhat --------------- +The default attributes created by this recipe are easy to override with normal attributes because of Chef attribute precedence. For example, suppose a DBA wanted to keep log files indefinitely, rolling over daily or when growing to 10MB. The Chef installation could include the `postgresql::config_initdb` recipe for the locale and timezone settings, but customize the logging settings with these node JSON attributes: -Manages the postgres user and group (with UID/GID 26, per RHEL package -conventions), installs the postgresql server packages, initializes the -database, and manages the postgresql service. You should include the -`postgresql::server` recipe, which will include this on RHEL/Fedora -platforms. +```javascript +"postgresql": { + "config": { + "log_rotation_age": "1d", + "log_rotation_size": "10MB", + "log_filename": "postgresql-%Y-%m-%d_%H%M%S.log" + } +} +``` -config\_initdb --------------- +Credits: This `postgresql::config_initdb` recipe is based on algorithms in the [source code](http://doxygen.postgresql.org/initdb_8c_source.html) for the PostgreSQL `initdb` utility. -Takes locale and timezone settings from the system configuration. -This recipe creates `node.default['postgresql']['config']` attributes -that conform to the system's locale and timezone. In addition, this -recipe creates the same error reporting and logging settings that -`initdb` provided: a rotation of 7 days of log files named -postgresql-Mon.log, etc. +### config_pgtune -The default attributes created by this recipe are easy to override with -normal attributes because of Chef attribute precedence. For example, -suppose a DBA wanted to keep log files indefinitely, rolling over daily -or when growing to 10MB. The Chef installation could include the -`postgresql::config_initdb` recipe for the locale and timezone settings, -but customize the logging settings with these node JSON attributes: +Performance tuning. Takes the wimpy default postgresql.conf and expands the database server to be as powerful as the hardware it's being deployed on. This recipe creates a baseline configuration of `node.default['postgresql']['config']` attributes in the right general range for a dedicated Postgresql system. Most installations won't need additional performance tuning. - "postgresql": { - "config": { - "log_rotation_age": "1d", - "log_rotation_size": "10MB", - "log_filename": "postgresql-%Y-%m-%d_%H%M%S.log" - } +The only decision you need to make is to choose a `db_type` from the following database workloads. (See the recipe code comments for more detailed descriptions.) + +- "dw" -- Data Warehouse +- "oltp" -- Online Transaction Processing +- "web" -- Web Application +- "mixed" -- Mixed DW and OLTP characteristics +- "desktop" -- Not a dedicated database + +This recipe uses a performance model with three input parameters. These node attributes are completely optional, but it is obviously important to choose the `db_type` correctly: + +- `node['postgresql']['config_pgtune']['db_type']` -- Specifies database type from the list of five choices above. If not specified, the default is "mixed". + +- `node['postgresql']['config_pgtune']['max_connections']` -- Specifies maximum number of connections expected. If not specified, it depends on database type: "web":200, "oltp":300, "dw":20, "mixed":80, "desktop":5 + +- `node['postgresql']['config_pgtune']['total_memory']` -- Specifies total system memory in kB. (E.g., "49416564kB".) If not specified, it will be taken from Ohai automatic attributes. This could be used to tune a system that isn't a dedicated database. + +The default attributes created by this recipe are easy to override with normal attributes because of Chef attribute precedence. For example, if you are running application benchmarks to try different buffer cache sizes, you would experiment with this node JSON attribute: + +```javascript +"postgresql": { + "config": { + "shared_buffers": "3GB" + } +} +``` + +Note that the recipe uses `max_connections` in its computations. If you want to override that setting, you should specify `node['postgresql']['config_pgtune']['max_connections']` instead of `node['postgresql']['config']['max_connections']`. + +Credits: This `postgresql::config_pgtune` recipe is based on the [pgtune python script](https://github.com/gregs1104/pgtune) developed by [Greg Smith](http://notemagnet.blogspot.com/2008/11/automating-initial-postgresqlconf.html) and [other pgsql-hackers](http://www.postgresql.org/message-id/491C6CDC.8090506@agliodbs.com). + +### contrib + +Installs the packages defined in the `node['postgresql']['contrib']['packages']` attribute. The contrib directory of the PostgreSQL distribution includes porting tools, analysis utilities, and plug-in features that database engineers often require. Some (like `pgbench`) are executable. Others (like `pg_buffercache`) would need to be installed into the database. + +Also installs any contrib module extensions defined in the `node['postgresql']['contrib']['extensions']` attribute. These will be available in any subsequently created databases in the cluster, because they will be installed into the `template1` database using the `CREATE EXTENSION` command. For example, it is often necessary/helpful for problem troubleshooting and maintenance planning to install the views and functions in these [standard instrumentation extensions] ([http://www.postgresql.org/message-id/flat/4DC32600.6080900@pgexperts.com#4DD3D6C6.5060006@2ndquadrant.com](mailto:http://www.postgresql.org/message-id/flat/4DC32600.6080900@pgexperts.com#4DD3D6C6.5060006@2ndquadrant.com)): + +```ruby +node['postgresql']['contrib']['extensions'] = [ + "pageinspect", + "pg_buffercache", + "pg_freespacemap", + "pgrowlocks", + "pg_stat_statements", + "pgstattuple" +] +``` + +Note that the `pg_stat_statements` view only works if `postgresql.conf` loads its shared library, which can be done with this node attribute: + +```ruby +node['postgresql']['config']['shared_preload_libraries'] = 'pg_stat_statements' +``` + +If using `shared_preload_libraries` in combination with the `contrib` recipe, make sure that the `contrib` recipe is called before the `server` recipe (to ensure the dependencies are installed and setup in order). + +### apt_pgdg_postgresql + +Enables the PostgreSQL Global Development Group yum repository maintained by Devrim Gündüz for updated PostgreSQL packages. (The PGDG is the groups that develops PostgreSQL.) Automatically included if the `node['postgresql']['enable_pgdg_apt']` attribute is true. Also set the `node['postgresql']['client']['packages']` and `node['postgresql']['server]['packages']` to the list of packages to use from this repository, and set the `node['postgresql']['version']` attribute to the version to use (e.g., "9.2"). + +### yum_pgdg_postgresql + +Enables the PostgreSQL Global Development Group yum repository maintained by Devrim Gündüz for updated PostgreSQL packages. (The PGDG is the groups that develops PostgreSQL.) Automatically included if the `node['postgresql']['enable_pgdg_yum']` attribute is true. Also use `override_attributes` to set a number of values that will need to have embedded version numbers. For example: + +```ruby +node['postgresql']['enable_pgdg_yum'] = true +node['postgresql']['version'] = "9.4" +node['postgresql']['dir'] = "/var/lib/pgsql/9.4/data" +node['postgresql']['config']['data_directory'] = node['postgresql']['dir'] +node['postgresql']['client']['packages'] = ["postgresql94", "postgresql94-devel"] +node['postgresql']['server']['packages'] = ["postgresql94-server"] +node['postgresql']['server']['service_name'] = "postgresql-9.4" +node['postgresql']['contrib']['packages'] = ["postgresql94-contrib"] +node['postgresql']['setup_script'] = "postgresql94-setup" +``` + +You may set `node['postgresql']['pgdg']['repo_rpm_url']` attributes to pick up recent [PGDG repo packages](http://yum.postgresql.org/repopackages.php). + +## Usage + +On systems that need to connect to a PostgreSQL database, add to a run list `recipe[postgresql]` or `recipe[postgresql::client]`. + +On systems that should be PostgreSQL servers, use `recipe[postgresql::server]` on a run list. This recipe does set a password for the `postgres` user. If you're using `chef server`, if the attribute `node['postgresql']['password']['postgres']` is not found, the recipe generates a random password and performs a node.save. (TODO: This is broken, as it disables the password.) If you're using `chef-solo`, you'll need to set the attribute `node['postgresql']['password']['postgres']` in your node's `json_attribs` file or in a role. + +On Debian family systems, SSL will be enabled, as the packages on Debian/Ubuntu also generate the SSL certificates. If you use another platform and wish to use SSL in postgresql, then generate your SSL certificates and distribute them in your own cookbook, and set the `node['postgresql']['config']['ssl']` attribute to true in your role/cookboook/node. + +On server systems, the postgres server is restarted when a configuration file changes. This can be changed to reload only by setting the following attribute: + +```ruby +node['postgresql']['server']['config_change_notify'] = :reload +``` + +## Chef Solo Note + +The following node attribute is stored on the Chef Server when using `chef-client`. Because `chef-solo` does not connect to a server or save the node object at all, to have the password persist across `chef-solo` runs, you must specify them in the `json_attribs` file used. For Example: + +``` +{ + "postgresql": { + "password": { + "postgres": "iloverandompasswordsbutthiswilldo" } + }, + "run_list": ["recipe[postgresql::server]"] +} +``` -Credits: This `postgresql::config_initdb` recipe is based on algorithms -in the [source code](http://doxygen.postgresql.org/initdb_8c_source.html) -for the PostgreSQL `initdb` utility. +That should actually be the "encrypted password" instead of cleartext, so you should generate it as an md5 hash using the PostgreSQL algorithm. -config\_pgtune --------------- +- You could copy the md5-hashed password from an existing postgres database if you have `postgres` access and want to use the same password:
+ `select * from pg_shadow where usename='postgres';` +- You can run this from any postgres database session to use a new password:
+ `select 'md5'||md5('iloverandompasswordsbutthiswilldo'||'postgres');` +- You can run this from a linux commandline:
+ `echo -n 'iloverandompasswordsbutthiswilldo''postgres' | openssl md5 | sed -e 's/.* /md5/'` -Performance tuning. -Takes the wimpy default postgresql.conf and expands the database server -to be as powerful as the hardware it's being deployed on. This recipe -creates a baseline configuration of `node.default['postgresql']['config']` -attributes in the right general range for a dedicated Postgresql system. -Most installations won't need additional performance tuning. +## License -The only decision you need to make is to choose a `db_type` from the -following database workloads. (See the recipe code comments for more -detailed descriptions.) - - * "dw" -- Data Warehouse - * "oltp" -- Online Transaction Processing - * "web" -- Web Application - * "mixed" -- Mixed DW and OLTP characteristics - * "desktop" -- Not a dedicated database - -This recipe uses a performance model with three input parameters. -These node attributes are completely optional, but it is obviously -important to choose the `db_type` correctly: - - * `node['postgresql']['config_pgtune']['db_type']` -- - Specifies database type from the list of five choices above. - If not specified, the default is "mixed". - - * `node['postgresql']['config_pgtune']['max_connections']` -- - Specifies maximum number of connections expected. - If not specified, it depends on database type: - "web":200, "oltp":300, "dw":20, "mixed":80, "desktop":5 - - * `node['postgresql']['config_pgtune']['total_memory']` -- - Specifies total system memory in kB. (E.g., "49416564kB".) - If not specified, it will be taken from Ohai automatic attributes. - This could be used to tune a system that isn't a dedicated database. - -The default attributes created by this recipe are easy to override with -normal attributes because of Chef attribute precedence. For example, if -you are running application benchmarks to try different buffer cache -sizes, you would experiment with this node JSON attribute: - - "postgresql": { - "config": { - "shared_buffers": "3GB" - } - } - -Note that the recipe uses `max_connections` in its computations. If -you want to override that setting, you should specify -`node['postgresql']['config_pgtune']['max_connections']` instead of -`node['postgresql']['config']['max_connections']`. - -Credits: This `postgresql::config_pgtune` recipe is based on the -[pgtune python script](https://github.com/gregs1104/pgtune) -developed by -[Greg Smith](http://notemagnet.blogspot.com/2008/11/automating-initial-postgresqlconf.html) -and -[other pgsql-hackers](http://www.postgresql.org/message-id/491C6CDC.8090506@agliodbs.com). - -contrib -------- - -Installs the packages defined in the -`node['postgresql']['contrib']['packages']` attribute. The contrib -directory of the PostgreSQL distribution includes porting tools, -analysis utilities, and plug-in features that database engineers often -require. Some (like `pgbench`) are executable. Others (like -`pg_buffercache`) would need to be installed into the database. - -Also installs any contrib module extensions defined in the -`node['postgresql']['contrib']['extensions']` attribute. These will be -available in any subsequently created databases in the cluster, because -they will be installed into the `template1` database using the -`CREATE EXTENSION` command. For example, it is often necessary/helpful -for problem troubleshooting and maintenance planning to install the -views and functions in these [standard instrumentation extensions] -(http://www.postgresql.org/message-id/flat/4DC32600.6080900@pgexperts.com#4DD3D6C6.5060006@2ndquadrant.com): - - node['postgresql']['contrib']['extensions'] = [ - "pageinspect", - "pg_buffercache", - "pg_freespacemap", - "pgrowlocks", - "pg_stat_statements", - "pgstattuple" - ] - -Note that the `pg_stat_statements` view only works if `postgresql.conf` -loads its shared library, which can be done with this node attribute: - - node['postgresql']['config']['shared_preload_libraries'] = 'pg_stat_statements' - -If using `shared_preload_libraries` in combination with the `contrib` recipe, -make sure that the `contrib` recipe is called before the `server` recipe (to -ensure the dependencies are installed and setup in order). - -apt\_pgdg\_postgresql ----------------------- - -Enables the PostgreSQL Global Development Group yum repository -maintained by Devrim Gündüz for updated PostgreSQL packages. -(The PGDG is the groups that develops PostgreSQL.) -Automatically included if the `node['postgresql']['enable_pgdg_apt']` -attribute is true. Also set the -`node['postgresql']['client']['packages']` and -`node['postgresql']['server]['packages']` to the list of packages to -use from this repository, and set the `node['postgresql']['version']` -attribute to the version to use (e.g., "9.2"). - -yum\_pgdg\_postgresql ---------------------- - -Enables the PostgreSQL Global Development Group yum repository -maintained by Devrim Gündüz for updated PostgreSQL packages. -(The PGDG is the groups that develops PostgreSQL.) -Automatically included if the `node['postgresql']['enable_pgdg_yum']` -attribute is true. Also use `override_attributes` to set a number of -values that will need to have embedded version numbers. For example: - - node['postgresql']['enable_pgdg_yum'] = true - node['postgresql']['version'] = "9.2" - node['postgresql']['dir'] = "/var/lib/pgsql/9.2/data" - node['postgresql']['config']['data_directory'] = node['postgresql']['dir'] - node['postgresql']['client']['packages'] = ["postgresql92", "postgresql92-devel"] - node['postgresql']['server']['packages'] = ["postgresql92-server"] - node['postgresql']['server']['service_name'] = "postgresql-9.2" - node['postgresql']['contrib']['packages'] = ["postgresql92-contrib"] - -You may set `node['postgresql']['pgdg']['repo_rpm_url']` attributes -to pick up recent [PGDG repo packages](http://yum.postgresql.org/repopackages.php). - -Resources/Providers -=================== - -See the [database](http://community.opscode.com/cookbooks/database) -for resources and providers that can be used for managing PostgreSQL -users and databases. - -Usage -===== - -On systems that need to connect to a PostgreSQL database, add to a run -list `recipe[postgresql]` or `recipe[postgresql::client]`. - -On systems that should be PostgreSQL servers, use -`recipe[postgresql::server]` on a run list. This recipe does set a -password for the `postgres` user. -If you're using `chef server`, if the attribute -`node['postgresql']['password']['postgres']` is not found, -the recipe generates a random password and performs a node.save. -(TODO: This is broken, as it disables the password.) -If you're using `chef-solo`, you'll need -to set the attribute `node['postgresql']['password']['postgres']` in -your node's `json_attribs` file or in a role. - -On Debian family systems, SSL will be enabled, as the packages on -Debian/Ubuntu also generate the SSL certificates. If you use another -platform and wish to use SSL in postgresql, then generate your SSL -certificates and distribute them in your own cookbook, and set the -`node['postgresql']['config']['ssl']` attribute to true in your -role/cookboook/node. - -On server systems, the postgres server is restarted when a configuration -file changes. This can be changed to reload only by setting the -following attribute: - - node['postgresql']['server']['config_change_notify'] = :reload - -Chef Solo Note -============== - -The following node attribute is stored on the Chef Server when using -`chef-client`. Because `chef-solo` does not connect to a server or -save the node object at all, to have the password persist across -`chef-solo` runs, you must specify them in the `json_attribs` file -used. For Example: - - { - "postgresql": { - "password": { - "postgres": "iloverandompasswordsbutthiswilldo" - } - }, - "run_list": ["recipe[postgresql::server]"] - } - -That should actually be the "encrypted password" instead of cleartext, -so you should generate it as an md5 hash using the PostgreSQL algorithm. - -* You could copy the md5-hashed password from an existing postgres -database if you have `postgres` access and want to use the same password:
-`select * from pg_shadow where usename='postgres';` -* You can run this from any postgres database session to use a new password:
-`select 'md5'||md5('iloverandompasswordsbutthiswilldo'||'postgres');` -* You can run this from a linux commandline:
-`echo -n 'iloverandompasswordsbutthiswilldo''postgres' | openssl md5 | sed -e 's/.* /md5/'` - -License and Author -================== - -- Author:: Joshua Timberman () -- Author:: Lamont Granquist () -- Author:: Chris Roberts () -- Author:: David Crane () -- Author:: Aaron Baer () +Copyright 2010-2016, Chef Software, Inc. +```text 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 @@ -449,3 +281,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/postgresql/attributes/default.rb b/cookbooks/postgresql/attributes/default.rb index 345ed7d..27d2c7f 100644 --- a/cookbooks/postgresql/attributes/default.rb +++ b/cookbooks/postgresql/attributes/default.rb @@ -1,5 +1,6 @@ +# frozen_string_literal: true # -# Cookbook Name:: postgresql +# Cookbook:: postgresql # Attributes:: postgresql # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,6 +18,7 @@ default['postgresql']['enable_pgdg_apt'] = false default['postgresql']['enable_pgdg_yum'] = false +default['postgresql']['use_pgdg_packages'] = false default['postgresql']['server']['config_change_notify'] = :restart default['postgresql']['assign_postgres_password'] = true @@ -25,17 +27,16 @@ default['postgresql']['assign_postgres_password'] = true default['postgresql']['database_name'] = 'template1' # Sets OS init system (upstart, systemd, ...), instead of relying on Ohai -default['postgresql']['server']['init_package'] = case node['platform'] +default['postgresql']['server']['init_package'] = + case node['platform'] when 'debian' - case - when node['platform_version'].to_f < 7.0 + if node['platform_version'].to_f < 7.0 'sysv' else 'systemd' end when 'ubuntu' - case - when node['platform_version'].to_f < 15.04 + if node['platform_version'].to_f < 15.04 'upstart' else 'systemd' @@ -43,195 +44,154 @@ default['postgresql']['server']['init_package'] = case node['platform'] when 'amazon' 'upstart' when 'redhat', 'centos', 'scientific', 'oracle' - case - when node['platform_version'].to_f < 6.0 + if node['platform_version'].to_i < 7 'sysv' - when node['platform_version'].to_f < 7.0 - 'upstart' else 'systemd' end when 'fedora' - case - when node['platform_version'].to_f < 15 - 'upstart' - else - 'systemd' - end - when 'opensuse' - case - when node['platform_version'].to_f < 13 - 'sysv' - else - 'systemd' - end + 'systemd' + when 'opensuse', 'opensuseleap' + 'systemd' else 'upstart' end case node['platform'] -when "debian" - - case - when node['platform_version'].to_f < 6.0 # All 5.X - default['postgresql']['version'] = "8.3" - default['postgresql']['dir'] = "/etc/postgresql/8.3/main" - default['postgresql']['client']['packages'] = ["postgresql-client-8.3","libpq-dev"] - default['postgresql']['server']['packages'] = ["postgresql-8.3"] - default['postgresql']['contrib']['packages'] = ["postgresql-contrib-8.3"] - when node['platform_version'].to_f < 7.0 # All 6.X - default['postgresql']['version'] = "8.4" - default['postgresql']['dir'] = "/etc/postgresql/8.4/main" - default['postgresql']['client']['packages'] = ["postgresql-client-8.4","libpq-dev"] - default['postgresql']['server']['packages'] = ["postgresql-8.4"] - default['postgresql']['contrib']['packages'] = ["postgresql-contrib-8.4"] - when node['platform_version'].to_f < 8.0 # All 7.X - default['postgresql']['version'] = "9.1" - default['postgresql']['dir'] = "/etc/postgresql/9.1/main" - default['postgresql']['client']['packages'] = ["postgresql-client-9.1","libpq-dev"] - default['postgresql']['server']['packages'] = ["postgresql-9.1"] - default['postgresql']['contrib']['packages'] = ["postgresql-contrib-9.1"] - else - default['postgresql']['version'] = "9.4" - default['postgresql']['dir'] = "/etc/postgresql/9.4/main" - default['postgresql']['client']['packages'] = ["postgresql-client-9.4","libpq-dev"] - default['postgresql']['server']['packages'] = ["postgresql-9.4"] - default['postgresql']['contrib']['packages'] = ["postgresql-contrib-9.4"] +when 'debian' + if node['platform_version'].to_i == 7 + default['postgresql']['version'] = '9.1' + default['postgresql']['dir'] = '/etc/postgresql/9.1/main' + default['postgresql']['client']['packages'] = ['postgresql-client-9.1', 'libpq-dev'] + default['postgresql']['server']['packages'] = ['postgresql-9.1'] + default['postgresql']['contrib']['packages'] = ['postgresql-contrib-9.1'] + else # 8+ + default['postgresql']['version'] = '9.4' + default['postgresql']['dir'] = '/etc/postgresql/9.4/main' + default['postgresql']['client']['packages'] = ['postgresql-client-9.4', 'libpq-dev'] + default['postgresql']['server']['packages'] = ['postgresql-9.4'] + default['postgresql']['contrib']['packages'] = ['postgresql-contrib-9.4'] end - case - when node['platform_version'].to_f < 6.0 # All 5.X - default['postgresql']['server']['service_name'] = "postgresql-8.3" + default['postgresql']['server']['service_name'] = 'postgresql' + +when 'ubuntu' + + if node['platform_version'].to_f <= 13.10 + default['postgresql']['version'] = '9.1' + default['postgresql']['dir'] = '/etc/postgresql/9.1/main' + default['postgresql']['server']['service_name'] = 'postgresql' + default['postgresql']['client']['packages'] = ['postgresql-client-9.1', 'libpq-dev'] + default['postgresql']['server']['packages'] = ['postgresql-9.1'] + default['postgresql']['contrib']['packages'] = ['postgresql-contrib-9.1'] + elsif node['platform_version'].to_f <= 14.04 + default['postgresql']['version'] = '9.3' + default['postgresql']['dir'] = '/etc/postgresql/9.3/main' + default['postgresql']['server']['service_name'] = 'postgresql' + default['postgresql']['client']['packages'] = ['postgresql-client-9.3', 'libpq-dev'] + default['postgresql']['server']['packages'] = ['postgresql-9.3'] + default['postgresql']['contrib']['packages'] = ['postgresql-contrib-9.3'] + elsif node['platform_version'].to_f <= 15.10 + default['postgresql']['version'] = '9.4' + default['postgresql']['dir'] = '/etc/postgresql/9.4/main' + default['postgresql']['server']['service_name'] = 'postgresql' + default['postgresql']['client']['packages'] = ['postgresql-client-9.4', 'libpq-dev'] + default['postgresql']['server']['packages'] = ['postgresql-9.4'] + default['postgresql']['contrib']['packages'] = ['postgresql-contrib-9.4'] else - default['postgresql']['server']['service_name'] = "postgresql" + default['postgresql']['version'] = '9.5' + default['postgresql']['dir'] = '/etc/postgresql/9.5/main' + default['postgresql']['server']['service_name'] = 'postgresql' + default['postgresql']['client']['packages'] = ['postgresql-client-9.5', 'libpq-dev'] + default['postgresql']['server']['packages'] = ['postgresql-9.5'] + default['postgresql']['contrib']['packages'] = ['postgresql-contrib-9.5'] end +when 'fedora' -when "ubuntu" + default['postgresql']['version'] = '9.5' + default['postgresql']['setup_script'] = 'postgresql-setup' + default['postgresql']['dir'] = '/var/lib/pgsql/data' + default['postgresql']['client']['packages'] = %w(postgresql-devel postgresql-contrib) + default['postgresql']['server']['packages'] = %w(postgresql-server) + default['postgresql']['contrib']['packages'] = %w(postgresql-contrib) + default['postgresql']['server']['service_name'] = 'postgresql' + default['postgresql']['uid'] = '26' + default['postgresql']['gid'] = '26' - case - when node['platform_version'].to_f <= 9.04 - default['postgresql']['version'] = "8.3" - default['postgresql']['dir'] = "/etc/postgresql/8.3/main" - default['postgresql']['server']['service_name'] = "postgresql-8.3" - default['postgresql']['client']['packages'] = ["postgresql-client-8.3","libpq-dev"] - default['postgresql']['server']['packages'] = ["postgresql-8.3"] - default['postgresql']['contrib']['packages'] = ["postgresql-contrib-8.3"] - when node['platform_version'].to_f <= 11.04 - default['postgresql']['version'] = "8.4" - default['postgresql']['dir'] = "/etc/postgresql/8.4/main" - default['postgresql']['server']['service_name'] = "postgresql" - default['postgresql']['client']['packages'] = ["postgresql-client-8.4","libpq-dev"] - default['postgresql']['server']['packages'] = ["postgresql-8.4"] - default['postgresql']['contrib']['packages'] = ["postgresql-contrib-8.4"] - when node['platform_version'].to_f <= 13.10 - default['postgresql']['version'] = "9.1" - default['postgresql']['dir'] = "/etc/postgresql/9.1/main" - default['postgresql']['server']['service_name'] = "postgresql" - default['postgresql']['client']['packages'] = ["postgresql-client-9.1","libpq-dev"] - default['postgresql']['server']['packages'] = ["postgresql-9.1"] - default['postgresql']['contrib']['packages'] = ["postgresql-contrib-9.1"] - else - default['postgresql']['version'] = "9.3" - default['postgresql']['dir'] = "/etc/postgresql/9.3/main" - default['postgresql']['server']['service_name'] = "postgresql" - default['postgresql']['client']['packages'] = ["postgresql-client-9.3","libpq-dev"] - default['postgresql']['server']['packages'] = ["postgresql-9.3"] - default['postgresql']['contrib']['packages'] = ["postgresql-contrib-9.3"] +when 'amazon' + + if node['platform_version'].to_f >= 2015.03 + default['postgresql']['version'] = '9.2' + default['postgresql']['dir'] = '/var/lib/pgsql9/data' end -when "fedora" + default['postgresql']['client']['packages'] = %w(postgresql-devel) + default['postgresql']['server']['packages'] = %w(postgresql-server) + default['postgresql']['contrib']['packages'] = %w(postgresql-contrib) + default['postgresql']['server']['service_name'] = 'postgresql' + default['postgresql']['uid'] = '26' + default['postgresql']['gid'] = '26' - if node['platform_version'].to_f <= 12 - default['postgresql']['version'] = "8.3" - else - default['postgresql']['version'] = "8.4" - end +when 'redhat', 'centos', 'scientific', 'oracle' - default['postgresql']['setup_script'] = "postgresql-setup" + default['postgresql']['version'] = '8.4' - default['postgresql']['dir'] = "/var/lib/pgsql/data" - default['postgresql']['client']['packages'] = %w{postgresql-devel} - default['postgresql']['server']['packages'] = %w{postgresql-server} - default['postgresql']['contrib']['packages'] = %w{postgresql-contrib} - default['postgresql']['server']['service_name'] = "postgresql" + default['postgresql']['client']['packages'] = 'postgresql84-devel' + default['postgresql']['server']['packages'] = ['postgresql84-server'] + default['postgresql']['contrib']['packages'] = ['postgresql84-contrib'] -when "amazon" - - if node['platform_version'].to_f == 2012.03 - default['postgresql']['version'] = "9.0" - default['postgresql']['dir'] = "/var/lib/pgsql9/data" - elsif node['platform_version'].to_f >= 2015.03 - default['postgresql']['version'] = "9.2" - default['postgresql']['dir'] = "/var/lib/pgsql9/data" - else - default['postgresql']['version'] = "8.4" - default['postgresql']['dir'] = "/var/lib/pgsql/data" - end - - default['postgresql']['client']['packages'] = %w{postgresql-devel} - default['postgresql']['server']['packages'] = %w{postgresql-server} - default['postgresql']['contrib']['packages'] = %w{postgresql-contrib} - default['postgresql']['server']['service_name'] = "postgresql" - -when "redhat", "centos", "scientific", "oracle" - - default['postgresql']['version'] = "8.4" - - default['postgresql']['client']['packages'] = ["postgresql84-devel"] - default['postgresql']['server']['packages'] = ["postgresql84-server"] - default['postgresql']['contrib']['packages'] = ["postgresql84-contrib"] - - default['postgresql']['setup_script'] = "postgresql-setup" - default['postgresql']['server']['service_name'] = "postgresql" + default['postgresql']['setup_script'] = 'postgresql-setup' + default['postgresql']['server']['service_name'] = 'postgresql' + default['postgresql']['uid'] = '26' + default['postgresql']['gid'] = '26' if node['platform_version'].to_f >= 6.0 && node['postgresql']['version'].to_f == 8.4 - default['postgresql']['client']['packages'] = ['postgresql-devel'] + default['postgresql']['client']['packages'] = 'postgresql-devel' default['postgresql']['server']['packages'] = ['postgresql-server'] default['postgresql']['contrib']['packages'] = ['postgresql-contrib'] end -when "opensuse" + if node['platform_version'].to_f >= 7.0 + default['postgresql']['version'] = '9.2' + default['postgresql']['client']['packages'] = 'postgresql-devel' + default['postgresql']['server']['packages'] = ['postgresql-server'] + default['postgresql']['contrib']['packages'] = ['postgresql-contrib'] + end - default['postgresql']['dir'] = "/var/lib/pgsql/data" +when 'opensuse', 'opensuseleap' - if node['platform_version'].to_f == 13.2 - default['postgresql']['version'] = '9.3' - default['postgresql']['client']['packages'] = ['postgresql93', 'postgresql93-devel'] - default['postgresql']['server']['packages'] = ['postgresql93-server'] - default['postgresql']['contrib']['packages'] = ['postgresql93-contrib'] - elsif node['platform_version'].to_f == 13.1 + default['postgresql']['dir'] = '/var/lib/pgsql/data' + default['postgresql']['uid'] = '26' + default['postgresql']['gid'] = '26' + + case node['platform_version'].to_f + when 13.1 default['postgresql']['version'] = '9.2' default['postgresql']['client']['packages'] = ['postgresql92', 'postgresql92-devel'] default['postgresql']['server']['packages'] = ['postgresql92-server'] default['postgresql']['contrib']['packages'] = ['postgresql92-contrib'] + when 13.2 + default['postgresql']['version'] = '9.3' + default['postgresql']['client']['packages'] = ['postgresql93', 'postgresql93-devel'] + default['postgresql']['server']['packages'] = ['postgresql93-server'] + default['postgresql']['contrib']['packages'] = ['postgresql93-contrib'] + else # opensuseleap + default['postgresql']['version'] = '9.4' + default['postgresql']['client']['packages'] = ['postgresql94', 'postgresql94-devel'] + default['postgresql']['server']['packages'] = ['postgresql94-server'] + default['postgresql']['contrib']['packages'] = ['postgresql94-contrib'] end - default['postgresql']['server']['service_name'] = "postgresql" + default['postgresql']['server']['service_name'] = 'postgresql' -when "suse" - if node['platform_version'].to_f <= 11.1 - default['postgresql']['version'] = "8.3" - default['postgresql']['client']['packages'] = ['postgresql', 'rubygem-pg'] - default['postgresql']['server']['packages'] = ['postgresql-server'] - default['postgresql']['contrib']['packages'] = ['postgresql-contrib'] - else - default['postgresql']['version'] = "9.1" - default['postgresql']['client']['packages'] = ['postgresql91', 'rubygem-pg'] - default['postgresql']['server']['packages'] = ['postgresql91-server'] - default['postgresql']['contrib']['packages'] = ['postgresql91-contrib'] - end - - default['postgresql']['dir'] = "/var/lib/pgsql/data" - default['postgresql']['server']['service_name'] = "postgresql" - -else - default['postgresql']['version'] = "8.4" - default['postgresql']['dir'] = "/etc/postgresql/8.4/main" - default['postgresql']['client']['packages'] = ["postgresql"] - default['postgresql']['server']['packages'] = ["postgresql"] - default['postgresql']['contrib']['packages'] = ["postgresql"] - default['postgresql']['server']['service_name'] = "postgresql" +when 'suse' # sles 12+ + default['postgresql']['version'] = '9.1' + default['postgresql']['client']['packages'] = ['postgresql91', 'rubygem-pg'] + default['postgresql']['server']['packages'] = ['postgresql91-server'] + default['postgresql']['contrib']['packages'] = ['postgresql91-contrib'] + default['postgresql']['dir'] = '/var/lib/pgsql/data' + default['postgresql']['server']['service_name'] = 'postgresql' end case node['platform_family'] @@ -264,13 +224,17 @@ when 'rhel', 'fedora', 'suse' end default['postgresql']['pg_hba'] = [ - {:type => 'local', :db => 'all', :user => 'postgres', :addr => nil, :method => 'ident'}, - {:type => 'local', :db => 'all', :user => 'all', :addr => nil, :method => 'ident'}, - {:type => 'host', :db => 'all', :user => 'all', :addr => '127.0.0.1/32', :method => 'md5'}, - {:type => 'host', :db => 'all', :user => 'all', :addr => '::1/128', :method => 'md5'} + { type: 'local', db: 'all', user: 'postgres', addr: nil, method: 'ident' }, + { type: 'local', db: 'all', user: 'all', addr: nil, method: 'ident' }, + { type: 'host', db: 'all', user: 'all', addr: '127.0.0.1/32', method: 'md5' }, + { type: 'host', db: 'all', user: 'all', addr: '::1/128', method: 'md5' }, ] -default['postgresql']['password'] = Hash.new +default['postgresql']['password'] = {} + +# set to install a specific version of the ruby gem pg +# if attribute is not defined, install will pick the latest available pg gem +default['postgresql']['pg_gem']['version'] = nil case node['platform_family'] when 'debian' @@ -278,4 +242,3 @@ when 'debian' end default['postgresql']['initdb_locale'] = 'UTF-8' - diff --git a/cookbooks/postgresql/attributes/yum_pgdg_packages.rb b/cookbooks/postgresql/attributes/yum_pgdg_packages.rb index 04f8155..0dfb8dc 100644 --- a/cookbooks/postgresql/attributes/yum_pgdg_packages.rb +++ b/cookbooks/postgresql/attributes/yum_pgdg_packages.rb @@ -1,452 +1,507 @@ +# frozen_string_literal: true # The PostgreSQL RPM Building Project built repository RPMs for easy # access to the PGDG yum repositories. Links to RPMs for installation # on the supported version/platform combinations are listed at # http://yum.postgresql.org/repopackages.php, and the links for -# PostgreSQL 9.2, 9.3 and 9.4 are captured below. +# PostgreSQL 9.2, 9.3, 9.4, 9.5 and 9.6 are captured below. # default['postgresql']['pgdg']['repo_rpm_url'] = { - "9.4" => { - "redhat" => { - "7" => { - "x86_64" => { - "url" => "http://yum.postgresql.org/9.4/redhat/rhel-7-x86_64/", - "package" => "pgdg-redhat94-9.4-1.noarch.rpm" - } - }, - "6" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.4/redhat/rhel-6-i386/", - "package" => "pgdg-redhat94-9.4-1.noarch.rpm" + '9.6' => { + 'amazon' => { + '2015' => { + 'i386' => { + 'url' => 'http://yum.postgresql.org/9.6/redhat/rhel-6-i386/', + 'package' => 'pgdg-ami201503-96-9.6-3.noarch.rpm', }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.4/redhat/rhel-6-x86_64/", - "package" => "pgdg-redhat94-9.4-1.noarch.rpm" - } - }, - "5" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.4/redhat/rhel-5-i386/", - "package" => "pgdg-redhat94-9.4-1.noarch.rpm" + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.6/redhat/rhel-6-x86_64/', + 'package' => 'pgdg-ami201503-96-9.6-3.noarch.rpm', }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.4/redhat/rhel-5-x86_64/", - "package" => "pgdg-redhat94-9.4-1.noarch.rpm" - } - } + }, }, - "centos" => { - "7" => { - "x86_64" => { - "url" => "http://yum.postgresql.org/9.4/redhat/rhel-7-x86_64/", - "package" => "pgdg-centos94-9.4-1.noarch.rpm" - } - }, - "6" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.4/redhat/rhel-6-i386/", - "package" => "pgdg-centos94-9.4-1.noarch.rpm" + 'centos' => { + '7' => { + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.6/redhat/rhel-7-x86_64/', + 'package' => 'pgdg-centos96-9.6-3.noarch.rpm', }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.4/redhat/rhel-6-x86_64/", - "package" => "pgdg-centos94-9.4-1.noarch.rpm" - } }, - "5" => { - "x86_64" => { - "url" => "http://yum.postgresql.org/9.4/redhat/rhel-5-x86_64/", - "package" => "pgdg-centos94-9.4-1.noarch.rpm" + '6' => { + 'i386' => { + 'url' => 'http://yum.postgresql.org/9.6/redhat/rhel-6-i386/', + 'package' => 'pgdg-centos96-9.6-3.noarch.rpm', }, - "i386" => { - "url" => "http://yum.postgresql.org/9.4/redhat/rhel-5-i386/", - "package" => "pgdg-centos94-9.4-1.noarch.rpm" - } - } + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.6/redhat/rhel-6-x86_64/', + 'package' => 'pgdg-centos96-9.6-3.noarch.rpm', + }, + }, }, - "fedora" => { - "22" => { - "x86_64" => { - "url" => "http://yum.postgresql.org/9.4/fedora/fedora-22-x86_64/", - "package" => "pgdg-fedora94-9.4-3.noarch.rpm" - } - }, - "21" => { - "x86_64" => { - "url" => "http://yum.postgresql.org/9.4/fedora/fedora-21-x86_64/", - "package" => "pgdg-fedora94-9.4-2.noarch.rpm" - }, - "i386" => { - "url" => "http://yum.postgresql.org/9.4/fedora/fedora-21-i686/", - "package" => "pgdg-fedora94-9.4-2.noarch.rpm" - } - }, - "20" => { - "x86_64" => { - "url" => "http://yum.postgresql.org/9.4/fedora/fedora-20-x86_64/", - "package" => "pgdg-fedora94-9.4-1.noarch.rpm" + 'redhat' => { + '7' => { + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.6/redhat/rhel-7-x86_64/', + 'package' => 'pgdg-redhat96-9.6-3.noarch.rpm', }, - "i386" => { - "url" => "http://yum.postgresql.org/9.4/fedora/fedora-20-i686/", - "package" => "pgdg-fedora94-9.4-1.noarch.rpm" - } - } + }, + '6' => { + 'i386' => { + 'url' => 'http://yum.postgresql.org/9.6/redhat/rhel-6-i386/', + 'package' => 'pgdg-redhat96-9.6-3.noarch.rpm', + }, + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.6/redhat/rhel-6-x86_64/', + 'package' => 'pgdg-redhat96-9.6-3.noarch.rpm', + }, + }, }, - "amazon" => { - "2015" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.4/redhat/rhel-6-i386/", - "package" => "pgdg-ami201503-94-9.4-1.noarch.rpm" + 'oracle' => { + '7' => { + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.6/redhat/rhel-7-x86_64/', + 'package' => 'pgdg-oraclelinux96-9.6-3.noarch.rpm', }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.4/redhat/rhel-6-x86_64/", - "package" => "pgdg-ami201503-94-9.4-1.noarch.rpm" - } - } + }, + '6' => { + 'i386' => { + 'url' => 'http://yum.postgresql.org/9.6/redhat/rhel-6-i386/', + 'package' => 'pgdg-oraclelinux96-9.6-3.noarch.rpm', + }, + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.6/redhat/rhel-6-x86_64/', + 'package' => 'pgdg-oraclelinux96-9.6-3.noarch.rpm', + }, + }, }, - "scientific" => { - "7" => { - "x86_64" => { - "url" => "http://yum.postgresql.org/9.4/redhat/rhel-7-x86_64/", - "package" => "pgdg-sl94-9.4-1.noarch.rpm" - } - }, - "6" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.4/redhat/rhel-6-i386/", - "package" => "pgdg-sl94-9.4-1.noarch.rpm" + 'scientific' => { + '7' => { + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.6/redhat/rhel-7-x86_64/', + 'package' => 'pgdg-sl96-9.6-3.noarch.rpm', }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.4/redhat/rhel-6-x86_64/", - "package" => "pgdg-sl94-9.4-1.noarch.rpm" - } }, - "5" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.4/redhat/rhel-5-i386/", - "package" => "pgdg-sl94-9.4-1.noarch.rpm" + '6' => { + 'i386' => { + 'url' => 'http://yum.postgresql.org/9.6/redhat/rhel-6-i386/', + 'package' => 'pgdg-sl96-9.6-3.noarch.rpm', }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.4/redhat/rhel-5-x86_64/", - "package" => "pgdg-sl94-9.4-1.noarch.rpm" - } - } + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.6/redhat/rhel-6-x86_64/', + 'package' => 'pgdg-sl96-9.6-3.noarch.rpm', + }, + }, }, - "oracle" => { - "7" => { - "x86_64" => { - "url" => "http://yum.postgresql.org/9.4/redhat/rhel-7-x86_64/", - "package" => "pgdg-oraclelinux94-9.4-1.noarch.rpm" - } - }, - "6" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.4/redhat/rhel-6-i386/", - "package" => "pgdg-oraclelinux94-9.4-1.noarch.rpm" + 'fedora' => { + '22' => { + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.6/fedora/fedora-22-x86_64/', + 'package' => 'pgdg-fedora96-9.6-3.noarch.rpm', }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.4/redhat/rhel-6-x86_64/", - "package" => "pgdg-oraclelinux94-9.4-1.noarch.rpm" - } - } - } + }, + '23' => { + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.6/fedora/fedora-23-x86_64/', + 'package' => 'pgdg-fedora96-9.6-3.noarch.rpm', + }, + }, + '24' => { + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.6/fedora/fedora-24-x86_64/', + 'package' => 'pgdg-fedora96-9.6-3.noarch.rpm', + }, + }, + '25' => { + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.6/fedora/fedora-25-x86_64/', + 'package' => 'pgdg-fedora96-9.6-3.noarch.rpm', + }, + }, + }, }, - "9.3" => { - "amazon" => { - "2015" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.3/redhat/rhel-6-i386/", - "package" => "pgdg-redhat93-9.3-1.noarch.rpm" + '9.5' => { + 'amazon' => { + '2015' => { + 'i386' => { + 'url' => 'http://yum.postgresql.org/9.5/redhat/rhel-6-i386/', + 'package' => 'pgdg-ami201503-95-9.5-3.noarch.rpm', + }, + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.5/redhat/rhel-6-x86_64/', + 'package' => 'pgdg-ami201503-95-9.5-3.noarch.rpm', }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/", - "package" => "pgdg-redhat93-9.3-1.noarch.rpm" - } }, - "2014" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.3/redhat/rhel-6-i386/", - "package" => "pgdg-redhat93-9.3-1.noarch.rpm" - }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/", - "package" => "pgdg-redhat93-9.3-1.noarch.rpm" - } - }, - "2013" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.3/redhat/rhel-6-i386/", - "package" => "pgdg-redhat93-9.3-1.noarch.rpm" - }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/", - "package" => "pgdg-redhat93-9.3-1.noarch.rpm" - } - } }, - "centos" => { - "7" => { - "x86_64" => { - "url" => "http://yum.postgresql.org/9.3/redhat/rhel-7-x86_64/", - "package" => "pgdg-centos93-9.3-1.noarch.rpm" - } - }, - "6" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.3/redhat/rhel-6-i386/", - "package" => "pgdg-centos93-9.3-1.noarch.rpm" + 'centos' => { + '7' => { + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.5/redhat/rhel-7-x86_64/', + 'package' => 'pgdg-centos95-9.5-3.noarch.rpm', }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/", - "package" => "pgdg-centos93-9.3-1.noarch.rpm" - } }, - "5" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.3/redhat/rhel-5-i386/", - "package" => "pgdg-centos93-9.3-1.noarch.rpm" + '6' => { + 'i386' => { + 'url' => 'http://yum.postgresql.org/9.5/redhat/rhel-6-i386/', + 'package' => 'pgdg-centos95-9.5-3.noarch.rpm', }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.3/redhat/rhel-5-x86_64/", - "package" => "pgdg-centos93-9.3-1.noarch.rpm" - } - } + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.5/redhat/rhel-6-x86_64/', + 'package' => 'pgdg-centos95-9.5-3.noarch.rpm', + }, + }, }, - "redhat" => { - "7" => { - "x86_64" => { - "url" => "http://yum.postgresql.org/9.3/redhat/rhel-7-x86_64/", - "package" => "pgdg-redhat93-9.3-1.noarch.rpm" - } - }, - "6" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.3/redhat/rhel-6-i386/", - "package" => "pgdg-redhat93-9.3-1.noarch.rpm", + 'redhat' => { + '7' => { + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.5/redhat/rhel-7-x86_64/', + 'package' => 'pgdg-redhat95-9.5-3.noarch.rpm', }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/", - "package" => "pgdg-redhat93-9.3-1.noarch.rpm" - } }, - "5" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.3/redhat/rhel-5-i386/", - "package" => "pgdg-redhat93-9.3-1.noarch.rpm" + '6' => { + 'i386' => { + 'url' => 'http://yum.postgresql.org/9.5/redhat/rhel-6-i386/', + 'package' => 'pgdg-redhat95-9.5-3.noarch.rpm', }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.3/redhat/rhel-5-x86_64/", - "package" => "pgdg-redhat93-9.3-1.noarch.rpm" - } - } + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.5/redhat/rhel-6-x86_64/', + 'package' => 'pgdg-redhat95-9.5-3.noarch.rpm', + }, + }, }, - "oracle" => { - "6" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.3/redhat/rhel-6-i386/", - "package" => "pgdg-redhat93-9.3-1.noarch.rpm" + 'oracle' => { + '7' => { + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.5/redhat/rhel-7-x86_64/', + 'package' => 'pgdg-oraclelinux95-9.5-3.noarch.rpm', }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/", - "package" => "pgdg-redhat93-9.3-1.noarch.rpm" - } }, - "5" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.3/redhat/rhel-5-i386/", - "package" => "pgdg-redhat93-9.3-1.noarch.rpm" + '6' => { + 'i386' => { + 'url' => 'http://yum.postgresql.org/9.5/redhat/rhel-6-i386/', + 'package' => 'pgdg-oraclelinux95-9.5-3.noarch.rpm', }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.3/redhat/rhel-5-x86_64/", - "package" => "pgdg-redhat93-9.3-1.noarch.rpm" - } - } + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.5/redhat/rhel-6-x86_64/', + 'package' => 'pgdg-oraclelinux95-9.5-3.noarch.rpm', + }, + }, }, - "scientific" => { - "6" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.3/redhat/rhel-6-i386/", - "package" => "pgdg-sl93-9.3-1.noarch.rpm" + 'scientific' => { + '7' => { + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.5/redhat/rhel-7-x86_64/', + 'package' => 'pgdg-sl95-9.5-3.noarch.rpm', }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/", - "package" => "pgdg-sl93-9.3-1.noarch.rpm" - } }, - "5" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.3/redhat/rhel-5-i386/", - "package" => "pgdg-sl93-9.3-1.noarch.rpm" + '6' => { + 'i386' => { + 'url' => 'http://yum.postgresql.org/9.5/redhat/rhel-6-i386/', + 'package' => 'pgdg-sl95-9.5-3.noarch.rpm', }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.3/redhat/rhel-5-x86_64/", - "package" => "pgdg-sl93-9.3-1.noarch.rpm" - } - } + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.5/redhat/rhel-6-x86_64/', + 'package' => 'pgdg-sl95-9.5-3.noarch.rpm', + }, + }, }, - "fedora" => { - "20" => { - "x86_64" => { - "url" => "http://yum.postgresql.org/9.3/fedora/fedora-20-x86_64/", - "pakcage" => "pgdg-fedora93-9.3-1.noarch.rpm" - } - }, - "19" => { - "x86_64" => { - "url" => "http://yum.postgresql.org/9.3/fedora/fedora-19-x86_64/", - "pakcage" => "pgdg-fedora93-9.3-1.noarch.rpm" - } - }, - "18" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.3/fedora/fedora-18-i386/", - "package" => "pgdg-fedora93-9.3-1.noarch.rpm" + 'fedora' => { + '22' => { + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.5/fedora/fedora-22-x86_64/', + 'package' => 'pgdg-fedora95-9.5-3.noarch.rpm', }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.3/fedora/fedora-18-x86_64/", - "package" => "pgdg-fedora93-9.3-1.noarch.rpm" - } }, - "17" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.3/fedora/fedora-17-i386/", - "package" => "pgdg-fedora93-9.3-1.noarch.rpm" + '23' => { + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.5/fedora/fedora-23-x86_64/', + 'package' => 'pgdg-fedora95-9.5-4.noarch.rpm', }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.3/fedora/fedora-17-x86_64/", - "package" => "pgdg-fedora93-9.3-1.noarch.rpm" - } - } - } + }, + '24' => { + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.5/fedora/fedora-24-x86_64/', + 'package' => 'pgdg-fedora95-9.5-4.noarch.rpm', + }, + }, + '25' => { + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.5/fedora/fedora-25-x86_64/', + 'package' => 'pgdg-fedora95-9.5-4.noarch.rpm', + }, + }, + }, }, - "9.2" => { - "centos" => { - "6" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.2/redhat/rhel-6-i386/", - "package" => "pgdg-centos92-9.2-7.noarch.rpm" + '9.4' => { + 'redhat' => { + '7' => { + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.4/redhat/rhel-7-x86_64/', + 'package' => 'pgdg-redhat94-9.4-2.noarch.rpm', }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.2/redhat/rhel-6-x86_64/", - "package" => "pgdg-centos92-9.2-7.noarch.rpm" - } }, - "5" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.2/redhat/rhel-5-i386/", - "package" => "pgdg-centos92-9.2-7.noarch.rpm" + '6' => { + 'i386' => { + 'url' => 'http://yum.postgresql.org/9.4/redhat/rhel-6-i386/', + 'package' => 'pgdg-redhat94-9.4-2.noarch.rpm', }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.2/redhat/rhel-5-x86_64/", - "package" => "pgdg-centos92-9.2-7.noarch.rpm" - } - } + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.4/redhat/rhel-6-x86_64/', + 'package' => 'pgdg-redhat94-9.4-2.noarch.rpm', + }, + }, }, - "redhat" => { - "6" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.2/redhat/rhel-6-i386/", - "package" => "pgdg-redhat92-9.2-7.noarch.rpm" + 'centos' => { + '7' => { + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.4/redhat/rhel-7-x86_64/', + 'package' => 'pgdg-centos94-9.4-2.noarch.rpm', }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.2/redhat/rhel-6-x86_64/", - "package" => "pgdg-redhat92-9.2-7.noarch.rpm" - } }, - "5" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.2/redhat/rhel-5-i386/", - "package" => "pgdg-redhat92-9.2-7.noarch.rpm" + '6' => { + 'i386' => { + 'url' => 'http://yum.postgresql.org/9.4/redhat/rhel-6-i386/', + 'package' => 'pgdg-centos94-9.4-2.noarch.rpm', }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.2/redhat/rhel-5-x86_64/", - "package" => "pgdg-redhat92-9.2-7.noarch.rpm" - } - } + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.4/redhat/rhel-6-x86_64/', + 'package' => 'pgdg-centos94-9.4-2.noarch.rpm', + }, + }, + '5' => { + 'i386' => { + 'url' => 'http://yum.postgresql.org/9.4/redhat/rhel-5-i386/', + 'package' => 'pgdg-centos94-9.4-3.noarch.rpm', + }, + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.4/redhat/rhel-5-x86_64/', + 'package' => 'pgdg-centos94-9.4-3.noarch.rpm', + }, + }, }, - "oracle" => { - "6" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.2/redhat/rhel-6-i386/", - "package" => "pgdg-redhat92-9.2-7.noarch.rpm" + 'fedora' => { + '22' => { + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.4/fedora/fedora-22-x86_64/', + 'package' => 'pgdg-fedora94-9.4-4.noarch.rpm', }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.2/redhat/rhel-6-x86_64/", - "package" => "pgdg-redhat92-9.2-7.noarch.rpm" - } }, - "5" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.2/redhat/rhel-5-i386/", - "package" => "pgdg-redhat92-9.2-7.noarch.rpm" + '23' => { + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.4/fedora/fedora-23-x86_64/', + 'package' => 'pgdg-fedora94-9.4-5.noarch.rpm', }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.2/redhat/rhel-5-x86_64/", - "package" => "pgdg-redhat92-9.2-7.noarch.rpm" - } - } + }, + '24' => { + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.4/fedora/fedora-24-x86_64/', + 'package' => 'pgdg-fedora94-9.4-5.noarch.rpm', + }, + }, + '25' => { + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.4/fedora/fedora-25-x86_64/', + 'package' => 'pgdg-fedora94-9.4-5.noarch.rpm', + }, + }, }, - "scientific" => { - "6" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.2/redhat/rhel-6-i386/", - "package" => "pgdg-sl92-9.2-8.noarch.rpm" + 'amazon' => { + '2015' => { + 'i386' => { + 'url' => 'http://yum.postgresql.org/9.4/redhat/rhel-6-i386/', + 'package' => 'pgdg-ami201503-94-9.4-3.noarch.rpm', + }, + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.4/redhat/rhel-6-x86_64/', + 'package' => 'pgdg-ami201503-94-9.4-3.noarch.rpm', }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.2/redhat/rhel-6-x86_64/", - "package" => "pgdg-sl92-9.2-8.noarch.rpm" - } }, - "5" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.2/redhat/rhel-5-i386/", - "package" => "pgdg-sl92-9.2-8.noarch.rpm" - }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.2/redhat/rhel-5-x86_64/", - "package" => "pgdg-sl92-9.2-8.noarch.rpm" - } - } }, - "fedora" => { - "19" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.2/fedora/fedora-19-i386/", - "package" => "pgdg-fedora92-9.2-6.noarch.rpm" + 'scientific' => { + '7' => { + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.4/redhat/rhel-7-x86_64/', + 'package' => 'pgdg-sl94-9.4-3.noarch.rpm', }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.2/fedora/fedora-19-x86_64/", - "package" => "pgdg-fedora92-9.2-6.noarch.rpm" - } }, - "18" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.2/fedora/fedora-18-i386/", - "package" => "pgdg-fedora92-9.2-6.noarch.rpm" + '6' => { + 'i386' => { + 'url' => 'http://yum.postgresql.org/9.4/redhat/rhel-6-i386/', + 'package' => 'pgdg-sl94-9.4-3.noarch.rpm', + }, + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.4/redhat/rhel-6-x86_64/', + 'package' => 'pgdg-sl94-9.4-3.noarch.rpm', }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.2/fedora/fedora-18-x86_64/", - "package" => "pgdg-fedora92-9.2-6.noarch.rpm" - } }, - "17" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.2/fedora/fedora-17-i386/", - "package" => "pgdg-fedora92-9.2-6.noarch.rpm" + }, + 'oracle' => { + '7' => { + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.4/redhat/rhel-7-x86_64/', + 'package' => 'pgdg-oraclelinux94-9.4-3.noarch.rpm', }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.2/fedora/fedora-17-x86_64/", - "package" => "pgdg-fedora92-9.2-5.noarch.rpm" - } }, - "16" => { - "i386" => { - "url" => "http://yum.postgresql.org/9.2/fedora/fedora-16-i386/", - "package" => "pgdg-fedora92-9.2-5.noarch.rpm" + '6' => { + 'i386' => { + 'url' => 'http://yum.postgresql.org/9.4/redhat/rhel-6-i386/', + 'package' => 'pgdg-oraclelinux94-9.4-3.noarch.rpm', }, - "x86_64" => { - "url" => "http://yum.postgresql.org/9.2/fedora/fedora-16-x86_64/", - "package" => "pgdg-fedora92-9.2-5.noarch.rpm" - } - } - } - } + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.4/redhat/rhel-6-x86_64/', + 'package' => 'pgdg-oraclelinux94-9.4-3.noarch.rpm', + }, + }, + }, + }, + '9.3' => { + 'amazon' => { + '2015' => { + 'i386' => { + 'url' => 'http://yum.postgresql.org/9.3/redhat/rhel-6-i386/', + 'package' => 'pgdg-redhat93-9.3-3.noarch.rpm', + }, + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/', + 'package' => 'pgdg-redhat93-9.3-3.noarch.rpm', + }, + }, + '2014' => { + 'i386' => { + 'url' => 'http://yum.postgresql.org/9.3/redhat/rhel-6-i386/', + 'package' => 'pgdg-redhat93-9.3-3.noarch.rpm', + }, + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/', + 'package' => 'pgdg-redhat93-9.3-3.noarch.rpm', + }, + }, + }, + 'centos' => { + '7' => { + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.3/redhat/rhel-7-x86_64/', + 'package' => 'pgdg-centos93-9.3-3.noarch.rpm', + }, + }, + '6' => { + 'i386' => { + 'url' => 'http://yum.postgresql.org/9.3/redhat/rhel-6-i386/', + 'package' => 'pgdg-centos93-9.3-3.noarch.rpm', + }, + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/', + 'package' => 'pgdg-centos93-9.3-3.noarch.rpm', + }, + }, + }, + 'fedora' => { + '23' => { + 'x86_64' => { + 'url' => 'https://yum.postgresql.org/9.3/fedora/fedora-23-x86_64/', + 'package' => 'pgdg-fedora93-9.3-4.noarch.rpm', + }, + }, + }, + 'redhat' => { + '7' => { + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.3/redhat/rhel-7-x86_64/', + 'package' => 'pgdg-redhat93-9.3-2.noarch.rpm', + }, + }, + '6' => { + 'i386' => { + 'url' => 'http://yum.postgresql.org/9.3/redhat/rhel-6-i386/', + 'package' => 'pgdg-redhat93-9.3-3.noarch.rpm', + }, + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/', + 'package' => 'pgdg-redhat93-9.3-3.noarch.rpm', + }, + }, + }, + 'oracle' => { + '6' => { + 'i386' => { + 'url' => 'http://yum.postgresql.org/9.3/redhat/rhel-6-i386/', + 'package' => 'pgdg-redhat93-9.3-3.noarch.rpm', + }, + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/', + 'package' => 'pgdg-redhat93-9.3-3.noarch.rpm', + }, + }, + }, + 'scientific' => { + '6' => { + 'i386' => { + 'url' => 'http://yum.postgresql.org/9.3/redhat/rhel-6-i386/', + 'package' => 'pgdg-sl93-9.3-3.noarch.rpm', + }, + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/', + 'package' => 'pgdg-sl93-9.3-3.noarch.rpm', + }, + }, + '5' => { + 'i386' => { + 'url' => 'http://yum.postgresql.org/9.3/redhat/rhel-5-i386/', + 'package' => 'pgdg-sl93-9.3-3.noarch.rpm', + }, + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.3/redhat/rhel-5-x86_64/', + 'package' => 'pgdg-sl93-9.3-3.noarch.rpm', + }, + }, + }, + }, + '9.2' => { + 'centos' => { + '6' => { + 'i386' => { + 'url' => 'http://yum.postgresql.org/9.2/redhat/rhel-6-i386/', + 'package' => 'pgdg-centos92-9.2-8.noarch.rpm', + }, + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.2/redhat/rhel-6-x86_64/', + 'package' => 'pgdg-centos92-9.2-8.noarch.rpm', + }, + }, + }, + 'redhat' => { + '6' => { + 'i386' => { + 'url' => 'http://yum.postgresql.org/9.2/redhat/rhel-6-i386/', + 'package' => 'pgdg-redhat92-9.2-9.noarch.rpm', + }, + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.2/redhat/rhel-6-x86_64/', + 'package' => 'pgdg-redhat92-9.2-9.noarch.rpm', + }, + }, + }, + 'oracle' => { + '6' => { + 'i386' => { + 'url' => 'http://yum.postgresql.org/9.2/redhat/rhel-6-i386/', + 'package' => 'pgdg-redhat92-9.2-9.noarch.rpm', + }, + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.2/redhat/rhel-6-x86_64/', + 'package' => 'pgdg-redhat92-9.2-9.noarch.rpm', + }, + }, + }, + 'scientific' => { + '6' => { + 'i386' => { + 'url' => 'http://yum.postgresql.org/9.2/redhat/rhel-6-i386/', + 'package' => 'pgdg-sl92-9.2-10.noarch.rpm', + }, + 'x86_64' => { + 'url' => 'http://yum.postgresql.org/9.2/redhat/rhel-6-x86_64/', + 'package' => 'pgdg-sl92-9.2-10.noarch.rpm', + }, + }, + }, + }, } diff --git a/cookbooks/postgresql/files/default/tests/minitest/apt_pgdg_postgresql_test.rb b/cookbooks/postgresql/files/default/tests/minitest/apt_pgdg_postgresql_test.rb deleted file mode 100644 index 551bc6a..0000000 --- a/cookbooks/postgresql/files/default/tests/minitest/apt_pgdg_postgresql_test.rb +++ /dev/null @@ -1,39 +0,0 @@ -# -# Copyright 2012, 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. -# - -require File.expand_path('../support/helpers', __FILE__) - -describe 'postgresql::apt_pgdg_postgresql' do - include Helpers::Postgresql - - it 'removes the Pitti PPA sources.list' do - skip unless %w{debian}.include?(node['platform_family']) - file("/etc/apt/sources.list.d/pitti-postgresql-ppa").wont_exist - end - it 'creates the PGDG apt sources.list' do - skip unless %w{debian}.include?(node['platform_family']) - file("/etc/apt/sources.list.d/apt.postgresql.org.list").must_exist - end - - it 'installs postgresql-client-9.4' do - package("postgresql-client-9.4").must_be_installed - end - - it 'makes psql version 9.4 available' do - psql = shell_out("psql --version") - assert psql.stdout.include?("psql (PostgreSQL) 9.4") - end -end diff --git a/cookbooks/postgresql/files/default/tests/minitest/server_test.rb b/cookbooks/postgresql/files/default/tests/minitest/server_test.rb deleted file mode 100644 index ea50064..0000000 --- a/cookbooks/postgresql/files/default/tests/minitest/server_test.rb +++ /dev/null @@ -1,44 +0,0 @@ -# -# Copyright 2012, 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. -# - -require File.expand_path('../support/helpers', __FILE__) - -describe 'postgresql::server' do - include Helpers::Postgresql - - it 'installs the postgresql server packages' do - node['postgresql']['server']['packages'].each do |pkg| - package(pkg).must_be_installed - end - end - - it 'runs the postgresql service' do - service((node['postgresql']['server']['service_name'] || 'postgresql')).must_be_running - end - - it 'can connect to postgresql' do - Gem.clear_paths - require 'pg' - conn = PG::Connection.new( - :host => 'localhost', - :port => '5432', - :password => node['postgresql']['password']['postgres'], - :user => "postgres" - ) - assert_match(/localhost/, conn.host) - end - -end diff --git a/cookbooks/postgresql/libraries/default.rb b/cookbooks/postgresql/libraries/default.rb index 24b0e1b..61eaf39 100644 --- a/cookbooks/postgresql/libraries/default.rb +++ b/cookbooks/postgresql/libraries/default.rb @@ -1,5 +1,6 @@ +# frozen_string_literal: false # -# Cookbook Name:: postgresql +# Cookbook:: postgresql # Library:: default # Author:: David Crane () # @@ -20,186 +21,179 @@ include Chef::Mixin::ShellOut module Opscode module PostgresqlHelpers - -####### -# Function to truncate value to 4 significant bits, render human readable. -# Used in recipes/config_initdb.rb to set this attribute: -# -# The memory settings (shared_buffers, effective_cache_size, work_mem, -# maintenance_work_mem and wal_buffers) will be rounded down to keep -# the 4 most significant bits, so that SHOW will be likely to use a -# larger divisor. The output is actually a human readable string that -# ends with "GB", "MB" or "kB" if over 1023, exactly what Postgresql -# will expect in a postgresql.conf setting. The output may be up to -# 6.25% less than the original value because of the rounding. -def binaryround(value) - - # Keep a multiplier which grows through powers of 1 - multiplier = 1 - - # Truncate value to 4 most significant bits - while value >= 16 - value = (value / 2).floor - multiplier = multiplier * 2 - end - - # Factor any remaining powers of 2 into the multiplier - while value == 2*((value / 2).floor) - value = (value / 2).floor - multiplier = multiplier * 2 - end - - # Factor enough powers of 2 back into the value to - # leave the multiplier as a power of 1024 that can - # be represented as units of "GB", "MB" or "kB". - if multiplier >= 1024*1024*1024 - while multiplier > 1024*1024*1024 - value = 2*value - multiplier = (multiplier/2).floor - end - multiplier = 1 - units = "GB" - - elsif multiplier >= 1024*1024 - while multiplier > 1024*1024 - value = 2*value - multiplier = (multiplier/2).floor - end - multiplier = 1 - units = "MB" - - elsif multiplier >= 1024 - while multiplier > 1024 - value = 2*value - multiplier = (multiplier/2).floor - end - multiplier = 1 - units = "kB" - - else - units = "" - end - - # Now we can return a nice human readable string. - return "#{multiplier * value}#{units}" -end - -####### -# Locale Configuration - -# Function to test the date order. -# Used in recipes/config_initdb.rb to set this attribute: -# node.default['postgresql']['config']['datestyle'] -def locale_date_order - # Test locale conversion of mon=11, day=22, year=33 - testtime = DateTime.new(2033,11,22,0,0,0,"-00:00") - #=> # - - # %x - Preferred representation for the date alone, no time - res = testtime.strftime("%x") - - if res.nil? - return 'mdy' - end - - posM = res.index("11") - posD = res.index("22") - posY = res.index("33") - - if (posM.nil? || posD.nil? || posY.nil?) - return 'mdy' - elseif (posY < posM && posM < posD) - return 'ymd' - elseif (posD < posM) - return 'dmy' - else - return 'mdy' - end -end - -####### -# Timezone Configuration -require 'find' - -# Function to determine where the system stored shared timezone data. -# Used in recipes/config_initdb.rb to detemine where it should have -# select_default_timezone(tzdir) search. -def pg_TZDIR() - # System time zone conversions are controlled by a timezone data file - # identified through environment variables (TZ and TZDIR) and/or file - # and directory naming conventions specific to the Linux distribution. - # Each of these timezone names will have been loaded into the PostgreSQL - # pg_timezone_names view by the package maintainer. + ####### + # Function to truncate value to 4 significant bits, render human readable. + # Used in recipes/config_initdb.rb to set this attribute: # - # Instead of using the timezone name configured as the system default, - # the PostgreSQL server uses ones named in postgresql.conf settings - # (timezone and log_timezone). The initdb utility does initialize those - # settings to the timezone name that corresponds to the system default. - # - # The system's timezone name is actually a filename relative to the - # shared zoneinfo directory. That is usually /usr/share/zoneinfo, but - # it was /usr/lib/zoneinfo in older distributions and can be anywhere - # if specified by the environment variable TZDIR. The tzset(3) manpage - # seems to indicate the following precedence: - tzdir = nil - if ::File.directory?("/usr/lib/zoneinfo") - tzdir = "/usr/lib/zoneinfo" - else - share_path = [ ENV['TZDIR'], "/usr/share/zoneinfo" ].compact.first - if ::File.directory?(share_path) - tzdir = share_path + # The memory settings (shared_buffers, effective_cache_size, work_mem, + # maintenance_work_mem and wal_buffers) will be rounded down to keep + # the 4 most significant bits, so that SHOW will be likely to use a + # larger divisor. The output is actually a human readable string that + # ends with "GB", "MB" or "kB" if over 1023, exactly what Postgresql + # will expect in a postgresql.conf setting. The output may be up to + # 6.25% less than the original value because of the rounding. + def binaryround(value) + # Keep a multiplier which grows through powers of 1 + multiplier = 1 + + # Truncate value to 4 most significant bits + while value >= 16 + value = (value / 2).floor + multiplier *= 2 + end + + # Factor any remaining powers of 2 into the multiplier + while value == 2 * (value / 2).floor + value = (value / 2).floor + multiplier *= 2 + end + + # Factor enough powers of 2 back into the value to + # leave the multiplier as a power of 1024 that can + # be represented as units of "GB", "MB" or "kB". + if multiplier >= 1024 * 1024 * 1024 + while multiplier > 1024 * 1024 * 1024 + value = 2 * value + multiplier = (multiplier / 2).floor end + multiplier = 1 + units = 'GB' + + elsif multiplier >= 1024 * 1024 + while multiplier > 1024 * 1024 + value = 2 * value + multiplier = (multiplier / 2).floor + end + multiplier = 1 + units = 'MB' + + elsif multiplier >= 1024 + while multiplier > 1024 + value = 2 * value + multiplier = (multiplier / 2).floor + end + multiplier = 1 + units = 'kB' + + else + units = '' + end + + # Now we can return a nice human readable string. + "#{multiplier * value}#{units}" end - return tzdir -end -####### -# Function to support select_default_timezone(tzdir), which is -# used in recipes/config_initdb.rb. -def validate_zone(tzname) - # PostgreSQL does not support leap seconds, so this function tests - # the usual Linux tzname convention to avoid a misconfiguration. - # Assume that the tzdata package maintainer has kept all timezone - # data files with support for leap seconds is kept under the - # so-named "right/" subdir of the shared zoneinfo directory. - # - # The original PostgreSQL initdb is not Unix-specific, so it did a - # very complicated, thorough test in its pg_tz_acceptable() function - # that I could not begin to understand how to do in ruby :). - # - # Testing the tzname is good enough, since a misconfiguration - # will result in an immediate fatal error when the PostgreSQL - # service is started, with pgstartup.log messages such as: - # LOG: time zone "right/US/Eastern" appears to use leap seconds - # DETAIL: PostgreSQL does not support leap seconds. + ####### + # Locale Configuration - if tzname.index("right/") == 0 - return false - else - return true + # Function to test the date order. + # Used in recipes/config_initdb.rb to set this attribute: + # node.default['postgresql']['config']['datestyle'] + def locale_date_order + # Test locale conversion of mon=11, day=22, year=33 + testtime = DateTime.new(2033, 11, 22, 0, 0, 0, '-00:00') + #=> # + + # %x - Preferred representation for the date alone, no time + res = testtime.strftime('%x') + + return 'mdy' if res.nil? + + posM = res.index('11') + posD = res.index('22') + posY = res.index('33') + + if posM.nil? || posD.nil? || posY.nil? + return 'mdy' + elseif (posY < posM && posM < posD) + return 'ymd' + elseif (posD < posM) + return 'dmy' + end + 'mdy' end -end -# Function to support select_default_timezone(tzdir), which is -# used in recipes/config_initdb.rb. -def scan_available_timezones(tzdir) - # There should be an /etc/localtime zoneinfo file that is a link to - # (or a copy of) a timezone data file under tzdir, which should have - # been installed under the "share" directory by the tzdata package. - # - # The initdb utility determines which shared timezone file is being - # used as the system's default /etc/localtime. The timezone name is - # the timezone file path relative to the tzdir. + ####### + # Timezone Configuration + require 'find' - bestzonename = nil + # Function to determine where the system stored shared timezone data. + # Used in recipes/config_initdb.rb to detemine where it should have + # select_default_timezone(tzdir) search. + def pg_TZDIR + # System time zone conversions are controlled by a timezone data file + # identified through environment variables (TZ and TZDIR) and/or file + # and directory naming conventions specific to the Linux distribution. + # Each of these timezone names will have been loaded into the PostgreSQL + # pg_timezone_names view by the package maintainer. + # + # Instead of using the timezone name configured as the system default, + # the PostgreSQL server uses ones named in postgresql.conf settings + # (timezone and log_timezone). The initdb utility does initialize those + # settings to the timezone name that corresponds to the system default. + # + # The system's timezone name is actually a filename relative to the + # shared zoneinfo directory. That is usually /usr/share/zoneinfo, but + # it was /usr/lib/zoneinfo in older distributions and can be anywhere + # if specified by the environment variable TZDIR. The tzset(3) manpage + # seems to indicate the following precedence: + tzdir = nil + if ::File.directory?('/usr/lib/zoneinfo') + tzdir = '/usr/lib/zoneinfo' + else + share_path = [ENV['TZDIR'], '/usr/share/zoneinfo'].compact.first + tzdir = share_path if ::File.directory?(share_path) + end + tzdir + end - if (tzdir.nil?) - Chef::Log.error("The zoneinfo directory not found (looked for /usr/share/zoneinfo and /usr/lib/zoneinfo)") - elsif !::File.exists?("/etc/localtime") - Chef::Log.error("The system zoneinfo file not found (looked for /etc/localtime)") - elsif ::File.directory?("/etc/localtime") - Chef::Log.error("The system zoneinfo file not found (/etc/localtime is a directory instead)") - elsif ::File.symlink?("/etc/localtime") + ####### + # Function to support select_default_timezone(tzdir), which is + # used in recipes/config_initdb.rb. + def validate_zone(tzname) + # PostgreSQL does not support leap seconds, so this function tests + # the usual Linux tzname convention to avoid a misconfiguration. + # Assume that the tzdata package maintainer has kept all timezone + # data files with support for leap seconds is kept under the + # so-named "right/" subdir of the shared zoneinfo directory. + # + # The original PostgreSQL initdb is not Unix-specific, so it did a + # very complicated, thorough test in its pg_tz_acceptable() function + # that I could not begin to understand how to do in ruby :). + # + # Testing the tzname is good enough, since a misconfiguration + # will result in an immediate fatal error when the PostgreSQL + # service is started, with pgstartup.log messages such as: + # LOG: time zone "right/US/Eastern" appears to use leap seconds + # DETAIL: PostgreSQL does not support leap seconds. + + if tzname.index('right/') == 0 + false + else + true + end + end + + # Function to support select_default_timezone(tzdir), which is + # used in recipes/config_initdb.rb. + def scan_available_timezones(tzdir) + # There should be an /etc/localtime zoneinfo file that is a link to + # (or a copy of) a timezone data file under tzdir, which should have + # been installed under the "share" directory by the tzdata package. + # + # The initdb utility determines which shared timezone file is being + # used as the system's default /etc/localtime. The timezone name is + # the timezone file path relative to the tzdir. + + bestzonename = nil + + if tzdir.nil? + Chef::Log.error('The zoneinfo directory not found (looked for /usr/share/zoneinfo and /usr/lib/zoneinfo)') + elsif !::File.exist?('/etc/localtime') + Chef::Log.error('The system zoneinfo file not found (looked for /etc/localtime)') + elsif ::File.directory?('/etc/localtime') + Chef::Log.error('The system zoneinfo file not found (/etc/localtime is a directory instead)') + elsif ::File.symlink?('/etc/localtime') # PostgreSQL initdb doesn't use the symlink target, but this # certainly will make sense to any system administrator. A full # scan of the tzdir to find the shortest filename could result @@ -207,147 +201,107 @@ def scan_available_timezones(tzdir) # in spite of what the sysadmin had specified in the symlink. # (There are many duplicates under tzdir, with the same timezone # content appearing as an average of 2-3 different file names.) - path = ::File.readlink("/etc/localtime") - bestzonename = path.gsub("#{tzdir}/","") - else # /etc/localtime is a file, so scan for it under tzdir - localtime_content = File.read("/etc/localtime") + path = ::File.realdirpath('/etc/localtime') + bestzonename = path.gsub("#{tzdir}/", '') + else # /etc/localtime is a file, so scan for it under tzdir + localtime_content = File.read('/etc/localtime') Find.find(tzdir) do |path| - # Only consider files (skip directories or symlinks) - if !::File.directory?(path) && !::File.symlink?(path) - # Ignore any file named "posixrules" or "localtime" - if ::File.basename(path) != "posixrules" && ::File.basename(path) != "localtime" - # Do consider if content exactly matches /etc/localtime. - if localtime_content == File.read(path) - tzname = path.gsub("#{tzdir}/","") - if validate_zone(tzname) - if (bestzonename.nil? || - tzname.length < bestzonename.length || - (tzname.length == bestzonename.length && - (tzname <=> bestzonename) < 0) - ) - bestzonename = tzname - end - end - end - end - end - end + # Only consider files (skip directories or symlinks) + next unless !::File.directory?(path) && !::File.symlink?(path) + # Ignore any file named "posixrules" or "localtime" + next unless ::File.basename(path) != 'posixrules' && ::File.basename(path) != 'localtime' + # Do consider if content exactly matches /etc/localtime. + next unless localtime_content == File.read(path) + tzname = path.gsub("#{tzdir}/", '') + next unless validate_zone(tzname) + if bestzonename.nil? || + tzname.length < bestzonename.length || + (tzname.length == bestzonename.length && + (tzname <=> bestzonename) < 0) + + bestzonename = tzname + end + end + end + + bestzonename end - return bestzonename -end + # Function to support select_default_timezone(tzdir), which is + # used in recipes/config_initdb.rb. + def identify_system_timezone(tzdir) + resultbuf = scan_available_timezones(tzdir) -# Function to support select_default_timezone(tzdir), which is -# used in recipes/config_initdb.rb. -def identify_system_timezone(tzdir) - resultbuf = scan_available_timezones(tzdir) - - if !resultbuf.nil? + if !resultbuf.nil? # Ignore Olson's rather silly "Factory" zone; use GMT instead - if (resultbuf <=> "Factory") == 0 - resultbuf = nil - end + resultbuf = nil if (resultbuf <=> 'Factory') == 0 - else + else # Did not find the timezone. Fallback to use a GMT zone. Note that the # Olson timezone database names the GMT-offset zones in POSIX style: plus # is west of Greenwich. testtime = DateTime.now - std_ofs = testtime.strftime("%:z").split(":")[0].to_i + std_ofs = testtime.strftime('%:z').split(':')[0].to_i resultbuf = [ - "Etc/GMT", - (-std_ofs > 0) ? "+" : "", - (-std_ofs).to_s - ].join('') + 'Etc/GMT', + -std_ofs > 0 ? '+' : '', + (-std_ofs).to_s, + ].join('') + end + + resultbuf end - return resultbuf -end + ####### + # Function to determine the name of the system's default timezone. + # Used in recipes/config_initdb.rb to set these attributes: + # node.default['postgresql']['config']['log_timezone'] + # node.default['postgresql']['config']['timezone'] + def select_default_timezone(tzdir) + system_timezone = nil -####### -# Function to determine the name of the system's default timezone. -# Used in recipes/config_initdb.rb to set these attributes: -# node.default['postgresql']['config']['log_timezone'] -# node.default['postgresql']['config']['timezone'] -def select_default_timezone(tzdir) - - system_timezone = nil - - # Check TZ environment variable - tzname = ENV['TZ'] - if !tzname.nil? && !tzname.empty? && validate_zone(tzname) + # Check TZ environment variable + tzname = ENV['TZ'] + if !tzname.nil? && !tzname.empty? && validate_zone(tzname) system_timezone = tzname - else + else # Nope, so try to identify system timezone from /etc/localtime tzname = identify_system_timezone(tzdir) - if validate_zone(tzname) - system_timezone = tzname - end + system_timezone = tzname if validate_zone(tzname) + end + + system_timezone end - return system_timezone -end - -####### -# Function to determine the name of the system's default timezone. -def get_result_orig(query) - # query could be a String or an Array of String - if (query.is_a?(String)) - stdin = query - else - stdin = query.join("\n") - end - @get_result ||= begin - cmd = shell_out("cat", :input => stdin) - cmd.stdout - end -end - -####### -# Function to execute an SQL statement in the default database. -# Input: Query could be a single String or an Array of String. -# Output: A String with |-separated columns and \n-separated rows. -# Note an empty output could mean psql couldn't connect. -# This is easiest for 1-field (1-row, 1-col) results, otherwise -# it will be complex to parse the results. -def execute_sql(query) - db_name = node['postgresql']['database_name'] - # query could be a String or an Array of String - statement = query.is_a?(String) ? query : query.join("\n") - @execute_sql ||= begin - cmd = shell_out("psql -q --tuples-only --no-align -d #{db_name} -f -", - :user => "postgres", - :input => statement - ) - # If psql fails, generally the postgresql service is down. - # Instead of aborting chef with a fatal error, let's just - # pass these non-zero exitstatus back as empty cmd.stdout. - if (cmd.exitstatus() == 0 and !cmd.stderr.empty?) - # An SQL failure is still a zero exitstatus, but then the - # stderr explains the error, so let's rais that as fatal. - Chef::Log.fatal("psql failed executing this SQL statement:\n#{statement}") - Chef::Log.fatal(cmd.stderr) - raise "SQL ERROR" + ####### + # Function to execute an SQL statement in the default database. + # Input: Query could be a single String or an Array of String. + # Output: A String with |-separated columns and \n-separated rows. + # Note an empty output could mean psql couldn't connect. + # This is easiest for 1-field (1-row, 1-col) results, otherwise + # it will be complex to parse the results. + def execute_sql(query, db_name = node['postgresql']['database_name']) + # query could be a String or an Array of String + statement = query.is_a?(String) ? query : query.join("\n") + cmd = shell_out("psql -q --tuples-only --no-align -d #{db_name} -f -", + user: 'postgres', + input: statement) + # If psql fails, generally the postgresql service is down. + # Instead of aborting chef with a fatal error, let's just + # pass these non-zero exitstatus back as empty cmd.stdout. + if cmd.exitstatus == 0 && !cmd.stderr.empty? + # An SQL failure is still a zero exitstatus, but then the + # stderr explains the error, so let's rais that as fatal. + Chef::Log.fatal("psql failed executing this SQL statement:\n#{statement}") + Chef::Log.fatal(cmd.stderr) + raise 'SQL ERROR' + end + cmd.stdout.chomp end - cmd.stdout.chomp - end -end -####### -# Function to determine if a standard contrib extension is already installed. -# Input: Extension name -# Output: true or false -# Best use as a not_if gate on bash "install-#{pg_ext}-extension" resource. -def extension_installed?(pg_ext) - @extension_installed ||= begin - installed=execute_sql("select 'installed' from pg_extension where extname = '#{pg_ext}';") - installed =~ /^installed$/ - end -end - -# End the Opscode::PostgresqlHelpers module + # End the Opscode::PostgresqlHelpers module end end diff --git a/cookbooks/postgresql/metadata.json b/cookbooks/postgresql/metadata.json index 0af3c80..419148d 100644 --- a/cookbooks/postgresql/metadata.json +++ b/cookbooks/postgresql/metadata.json @@ -1,57 +1 @@ -{ - "name": "postgresql", - "description": "Installs and configures postgresql for clients or servers", - "long_description": "Description\n===========\n\nInstalls and configures PostgreSQL as a client or a server.\n\nRequirements\n============\n\n## Platforms\n\n* Debian, Ubuntu\n* Red Hat/CentOS/Scientific (6.0+ required) - \"EL6-family\"\n* Fedora\n* SUSE\n\nTested on:\n\n* Ubuntu 12.04, 14.04, 14.10\n* Red Hat 6.1, Scientific 6.1, CentOS 6.3, 7.0, OpenSuse\n\n## Cookbooks\n\nRequires Opscode's `openssl` cookbook for secure password generation.\n\nRequires a C compiler and development headers in order to build the\n`pg` RubyGem to provide Ruby bindings in the `ruby` recipe.\n\nOpscode's `build-essential` cookbook provides this functionality on\nDebian, Ubuntu, and EL6-family.\n\nWhile not required, Opscode's `database` cookbook contains resources\nand providers that can interact with a PostgreSQL database. This\ncookbook is a dependency of database.\n\nAttributes\n==========\n\nThe following attributes are set based on the platform, see the\n`attributes/default.rb` file for default values.\n\n* `node['postgresql']['version']` - version of postgresql to manage\n* `node['postgresql']['dir']` - home directory of where postgresql\n data and configuration lives.\n\n* `node['postgresql']['client']['packages']` - An array of package names\n that should be installed on \"client\" systems.\n* `node['postgresql']['server']['packages']` - An array of package names\n that should be installed on \"server\" systems.\n* `node['postgresql']['server']['config_change_notify']` - Type of\n notification triggered when a config file changes.\n* `node['postgresql']['contrib']['packages']` - An array of package names\n that could be installed on \"server\" systems for useful sysadmin tools.\n\n* `node['postgresql']['enable_pgdg_apt']` - Whether to enable the apt repo\n by the PostgreSQL Global Development Group, which contains newer versions\n of PostgreSQL.\n\n* `node['postgresql']['enable_pgdg_yum']` - Whether to enable the yum repo\n by the PostgreSQL Global Development Group, which contains newer versions\n of PostgreSQL.\n\n* `node['postgresql']['initdb_locale']` - Sets the default locale for the\n database cluster. If this attribute is not specified, the locale is\n inherited from the environment that initdb runs in. Sometimes you must\n have a system locale that is not what you want for your database cluster,\n and this attribute addresses that scenario. Valid only for EL-family\n distros (RedHat/Centos/etc.).\n\nThe following attributes are generated in\n`recipe[postgresql::server]`.\n\nConfiguration\n-------------\n\nThe `postgresql.conf` and `pg_hba.conf` files are dynamically\ngenerated from attributes. Each key in `node['postgresql']['config']`\nis a postgresql configuration directive, and will be rendered in the\nconfig file. For example, the attribute:\n\n node['postgresql']['config']['listen_addresses'] = 'localhost'\n\nWill result in the following line in the `postgresql.conf` file:\n\n listen_addresses = 'localhost'\n\nThe attributes file contains default values for Debian and RHEL\nplatform families (per the `node['platform_family']`). These defaults\nhave disparity between the platforms because they were originally\nextracted from the postgresql.conf files in the previous version of\nthis cookbook, which differed in their default config. The resulting\nconfiguration files will be the same as before, but the content will\nbe dynamically rendered from the attributes. The helpful commentary\nwill no longer be present. You should consult the PostgreSQL\ndocumentation for specific configuration details.\n\nSee __Recipes__ `config_initdb` and `config_pgtune` below to\nauto-generate many postgresql.conf settings.\n\nFor values that are \"on\" or \"off\", they should be specified as literal\n`true` or `false`. String values will be used with single quotes. Any\nconfiguration option set to the literal `nil` will be skipped\nentirely. All other values (e.g., numeric literals) will be used as\nis. So for example:\n\n node.default['postgresql']['config']['logging_collector'] = true\n node.default['postgresql']['config']['datestyle'] = 'iso, mdy'\n node.default['postgresql']['config']['ident_file'] = nil\n node.default['postgresql']['config']['port'] = 5432\n\nWill result in the following config lines:\n\n logging_collector = 'on'\n datestyle = 'iso,mdy'\n port = 5432\n\n(no line printed for `ident_file` as it is `nil`)\n\nNote that the `unix_socket_directory` configuration was renamed to\n`unix_socket_directories` in Postgres 9.3 so make sure to use the\n`node['postgresql']['unix_socket_directories']` attribute instead of\n`node['postgresql']['unix_socket_directory']`.\n\nThe `pg_hba.conf` file is dynamically generated from the\n`node['postgresql']['pg_hba']` attribute. This attribute must be an\narray of hashes, each hash containing the authorization data. As it is\nan array, you can append to it in your own recipes. The hash keys in\nthe array must be symbols. Each hash will be written as a line in\n`pg_hba.conf`. For example, this entry from\n`node['postgresql']['pg_hba']`:\n\n [{:comment => '# Optional comment',\n :type => 'local', :db => 'all', :user => 'postgres', :addr => nil, :method => 'md5'}]\n\nWill result in the following line in `pg_hba.conf`:\n\n # Optional comment\n local all postgres md5\n\nUse `nil` if the CIDR-ADDRESS should be empty (as above).\nDon't provide a comment if none is desired in the `pg_hba.conf` file.\n\nNote that the following authorization rule is supplied automatically by\nthe cookbook template. The cookbook needs this to execute SQL in the\nPostgreSQL server without supplying the clear-text password (which isn't\nknown by the cookbook). Therefore, your `node['postgresql']['pg_hba']`\nattributes don't need to specify this authorization rule:\n\n # \"local\" is for Unix domain socket connections only\n local all all ident\n\n(By the way, the template uses `peer` instead of `ident` for PostgreSQL-9.1\nand above, which has the same effect.)\n\nRecipes\n=======\n\ndefault\n-------\n\nIncludes the client recipe.\n\nclient\n------\n\nInstalls the packages defined in the\n`node['postgresql']['client']['packages']` attribute.\n\nruby\n----\n\nInstall the `pg` gem under Chef's Ruby environment so it can be used\nin other recipes. The build-essential packages and postgresql client\npackages will be installed during the compile phase, so that the\nnative extensions of `pg` can be compiled.\n\nserver\n------\n\nIncludes the `server_debian` or `server_redhat` recipe to get the\nappropriate server packages installed and service managed. Also\nmanages the configuration for the server:\n\n* generates a strong default password (via `openssl`) for `postgres`\n* sets the password for postgres\n* manages the `postgresql.conf` file.\n* manages the `pg_hba.conf` file.\n\nserver\\_debian\n--------------\n\nInstalls the postgresql server packages and sets up the service. You\nshould include the `postgresql::server` recipe, which will include\nthis on Debian platforms.\n\nserver\\_redhat\n--------------\n\nManages the postgres user and group (with UID/GID 26, per RHEL package\nconventions), installs the postgresql server packages, initializes the\ndatabase, and manages the postgresql service. You should include the\n`postgresql::server` recipe, which will include this on RHEL/Fedora\nplatforms.\n\nconfig\\_initdb\n--------------\n\nTakes locale and timezone settings from the system configuration.\nThis recipe creates `node.default['postgresql']['config']` attributes\nthat conform to the system's locale and timezone. In addition, this\nrecipe creates the same error reporting and logging settings that\n`initdb` provided: a rotation of 7 days of log files named\npostgresql-Mon.log, etc.\n\nThe default attributes created by this recipe are easy to override with\nnormal attributes because of Chef attribute precedence. For example,\nsuppose a DBA wanted to keep log files indefinitely, rolling over daily\nor when growing to 10MB. The Chef installation could include the\n`postgresql::config_initdb` recipe for the locale and timezone settings,\nbut customize the logging settings with these node JSON attributes:\n\n \"postgresql\": {\n \"config\": {\n \"log_rotation_age\": \"1d\",\n \"log_rotation_size\": \"10MB\",\n \"log_filename\": \"postgresql-%Y-%m-%d_%H%M%S.log\"\n }\n }\n\nCredits: This `postgresql::config_initdb` recipe is based on algorithms\nin the [source code](http://doxygen.postgresql.org/initdb_8c_source.html)\nfor the PostgreSQL `initdb` utility.\n\nconfig\\_pgtune\n--------------\n\nPerformance tuning.\nTakes the wimpy default postgresql.conf and expands the database server\nto be as powerful as the hardware it's being deployed on. This recipe\ncreates a baseline configuration of `node.default['postgresql']['config']`\nattributes in the right general range for a dedicated Postgresql system.\nMost installations won't need additional performance tuning.\n\nThe only decision you need to make is to choose a `db_type` from the\nfollowing database workloads. (See the recipe code comments for more\ndetailed descriptions.)\n\n * \"dw\" -- Data Warehouse\n * \"oltp\" -- Online Transaction Processing\n * \"web\" -- Web Application\n * \"mixed\" -- Mixed DW and OLTP characteristics\n * \"desktop\" -- Not a dedicated database\n\nThis recipe uses a performance model with three input parameters.\nThese node attributes are completely optional, but it is obviously\nimportant to choose the `db_type` correctly:\n\n * `node['postgresql']['config_pgtune']['db_type']` --\n Specifies database type from the list of five choices above.\n If not specified, the default is \"mixed\".\n\n * `node['postgresql']['config_pgtune']['max_connections']` --\n Specifies maximum number of connections expected.\n If not specified, it depends on database type:\n \"web\":200, \"oltp\":300, \"dw\":20, \"mixed\":80, \"desktop\":5\n\n * `node['postgresql']['config_pgtune']['total_memory']` --\n Specifies total system memory in kB. (E.g., \"49416564kB\".)\n If not specified, it will be taken from Ohai automatic attributes.\n This could be used to tune a system that isn't a dedicated database.\n\nThe default attributes created by this recipe are easy to override with\nnormal attributes because of Chef attribute precedence. For example, if\nyou are running application benchmarks to try different buffer cache\nsizes, you would experiment with this node JSON attribute:\n\n \"postgresql\": {\n \"config\": {\n \"shared_buffers\": \"3GB\"\n }\n }\n\nNote that the recipe uses `max_connections` in its computations. If\nyou want to override that setting, you should specify\n`node['postgresql']['config_pgtune']['max_connections']` instead of\n`node['postgresql']['config']['max_connections']`.\n\nCredits: This `postgresql::config_pgtune` recipe is based on the\n[pgtune python script](https://github.com/gregs1104/pgtune)\ndeveloped by\n[Greg Smith](http://notemagnet.blogspot.com/2008/11/automating-initial-postgresqlconf.html)\nand\n[other pgsql-hackers](http://www.postgresql.org/message-id/491C6CDC.8090506@agliodbs.com).\n\ncontrib\n-------\n\nInstalls the packages defined in the\n`node['postgresql']['contrib']['packages']` attribute. The contrib\ndirectory of the PostgreSQL distribution includes porting tools,\nanalysis utilities, and plug-in features that database engineers often\nrequire. Some (like `pgbench`) are executable. Others (like\n`pg_buffercache`) would need to be installed into the database.\n\nAlso installs any contrib module extensions defined in the\n`node['postgresql']['contrib']['extensions']` attribute. These will be\navailable in any subsequently created databases in the cluster, because\nthey will be installed into the `template1` database using the\n`CREATE EXTENSION` command. For example, it is often necessary/helpful\nfor problem troubleshooting and maintenance planning to install the\nviews and functions in these [standard instrumentation extensions]\n(http://www.postgresql.org/message-id/flat/4DC32600.6080900@pgexperts.com#4DD3D6C6.5060006@2ndquadrant.com):\n\n node['postgresql']['contrib']['extensions'] = [\n \"pageinspect\",\n \"pg_buffercache\",\n \"pg_freespacemap\",\n \"pgrowlocks\",\n \"pg_stat_statements\",\n \"pgstattuple\"\n ]\n\nNote that the `pg_stat_statements` view only works if `postgresql.conf`\nloads its shared library, which can be done with this node attribute:\n\n node['postgresql']['config']['shared_preload_libraries'] = 'pg_stat_statements'\n\nIf using `shared_preload_libraries` in combination with the `contrib` recipe,\nmake sure that the `contrib` recipe is called before the `server` recipe (to\nensure the dependencies are installed and setup in order).\n\napt\\_pgdg\\_postgresql\n----------------------\n\nEnables the PostgreSQL Global Development Group yum repository\nmaintained by Devrim Gündüz for updated PostgreSQL packages.\n(The PGDG is the groups that develops PostgreSQL.)\nAutomatically included if the `node['postgresql']['enable_pgdg_apt']`\nattribute is true. Also set the\n`node['postgresql']['client']['packages']` and\n`node['postgresql']['server]['packages']` to the list of packages to\nuse from this repository, and set the `node['postgresql']['version']`\nattribute to the version to use (e.g., \"9.2\").\n\nyum\\_pgdg\\_postgresql\n---------------------\n\nEnables the PostgreSQL Global Development Group yum repository\nmaintained by Devrim Gündüz for updated PostgreSQL packages.\n(The PGDG is the groups that develops PostgreSQL.)\nAutomatically included if the `node['postgresql']['enable_pgdg_yum']`\nattribute is true. Also use `override_attributes` to set a number of\nvalues that will need to have embedded version numbers. For example:\n\n node['postgresql']['enable_pgdg_yum'] = true\n node['postgresql']['version'] = \"9.2\"\n node['postgresql']['dir'] = \"/var/lib/pgsql/9.2/data\"\n node['postgresql']['config']['data_directory'] = node['postgresql']['dir']\n node['postgresql']['client']['packages'] = [\"postgresql92\", \"postgresql92-devel\"]\n node['postgresql']['server']['packages'] = [\"postgresql92-server\"]\n node['postgresql']['server']['service_name'] = \"postgresql-9.2\"\n node['postgresql']['contrib']['packages'] = [\"postgresql92-contrib\"]\n\nYou may set `node['postgresql']['pgdg']['repo_rpm_url']` attributes\nto pick up recent [PGDG repo packages](http://yum.postgresql.org/repopackages.php).\n\nResources/Providers\n===================\n\nSee the [database](http://community.opscode.com/cookbooks/database)\nfor resources and providers that can be used for managing PostgreSQL\nusers and databases.\n\nUsage\n=====\n\nOn systems that need to connect to a PostgreSQL database, add to a run\nlist `recipe[postgresql]` or `recipe[postgresql::client]`.\n\nOn systems that should be PostgreSQL servers, use\n`recipe[postgresql::server]` on a run list. This recipe does set a\npassword for the `postgres` user.\nIf you're using `chef server`, if the attribute\n`node['postgresql']['password']['postgres']` is not found,\nthe recipe generates a random password and performs a node.save.\n(TODO: This is broken, as it disables the password.)\nIf you're using `chef-solo`, you'll need\nto set the attribute `node['postgresql']['password']['postgres']` in\nyour node's `json_attribs` file or in a role.\n\nOn Debian family systems, SSL will be enabled, as the packages on\nDebian/Ubuntu also generate the SSL certificates. If you use another\nplatform and wish to use SSL in postgresql, then generate your SSL\ncertificates and distribute them in your own cookbook, and set the\n`node['postgresql']['config']['ssl']` attribute to true in your\nrole/cookboook/node.\n\nOn server systems, the postgres server is restarted when a configuration\nfile changes. This can be changed to reload only by setting the\nfollowing attribute:\n\n node['postgresql']['server']['config_change_notify'] = :reload\n\nChef Solo Note\n==============\n\nThe following node attribute is stored on the Chef Server when using\n`chef-client`. Because `chef-solo` does not connect to a server or\nsave the node object at all, to have the password persist across\n`chef-solo` runs, you must specify them in the `json_attribs` file\nused. For Example:\n\n {\n \"postgresql\": {\n \"password\": {\n \"postgres\": \"iloverandompasswordsbutthiswilldo\"\n }\n },\n \"run_list\": [\"recipe[postgresql::server]\"]\n }\n\nThat should actually be the \"encrypted password\" instead of cleartext,\nso you should generate it as an md5 hash using the PostgreSQL algorithm.\n\n* You could copy the md5-hashed password from an existing postgres\ndatabase if you have `postgres` access and want to use the same password:
\n`select * from pg_shadow where usename='postgres';`\n* You can run this from any postgres database session to use a new password:
\n`select 'md5'||md5('iloverandompasswordsbutthiswilldo'||'postgres');`\n* You can run this from a linux commandline:
\n`echo -n 'iloverandompasswordsbutthiswilldo''postgres' | openssl md5 | sed -e 's/.* /md5/'`\n\nLicense and Author\n==================\n\n- Author:: Joshua Timberman ()\n- Author:: Lamont Granquist ()\n- Author:: Chris Roberts ()\n- Author:: David Crane ()\n- Author:: Aaron Baer ()\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": "Heavy Water Operations, LLC", - "maintainer_email": "helpdesk@heavywater.io", - "license": "Apache 2.0", - "platforms": { - "ubuntu": "< 14.10", - "debian": ">= 0.0.0", - "fedora": ">= 0.0.0", - "suse": ">= 0.0.0", - "opensuse": ">= 0.0.0", - "amazon": ">= 0.0.0", - "redhat": "~> 6.0", - "centos": "~> 6.0", - "scientific": "~> 6.0", - "oracle": "~> 6.0" - }, - "dependencies": { - "apt": ">= 1.9.0", - "build-essential": ">= 0.0.0", - "openssl": "~> 4.0" - }, - "recommendations": { - - }, - "suggestions": { - - }, - "conflicting": { - - }, - "providing": { - - }, - "replacing": { - - }, - "attributes": { - - }, - "groupings": { - - }, - "recipes": { - "postgresql": "Includes postgresql::client", - "postgresql::ruby": "Installs pg gem for Ruby bindings", - "postgresql::client": "Installs postgresql client package(s)", - "postgresql::server": "Installs postgresql server packages, templates", - "postgresql::server_redhat": "Installs postgresql server packages, redhat family style", - "postgresql::server_debian": "Installs postgresql server packages, debian family style" - }, - "version": "4.0.0", - "source_url": "", - "issues_url": "" -} +{"name":"postgresql","version":"6.1.1","description":"Installs and configures postgresql for clients or servers","long_description":"# postgresql cookbook\n\n[![Build Status](https://travis-ci.org/sous-chefs/postgresql.svg?branch=master)](https://travis-ci.org/sous-chefs/postgresql) [![Cookbook Version](https://img.shields.io/cookbook/v/postgresql.svg)](https://supermarket.chef.io/cookbooks/postgresql)\n\nInstalls and configures PostgreSQL as a client or a server.\n\n## Requirements\n\n### Platforms\n\n- Debian 7+\n- Ubuntu 12.04+\n- Red Hat/CentOS/Scientific (6.0+ required) - \"EL6-family\"\n- Fedora\n- SLES 12+\n- openSUSE 13+ / openSUSE Leap\n\n### Chef\n\n- Chef 12.1+\n\n### Cookbooks\n\n- `compat_resource`\n- `openssl`\n- `build-essential`\n\n## Attributes\n\nThe following attributes are set based on the platform, see the `attributes/default.rb` file for default values.\n\n- `node['postgresql']['version']` - version of postgresql to manage\n- `node['postgresql']['dir']` - home directory of where postgresql data and configuration lives.\n- `node['postgresql']['client']['packages']` - An array of package names that should be installed on \"client\" systems.\n- `node['postgresql']['server']['packages']` - An array of package names that should be installed on \"server\" systems.\n- `node['postgresql']['server']['config_change_notify']` - Type of notification triggered when a config file changes.\n- `node['postgresql']['contrib']['packages']` - An array of package names that could be installed on \"server\" systems for useful sysadmin tools.\n- `node['postgresql']['enable_pgdg_apt']` - Whether to enable the apt repo by the PostgreSQL Global Development Group, which contains newer versions of PostgreSQL.\n- `node['postgresql']['enable_pgdg_yum']` - Whether to enable the yum repo by the PostgreSQL Global Development Group, which contains newer versions of PostgreSQL.\n- `node['postgresql']['initdb_locale']` - Sets the default locale for the database cluster. If this attribute is not specified, the locale is inherited from the environment that initdb runs in. Sometimes you must have a system locale that is not what you want for your database cluster, and this attribute addresses that scenario. Valid only for EL-family distros (RedHat/Centos/etc.).\n\nThe following attributes are generated in `recipe[postgresql::server]`.\n\n## Configuration\n\nThe `postgresql.conf` and `pg_hba.conf` files are dynamically generated from attributes. Each key in `node['postgresql']['config']` is a postgresql configuration directive, and will be rendered in the config file. For example, the attribute:\n\n```ruby\nnode['postgresql']['config']['listen_addresses'] = 'localhost'\n```\n\nWill result in the following line in the `postgresql.conf` file:\n\n```ruby\nlisten_addresses = 'localhost'\n```\n\nThe attributes file contains default values for Debian and RHEL platform families (per the `node['platform_family']`). These defaults have disparity between the platforms because they were originally extracted from the postgresql.conf files in the previous version of this cookbook, which differed in their default config. The resulting configuration files will be the same as before, but the content will be dynamically rendered from the attributes. The helpful commentary will no longer be present. You should consult the PostgreSQL documentation for specific configuration details.\n\nSee **Recipes** `config_initdb` and `config_pgtune` below to auto-generate many postgresql.conf settings.\n\nFor values that are \"on\" or \"off\", they should be specified as literal `true` or `false`. String values will be used with single quotes. Any configuration option set to the literal `nil` will be skipped entirely. All other values (e.g., numeric literals) will be used as is. So for example:\n\n```ruby\nnode.default['postgresql']['config']['logging_collector'] = true\nnode.default['postgresql']['config']['datestyle'] = 'iso, mdy'\nnode.default['postgresql']['config']['ident_file'] = nil\nnode.default['postgresql']['config']['port'] = 5432\n```\n\nWill result in the following config lines:\n\n```ruby\nlogging_collector = 'on'\ndatestyle = 'iso,mdy'\nport = 5432\n```\n\n(no line printed for `ident_file` as it is `nil`)\n\nNote that the `unix_socket_directory` configuration was renamed to `unix_socket_directories` in Postgres 9.3 so make sure to use the `node['postgresql']['unix_socket_directories']` attribute instead of `node['postgresql']['unix_socket_directory']`.\n\nThe `pg_hba.conf` file is dynamically generated from the `node['postgresql']['pg_hba']` attribute. This attribute must be an array of hashes, each hash containing the authorization data. As it is an array, you can append to it in your own recipes. The hash keys in the array must be symbols. Each hash will be written as a line in `pg_hba.conf`. For example, this entry from `node['postgresql']['pg_hba']`:\n\n```\n[{:comment => '# Optional comment',\n:type => 'local', :db => 'all', :user => 'postgres', :addr => nil, :method => 'md5'}]\n```\n\nWill result in the following line in `pg_hba.conf`:\n\n```\n# Optional comment\nlocal all postgres md5\n```\n\nUse `nil` if the CIDR-ADDRESS should be empty (as above). Don't provide a comment if none is desired in the `pg_hba.conf` file.\n\nNote that the following authorization rule is supplied automatically by the cookbook template. The cookbook needs this to execute SQL in the PostgreSQL server without supplying the clear-text password (which isn't known by the cookbook). Therefore, your `node['postgresql']['pg_hba']` attributes don't need to specify this authorization rule:\n\n```\n# \"local\" is for Unix domain socket connections only\nlocal all all ident\n```\n\n(By the way, the template uses `peer` instead of `ident` for PostgreSQL-9.1 and above, which has the same effect.)\n\n## Recipes\n\n### default\n\nIncludes the client recipe.\n\n### client\n\nInstalls the packages defined in the `node['postgresql']['client']['packages']` attribute.\n\n### ruby\n\nInstall the `pg` gem under Chef's Ruby environment so it can be used in other recipes. The build-essential packages and postgresql client packages will be installed during the compile phase, so that the native extensions of `pg` can be compiled.\n\n### server\n\nIncludes the `server_debian` or `server_redhat` recipe to get the appropriate server packages installed and service managed. Also manages the configuration for the server:\n\n- generates a strong default password (via `openssl`) for `postgres`\n- sets the password for postgres\n- manages the `postgresql.conf` file.\n- manages the `pg_hba.conf` file.\n\n### config_initdb\n\nTakes locale and timezone settings from the system configuration. This recipe creates `node.default['postgresql']['config']` attributes that conform to the system's locale and timezone. In addition, this recipe creates the same error reporting and logging settings that `initdb` provided: a rotation of 7 days of log files named postgresql-Mon.log, etc.\n\nThe default attributes created by this recipe are easy to override with normal attributes because of Chef attribute precedence. For example, suppose a DBA wanted to keep log files indefinitely, rolling over daily or when growing to 10MB. The Chef installation could include the `postgresql::config_initdb` recipe for the locale and timezone settings, but customize the logging settings with these node JSON attributes:\n\n```javascript\n\"postgresql\": {\n \"config\": {\n \"log_rotation_age\": \"1d\",\n \"log_rotation_size\": \"10MB\",\n \"log_filename\": \"postgresql-%Y-%m-%d_%H%M%S.log\"\n }\n}\n```\n\nCredits: This `postgresql::config_initdb` recipe is based on algorithms in the [source code](http://doxygen.postgresql.org/initdb_8c_source.html) for the PostgreSQL `initdb` utility.\n\n### config_pgtune\n\nPerformance tuning. Takes the wimpy default postgresql.conf and expands the database server to be as powerful as the hardware it's being deployed on. This recipe creates a baseline configuration of `node.default['postgresql']['config']` attributes in the right general range for a dedicated Postgresql system. Most installations won't need additional performance tuning.\n\nThe only decision you need to make is to choose a `db_type` from the following database workloads. (See the recipe code comments for more detailed descriptions.)\n\n- \"dw\" -- Data Warehouse\n- \"oltp\" -- Online Transaction Processing\n- \"web\" -- Web Application\n- \"mixed\" -- Mixed DW and OLTP characteristics\n- \"desktop\" -- Not a dedicated database\n\nThis recipe uses a performance model with three input parameters. These node attributes are completely optional, but it is obviously important to choose the `db_type` correctly:\n\n- `node['postgresql']['config_pgtune']['db_type']` -- Specifies database type from the list of five choices above. If not specified, the default is \"mixed\".\n\n- `node['postgresql']['config_pgtune']['max_connections']` -- Specifies maximum number of connections expected. If not specified, it depends on database type: \"web\":200, \"oltp\":300, \"dw\":20, \"mixed\":80, \"desktop\":5\n\n- `node['postgresql']['config_pgtune']['total_memory']` -- Specifies total system memory in kB. (E.g., \"49416564kB\".) If not specified, it will be taken from Ohai automatic attributes. This could be used to tune a system that isn't a dedicated database.\n\nThe default attributes created by this recipe are easy to override with normal attributes because of Chef attribute precedence. For example, if you are running application benchmarks to try different buffer cache sizes, you would experiment with this node JSON attribute:\n\n```javascript\n\"postgresql\": {\n \"config\": {\n \"shared_buffers\": \"3GB\"\n }\n}\n```\n\nNote that the recipe uses `max_connections` in its computations. If you want to override that setting, you should specify `node['postgresql']['config_pgtune']['max_connections']` instead of `node['postgresql']['config']['max_connections']`.\n\nCredits: This `postgresql::config_pgtune` recipe is based on the [pgtune python script](https://github.com/gregs1104/pgtune) developed by [Greg Smith](http://notemagnet.blogspot.com/2008/11/automating-initial-postgresqlconf.html) and [other pgsql-hackers](http://www.postgresql.org/message-id/491C6CDC.8090506@agliodbs.com).\n\n### contrib\n\nInstalls the packages defined in the `node['postgresql']['contrib']['packages']` attribute. The contrib directory of the PostgreSQL distribution includes porting tools, analysis utilities, and plug-in features that database engineers often require. Some (like `pgbench`) are executable. Others (like `pg_buffercache`) would need to be installed into the database.\n\nAlso installs any contrib module extensions defined in the `node['postgresql']['contrib']['extensions']` attribute. These will be available in any subsequently created databases in the cluster, because they will be installed into the `template1` database using the `CREATE EXTENSION` command. For example, it is often necessary/helpful for problem troubleshooting and maintenance planning to install the views and functions in these [standard instrumentation extensions] ([http://www.postgresql.org/message-id/flat/4DC32600.6080900@pgexperts.com#4DD3D6C6.5060006@2ndquadrant.com](mailto:http://www.postgresql.org/message-id/flat/4DC32600.6080900@pgexperts.com#4DD3D6C6.5060006@2ndquadrant.com)):\n\n```ruby\nnode['postgresql']['contrib']['extensions'] = [\n \"pageinspect\",\n \"pg_buffercache\",\n \"pg_freespacemap\",\n \"pgrowlocks\",\n \"pg_stat_statements\",\n \"pgstattuple\"\n]\n```\n\nNote that the `pg_stat_statements` view only works if `postgresql.conf` loads its shared library, which can be done with this node attribute:\n\n```ruby\nnode['postgresql']['config']['shared_preload_libraries'] = 'pg_stat_statements'\n```\n\nIf using `shared_preload_libraries` in combination with the `contrib` recipe, make sure that the `contrib` recipe is called before the `server` recipe (to ensure the dependencies are installed and setup in order).\n\n### apt_pgdg_postgresql\n\nEnables the PostgreSQL Global Development Group yum repository maintained by Devrim Gündüz for updated PostgreSQL packages. (The PGDG is the groups that develops PostgreSQL.) Automatically included if the `node['postgresql']['enable_pgdg_apt']` attribute is true. Also set the `node['postgresql']['client']['packages']` and `node['postgresql']['server]['packages']` to the list of packages to use from this repository, and set the `node['postgresql']['version']` attribute to the version to use (e.g., \"9.2\").\n\n### yum_pgdg_postgresql\n\nEnables the PostgreSQL Global Development Group yum repository maintained by Devrim Gündüz for updated PostgreSQL packages. (The PGDG is the groups that develops PostgreSQL.) Automatically included if the `node['postgresql']['enable_pgdg_yum']` attribute is true. Also use `override_attributes` to set a number of values that will need to have embedded version numbers. For example:\n\n```ruby\nnode['postgresql']['enable_pgdg_yum'] = true\nnode['postgresql']['version'] = \"9.4\"\nnode['postgresql']['dir'] = \"/var/lib/pgsql/9.4/data\"\nnode['postgresql']['config']['data_directory'] = node['postgresql']['dir']\nnode['postgresql']['client']['packages'] = [\"postgresql94\", \"postgresql94-devel\"]\nnode['postgresql']['server']['packages'] = [\"postgresql94-server\"]\nnode['postgresql']['server']['service_name'] = \"postgresql-9.4\"\nnode['postgresql']['contrib']['packages'] = [\"postgresql94-contrib\"]\nnode['postgresql']['setup_script'] = \"postgresql94-setup\"\n```\n\nYou may set `node['postgresql']['pgdg']['repo_rpm_url']` attributes to pick up recent [PGDG repo packages](http://yum.postgresql.org/repopackages.php).\n\n## Usage\n\nOn systems that need to connect to a PostgreSQL database, add to a run list `recipe[postgresql]` or `recipe[postgresql::client]`.\n\nOn systems that should be PostgreSQL servers, use `recipe[postgresql::server]` on a run list. This recipe does set a password for the `postgres` user. If you're using `chef server`, if the attribute `node['postgresql']['password']['postgres']` is not found, the recipe generates a random password and performs a node.save. (TODO: This is broken, as it disables the password.) If you're using `chef-solo`, you'll need to set the attribute `node['postgresql']['password']['postgres']` in your node's `json_attribs` file or in a role.\n\nOn Debian family systems, SSL will be enabled, as the packages on Debian/Ubuntu also generate the SSL certificates. If you use another platform and wish to use SSL in postgresql, then generate your SSL certificates and distribute them in your own cookbook, and set the `node['postgresql']['config']['ssl']` attribute to true in your role/cookboook/node.\n\nOn server systems, the postgres server is restarted when a configuration file changes. This can be changed to reload only by setting the following attribute:\n\n```ruby\nnode['postgresql']['server']['config_change_notify'] = :reload\n```\n\n## Chef Solo Note\n\nThe following node attribute is stored on the Chef Server when using `chef-client`. Because `chef-solo` does not connect to a server or save the node object at all, to have the password persist across `chef-solo` runs, you must specify them in the `json_attribs` file used. For Example:\n\n```\n{\n \"postgresql\": {\n \"password\": {\n \"postgres\": \"iloverandompasswordsbutthiswilldo\"\n }\n },\n \"run_list\": [\"recipe[postgresql::server]\"]\n}\n```\n\nThat should actually be the \"encrypted password\" instead of cleartext, so you should generate it as an md5 hash using the PostgreSQL algorithm.\n\n- You could copy the md5-hashed password from an existing postgres database if you have `postgres` access and want to use the same password:
\n `select * from pg_shadow where usename='postgres';`\n- You can run this from any postgres database session to use a new password:
\n `select 'md5'||md5('iloverandompasswordsbutthiswilldo'||'postgres');`\n- You can run this from a linux commandline:
\n `echo -n 'iloverandompasswordsbutthiswilldo''postgres' | openssl md5 | sed -e 's/.* /md5/'`\n\n## License\n\nCopyright 2010-2016, Chef Software, Inc.\n\n```text\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":"Sous Chefs","maintainer_email":"help@sous-chefs.org","license":"Apache 2.0","platforms":{"ubuntu":">= 12.04","debian":">= 7.0","opensuse":">= 13.0","suse":">= 12.0","fedora":">= 0.0.0","opensuseleap":">= 0.0.0","amazon":">= 0.0.0","redhat":">= 6.0","centos":">= 6.0","scientific":">= 6.0","oracle":">= 6.0"},"dependencies":{"compat_resource":">= 12.16.3","build-essential":">= 2.0.0","openssl":">= 4.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{"postgresql::default":"Includes postgresql::client","postgresql::ruby":"Installs pg gem for Ruby bindings","postgresql::client":"Installs postgresql client package(s)","postgresql::server":"Installs postgresql server packages, templates"}} \ No newline at end of file diff --git a/cookbooks/postgresql/metadata.rb b/cookbooks/postgresql/metadata.rb deleted file mode 100644 index 30a4ae0..0000000 --- a/cookbooks/postgresql/metadata.rb +++ /dev/null @@ -1,28 +0,0 @@ -name "postgresql" -maintainer "Heavy Water Operations, LLC" -maintainer_email "helpdesk@heavywater.io" -license "Apache 2.0" -description "Installs and configures postgresql for clients or servers" -long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -version "4.0.0" -recipe "postgresql", "Includes postgresql::client" -recipe "postgresql::ruby", "Installs pg gem for Ruby bindings" -recipe "postgresql::client", "Installs postgresql client package(s)" -recipe "postgresql::server", "Installs postgresql server packages, templates" -recipe "postgresql::server_redhat", "Installs postgresql server packages, redhat family style" -recipe "postgresql::server_debian", "Installs postgresql server packages, debian family style" - - -supports "ubuntu", "< 14.10" - -%w{debian fedora suse opensuse amazon}.each do |os| - supports os -end - -%w{redhat centos scientific oracle}.each do |el| - supports el, "~> 6.0" -end - -depends "apt", ">= 1.9.0" -depends "build-essential" -depends "openssl", "~> 4.0" diff --git a/cookbooks/postgresql/recipes/apt_pgdg_postgresql.rb b/cookbooks/postgresql/recipes/apt_pgdg_postgresql.rb index bab1afe..437cf37 100644 --- a/cookbooks/postgresql/recipes/apt_pgdg_postgresql.rb +++ b/cookbooks/postgresql/recipes/apt_pgdg_postgresql.rb @@ -1,14 +1,4 @@ -if not %w(jessie squeeze wheezy sid lucid precise saucy trusty utopic).include? node['postgresql']['pgdg']['release_apt_codename'] - raise "Not supported release by PGDG apt repository" -end - -include_recipe 'apt' - -file "remove deprecated Pitti PPA apt repository" do - action :delete - path "/etc/apt/sources.list.d/pitti-postgresql-ppa" -end - +# frozen_string_literal: true apt_repository 'apt.postgresql.org' do uri 'http://apt.postgresql.org/pub/repos/apt' distribution "#{node['postgresql']['pgdg']['release_apt_codename']}-pgdg" diff --git a/cookbooks/postgresql/recipes/ca_certificates.rb b/cookbooks/postgresql/recipes/ca_certificates.rb index f187281..67b14ef 100644 --- a/cookbooks/postgresql/recipes/ca_certificates.rb +++ b/cookbooks/postgresql/recipes/ca_certificates.rb @@ -1,6 +1,2 @@ -# some older linux distributions have expired certificate bundles -# for pgdg repositories. Upgrading this package before trying to -# install postgresql is necessary. -package "ca-certificates" do - action :upgrade -end +# frozen_string_literal: true +Chef::Log.warn('The postgresql::ca-certificates recipe has been deprecated and will be removed in the next major release of the cookbook') diff --git a/cookbooks/postgresql/recipes/client.rb b/cookbooks/postgresql/recipes/client.rb index 20d6774..2158e48 100644 --- a/cookbooks/postgresql/recipes/client.rb +++ b/cookbooks/postgresql/recipes/client.rb @@ -1,5 +1,6 @@ +# frozen_string_literal: true # -# Cookbook Name:: postgresql +# Cookbook:: postgresql # Recipe:: client # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,23 +16,19 @@ # limitations under the License. # -include_recipe "postgresql::ca_certificates" - case node['platform_family'] when 'debian' if node['postgresql']['version'].to_f > 9.3 - node.set['postgresql']['enable_pgdg_apt'] = true + node.normal['postgresql']['enable_pgdg_apt'] = true end if node['postgresql']['enable_pgdg_apt'] include_recipe 'postgresql::apt_pgdg_postgresql' end -when 'rhel' +when 'rhel', 'fedora' if node['postgresql']['enable_pgdg_yum'] include_recipe 'postgresql::yum_pgdg_postgresql' end end -node['postgresql']['client']['packages'].each do |pkg| - package pkg -end +package node['postgresql']['client']['packages'] diff --git a/cookbooks/postgresql/recipes/config_initdb.rb b/cookbooks/postgresql/recipes/config_initdb.rb index 92973ef..f0d3844 100644 --- a/cookbooks/postgresql/recipes/config_initdb.rb +++ b/cookbooks/postgresql/recipes/config_initdb.rb @@ -1,5 +1,6 @@ +# frozen_string_literal: true # -# Cookbook Name:: postgresql +# Cookbook:: postgresql # Recipe:: config_initdb # Author:: David Crane () # @@ -69,23 +70,23 @@ # Locale Configuration # See libraries/default.rb for the locale_date_order() method. -node.default['postgresql']['config']['datestyle'] = "iso, #{locale_date_order()}" +node.default['postgresql']['config']['datestyle'] = "iso, #{locale_date_order}" # According to the locale(1) manpage, the locale settings are determined # by environment variables according to the following precedence: # LC_ALL > (LC_MESSAGES, LC_MONETARY, LC_NUMERIC, LC_TIME) > LANG. node.default['postgresql']['config']['lc_messages'] = - [ ENV['LC_ALL'], ENV['LC_MESSAGES'], ENV['LANG'] ].compact.first + [ENV['LC_ALL'], ENV['LC_MESSAGES'], ENV['LANG']].compact.first node.default['postgresql']['config']['lc_monetary'] = - [ ENV['LC_ALL'], ENV['LC_MONETARY'], ENV['LANG'] ].compact.first + [ENV['LC_ALL'], ENV['LC_MONETARY'], ENV['LANG']].compact.first node.default['postgresql']['config']['lc_numeric'] = - [ ENV['LC_ALL'], ENV['LC_NUMERIC'], ENV['LANG'] ].compact.first + [ENV['LC_ALL'], ENV['LC_NUMERIC'], ENV['LANG']].compact.first node.default['postgresql']['config']['lc_time'] = - [ ENV['LC_ALL'], ENV['LC_TIME'], ENV['LANG'] ].compact.first + [ENV['LC_ALL'], ENV['LC_TIME'], ENV['LANG']].compact.first node.default['postgresql']['config']['default_text_search_config'] = case ENV['LANG'] @@ -119,8 +120,6 @@ node.default['postgresql']['config']['default_text_search_config'] = 'pg_catalog.swedish' when /tr_.*/ 'pg_catalog.turkish' - else - nil end ####### @@ -130,11 +129,11 @@ node.default['postgresql']['config']['default_text_search_config'] = # defaults for the postgresql.cof settings. If the timezone cannot be # identified, do as initdb would do: leave it unspecified so PostgreSQL # uses it's internal default of GMT. -tzdirpath = pg_TZDIR() # See libraries/default.rb +tzdirpath = pg_TZDIR # See libraries/default.rb default_timezone = select_default_timezone(tzdirpath) # See libraries/default.rb -if !default_timezone.nil? - node.default['postgresql']['config']['log_timezone'] = default_timezone - node.default['postgresql']['config']['timezone'] = default_timezone +unless default_timezone.nil? + node.default['postgresql']['config']['log_timezone'] = default_timezone + node.default['postgresql']['config']['timezone'] = default_timezone end ####### diff --git a/cookbooks/postgresql/recipes/config_pgtune.rb b/cookbooks/postgresql/recipes/config_pgtune.rb index 361bae7..f34fa67 100644 --- a/cookbooks/postgresql/recipes/config_pgtune.rb +++ b/cookbooks/postgresql/recipes/config_pgtune.rb @@ -1,5 +1,6 @@ +# frozen_string_literal: true # -# Cookbook Name:: postgresql +# Cookbook:: postgresql # Recipe:: config_pgtune # Author:: David Crane () # @@ -86,35 +87,35 @@ # Parse out db_type option, or use default. db_type = 'mixed' -if (node['postgresql'].attribute?('config_pgtune') && node['postgresql']['config_pgtune'].attribute?('db_type')) +if node['postgresql'].attribute?('config_pgtune') && node['postgresql']['config_pgtune'].attribute?('db_type') db_type = node['postgresql']['config_pgtune']['db_type'] - if (!(["dw","oltp","web","mixed","desktop"].include?(db_type))) + unless %w(dw oltp web mixed desktop).include?(db_type) Chef::Log.fatal([ - "Bad value (#{db_type})", - "for node['postgresql']['config_pgtune']['db_type'] attribute.", - "Valid values are one of dw, oltp, web, mixed, desktop." - ].join(' ')) + "Bad value (#{db_type})", + "for node['postgresql']['config_pgtune']['db_type'] attribute.", + 'Valid values are one of dw, oltp, web, mixed, desktop.', + ].join(' ')) raise end end # Parse out max_connections option, or use a value based on db_type. con = -{ "web" => 200, - "oltp" => 300, - "dw" => 20, - "mixed" => 80, - "desktop" => 5 -}.fetch(db_type) + { 'web' => 200, + 'oltp' => 300, + 'dw' => 20, + 'mixed' => 80, + 'desktop' => 5, + }.fetch(db_type) -if (node['postgresql'].attribute?('config_pgtune') && node['postgresql']['config_pgtune'].attribute?('max_connections')) +if node['postgresql'].attribute?('config_pgtune') && node['postgresql']['config_pgtune'].attribute?('max_connections') max_connections = node['postgresql']['config_pgtune']['max_connections'].to_i if max_connections <= 0 Chef::Log.fatal([ - "Bad value (#{max_connections})", - "for node['postgresql']['config_pgtune']['max_connections'] attribute.", - "Valid values are non-zero integers only." - ].join(' ')) + "Bad value (#{max_connections})", + "for node['postgresql']['config_pgtune']['max_connections'] attribute.", + 'Valid values are non-zero integers only.', + ].join(' ')) raise end con = max_connections @@ -125,19 +126,19 @@ total_memory = node['memory']['total'] # Override max_connections with a node attribute if DevOps desires. # For example, on a system *not* dedicated to Postgresql. -if (node['postgresql'].attribute?('config_pgtune') && node['postgresql']['config_pgtune'].attribute?('total_memory')) +if node['postgresql'].attribute?('config_pgtune') && node['postgresql']['config_pgtune'].attribute?('total_memory') total_memory = node['postgresql']['config_pgtune']['total_memory'] - if (total_memory.match(/\A[1-9]\d*kB\Z/) == nil) + if total_memory.match(/\A[1-9]\d*kB\Z/).nil? Chef::Application.fatal!([ - "Bad value (#{total_memory})", - "for node['postgresql']['config_pgtune']['total_memory'] attribute.", - "Valid values are non-zero integers followed by kB (e.g., 49416564kB)." - ].join(' ')) + "Bad value (#{total_memory})", + "for node['postgresql']['config_pgtune']['total_memory'] attribute.", + 'Valid values are non-zero integers followed by kB (e.g., 49416564kB).', + ].join(' ')) end end # Ohai reports node[:memory][:total] in kB, as in "921756kB" -mem = total_memory.split("kB")[0].to_i / 1024 # in MB +mem = total_memory.split('kB')[0].to_i / 1024 # in MB ####### # RAM-related settings computed as in Greg Smith's pgtune script. @@ -152,79 +153,73 @@ node.default['postgresql']['config']['max_connections'] = con # for low memory systems. In that case, the calculation is skipped, # leaving the built-in Postgresql settings, which are actually # intended for those low memory systems. -if (mem >= 256) +if mem >= 256 # (2) shared_buffers # Sets the number of shared memory buffers used by the server. shared_buffers = - { "web" => mem/4, - "oltp" => mem/4, - "dw" => mem/4, - "mixed" => mem/4, - "desktop" => mem/16 - }.fetch(db_type) + { 'web' => mem / 4, + 'oltp' => mem / 4, + 'dw' => mem / 4, + 'mixed' => mem / 4, + 'desktop' => mem / 16, + }.fetch(db_type) # Robert Haas has advised to cap the size of shared_buffers based on # the memory architecture: 2GB on 32-bit and 8GB on 64-bit machines. # http://rhaas.blogspot.com/2012/03/tuning-sharedbuffers-and-walbuffers.html case node['kernel']['machine'] - when "i386" # 32-bit machines - if shared_buffers > 2*1024 - shared_buffers = 2*1024 - end - when "x86_64" # 64-bit machines - if shared_buffers > 8*1024 - shared_buffers = 8*1024 - end + when 'i386' # 32-bit machines + shared_buffers = 2 * 1024 if shared_buffers > 2 * 1024 + when 'x86_64' # 64-bit machines + shared_buffers = 8 * 1024 if shared_buffers > 8 * 1024 end - node.default['postgresql']['config']['shared_buffers'] = binaryround(shared_buffers*1024*1024) + node.default['postgresql']['config']['shared_buffers'] = binaryround(shared_buffers * 1024 * 1024) # (3) effective_cache_size # Sets the planner's assumption about the size of the disk cache. # That is, the portion of the kernel's disk cache that will be # used for PostgreSQL data files. effective_cache_size = - { "web" => mem * 3 / 4, - "oltp" => mem * 3 / 4, - "dw" => mem * 3 / 4, - "mixed" => mem * 3 / 4, - "desktop" => mem / 4 - }.fetch(db_type) + { 'web' => mem * 3 / 4, + 'oltp' => mem * 3 / 4, + 'dw' => mem * 3 / 4, + 'mixed' => mem * 3 / 4, + 'desktop' => mem / 4, + }.fetch(db_type) - node.default['postgresql']['config']['effective_cache_size'] = binaryround(effective_cache_size*1024*1024) + node.default['postgresql']['config']['effective_cache_size'] = binaryround(effective_cache_size * 1024 * 1024) # (4) work_mem # Sets the maximum memory to be used for query workspaces. mem_con_v = (mem.to_f / con).ceil work_mem = - { "web" => mem_con_v, - "oltp" => mem_con_v, - "dw" => mem_con_v / 2, - "mixed" => mem_con_v / 2, - "desktop" => mem_con_v / 6 + { 'web' => mem_con_v, + 'oltp' => mem_con_v, + 'dw' => mem_con_v / 2, + 'mixed' => mem_con_v / 2, + 'desktop' => mem_con_v / 6, }.fetch(db_type) - node.default['postgresql']['config']['work_mem'] = binaryround(work_mem*1024*1024) + node.default['postgresql']['config']['work_mem'] = binaryround(work_mem * 1024 * 1024) # (5) maintenance_work_mem # Sets the maximum memory to be used for maintenance operations. # This includes operations such as VACUUM and CREATE INDEX. maintenance_work_mem = - { "web" => mem / 16, - "oltp" => mem / 16, - "dw" => mem / 8, - "mixed" => mem / 16, - "desktop" => mem / 16 - }.fetch(db_type) + { 'web' => mem / 16, + 'oltp' => mem / 16, + 'dw' => mem / 8, + 'mixed' => mem / 16, + 'desktop' => mem / 16, + }.fetch(db_type) # Cap maintenence RAM at 1GB on servers with lots of memory - if (maintenance_work_mem > 1*1024) - maintenance_work_mem = 1*1024 - end + maintenance_work_mem = 1 * 1024 if maintenance_work_mem > 1 * 1024 - node.default['postgresql']['config']['maintenance_work_mem'] = binaryround(maintenance_work_mem*1024*1024) + node.default['postgresql']['config']['maintenance_work_mem'] = binaryround(maintenance_work_mem * 1024 * 1024) end @@ -235,25 +230,29 @@ end # (6) checkpoint_segments # Sets the maximum distance in log segments between automatic WAL checkpoints. checkpoint_segments = -{ "web" => 8, - "oltp" => 16, - "dw" => 64, - "mixed" => 16, - "desktop" => 3 -}.fetch(db_type) + { 'web' => 8, + 'oltp' => 16, + 'dw' => 64, + 'mixed' => 16, + 'desktop' => 3, + }.fetch(db_type) -node.default['postgresql']['config']['checkpoint_segments'] = checkpoint_segments +if node['postgresql']['version'].to_f >= 9.5 + node.default['postgresql']['config']['max_wal_size'] = ((3 * checkpoint_segments) * 16).to_s + 'MB' +else + node.default['postgresql']['config']['checkpoint_segments'] = checkpoint_segments +end # (7) checkpoint_completion_target # Time spent flushing dirty buffers during checkpoint, as fraction # of checkpoint interval. checkpoint_completion_target = -{ "web" => "0.7", - "oltp" => "0.9", - "dw" => "0.9", - "mixed" => "0.9", - "desktop" => "0.5" -}.fetch(db_type) + { 'web' => '0.7', + 'oltp' => '0.9', + 'dw' => '0.9', + 'mixed' => '0.9', + 'desktop' => '0.5', + }.fetch(db_type) node.default['postgresql']['config']['checkpoint_completion_target'] = checkpoint_completion_target @@ -264,9 +263,9 @@ node.default['postgresql']['config']['checkpoint_completion_target'] = checkpoin if node['postgresql']['version'].to_f < 9.1 wal_buffers = 512 * checkpoint_segments # The pgtune seems to use 1kB units for wal_buffers - node.default['postgresql']['config']['wal_buffers'] = binaryround(wal_buffers*1024) + node.default['postgresql']['config']['wal_buffers'] = binaryround(wal_buffers * 1024) else - node.default['postgresql']['config']['wal_buffers'] = "-1" + node.default['postgresql']['config']['wal_buffers'] = '-1' end # (9) default_statistics_target @@ -274,11 +273,11 @@ end # that have not had a column-specific target set via # ALTER TABLE SET STATISTICS. default_statistics_target = -{ "web" => 100, - "oltp" => 100, - "dw" => 500, - "mixed" => 100, - "desktop" => 100 -}.fetch(db_type) + { 'web' => 100, + 'oltp' => 100, + 'dw' => 500, + 'mixed' => 100, + 'desktop' => 100, + }.fetch(db_type) node.default['postgresql']['config']['default_statistics_target'] = default_statistics_target diff --git a/cookbooks/postgresql/recipes/contrib.rb b/cookbooks/postgresql/recipes/contrib.rb index e4cae04..8990b58 100644 --- a/cookbooks/postgresql/recipes/contrib.rb +++ b/cookbooks/postgresql/recipes/contrib.rb @@ -1,5 +1,6 @@ +# frozen_string_literal: true # -# Cookbook Name:: postgresql +# Cookbook:: postgresql # Recipe:: contrib # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,26 +20,14 @@ db_name = node['postgresql']['database_name'] # Install the PostgreSQL contrib package(s) from the distribution, # as specified by the node attributes. -node['postgresql']['contrib']['packages'].each do |pg_pack| +package node['postgresql']['contrib']['packages'] - package pg_pack - -end - -include_recipe "postgresql::server" +include_recipe 'postgresql::server' # Install PostgreSQL contrib extentions into the database, as specified by the # node attribute node['postgresql']['database_name']. -if (node['postgresql']['contrib'].attribute?('extensions')) +if node['postgresql']['contrib'].attribute?('extensions') node['postgresql']['contrib']['extensions'].each do |pg_ext| - bash "install-#{pg_ext}-extension" do - user 'postgres' - code <<-EOH - echo 'CREATE EXTENSION IF NOT EXISTS "#{pg_ext}";' | psql -d "#{db_name}" - EOH - action :run - ::Chef::Resource.send(:include, Opscode::PostgresqlHelpers) - not_if {extension_installed?(pg_ext)} - end + postgresql_extension "#{db_name}/#{pg_ext}" end end diff --git a/cookbooks/postgresql/recipes/default.rb b/cookbooks/postgresql/recipes/default.rb index ea68f9b..0a25b15 100644 --- a/cookbooks/postgresql/recipes/default.rb +++ b/cookbooks/postgresql/recipes/default.rb @@ -1,5 +1,6 @@ +# frozen_string_literal: true # -# Cookbook Name:: postgresql +# Cookbook:: postgresql # Recipe:: default # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,4 +16,4 @@ # limitations under the License. # -include_recipe "postgresql::client" +include_recipe 'postgresql::client' diff --git a/cookbooks/postgresql/recipes/ruby.rb b/cookbooks/postgresql/recipes/ruby.rb index 68c9c71..2ab4bdc 100644 --- a/cookbooks/postgresql/recipes/ruby.rb +++ b/cookbooks/postgresql/recipes/ruby.rb @@ -1,5 +1,6 @@ +# frozen_string_literal: false # -# Cookbook Name:: postgresql +# Cookbook:: postgresql # Recipe:: ruby # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,70 +22,51 @@ begin require 'pg' rescue LoadError - - if platform_family?('ubuntu', 'debian') - e = execute 'apt-get update' do + if platform_family?('debian') + e = apt_update 'update' do action :nothing end - e.run_action(:run) unless ::File.exists?('/var/lib/apt/periodic/update-success-stamp') + e.run_action(:update) end - node.set['build-essential']['compile_time'] = true - include_recipe "build-essential" + node.override['build-essential']['compile_time'] = true + include_recipe 'build-essential' - if node['postgresql']['enable_pgdg_yum'] - package "ca-certificates" do - action :nothing - end.run_action(:upgrade) - - include_recipe "postgresql::yum_pgdg_postgresql" + if node['postgresql']['enable_pgdg_yum'] && platform_family?('rhel', 'fedora') + include_recipe 'postgresql::yum_pgdg_postgresql' rpm_platform = node['platform'] - rpm_platform_version = node['platform_version'].to_f.to_i.to_s + rpm_platform_version = node['platform_version'].to_i.to_s arch = node['kernel']['machine'] - resources("remote_file[#{Chef::Config[:file_cache_path]}/#{node[:postgresql][:pgdg][:repo_rpm_url][node[:postgresql][:version]][rpm_platform][rpm_platform_version][arch][:package]}]").run_action(:create) - resources("package[#{node[:postgresql][:pgdg][:repo_rpm_url][node[:postgresql][:version]][rpm_platform][rpm_platform_version][arch][:package]}]").run_action(:install) + resources("remote_file[#{Chef::Config[:file_cache_path]}/#{node['postgresql']['pgdg']['repo_rpm_url'][node['postgresql']['version']][rpm_platform][rpm_platform_version][arch]['package']}]").run_action(:create) + resources("package[#{node['postgresql']['pgdg']['repo_rpm_url'][node['postgresql']['version']][rpm_platform][rpm_platform_version][arch]['package']}]").run_action(:install) ENV['PATH'] = "/usr/pgsql-#{node['postgresql']['version']}/bin:#{ENV['PATH']}" - - node['postgresql']['client']['packages'].each do |pkg| - package pkg do - action :nothing - end.run_action(:install) - end - end - if node['postgresql']['enable_pgdg_apt'] - include_recipe "postgresql::apt_pgdg_postgresql" - resources("file[remove deprecated Pitti PPA apt repository]").run_action(:delete) - resources("apt_repository[apt.postgresql.org]").run_action(:add) - - node['postgresql']['client']['packages'].each do |pkg| - package pkg do - action :nothing - end.run_action(:install) - end - + if node['postgresql']['enable_pgdg_apt'] && platform_family?('debian') + include_recipe 'postgresql::apt_pgdg_postgresql' + resources('apt_repository[apt.postgresql.org]').run_action(:add) end - include_recipe "postgresql::client" + include_recipe 'postgresql::client' - node['postgresql']['client']['packages'].each do |pkg| - package pkg do - action :nothing - end.run_action(:install) - end + package node['postgresql']['client']['packages'] do + action :nothing + end.run_action(:install) begin - chef_gem "pg" + chef_gem 'pg' do + compile_time true + version node['postgresql']['pg_gem']['version'] if node['postgresql']['pg_gem']['version'] + end rescue Gem::Installer::ExtensionBuildError, Mixlib::ShellOut::ShellCommandFailed => e # Are we an omnibus install? - raise if RbConfig.ruby.scan(%r{(chef|opscode)}).empty? + raise if RbConfig.ruby.scan(/(chef|opscode)/).empty? # Still here, must be omnibus. Lets make this thing install! Chef::Log.warn 'Failed to properly build pg gem. Forcing properly linking and retrying (omnibus fix)' - gem_dir = e.message.scan(%r{will remain installed in ([^ ]+)}).flatten.first + gem_dir = e.message.scan(/will remain installed in ([^ ]+)/).flatten.first raise unless gem_dir gem_name = File.basename(gem_dir) ext_dir = File.join(gem_dir, 'ext') diff --git a/cookbooks/postgresql/recipes/server.rb b/cookbooks/postgresql/recipes/server.rb index 211d170..58c5419 100644 --- a/cookbooks/postgresql/recipes/server.rb +++ b/cookbooks/postgresql/recipes/server.rb @@ -1,5 +1,6 @@ +# frozen_string_literal: true # -# Cookbook Name:: postgresql +# Cookbook:: postgresql # Recipe:: server # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,25 +16,23 @@ # limitations under the License. # -include_recipe "postgresql::ca_certificates" - ::Chef::Recipe.send(:include, OpenSSLCookbook::RandomPassword) -include_recipe "postgresql::client" +include_recipe 'postgresql::client' # randomly generate postgres password, unless using solo - see README if Chef::Config[:solo] - missing_attrs = %w{ + missing_attrs = %w( postgres - }.select do |attr| + ).select do |attr| node['postgresql']['password'][attr].nil? end.map { |attr| "node['postgresql']['password']['#{attr}']" } - if !missing_attrs.empty? + unless missing_attrs.empty? Chef::Log.fatal([ - "You must set #{missing_attrs.join(', ')} in chef-solo mode.", - "For more information, see https://github.com/opscode-cookbooks/postgresql#chef-solo-note" - ].join(' ')) + "You must set #{missing_attrs.join(', ')} in chef-solo mode.", + 'For more information, see https://github.com/opscode-cookbooks/postgresql#chef-solo-note', + ].join(' ')) raise end else @@ -44,7 +43,7 @@ else # useful if it weren't saved as clear text in Chef Server for later # retrieval. unless node.key?('postgresql') && node['postgresql'].key?('password') && node['postgresql']['password'].key?('postgres') - node.set_unless['postgresql']['password']['postgres'] = random_password(length: 20, mode: :base64) + node.normal_unless['postgresql']['password']['postgres'] = random_password(length: 20, mode: :base64) node.save end end @@ -52,30 +51,29 @@ end # Include the right "family" recipe for installing the server # since they do things slightly differently. case node['platform_family'] -when "rhel", "fedora" - node.set['postgresql']['dir'] = "/var/lib/pgsql/#{node['postgresql']['version']}/data" - node.set['postgresql']['config']['data_directory'] = "/var/lib/pgsql/#{node['postgresql']['version']}/data" - include_recipe "postgresql::server_redhat" -when "debian" - node.set['postgresql']['config']['data_directory'] = "/var/lib/postgresql/#{node['postgresql']['version']}/main" - include_recipe "postgresql::server_debian" +when 'rhel', 'fedora' + node.normal['postgresql']['dir'] = "/var/lib/pgsql/#{node['postgresql']['version']}/data" + node.normal['postgresql']['config']['data_directory'] = "/var/lib/pgsql/#{node['postgresql']['version']}/data" + include_recipe 'postgresql::server_redhat' +when 'debian' + node.normal['postgresql']['config']['data_directory'] = "/var/lib/postgresql/#{node['postgresql']['version']}/main" + include_recipe 'postgresql::server_debian' when 'suse' - node.set['postgresql']['config']['data_directory'] = node['postgresql']['dir'] - include_recipe "postgresql::server_redhat" + node.normal['postgresql']['config']['data_directory'] = node['postgresql']['dir'] + include_recipe 'postgresql::server_redhat' end # Versions prior to 9.2 do not have a config file option to set the SSL # key and cert path, and instead expect them to be in a specific location. -if node['postgresql']['version'].to_f < 9.2 && node['postgresql']['config'].attribute?('ssl_cert_file') - link ::File.join(node['postgresql']['config']['data_directory'], 'server.crt') do - to node['postgresql']['config']['ssl_cert_file'] - end + +link ::File.join(node['postgresql']['config']['data_directory'], 'server.crt') do + to node['postgresql']['config']['ssl_cert_file'] + only_if { node['postgresql']['version'].to_f < 9.2 && node['postgresql']['config'].attribute?('ssl_cert_file') } end -if node['postgresql']['version'].to_f < 9.2 && node['postgresql']['config'].attribute?('ssl_key_file') - link ::File.join(node['postgresql']['config']['data_directory'], 'server.key') do - to node['postgresql']['config']['ssl_key_file'] - end +link ::File.join(node['postgresql']['config']['data_directory'], 'server.key') do + to node['postgresql']['config']['ssl_key_file'] + only_if { node['postgresql']['version'].to_f < 9.2 && node['postgresql']['config'].attribute?('ssl_key_file') } end # NOTE: Consider two facts before modifying "assign-postgres-password": @@ -86,7 +84,7 @@ end # setting the same password. This chef recipe doesn't have access to # the plain text password, and testing the encrypted (md5 digest) # version is not straight-forward. -bash "assign-postgres-password" do +bash 'assign-postgres-password' do user 'postgres' code <<-EOH echo "ALTER ROLE postgres ENCRYPTED PASSWORD \'#{node['postgresql']['password']['postgres']}\';" | psql -p #{node['postgresql']['config']['port']} diff --git a/cookbooks/postgresql/recipes/server_conf.rb b/cookbooks/postgresql/recipes/server_conf.rb index 39af1a6..f9d284f 100644 --- a/cookbooks/postgresql/recipes/server_conf.rb +++ b/cookbooks/postgresql/recipes/server_conf.rb @@ -1,5 +1,6 @@ +# frozen_string_literal: true # -# Cookbook Name:: postgresql +# Cookbook:: postgresql # Recipe:: server # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,37 +21,35 @@ change_notify = node['postgresql']['server']['config_change_notify'] # There are some configuration items which depend on correctly evaluating the intended version being installed if node['platform_family'] == 'debian' - node.set['postgresql']['config']['hba_file'] = "/etc/postgresql/#{node['postgresql']['version']}/main/pg_hba.conf" - node.set['postgresql']['config']['ident_file'] = "/etc/postgresql/#{node['postgresql']['version']}/main/pg_ident.conf" - node.set['postgresql']['config']['external_pid_file'] = "/var/run/postgresql/#{node['postgresql']['version']}-main.pid" + node.normal['postgresql']['config']['hba_file'] = "/etc/postgresql/#{node['postgresql']['version']}/main/pg_hba.conf" + node.normal['postgresql']['config']['ident_file'] = "/etc/postgresql/#{node['postgresql']['version']}/main/pg_ident.conf" + node.normal['postgresql']['config']['external_pid_file'] = "/var/run/postgresql/#{node['postgresql']['version']}-main.pid" if node['postgresql']['version'].to_f < 9.3 - node.set['postgresql']['config']['unix_socket_directory'] = '/var/run/postgresql' + node.normal['postgresql']['config']['unix_socket_directory'] = '/var/run/postgresql' else - node.set['postgresql']['config']['unix_socket_directories'] = '/var/run/postgresql' + node.normal['postgresql']['config']['unix_socket_directories'] = '/var/run/postgresql' end - node.set['postgresql']['config']['max_fsm_pages'] = 153600 if node['postgresql']['version'].to_f < 8.4 - if node['postgresql']['config']['ssl'] - node.set['postgresql']['config']['ssl_cert_file'] = '/etc/ssl/certs/ssl-cert-snakeoil.pem' if node['postgresql']['version'].to_f >= 9.2 - node.set['postgresql']['config']['ssl_key_file'] = '/etc/ssl/private/ssl-cert-snakeoil.key'if node['postgresql']['version'].to_f >= 9.2 + node.normal['postgresql']['config']['ssl_cert_file'] = '/etc/ssl/certs/ssl-cert-snakeoil.pem' if node['postgresql']['version'].to_f >= 9.2 + node.normal['postgresql']['config']['ssl_key_file'] = '/etc/ssl/private/ssl-cert-snakeoil.key' if node['postgresql']['version'].to_f >= 9.2 end end template "#{node['postgresql']['dir']}/postgresql.conf" do - source "postgresql.conf.erb" - owner "postgres" - group "postgres" - mode 0600 + source 'postgresql.conf.erb' + owner 'postgres' + group 'postgres' + mode '0600' notifies change_notify, 'service[postgresql]', :immediately end template "#{node['postgresql']['dir']}/pg_hba.conf" do - source "pg_hba.conf.erb" - owner "postgres" - group "postgres" - mode 00600 + source 'pg_hba.conf.erb' + owner 'postgres' + group 'postgres' + mode '0600' notifies change_notify, 'service[postgresql]', :immediately end diff --git a/cookbooks/postgresql/recipes/server_debian.rb b/cookbooks/postgresql/recipes/server_debian.rb index 65da795..292b805 100644 --- a/cookbooks/postgresql/recipes/server_debian.rb +++ b/cookbooks/postgresql/recipes/server_debian.rb @@ -1,5 +1,6 @@ +# frozen_string_literal: true # -# Cookbook Name:: postgresql +# Cookbook:: postgresql # Recipe:: server # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,19 +16,15 @@ # limitations under the License. # -include_recipe "postgresql::client" +include_recipe 'postgresql::client' -node['postgresql']['server']['packages'].each do |pg_pack| +package node['postgresql']['server']['packages'] - package pg_pack +include_recipe 'postgresql::server_conf' -end - -include_recipe "postgresql::server_conf" - -service "postgresql" do +service 'postgresql' do service_name node['postgresql']['server']['service_name'] - supports :restart => true, :status => true, :reload => true + supports restart: true, status: true, reload: true action [:enable, :start] end diff --git a/cookbooks/postgresql/recipes/server_redhat.rb b/cookbooks/postgresql/recipes/server_redhat.rb index 1c0834c..45c9309 100644 --- a/cookbooks/postgresql/recipes/server_redhat.rb +++ b/cookbooks/postgresql/recipes/server_redhat.rb @@ -1,5 +1,6 @@ +# frozen_string_literal: true # -# Cookbook Name:: postgresql +# Cookbook:: postgresql # Recipe:: server # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,7 +16,7 @@ # limitations under the License. # -include_recipe "postgresql::client" +include_recipe 'postgresql::client' svc_name = node['postgresql']['server']['service_name'] initdb_locale = node['postgresql']['initdb_locale'] @@ -25,44 +26,39 @@ shortver = node['postgresql']['version'].split('.').join # Create a group and user like the package will. # Otherwise the templates fail. -group "postgres" do - gid 26 +group 'postgres' do + gid node['postgresql']['gid'] end -user "postgres" do - shell "/bin/bash" - comment "PostgreSQL Server" - home "/var/lib/pgsql" - gid "postgres" +user 'postgres' do + shell '/bin/bash' + comment 'PostgreSQL Server' + home '/var/lib/pgsql' + gid 'postgres' system true - uid 26 - supports :manage_home => false + uid node['postgresql']['uid'] + manage_home false end directory node['postgresql']['config']['data_directory'] do - owner "postgres" - group "postgres" + owner 'postgres' + group 'postgres' recursive true action :create + mode '0700' end -node['postgresql']['server']['packages'].each do |pg_pack| - - package pg_pack - -end +package node['postgresql']['server']['packages'] # If using PGDG, add symlinks so that downstream commands all work -if node['postgresql']['enable_pgdg_yum'] == true +if node['postgresql']['enable_pgdg_yum'] == true || node['postgresql']['use_pgdg_packages'] == true [ "postgresql#{shortver}-setup", - "postgresql#{shortver}-check-db-dir" + "postgresql#{shortver}-check-db-dir", ].each do |cmd| - link "/usr/bin/#{cmd}" do to "/usr/pgsql-#{node['postgresql']['version']}/bin/#{cmd}" end - end end @@ -71,22 +67,44 @@ end unless node['postgresql']['server']['init_package'] == 'systemd' - directory "/etc/sysconfig/pgsql" do - mode "0644" + directory '/etc/sysconfig/pgsql' do + mode '0644' recursive true action :create end template "/etc/sysconfig/pgsql/#{svc_name}" do - source "pgsql.sysconfig.erb" - mode "0644" - notifies :restart, "service[postgresql]", :delayed + source 'pgsql.sysconfig.erb' + mode '0644' + notifies :restart, 'service[postgresql]', :delayed end end if node['postgresql']['server']['init_package'] == 'systemd' + if node['platform_family'] == 'rhel' + + template_path = if node['postgresql']['use_pgdg_packages'] + "/etc/systemd/system/postgresql-#{node['postgresql']['version']}.service" + else + '/etc/systemd/system/postgresql.service' + end + + template template_path do + source 'postgresql.service.erb' + owner 'root' + group 'root' + mode '0644' + notifies :run, 'execute[systemctl-reload]', :immediately + notifies :reload, 'service[postgresql]', :delayed + end + execute 'systemctl-reload' do + command 'systemctl daemon-reload' + action :nothing + end + end + case node['platform_family'] when 'suse' execute "initdb -d #{node['postgresql']['dir']}" do @@ -99,7 +117,7 @@ if node['postgresql']['server']['init_package'] == 'systemd' end end -elsif (!platform_family?("suse") && node['postgresql']['version'].to_f <= 9.3) +elsif !platform_family?('suse') && node['postgresql']['version'].to_f <= 9.3 execute "/sbin/service #{svc_name} initdb #{initdb_locale}" do not_if { ::File.exist?("#{node['postgresql']['config']['data_directory']}/PG_VERSION") } @@ -113,10 +131,10 @@ else end -service "postgresql" do +service 'postgresql' do service_name svc_name - supports :restart => true, :status => true, :reload => true + supports restart: true, status: true, reload: true action [:enable, :start] end -include_recipe "postgresql::server_conf" +include_recipe 'postgresql::server_conf' diff --git a/cookbooks/postgresql/recipes/yum_pgdg_postgresql.rb b/cookbooks/postgresql/recipes/yum_pgdg_postgresql.rb index 97faeb8..0e03b72 100644 --- a/cookbooks/postgresql/recipes/yum_pgdg_postgresql.rb +++ b/cookbooks/postgresql/recipes/yum_pgdg_postgresql.rb @@ -1,5 +1,6 @@ +# frozen_string_literal: true # -# Cookbook Name:: postgresql +# Cookbook:: postgresql # Recipe::yum_pgdg_postgresql # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,16 +22,20 @@ rpm_platform = node['platform'] rpm_platform_version = node['platform_version'].to_f.to_i.to_s arch = node['kernel']['machine'] +pg_version = node['postgresql']['version'] +pgdg_setup = node['postgresql']['pgdg']['repo_rpm_url'][pg_version][rpm_platform][rpm_platform_version][arch] +pgdg_package = pgdg_setup['package'] +pgdg_repository = pgdg_setup['url'] # Download the PGDG repository RPM as a local file -remote_file "#{Chef::Config[:file_cache_path]}/#{node[:postgresql][:pgdg][:repo_rpm_url][node[:postgresql][:version]][rpm_platform][rpm_platform_version][arch][:package]}" do - source "#{node[:postgresql][:pgdg][:repo_rpm_url][node[:postgresql][:version]][rpm_platform][rpm_platform_version][arch][:url]}#{node[:postgresql][:pgdg][:repo_rpm_url][node[:postgresql][:version]][rpm_platform][rpm_platform_version][arch][:package]}" - mode "0644" +remote_file "#{Chef::Config[:file_cache_path]}/#{pgdg_package}" do + source "#{pgdg_repository}#{pgdg_package}" + mode '0644' end # Install the PGDG repository RPM from the local file -package "#{node[:postgresql][:pgdg][:repo_rpm_url][node[:postgresql][:version]][rpm_platform][rpm_platform_version][arch][:package]}" do +package pgdg_package.to_s do provider Chef::Provider::Package::Rpm - source "#{Chef::Config[:file_cache_path]}/#{node[:postgresql][:pgdg][:repo_rpm_url][node[:postgresql][:version]][rpm_platform][rpm_platform_version][arch][:package]}" + source "#{Chef::Config[:file_cache_path]}/#{pgdg_package}" action :install end diff --git a/cookbooks/postgresql/resources/extension.rb b/cookbooks/postgresql/resources/extension.rb new file mode 100644 index 0000000..5a279c3 --- /dev/null +++ b/cookbooks/postgresql/resources/extension.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true +# +# Cookbook:: postgresql +# Resource:: extension +# +# 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. +# + +include Opscode::PostgresqlHelpers + +# name property should take the form: +# database/extension + +property :database, String, + required: true, + default: lazy { name.scan(%r{\A[^/]+(?=/)}).first } + +property :extension, String, + required: true, + default: lazy { name.scan(%r{(?<=/)[^/]+\Z}).first } + +action :create do + bash "CREATE EXTENSION #{name}" do + code psql("CREATE EXTENSION IF NOT EXISTS \"#{extension}\"") + user 'postgres' + action :run + not_if { extension_installed? } + end +end + +action :drop do + bash "DROP EXTENSION #{name}" do + code psql("DROP EXTENSION IF EXISTS \"#{extension}\"") + user 'postgres' + action :run + only_if { extension_installed? } + end +end + +def psql(query) + "psql -d #{database} <<< '\\set ON_ERROR_STOP on\n#{query};'" +end + +def extension_installed? + query = "SELECT 'installed' FROM pg_extension WHERE extname = '#{extension}';" + !(execute_sql(query, database) =~ /^installed$/).nil? +end diff --git a/cookbooks/postgresql/templates/default/pg_hba.conf.erb b/cookbooks/postgresql/templates/default/pg_hba.conf.erb index 55d757d..0c38c78 100644 --- a/cookbooks/postgresql/templates/default/pg_hba.conf.erb +++ b/cookbooks/postgresql/templates/default/pg_hba.conf.erb @@ -18,7 +18,7 @@ <% node['postgresql']['pg_hba'].each do |auth| -%> <% if auth[:comment] %> -<%= auth[:comment] %> +# <%= auth[:comment] %> <% end %> <% if auth[:addr] %> <%= auth[:type].ljust(7) %> <%= auth[:db].ljust(15) %> <%= auth[:user].ljust(15) %> <%= auth[:addr].ljust(23) %> <%= auth[:method] %> diff --git a/cookbooks/postgresql/templates/default/postgresql.service.erb b/cookbooks/postgresql/templates/default/postgresql.service.erb new file mode 100644 index 0000000..00ffff4 --- /dev/null +++ b/cookbooks/postgresql/templates/default/postgresql.service.erb @@ -0,0 +1,10 @@ +[Service] +<% if node['postgresql']['use_pgdg_packages'] %> +.include /usr/lib/systemd/system/postgresql-<%= node['postgresql']['version'] %>.service +<% else %> +.include /usr/lib/systemd/system/postgresql.service +<% end %> + +Environment= +Environment=PGPORT=<%= node['postgresql']['config']['port'] %> +Environment=PGDATA=<%= node['postgresql']['config']['data_directory'] %> diff --git a/cookbooks/wordpress/README.md b/cookbooks/wordpress/README.md index 1a99f24..3e42565 100644 --- a/cookbooks/wordpress/README.md +++ b/cookbooks/wordpress/README.md @@ -51,7 +51,6 @@ Attributes * `node['wordpress']['db']['port']` - Port of the WordPress MySQL database. * `node['wordpress']['db']['charset']` - [Character set](http://dev.mysql.com/doc/refman/5.7/en/charset-charsets.html) of the WordPress MySQL database tables. Defaults to 'utf8'. * `node['wordpress']['db']['collate']` - [Collation](http://dev.mysql.com/doc/refman/5.7/en/charset-collation-effect.html) of the WordPress MySQL database tables. -* `node['wordpress']['db']['mysql_version']` - Version of MySQL to install (for supporting community cookbook version 6+) * `node['wordpress']['allow_multisite']` - Enable [multisite](http://codex.wordpress.org/Create_A_Network) features (default: false). * `node['wordpress']['wp_config_options']` - A hash of options to define in wp_config.php, output as key value pairs into a PHP constant e.g. `define( '<%= @key %>', <%= @value %> );`. Note: for values you will need to add single quotes around text but omit them for booleans and numbers. (default: {}). diff --git a/cookbooks/wordpress/attributes/default.rb b/cookbooks/wordpress/attributes/default.rb index 873753d..92d9b86 100644 --- a/cookbooks/wordpress/attributes/default.rb +++ b/cookbooks/wordpress/attributes/default.rb @@ -35,25 +35,6 @@ default['wordpress']['db']['host'] = 'localhost' default['wordpress']['db']['port'] = '3306' # Must be a string default['wordpress']['db']['charset'] = 'utf8' default['wordpress']['db']['collate'] = '' -case node['platform'] -when 'ubuntu' - case node['platform_version'] - when '10.04' - default['wordpress']['db']['mysql_version'] = '5.1' - else - default['wordpress']['db']['mysql_version'] = '5.5' - end -when 'centos', 'redhat', 'amazon', 'scientific' - if node['platform_version'].to_i < 6 - default['wordpress']['db']['mysql_version'] = '5.0' - elsif node['platform_version'].to_i < 7 - default['wordpress']['db']['mysql_version'] = '5.1' - else - default['wordpress']['db']['mysql_version'] = '5.5' - end -else - default['wordpress']['db']['mysql_version'] = '5.5' -end default['wordpress']['allow_multisite'] = false diff --git a/cookbooks/wordpress/metadata.rb b/cookbooks/wordpress/metadata.rb index 344c6c5..e7e8515 100644 --- a/cookbooks/wordpress/metadata.rb +++ b/cookbooks/wordpress/metadata.rb @@ -16,7 +16,7 @@ end depends "apache2", ">= 2.0.0" depends "database", ">= 1.6.0" depends "mysql", ">= 6.0" -depends "mysql2_chef_gem", "~> 1.0.1" +depends "mysql2_chef_gem", ">= 1.0.1" depends "build-essential" depends "iis", ">= 1.6.2" depends "tar", ">= 0.3.1" diff --git a/cookbooks/wordpress/recipes/database.rb b/cookbooks/wordpress/recipes/database.rb index 3f61d78..cdbac48 100644 --- a/cookbooks/wordpress/recipes/database.rb +++ b/cookbooks/wordpress/recipes/database.rb @@ -44,7 +44,6 @@ if is_local_host? db['host'] mysql_service db['instance_name'] do port db['port'] - version db['mysql_version'] initial_root_password db['root_password'] action [:create, :start] end @@ -52,6 +51,11 @@ if is_local_host? db['host'] socket = "/var/run/mysql-#{db['instance_name']}/mysqld.sock" if node['platform_family'] == 'debian' + directory "/var/run/mysqld" do + action :create + owner "mysql" + group "mysql" + end link '/var/run/mysqld/mysqld.sock' do to socket not_if 'test -f /var/run/mysqld/mysqld.sock' diff --git a/data_bags/credentials/mastodon.json b/data_bags/credentials/mastodon.json new file mode 100644 index 0000000..093ee62 --- /dev/null +++ b/data_bags/credentials/mastodon.json @@ -0,0 +1,45 @@ +{ + "id": "mastodon", + "paperclip_secret": { + "encrypted_data": "/rai6Zj08FBtOdhpwCuRU6gSvBeYrQ3IiZ+NKCThOB4k7TrJ5/DZ+Jl3Pz1l\n3yJ1QfVf8w5dBLiGFmlimEu0uMi4fQohTdpi4pIczARneH5M9pN6jY2ZkMoy\nnmuO95bKGgX4GZi33F3T+XwwEQ3LPm+a6Ml2S7Ycffcx2xbNqTH5e/lWX3qF\ngDYZZR+R9g0GSQ2L+pZAdRMxDZz/WufBSA==\n", + "iv": "nsdbLOcJOHGAt4T/R+bwDA==\n", + "version": 1, + "cipher": "aes-256-cbc" + }, + "secret_key_base": { + "encrypted_data": "uvrKsWy+34xFMoC82n6nx2bjZyx1qseHm3mg7FvC5XzyTomc3km0jdr0cGo8\ngydAwZU5rOB3vX+eA2vqipRbROUboOoSahAxfzDI3187NgBhZgcootsmVqaB\njPs0y1un2C6YCF8owT/eTMnqta+Sfzyc+1fWSYQtoWVgoEejc54gyGB+vWB0\nxiLoPsDRIYM1LstGu8AdKP77iDYRpAsYsA==\n", + "iv": "anBxz01wpEH2iNVWktADYg==\n", + "version": 1, + "cipher": "aes-256-cbc" + }, + "otp_secret": { + "encrypted_data": "q8BLFwwZU/hoinL8Aizd27fWj2SIBFLmM5n/LBBuUt4q4zuauA4591fkTlPH\n1vihDK9hE4xl90V1t6IIwj3IpBq9w53rfToJrBwxD1l63j41bEvJ39qr8gsh\nbH4xT/rzsyp5cWXrakCDIOuOHBuoFDlJetIY2BLDLXbqDEwFG4CI5YoPn0gV\nCPCNmRKITulem2YjqnGswFd/tvvR2X/w5Q==\n", + "iv": "BMjOeH9mAW0J3pRJAMFlKw==\n", + "version": 1, + "cipher": "aes-256-cbc" + }, + "aws_access_key_id": { + "encrypted_data": "wSevnv6+7QbJb4HNEaTCXzL+QzcES+QZFjS6gcPxP+JvAnQhhNmf0FwlqGP2\n4gXN\n", + "iv": "mVIoUHFYRQUY/u8ZqCdd/w==\n", + "version": 1, + "cipher": "aes-256-cbc" + }, + "aws_secret_access_key": { + "encrypted_data": "ZNBp33pfndINgpyiGpM4nQc1/TeSg2KmeOWGJTaxf6KggKnqN+ZIcW/FhWTN\n0IE1Z4cxBJpzK/voCbeEhZC5Sg==\n", + "iv": "p1lGI0p+EOpGcyzATvofCQ==\n", + "version": 1, + "cipher": "aes-256-cbc" + }, + "smtp_user_name": { + "encrypted_data": "ZbcFLsjQOtrY+5WoK5CFgOywm2HMO5aivoAXLEKIXCh/5NpOJuMWr13RSbhu\n31b/\n", + "iv": "t1+hKaEUwRee3LGQ6H0a7g==\n", + "version": 1, + "cipher": "aes-256-cbc" + }, + "smtp_password": { + "encrypted_data": "EDmXwQjtqpJpClc+vbe8L+h/599gcTIvIzq2p+T/cY8+qUAYQzZpsvboJiVI\n43YQxYNtJ7Lm784QDhRdbTAEtw==\n", + "iv": "cQq5ym70FasDRIMQM5CLSg==\n", + "version": 1, + "cipher": "aes-256-cbc" + } +} \ No newline at end of file diff --git a/site-cookbooks/5apps-hubot/metadata.rb b/site-cookbooks/5apps-hubot/metadata.rb index 77446db..b445a18 100644 --- a/site-cookbooks/5apps-hubot/metadata.rb +++ b/site-cookbooks/5apps-hubot/metadata.rb @@ -7,5 +7,6 @@ long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) version '0.1.0' depends 'kosmos-nodejs' -depends 'application' -depends 'application_nodejs' +depends 'application_javascript' +depends 'application_git' +depends 'firewall' diff --git a/site-cookbooks/5apps-hubot/recipes/xmpp_botka.rb b/site-cookbooks/5apps-hubot/recipes/xmpp_botka.rb index 2805424..0df8447 100644 --- a/site-cookbooks/5apps-hubot/recipes/xmpp_botka.rb +++ b/site-cookbooks/5apps-hubot/recipes/xmpp_botka.rb @@ -7,59 +7,99 @@ # All rights reserved - Do Not Redistribute # -firewall_rule 'hubot_express_botka_xmpp' do - port 8082 - protocol :tcp - command :allow +unless node.chef_environment == "development" + include_recipe "firewall" + firewall_rule 'hubot_express_botka_xmpp' do + port 8082 + protocol :tcp + command :allow + end +end + +group "hubot" do + gid 48268 +end + +user "hubot" do + system true + manage_home true + comment "hubot user" + uid 48268 + gid 48268 + + shell "/bin/bash" end botka_xmpp_data_bag_item = Chef::EncryptedDataBagItem.load('credentials', '5apps_botka_xmpp') -application "botka_xmpp" do - path "/srv/botka_xmpp" +botka_xmpp_path = "/opt/botka_xmpp" +application botka_xmpp_path do owner "hubot" group "hubot" - action :deploy - - before_restart do - file "#{new_resource.release_path}/external-scripts.json" do - mode "0640" - owner "hubot" - group "hubot" - content [ - "hubot-help", - "hubot-remotestorage-logger" - ].to_json - end - - file "#{new_resource.release_path}/external-scripts.json" do - mode "0640" - owner "hubot" - group "hubot" - content [].to_json - end + git do + user "hubot" + group "hubot" + repository "https://github.com/67P/botka.git" + revision "master" end - repository "https://github.com/67P/botka.git" - revision "master" + file "external-scripts.json" do + mode "0640" + owner "hubot" + group "hubot" + content [ + "hubot-help", + "hubot-remotestorage-logger" + ].to_json + end - nodejs do - entry_point "/srv/botka_xmpp/current/bin/hubot -a xmpp --name botka" - # Use our own systemd service that depends on redis-server - template "nodejs.systemd.service.erb" - environment "HUBOT_XMPP_USERNAME" => "botka@5apps.com/hubot", - "HUBOT_XMPP_PASSWORD" => botka_xmpp_data_bag_item['password'], - "HUBOT_XMPP_ROOMS" => "5info@muc.5apps.com,5ops@muc.5apps.com,core@muc.5apps.com,deploy@muc.5apps.com,storage@muc.5apps.com,watercooler@muc.5apps.com,hilti@muc.5apps.com,gymapp@muc.5apps.com", - "HUBOT_XMPP_HOST" => "xmpp.5apps.com", - "HUBOT_RSS_PRINTSUMMARY" => "false", - "EXPRESS_PORT" => "8082", - "HUBOT_RSS_HEADER" => "Update:", - "HUBOT_AUTH_ADMIN" => "basti,garret,greg", - "REDIS_URL" => "redis://localhost:6379/5apps_botka_xmpp", - "RS_LOGGER_USER" => "5apps@5apps.com", - "RS_LOGGER_TOKEN" => botka_xmpp_data_bag_item['rs_logger_token'], - "RS_LOGGER_SERVER_NAME" => "5apps", - "WEBHOOK_TOKEN" => botka_xmpp_data_bag_item['webhook_token'] + file "external-scripts.json" do + mode "0640" + owner "hubot" + group "hubot" + content [].to_json + end + + npm_install do + user "hubot" + end + + execute "systemctl daemon-reload" do + command "systemctl daemon-reload" + action :nothing + end + + template "/lib/systemd/system/botka_xmpp_nodejs.service" do + source 'nodejs.systemd.service.erb' + owner 'root' + group 'root' + mode '0644' + variables( + :user => "hubot", + :group => "hubot", + :app_dir => botka_xmpp_path, + :entry => "#{botka_xmpp_path}/bin/hubot -a xmpp --name botka", + :environment => { "HUBOT_XMPP_USERNAME" => "botka@5apps.com/hubot", + "HUBOT_XMPP_PASSWORD" => botka_xmpp_data_bag_item['password'], + "HUBOT_XMPP_ROOMS" => "5info@muc.5apps.com,5ops@muc.5apps.com,core@muc.5apps.com,deploy@muc.5apps.com,storage@muc.5apps.com,watercooler@muc.5apps.com,hilti@muc.5apps.com,gymapp@muc.5apps.com", + "HUBOT_XMPP_HOST" => "xmpp.5apps.com", + "HUBOT_RSS_PRINTSUMMARY" => "false", + "EXPRESS_PORT" => "8082", + "HUBOT_RSS_HEADER" => "Update:", + "HUBOT_AUTH_ADMIN" => "basti,garret,greg", + "REDIS_URL" => "redis://localhost:6379/5apps_botka_xmpp", + "RS_LOGGER_USER" => "5apps@5apps.com", + "RS_LOGGER_TOKEN" => botka_xmpp_data_bag_item['rs_logger_token'], + "RS_LOGGER_SERVER_NAME" => "5apps", + "WEBHOOK_TOKEN" => botka_xmpp_data_bag_item['webhook_token'] } + ) + + notifies :run, "execute[systemctl daemon-reload]", :delayed + notifies :restart, "service[botka_xmpp_nodejs]", :delayed + end + + service "botka_xmpp_nodejs" do + action [:enable, :start] end end diff --git a/site-cookbooks/5apps-hubot/recipes/xmpp_schlupp.rb b/site-cookbooks/5apps-hubot/recipes/xmpp_schlupp.rb index d43eb5d..3d5227a 100644 --- a/site-cookbooks/5apps-hubot/recipes/xmpp_schlupp.rb +++ b/site-cookbooks/5apps-hubot/recipes/xmpp_schlupp.rb @@ -7,62 +7,99 @@ # All rights reserved - Do Not Redistribute # -firewall_rule 'hubot_express_schlupp_xmpp' do - port 8083 - protocol :tcp - command :allow +unless node.chef_environment == "development" + include_recipe "firewall" + firewall_rule 'hubot_express_schlupp_xmpp' do + port 8083 + protocol :tcp + command :allow + end +end + +group "hubot" do + gid 48268 +end + +user "hubot" do + system true + manage_home true + comment "hubot user" + uid 48268 + gid 48268 + shell "/bin/bash" end schlupp_xmpp_data_bag_item = Chef::EncryptedDataBagItem.load('credentials', '5apps_schlupp_xmpp') -application "schlupp_xmpp" do - path "/srv/schlupp_xmpp" +schlupp_xmpp_path = "/opt/schlupp_xmpp" +application schlupp_xmpp_path do owner "hubot" group "hubot" - action :deploy - - before_restart do - # No hubot-remotestorage-logger, botka takes care of that - file "#{new_resource.release_path}/external-scripts.json" do - mode "0640" - owner "hubot" - group "hubot" - content [ - "hubot-auth", - "hubot-help", - "hubot-redis-brain", - "hubot-rules", - "hubot-shipit", - "hubot-plusplus", - "hubot-tell", - "hubot-seen", - "hubot-rss-reader", - "hubot-incoming-webhook", - "hubot-yubikey-invalidation" - ].to_json - end + git "git@gitlab.com:5apps/schlupp.git" do + user "hubot" + group "hubot" + revision "master" + deploy_key schlupp_xmpp_data_bag_item['deploy_key'] end - repository "git@gitlab.com:5apps/schlupp.git" - revision "master" - deploy_key schlupp_xmpp_data_bag_item['deploy_key'] + file "external-scripts.json" do + mode "0640" + owner "hubot" + group "hubot" + content [ + "hubot-auth", + "hubot-help", + "hubot-redis-brain", + "hubot-rules", + "hubot-shipit", + "hubot-plusplus", + "hubot-tell", + "hubot-seen", + "hubot-rss-reader", + "hubot-incoming-webhook", + "hubot-yubikey-invalidation" + ].to_json + end - nodejs do - entry_point "/srv/schlupp_xmpp/current/bin/hubot -a xmpp --name schlupp" - # Use our own systemd service that depends on redis-server - template "nodejs.systemd.service.erb" - environment "HUBOT_XMPP_USERNAME" => "schlupp@5apps.com/hubot", - "HUBOT_XMPP_PASSWORD" => schlupp_xmpp_data_bag_item['password'], - "HUBOT_XMPP_ROOMS" => "5info@muc.5apps.com,5ops@muc.5apps.com,core@muc.5apps.com,deploy@muc.5apps.com,storage@muc.5apps.com,watercooler@muc.5apps.com,hilti@muc.5apps.com,test@muc.5apps.com,gymapp@muc.5apps.com", - "HUBOT_XMPP_HOST" => "xmpp.5apps.com", - "HUBOT_RSS_PRINTSUMMARY" => "false", - "EXPRESS_PORT" => "8083", - "HUBOT_RSS_HEADER" => "Update:", - "HUBOT_AUTH_ADMIN" => "basti,garret,greg", - "REDIS_URL" => "redis://localhost:6379/5apps_schlupp_xmpp", - "RS_OPS_TOKEN" => schlupp_xmpp_data_bag_item['rs_ops_token'], - "WEBHOOK_TOKEN" => schlupp_xmpp_data_bag_item['webhook_token'], - "AIRTABLE_API_KEY" => schlupp_xmpp_data_bag_item['airtable_api_key'] + npm_install do + user "hubot" + end + + execute "systemctl daemon-reload" do + command "systemctl daemon-reload" + action :nothing + end + + template "/lib/systemd/system/schlupp_xmpp_nodejs.service" do + source 'nodejs.systemd.service.erb' + owner 'root' + group 'root' + mode '0644' + variables( + :user => "hubot", + :group => "hubot", + :app_dir => schlupp_xmpp_path, + :entry => "#{schlupp_xmpp_path}/bin/hubot -a xmpp --name schlupp", + :environment => { "HUBOT_XMPP_USERNAME" => "schlupp@5apps.com/hubot", + "HUBOT_XMPP_PASSWORD" => schlupp_xmpp_data_bag_item['password'], + "HUBOT_XMPP_ROOMS" => "5info@muc.5apps.com,5ops@muc.5apps.com,core@muc.5apps.com,deploy@muc.5apps.com,storage@muc.5apps.com,watercooler@muc.5apps.com,hilti@muc.5apps.com,test@muc.5apps.com,gymapp@muc.5apps.com", + "HUBOT_XMPP_HOST" => "xmpp.5apps.com", + "HUBOT_RSS_PRINTSUMMARY" => "false", + "EXPRESS_PORT" => "8083", + "HUBOT_RSS_HEADER" => "Update:", + "HUBOT_AUTH_ADMIN" => "basti,garret,greg", + "REDIS_URL" => "redis://localhost:6379/5apps_schlupp_xmpp", + "RS_OPS_TOKEN" => schlupp_xmpp_data_bag_item['rs_ops_token'], + "WEBHOOK_TOKEN" => schlupp_xmpp_data_bag_item['webhook_token'], + "AIRTABLE_API_KEY" => schlupp_xmpp_data_bag_item['airtable_api_key'] } + ) + + notifies :run, "execute[systemctl daemon-reload]", :delayed + notifies :restart, "service[schlupp_xmpp_nodejs]", :delayed + end + + service "schlupp_xmpp_nodejs" do + action [:enable, :start] end end diff --git a/site-cookbooks/5apps-xmpp_server/recipes/default.rb b/site-cookbooks/5apps-xmpp_server/recipes/default.rb index 7332052..6a4bfa4 100644 --- a/site-cookbooks/5apps-xmpp_server/recipes/default.rb +++ b/site-cookbooks/5apps-xmpp_server/recipes/default.rb @@ -7,10 +7,13 @@ # All rights reserved - Do Not Redistribute # -firewall_rule "xmpp" do - port [5222, 5269] - protocol :tcp - command :allow +unless node.chef_environment == "development" + include_recipe "firewall" + firewall_rule "xmpp" do + port [5222, 5269] + protocol :tcp + command :allow + end end apt_repository "prosody" do diff --git a/site-cookbooks/backup/recipes/default.rb b/site-cookbooks/backup/recipes/default.rb index 482753f..f02f585 100644 --- a/site-cookbooks/backup/recipes/default.rb +++ b/site-cookbooks/backup/recipes/default.rb @@ -24,7 +24,7 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. gem_package 'backup' do - version '4.2.3' + version '4.4.0' end backup_data = Chef::EncryptedDataBagItem.load('credentials', 'backup') diff --git a/site-cookbooks/backup/templates/default/config.rb.erb b/site-cookbooks/backup/templates/default/config.rb.erb index 6887e11..736aa33 100644 --- a/site-cookbooks/backup/templates/default/config.rb.erb +++ b/site-cookbooks/backup/templates/default/config.rb.erb @@ -45,6 +45,15 @@ Database::MySQL.defaults do |db| end <%- end -%> +<%- if node["backup"]["postgresql"] -%> +Database::MySQL.defaults do |db| + db.host = "<%= node["backup"]["postgresql"]["host"] %>" + db.username = "<%= node["backup"]["postgresql"]["username"] %>" + db.password = "<%= node["backup"]["postgresql"]["password"] %>" + db.additional_options = ['--quick', '--single-transaction'] +end +<%- end -%> + Database::Redis.defaults do |db| db.host = "<%= node["backup"]["redis"]["host"] %>" db.port = 6379 @@ -53,6 +62,20 @@ Database::Redis.defaults do |db| <%# db.socket = "/tmp/redis.sock"%> end +<%- if node["backup"]["postgresql"] -%> + database PostgreSQL do |db| + db.username = "" + db.password = "<%= node['postgresql']['password']['postgres'] %>" + db.host = "localhost" + db.port = 5432 + db.socket = "/tmp/pg.sock" + # When dumping all databases, `skip_tables` and `only_tables` are ignored. + db.skip_tables = ['skip', 'these', 'tables'] + db.only_tables = ['only', 'these' 'tables'] + db.additional_options = [] + end +<% end -%> + preconfigure 'KosmosBackup' do split_into_chunks_of 250 # megabytes store_with S3 diff --git a/site-cookbooks/kosmos-base/recipes/firewall.rb b/site-cookbooks/kosmos-base/recipes/firewall.rb index bbabe75..2aff21f 100644 --- a/site-cookbooks/kosmos-base/recipes/firewall.rb +++ b/site-cookbooks/kosmos-base/recipes/firewall.rb @@ -21,3 +21,21 @@ firewall_rule 'mosh' do protocol :udp command :allow end + +firewall_rule 'hubot_express_hal8000' do + port 8080 + protocol :tcp + command :allow +end + +firewall_rule 'hubot_express_botka_xmpp' do + port 8082 + protocol :tcp + command :allow +end + +firewall_rule 'hubot_express_schlupp_xmpp' do + port 8083 + protocol :tcp + command :allow +end diff --git a/site-cookbooks/kosmos-base/recipes/letsencrypt.rb b/site-cookbooks/kosmos-base/recipes/letsencrypt.rb index ad435e2..716c3a2 100644 --- a/site-cookbooks/kosmos-base/recipes/letsencrypt.rb +++ b/site-cookbooks/kosmos-base/recipes/letsencrypt.rb @@ -10,7 +10,7 @@ git "/usr/local/certbot" do repository "https://github.com/certbot/certbot" action :sync - revision "v0.12.0" + revision "v0.13.0" user "root" group "root" end diff --git a/site-cookbooks/kosmos-hubot/metadata.rb b/site-cookbooks/kosmos-hubot/metadata.rb index e3406c5..a41559b 100644 --- a/site-cookbooks/kosmos-hubot/metadata.rb +++ b/site-cookbooks/kosmos-hubot/metadata.rb @@ -7,5 +7,6 @@ long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) version '0.1.0' depends 'kosmos-nodejs' -depends 'application' -depends 'application_nodejs' +depends 'kosmos-redis' +depends 'firewall' +depends 'application_javascript' diff --git a/site-cookbooks/kosmos-hubot/recipes/default.rb b/site-cookbooks/kosmos-hubot/recipes/default.rb index 8b44001..e0f3fe6 100644 --- a/site-cookbooks/kosmos-hubot/recipes/default.rb +++ b/site-cookbooks/kosmos-hubot/recipes/default.rb @@ -2,15 +2,18 @@ # Cookbook Name:: kosmos-hubot # Recipe:: default # -# Copyright 2015, Kosmos +# Copyright 2017, Kosmos # # All rights reserved - Do Not Redistribute # -firewall_rule 'hubot_express_hal8000' do - port 8080 - protocol :tcp - command :allow +unless node.chef_environment == "development" + include_recipe 'firewall' + firewall_rule 'hubot_express_hal8000' do + port 8080 + protocol :tcp + command :allow + end end include_recipe "kosmos-nodejs" @@ -25,113 +28,153 @@ user "hubot" do uid 48268 gid 48268 shell "/bin/bash" - home "/srv/hal8000" end hal8000_freenode_data_bag_item = Chef::EncryptedDataBagItem.load('credentials', 'hal8000_freenode') -application "hal8000" do - path "/srv/hal8000" +hal8000_path = "/opt/hal8000" +application hal8000_path do owner "hubot" group "hubot" - action :deploy - - before_restart do - file "#{new_resource.release_path}/external-scripts.json" do - mode "0640" - owner "hubot" - group "hubot" - content [ - "hubot-help", - "hubot-read-tweet", - "hubot-redis-brain", - "hubot-rules", - "hubot-shipit", - "hubot-plusplus", - "hubot-tell", - "hubot-seen", - "hubot-rss-reader", - "hubot-incoming-webhook", - "hubot-auth" - ].to_json - end + git do + repository "https://github.com/67P/hal8000.git" + revision "master" end - repository "https://github.com/67P/hal8000.git" - revision "master" + file "#{name}/external-scripts.json" do + mode "0640" + owner "hubot" + group "hubot" + content [ + "hubot-help", + "hubot-read-tweet", + "hubot-redis-brain", + "hubot-rules", + "hubot-shipit", + "hubot-plusplus", + "hubot-tell", + "hubot-seen", + "hubot-rss-reader", + "hubot-incoming-webhook", + "hubot-auth" + ].to_json + end - nodejs do - entry_point "/srv/hal8000/current/bin/hubot -a irc" - # Use our own systemd service that depends on redis-server - template "nodejs.systemd.service.erb" - environment "HUBOT_IRC_SERVER" => "irc.freenode.net", - "HUBOT_IRC_ROOMS" => "#5apps,#kosmos,#kosmos-dev,#remotestorage,#hackerbeach,#unhosted,#sockethub", - "HUBOT_IRC_NICK" => "hal8000", - "HUBOT_IRC_NICKSERV_USERNAME" => "hal8000", - "HUBOT_IRC_NICKSERV_PASSWORD" => hal8000_freenode_data_bag_item['nickserv_password'], - "HUBOT_IRC_UNFLOOD" => "100", - "HUBOT_RSS_PRINTSUMMARY" => "false", - "HUBOT_RSS_IRCCOLORS" => "true", - # "HUBOT_LOG_LEVEL" => "error", - "EXPRESS_PORT" => "8080", - "HUBOT_RSS_HEADER" => "Update:", - "HUBOT_AUTH_ADMIN" => "bkero,derbumi,galfert,gregkare,jaaan,slvrbckt,raucao", - "OA_ASSET_FROM_ADDRESS" => "akRWZJMETdM2U5UGKadKhv1PAj2npoGja1m", - "OA_DEFAULT_QUANTITY" => "100", - "OA_ASSET_ID" => "AbDn6L2AUGnDreUuNkGFEqcxnsoUP4HCjm", - "OA_SERVER_URL" => "http://localhost:4562", - "OA_SERVER_USERNAME" => "kosmos", - "OA_SERVER_PASSWORD" => "asEjdak1yqw", - "OA_MAX_QUANTITY" => "5000", - "OA_BOT_KEYWORD" => "kredits", - "OA_PLUSPLUS_ROOMS" => "#kosmos", - "WEBHOOK_TOKEN" => hal8000_freenode_data_bag_item['webhook_token'] + npm_install do + user "hubot" + end + + execute "systemctl daemon-reload" do + command "systemctl daemon-reload" + action :nothing + end + + template "/lib/systemd/system/hal8000_nodejs.service" do + source 'nodejs.systemd.service.erb' + owner 'root' + group 'root' + mode '0644' + variables( + :user => "hubot", + :group => "hubot", + :app_dir => hal8000_path, + :entry => "#{hal8000_path}/bin/hubot -a irc", + :environment => { "HUBOT_IRC_SERVER" => "irc.freenode.net", + "HUBOT_IRC_ROOMS" => "#5apps,#kosmos,#kosmos-dev,#remotestorage,#hackerbeach,#unhosted,#sockethub", + "HUBOT_IRC_NICK" => "hal8000", + "HUBOT_IRC_NICKSERV_USERNAME" => "hal8000", + "HUBOT_IRC_NICKSERV_PASSWORD" => hal8000_freenode_data_bag_item['nickserv_password'], + "HUBOT_IRC_UNFLOOD" => "100", + "HUBOT_RSS_PRINTSUMMARY" => "false", + "HUBOT_RSS_IRCCOLORS" => "true", + # "HUBOT_LOG_LEVEL" => "error", + "EXPRESS_PORT" => "8080", + "HUBOT_RSS_HEADER" => "Update:", + "HUBOT_AUTH_ADMIN" => "bkero,derbumi,galfert,gregkare,jaaan,slvrbckt,raucao", + "OA_ASSET_FROM_ADDRESS" => "akRWZJMETdM2U5UGKadKhv1PAj2npoGja1m", + "OA_DEFAULT_QUANTITY" => "100", + "OA_ASSET_ID" => "AbDn6L2AUGnDreUuNkGFEqcxnsoUP4HCjm", + "OA_SERVER_URL" => "http://localhost:4562", + "OA_SERVER_USERNAME" => "kosmos", + "OA_SERVER_PASSWORD" => "asEjdak1yqw", + "OA_MAX_QUANTITY" => "5000", + "OA_BOT_KEYWORD" => "kredits", + "OA_PLUSPLUS_ROOMS" => "#kosmos", + "WEBHOOK_TOKEN" => hal8000_freenode_data_bag_item['webhook_token'] } + ) + notifies :run, "execute[systemctl daemon-reload]", :delayed + notifies :restart, "service[hal8000_nodejs]", :delayed + end + + service "hal8000_nodejs" do + action [:enable, :start] end end botka_freenode_data_bag_item = Chef::EncryptedDataBagItem.load('credentials', 'botka_freenode') -application "botka_freenode" do - path "/srv/botka_freenode" +botka_freenode_path = "/opt/botka_freenode" +application botka_freenode_path do owner "hubot" group "hubot" - action :deploy - - before_restart do - file "#{new_resource.release_path}/external-scripts.json" do - mode "0640" - owner "hubot" - group "hubot" - content [ - "hubot-help", - "hubot-remotestorage-logger" - ].to_json - end + git do + repository "https://github.com/67P/botka.git" + revision "master" end - repository "https://github.com/67P/botka.git" - revision "master" + file "#{name}/external-scripts.json" do + mode "0640" + owner "hubot" + group "hubot" + content [ + "hubot-help", + "hubot-remotestorage-logger" + ].to_json + end - nodejs do - entry_point "/srv/botka_freenode/current/bin/hubot -a irc" - # Use our own systemd service that depends on redis-server - template "nodejs.systemd.service.erb" - environment "HUBOT_IRC_SERVER" => "irc.freenode.net", - "HUBOT_IRC_ROOMS" => "#5apps,#kosmos,#kosmos-dev,#remotestorage,#hackerbeach,#unhosted,#sockethub,#opensourcedesign,#openknot,#emberjs", - "HUBOT_IRC_NICK" => "botka", - "HUBOT_IRC_NICKSERV_USERNAME" => "botka", - "HUBOT_IRC_NICKSERV_PASSWORD" => botka_freenode_data_bag_item['nickserv_password'], - "HUBOT_IRC_UNFLOOD" => "100", - "HUBOT_RSS_PRINTSUMMARY" => "false", - "HUBOT_RSS_IRCCOLORS" => "true", - # "HUBOT_LOG_LEVEL" => "error", - "EXPRESS_PORT" => "8082", - "HUBOT_AUTH_ADMIN" => "bkero,derbumi,galfert,gregkare,jaaan,slvrbckt,raucao", - "RS_LOGGER_USER" => "kosmos@5apps.com", - "RS_LOGGER_TOKEN" => botka_freenode_data_bag_item['rs_logger_token'], - "RS_LOGGER_SERVER_NAME" => "freenode", - "RS_LOGGER_PUBLIC" => "true" + npm_install do + user "hubot" + end + + + execute "systemctl daemon-reload" do + command "systemctl daemon-reload" + action :nothing + end + + template "/lib/systemd/system/botka_freenode_nodejs.service" do + source 'nodejs.systemd.service.erb' + owner 'root' + group 'root' + mode '0644' + variables( + :user => "hubot", + :group => "hubot", + :app_dir => botka_freenode_path, + :entry => "#{botka_freenode_path}/bin/hubot -a irc", + :environment => { "HUBOT_IRC_SERVER" => "irc.freenode.net", + "HUBOT_IRC_ROOMS" => "#5apps,#kosmos,#kosmos-dev,#remotestorage,#hackerbeach,#unhosted,#sockethub,#opensourcedesign,#openknot,#emberjs,#mastodon,#indieweb", + "HUBOT_IRC_NICK" => "botka", + "HUBOT_IRC_NICKSERV_USERNAME" => "botka", + "HUBOT_IRC_NICKSERV_PASSWORD" => botka_freenode_data_bag_item['nickserv_password'], + "HUBOT_IRC_UNFLOOD" => "100", + "HUBOT_RSS_PRINTSUMMARY" => "false", + "HUBOT_RSS_IRCCOLORS" => "true", + # "HUBOT_LOG_LEVEL" => "error", + "EXPRESS_PORT" => "8082", + "HUBOT_AUTH_ADMIN" => "bkero,derbumi,galfert,gregkare,jaaan,slvrbckt,raucao", + "RS_LOGGER_USER" => "kosmos@5apps.com", + "RS_LOGGER_TOKEN" => botka_freenode_data_bag_item['rs_logger_token'], + "RS_LOGGER_SERVER_NAME" => "freenode", + "RS_LOGGER_PUBLIC" => "true" } + ) + notifies :run, "execute[systemctl daemon-reload]", :delayed + notifies :restart, "service[botka_freenode_nodejs]", :delayed + end + + service "botka_freenode_nodejs" do + action [:enable, :start] end end diff --git a/site-cookbooks/kosmos-ipfs/recipes/letsencrypt.rb b/site-cookbooks/kosmos-ipfs/recipes/letsencrypt.rb index 2775c60..d33cb9e 100644 --- a/site-cookbooks/kosmos-ipfs/recipes/letsencrypt.rb +++ b/site-cookbooks/kosmos-ipfs/recipes/letsencrypt.rb @@ -8,7 +8,9 @@ # # nginx config to generate a Let's Encrypt cert -include_recipe "kosmos-base::letsencrypt" +unless node.chef_environment == "development" + include_recipe "kosmos-base::letsencrypt" +end root_directory = "/var/www/ipfs.kosmos.org" @@ -37,20 +39,23 @@ nginx_site 'ipfs.kosmos.org' do enable true end -firewall_rule 'ipfs_api' do - port 5444 - protocol :tcp - command :allow -end - -# Generate a Let's Encrypt cert (only if the nginx vhost exists and no cert -# has been generated before. The renew cron will take care of renewing -execute "letsencrypt cert for ipfs.kosmos.org" do - command "./certbot-auto certonly --webroot --agree-tos --email ops@5apps.com --webroot-path #{root_directory} -d ipfs.kosmos.org -n" - cwd "/usr/local/certbot" - only_if do - File.exist?("#{node['nginx']['dir']}/sites-enabled/ipfs.kosmos.org") && - ! File.exist?("/etc/letsencrypt/live/ipfs.kosmos.org/fullchain.pem") +unless node.chef_environment == "development" + include_recipe "firewall" + firewall_rule 'ipfs_api' do + port 5444 + protocol :tcp + command :allow + end + + # Generate a Let's Encrypt cert (only if the nginx vhost exists and no cert + # has been generated before. The renew cron will take care of renewing + execute "letsencrypt cert for ipfs.kosmos.org" do + command "./certbot-auto certonly --webroot --agree-tos --email ops@5apps.com --webroot-path #{root_directory} -d ipfs.kosmos.org -n" + cwd "/usr/local/certbot" + only_if do + File.exist?("#{node['nginx']['dir']}/sites-enabled/ipfs.kosmos.org") && + ! File.exist?("/etc/letsencrypt/live/ipfs.kosmos.org/fullchain.pem") + end + notifies :create, "template[#{node['nginx']['dir']}/sites-available/ipfs.kosmos.org]", :delayed end - notifies :create, "template[#{node['nginx']['dir']}/sites-available/ipfs.kosmos.org]", :delayed end diff --git a/site-cookbooks/kosmos-mastodon/CHANGELOG.md b/site-cookbooks/kosmos-mastodon/CHANGELOG.md new file mode 100644 index 0000000..4e30fed --- /dev/null +++ b/site-cookbooks/kosmos-mastodon/CHANGELOG.md @@ -0,0 +1,11 @@ +# kosmos-mastodon CHANGELOG + +This file is used to list changes made in each version of the kosmos-mastodon cookbook. + +## 0.1.0 +- [your_name] - Initial release of kosmos-mastodon + +- - - +Check the [Markdown Syntax Guide](http://daringfireball.net/projects/markdown/syntax) for help with Markdown. + +The [Github Flavored Markdown page](http://github.github.com/github-flavored-markdown/) describes the differences between markdown on github and standard markdown. diff --git a/site-cookbooks/kosmos-mastodon/README.md b/site-cookbooks/kosmos-mastodon/README.md new file mode 100644 index 0000000..7f3e489 --- /dev/null +++ b/site-cookbooks/kosmos-mastodon/README.md @@ -0,0 +1,80 @@ +# kosmos-mastodon Cookbook + +TODO: Enter the cookbook description here. + +e.g. +This cookbook makes your favorite breakfast sandwich. + +## Requirements + +TODO: List your cookbook requirements. Be sure to include any requirements this cookbook has on platforms, libraries, other cookbooks, packages, operating systems, etc. + +e.g. +### Platforms + +- SandwichOS + +### Chef + +- Chef 12.0 or later + +### Cookbooks + +- `toaster` - kosmos-mastodon needs toaster to brown your bagel. + +## Attributes + +TODO: List your cookbook attributes here. + +e.g. +### kosmos-mastodon::default + + + + + + + + + + + + + + +
KeyTypeDescriptionDefault
['kosmos-mastodon']['bacon']Booleanwhether to include bacontrue
+ +## Usage + +### kosmos-mastodon::default + +TODO: Write usage instructions for each cookbook. + +e.g. +Just include `kosmos-mastodon` in your node's `run_list`: + +```json +{ + "name":"my_node", + "run_list": [ + "recipe[kosmos-mastodon]" + ] +} +``` + +## Contributing + +TODO: (optional) If this is a public cookbook, detail the process for contributing. If this is a private cookbook, remove this section. + +e.g. +1. Fork the repository on Github +2. Create a named feature branch (like `add_component_x`) +3. Write your change +4. Write tests for your change (if applicable) +5. Run the tests, ensuring they all pass +6. Submit a Pull Request using Github + +## License and Authors + +Authors: TODO: List authors + diff --git a/site-cookbooks/kosmos-mastodon/attributes/default.rb b/site-cookbooks/kosmos-mastodon/attributes/default.rb new file mode 100644 index 0000000..801cd7e --- /dev/null +++ b/site-cookbooks/kosmos-mastodon/attributes/default.rb @@ -0,0 +1,4 @@ +node.default["kosmos-mastodon"]["directory"] = "/opt/mastodon" +node.default["kosmos-mastodon"]["puma_port"] = 3000 +node.default["kosmos-mastodon"]["streaming_port"] = 4000 +node.default["kosmos-mastodon"]["server_name"] = "kosmos.social" diff --git a/site-cookbooks/kosmos-mastodon/metadata.rb b/site-cookbooks/kosmos-mastodon/metadata.rb new file mode 100644 index 0000000..6447a64 --- /dev/null +++ b/site-cookbooks/kosmos-mastodon/metadata.rb @@ -0,0 +1,15 @@ +name 'kosmos-mastodon' +maintainer 'Kosmos' +maintainer_email 'mail@kosmos.org' +license 'All rights reserved' +description 'Installs/Configures kosmos-mastodon' +long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) +version '0.1.0' + +depends "kosmos-nginx" +depends "kosmos-nodejs" +depends "kosmos-ruby" +depends "application_ruby" +depends "application_javascript" +depends "postgresql" +depends "database" diff --git a/site-cookbooks/kosmos-mastodon/recipes/default.rb b/site-cookbooks/kosmos-mastodon/recipes/default.rb new file mode 100644 index 0000000..694ca15 --- /dev/null +++ b/site-cookbooks/kosmos-mastodon/recipes/default.rb @@ -0,0 +1,156 @@ +# +# Cookbook Name:: kosmos-mastodon +# Recipe:: default +# +# Copyright 2017, Kosmos +# +# All rights reserved - Do Not Redistribute +# + +include_recipe "kosmos-nodejs" +include_recipe "kosmos-ruby" +node.override['postgresql']['enable_pgdg_apt'] = false +include_recipe "postgresql::server" +include_recipe "postgresql::ruby" +unless node.chef_environment == "development" + node.override['postgresql']['config_pgtune']['db_type'] = "web" + include_recipe "postgresql::config_pgtune" +end + +postgresql_database 'mastodon' do + connection( + :host => '127.0.0.1', + :port => 5432, + :username => 'postgres', + :password => node['postgresql']['password']['postgres'] + ) + action :create +end + +mastodon_path = node["kosmos-mastodon"]["directory"] + +group "mastodon" do + gid 62786 +end + +user "mastodon" do + comment "mastodon user" + uid 62786 + gid 62786 + shell "/bin/bash" + home mastodon_path +end + +package %w(imagemagick ffmpeg libxml2-dev libxslt1-dev file git curl) +node_package %w(yarn) + +application mastodon_path do + owner "mastodon" + group "mastodon" + + git do + user "mastodon" + group "mastodon" + repository "https://github.com/67P/mastodon.git" + revision "redis_db" + end + + mastodon_credentials = Chef::EncryptedDataBagItem.load('credentials', 'mastodon') + + template ".env.production" do + source "env.production.erb" + mode "0640" + owner "mastodon" + group "mastodon" + variables redis_db: 1, + redis_actioncable_db: 2, + domain: "kosmos.social", + paperclip_secret: mastodon_credentials['paperclip_secret'], + secret_key_base: mastodon_credentials['secret_key_base'], + otp_secret: mastodon_credentials['otp_secret'], + smtp_login: mastodon_credentials['smtp_user_name'], + smtp_password: mastodon_credentials['smtp_password'], + smtp_from_address: "mail@kosmos.social", + s3_bucket: "kosmos-social", + aws_access_key_id: mastodon_credentials['aws_access_key_id'], + aws_secret_access_key: mastodon_credentials['aws_secret_access_key'], + s3_region: "eu-west-1" + end + + directory "#{mastodon_path}/public/.well-known" do + owner node['nginx']['user'] + group node['nginx']['group'] + recursive true + end + + bundle_install do + user "mastodon" + deployment true + without %w{development test} + end + + npm_install do + user "mastodon" + end + + rails do + migrate true + rails_env "production" + end + + execute "systemctl daemon-reload" do + command "systemctl daemon-reload" + action :nothing + end + + # mastodon-web service + # + template "/lib/systemd/system/mastodon-web.service" do + source "mastodon-web.systemd.service.erb" + variables user: user, + app_dir: mastodon_path, + port: node["kosmos-mastodon"]["puma_port"] + notifies :run, "execute[systemctl daemon-reload]", :delayed + notifies :restart, "service[mastodon-web]", :delayed + end + + service "mastodon-web" do + action [:enable, :start] + end + + # mastodon-sidekiq service + # + template "/lib/systemd/system/mastodon-sidekiq.service" do + source "mastodon-sidekiq.systemd.service.erb" + variables user: user, + app_dir: mastodon_path + notifies :run, "execute[systemctl daemon-reload]", :delayed + notifies :restart, "service[mastodon-sidekiq]", :delayed + end + + service "mastodon-sidekiq" do + action [:enable, :start] + end + + # mastodon-streaming service + # + template "/lib/systemd/system/mastodon-streaming.service" do + source "mastodon-streaming.systemd.service.erb" + variables user: user, + app_dir: mastodon_path, + port: node["kosmos-mastodon"]["streaming_port"] + notifies :run, "execute[systemctl daemon-reload]", :delayed + notifies :restart, "service[mastodon-streaming]", :delayed + end + + service "mastodon-streaming" do + action [:enable, :start] + end +end + +# unless node.chef_environment == "development" +# node.override["backup"]["postgresql"]["host"] = "localhost" +# node.override["backup"]["postgresql"]["username"] = "postgres" +# node.override["backup"]["postgresql"]["password"] = node['postgresql']['password']['postgres'] +# include_recipe "backup" +# end diff --git a/site-cookbooks/kosmos-mastodon/recipes/nginx.rb b/site-cookbooks/kosmos-mastodon/recipes/nginx.rb new file mode 100644 index 0000000..8f314a6 --- /dev/null +++ b/site-cookbooks/kosmos-mastodon/recipes/nginx.rb @@ -0,0 +1,48 @@ +# +# Cookbook Name:: kosmos-mastodon +# Recipe:: nginx +# +# Copyright 2017, Kosmos +# +# All rights reserved - Do Not Redistribute +# + +mastodon_path = node["kosmos-mastodon"]["directory"] +server_name = node["kosmos-mastodon"]["server_name"] + +include_recipe "kosmos-nginx" + +directory "/var/www/mastodon/.well-known/acme-challenge" do + owner node["nginx"]["user"] + group node["nginx"]["group"] + recursive true + action :create +end + +template "#{node['nginx']['dir']}/sites-available/mastodon" do + source 'nginx_conf_mastodon.erb' + owner 'www-data' + mode 0640 + variables streaming_port: node["kosmos-mastodon"]["streaming_port"], + puma_port: node["kosmos-mastodon"]["puma_port"], + server_name: server_name, + ssl_cert: "/etc/letsencrypt/live/#{server_name}/fullchain.pem", + ssl_key: "/etc/letsencrypt/live/#{server_name}/privkey.pem", + mastodon_path: mastodon_path + notifies :reload, 'service[nginx]', :delayed +end + +nginx_site 'mastodon' do + enable true +end + +unless node.chef_environment == "development" + include_recipe "kosmos-base::letsencrypt" + execute "letsencrypt cert for kosmos.social" do + command "./certbot-auto certonly --webroot --agree-tos --email ops@5apps.com --webroot-path /var/www/mastodon -d #{server_name} -n" + cwd "/usr/local/certbot" + not_if { File.exist? "/etc/letsencrypt/live/#{server_name}/fullchain.pem" } + notifies :reload, "service[nginx]", :delayed + notifies :create, "template[#{node['nginx']['dir']}/sites-available/mastodon]", :immediately + end +end diff --git a/site-cookbooks/kosmos-mastodon/templates/default/config-environment-production.rb.erb b/site-cookbooks/kosmos-mastodon/templates/default/config-environment-production.rb.erb new file mode 100644 index 0000000..d4ea1e0 --- /dev/null +++ b/site-cookbooks/kosmos-mastodon/templates/default/config-environment-production.rb.erb @@ -0,0 +1,119 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # Code is not reloaded between requests. + config.cache_classes = true + + # Eager load code on boot. This eager loads most of Rails and + # your application in memory, allowing both threaded web servers + # and those relying on copy on write to perform better. + # Rake tasks automatically ignore this option for performance. + config.eager_load = true + + # Full error reports are disabled and caching is turned on. + config.consider_all_requests_local = false + config.action_controller.perform_caching = true + config.action_controller.asset_host = ENV['CDN_HOST'] if ENV.key?('CDN_HOST') + + # Disable serving static files from the `/public` folder by default since + # Apache or NGINX already handles this. + config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present? + + # Compress JavaScripts and CSS. + config.assets.js_compressor = Uglifier.new(mangle: false) + # config.assets.css_compressor = :sass + + # Do not fallback to assets pipeline if a precompiled asset is missed. + config.assets.compile = false + + # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb + + # Specifies the header that your server uses for sending files. + # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache + config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX + + # Allow to specify public IP of reverse proxy if it's needed + config.action_dispatch.trusted_proxies = [IPAddr.new(ENV['TRUSTED_PROXY_IP'])] unless ENV['TRUSTED_PROXY_IP'].blank? + + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. + config.force_ssl = false + + # Use the lowest log level to ensure availability of diagnostic information + # when problems arise. + config.log_level = :debug + + # Prepend all log lines with the following tags. + config.log_tags = [:request_id] + + # Use a different logger for distributed setups. + # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) + + # Parse and split the REDIS_URL if passed (used with hosting platforms such as Heroku). + # Set ENV variables because they are used elsewhere. + if ENV['REDIS_URL'] + redis_url = URI.parse(ENV['REDIS_URL']) + ENV['REDIS_HOST'] = redis_url.host + ENV['REDIS_PORT'] = redis_url.port.to_s + ENV['REDIS_PASSWORD'] = redis_url.password + end + + # Use a different cache store in production. + config.cache_store = :redis_store, { + host: ENV.fetch('REDIS_HOST') { 'localhost' }, + port: ENV.fetch('REDIS_PORT') { 6379 }, + password: ENV.fetch('REDIS_PASSWORD') { false }, + db: <%= @redis_db %>, + namespace: 'cache', + expires_in: 20.minutes, + } + + # Enable serving of images, stylesheets, and JavaScripts from an asset server. + # config.action_controller.asset_host = 'http://assets.example.com' + + # Ignore bad email addresses and do not raise email delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. + # config.action_mailer.raise_delivery_errors = false + + # Enable locale fallbacks for I18n (makes lookups for any locale fall back to + # the I18n.default_locale when a translation cannot be found). + config.i18n.fallbacks = true + + # Send deprecation notices to registered listeners. + config.active_support.deprecation = :notify + + # Use default logging formatter so that PID and timestamp are not suppressed. + config.log_formatter = ::Logger::Formatter.new + + # Better log formatting + config.lograge.enabled = true + + # Do not dump schema after migrations. + config.active_record.dump_schema_after_migration = false + + config.action_mailer.perform_caching = false + + # E-mails + config.action_mailer.smtp_settings = { + :port => ENV['SMTP_PORT'], + :address => ENV['SMTP_SERVER'], + :user_name => ENV['SMTP_LOGIN'], + :password => ENV['SMTP_PASSWORD'], + :domain => ENV['SMTP_DOMAIN'] || config.x.local_domain, + :authentication => :plain, + } + + config.action_mailer.delivery_method = :smtp + + config.react.variant = :production + + config.to_prepare do + StatsD.backend = StatsD::Instrument::Backends::NullBackend.new if ENV['STATSD_ADDR'].blank? + end + + config.action_dispatch.default_headers = { + 'Server' => 'Mastodon', + 'X-Frame-Options' => 'DENY', + 'X-Content-Type-Options' => 'nosniff', + 'X-XSS-Protection' => '1; mode=block', + } +end diff --git a/site-cookbooks/kosmos-mastodon/templates/default/env.production.erb b/site-cookbooks/kosmos-mastodon/templates/default/env.production.erb new file mode 100644 index 0000000..9aa0da0 --- /dev/null +++ b/site-cookbooks/kosmos-mastodon/templates/default/env.production.erb @@ -0,0 +1,49 @@ +# Service dependencies +REDIS_HOST=localhost +REDIS_PORT=6379 +REDIS_DB=<%= @redis_db %> +REDIS_ACTIONCABLE_DB=<%= @redis_actioncable_db %> +DB_HOST=localhost +DB_USER=postgres +DB_NAME=mastodon +DB_PASS=<%= node['postgresql']['password']['postgres'] %> +DB_PORT=5432 + +# Federation +LOCAL_DOMAIN=<%= @domain %> +LOCAL_HTTPS=true + +# Application secrets +# Generate each with the `rake secret` task (`docker-compose run --rm web rake secret` if you use docker compose) +PAPERCLIP_SECRET=<%= @paperclip_secret %> +SECRET_KEY_BASE=<%= @secret_key_base %> +OTP_SECRET=<%= @otp_secret %> + +# Registrations +# Single user mode will disable registrations and redirect frontpage to the first profile +# SINGLE_USER_MODE=true +# Prevent registrations with following e-mail domains +# EMAIL_DOMAIN_BLACKLIST=example1.com|example2.de|etc + +# E-mail configuration +SMTP_SERVER=smtp.mailgun.org +SMTP_PORT=587 +SMTP_LOGIN=<%= @smtp_login %> +SMTP_PASSWORD=<%= @smtp_password %> +SMTP_FROM_ADDRESS=<%= @smtp_from_address %> + +# Optional asset host for multi-server setups +# CDN_HOST=assets.example.com + +# S3 (optional) +S3_ENABLED=true +S3_BUCKET=<%= @s3_bucket %> +AWS_ACCESS_KEY_ID=<%= @aws_access_key_id %> +AWS_SECRET_ACCESS_KEY=<%= @aws_secret_access_key %> +S3_REGION=<%= @s3_region %> + +# Optional alias for S3 if you want to use Cloudfront or Cloudflare in front +# S3_CLOUDFRONT_HOST= + +# Streaming API integration +# STREAMING_API_BASE_URL= diff --git a/site-cookbooks/kosmos-mastodon/templates/default/mastodon-sidekiq.systemd.service.erb b/site-cookbooks/kosmos-mastodon/templates/default/mastodon-sidekiq.systemd.service.erb new file mode 100644 index 0000000..86a3759 --- /dev/null +++ b/site-cookbooks/kosmos-mastodon/templates/default/mastodon-sidekiq.systemd.service.erb @@ -0,0 +1,17 @@ +[Unit] +Description=mastodon-sidekiq +Requires=redis-server.service +After=redis-server.service + +[Service] +Type=simple +User=<%= @user %> +WorkingDirectory=<%= @app_dir %> +Environment="RAILS_ENV=production" +Environment="DB_POOL=5" +ExecStart=/usr/local/bin/bundle exec sidekiq -c 5 -q default -q mailers -q pull -q push +TimeoutSec=15 +Restart=always + +[Install] +WantedBy=multi-user.target diff --git a/site-cookbooks/kosmos-mastodon/templates/default/mastodon-streaming.systemd.service.erb b/site-cookbooks/kosmos-mastodon/templates/default/mastodon-streaming.systemd.service.erb new file mode 100644 index 0000000..7756124 --- /dev/null +++ b/site-cookbooks/kosmos-mastodon/templates/default/mastodon-streaming.systemd.service.erb @@ -0,0 +1,15 @@ +Description=mastodon-streaming +After=network.target + +[Service] +Type=simple +User=<%= @user %> +WorkingDirectory=<%= @app_dir %> +Environment="NODE_ENV=production" +Environment="PORT=<%= @port %>" +ExecStart=/usr/local/bin/npm run start +TimeoutSec=15 +Restart=always + +[Install] +WantedBy=multi-user.target diff --git a/site-cookbooks/kosmos-mastodon/templates/default/mastodon-web.systemd.service.erb b/site-cookbooks/kosmos-mastodon/templates/default/mastodon-web.systemd.service.erb new file mode 100644 index 0000000..879d87c --- /dev/null +++ b/site-cookbooks/kosmos-mastodon/templates/default/mastodon-web.systemd.service.erb @@ -0,0 +1,19 @@ +[Unit] +Description=mastodon-web +Requires=redis-server.service +After=redis-server.service +Requires=postgresql@9.4-main.service +After=postgresql@9.4-main.service + +[Service] +Type=simple +User=<%= @user %> +WorkingDirectory=<%= @app_dir %> +Environment="RAILS_ENV=production" +Environment="PORT=3000" +ExecStart=/usr/local/bin/bundle exec puma -C config/puma.rb +TimeoutSec=15 +Restart=always + +[Install] +WantedBy=multi-user.target diff --git a/site-cookbooks/kosmos-mastodon/templates/default/nginx_conf_mastodon.erb b/site-cookbooks/kosmos-mastodon/templates/default/nginx_conf_mastodon.erb new file mode 100644 index 0000000..2f87598 --- /dev/null +++ b/site-cookbooks/kosmos-mastodon/templates/default/nginx_conf_mastodon.erb @@ -0,0 +1,88 @@ +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} + +server { + listen 80; + server_name <%= @server_name %>; + + access_log "/var/log/nginx/mastodon.access.log"; + error_log "/var/log/nginx/mastodon.error.log"; + + location /.well-known { + root "/var/www/mastodon"; + } + location / { + return 301 https://$host$request_uri; + } +} + +server { + listen 443 ssl; + server_name <%= @server_name %>; + + access_log "/var/log/nginx/mastodon.access.log"; + error_log "/var/log/nginx/mastodon.error.log"; + + ssl_protocols TLSv1.2; + ssl_ciphers EECDH+AESGCM:EECDH+AES; + ssl_ecdh_curve secp384r1; + ssl_prefer_server_ciphers on; + ssl_session_cache shared:SSL:10m; + + <% if File.exist?(@ssl_cert) && + File.exist?(@ssl_key) -%> + ssl_certificate <%= @ssl_cert %>; + ssl_certificate_key <%= @ssl_key %>; + <% end -%> + + keepalive_timeout 70; + sendfile on; + client_max_body_size 0; + gzip off; + + root <%= @mastodon_path %>/public; + + # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains"; + + location / { + try_files $uri @proxy; + } + + location @proxy { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto https; + + proxy_pass_header Server; + + proxy_pass http://localhost:<%= @puma_port %>; + proxy_buffering off; + proxy_redirect off; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + + tcp_nodelay on; + } + + location /api/v1/streaming { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto https; + + proxy_pass http://localhost:<%= @streaming_port %>; + proxy_buffering off; + proxy_redirect off; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + + tcp_nodelay on; + } + + error_page 500 501 502 503 504 /500.html; +} diff --git a/site-cookbooks/kosmos-mediawiki/metadata.rb b/site-cookbooks/kosmos-mediawiki/metadata.rb index c25037b..0df6188 100644 --- a/site-cookbooks/kosmos-mediawiki/metadata.rb +++ b/site-cookbooks/kosmos-mediawiki/metadata.rb @@ -7,6 +7,5 @@ long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) version '0.1.0' depends "mediawiki" -depends "firewall" depends "ark" depends "backup" diff --git a/site-cookbooks/kosmos-nginx/recipes/default.rb b/site-cookbooks/kosmos-nginx/recipes/default.rb index e6e2042..6a17fc2 100644 --- a/site-cookbooks/kosmos-nginx/recipes/default.rb +++ b/site-cookbooks/kosmos-nginx/recipes/default.rb @@ -24,10 +24,13 @@ EOF include_recipe 'nginx' -include_recipe 'kosmos-base::firewall' -firewall_rule 'http/https' do - port [80, 443] - protocol :tcp - command :allow +unless node.chef_environment == "development" + include_recipe 'kosmos-base::firewall' + + firewall_rule 'http/https' do + port [80, 443] + protocol :tcp + command :allow + end end diff --git a/site-cookbooks/kosmos-ruby/CHANGELOG.md b/site-cookbooks/kosmos-ruby/CHANGELOG.md new file mode 100644 index 0000000..e0c9479 --- /dev/null +++ b/site-cookbooks/kosmos-ruby/CHANGELOG.md @@ -0,0 +1,11 @@ +# kosmos-ruby CHANGELOG + +This file is used to list changes made in each version of the kosmos-ruby cookbook. + +## 0.1.0 +- [your_name] - Initial release of kosmos-ruby + +- - - +Check the [Markdown Syntax Guide](http://daringfireball.net/projects/markdown/syntax) for help with Markdown. + +The [Github Flavored Markdown page](http://github.github.com/github-flavored-markdown/) describes the differences between markdown on github and standard markdown. diff --git a/site-cookbooks/kosmos-ruby/README.md b/site-cookbooks/kosmos-ruby/README.md new file mode 100644 index 0000000..2daaba1 --- /dev/null +++ b/site-cookbooks/kosmos-ruby/README.md @@ -0,0 +1,80 @@ +# kosmos-ruby Cookbook + +TODO: Enter the cookbook description here. + +e.g. +This cookbook makes your favorite breakfast sandwich. + +## Requirements + +TODO: List your cookbook requirements. Be sure to include any requirements this cookbook has on platforms, libraries, other cookbooks, packages, operating systems, etc. + +e.g. +### Platforms + +- SandwichOS + +### Chef + +- Chef 12.0 or later + +### Cookbooks + +- `toaster` - kosmos-ruby needs toaster to brown your bagel. + +## Attributes + +TODO: List your cookbook attributes here. + +e.g. +### kosmos-ruby::default + + + + + + + + + + + + + + +
KeyTypeDescriptionDefault
['kosmos-ruby']['bacon']Booleanwhether to include bacontrue
+ +## Usage + +### kosmos-ruby::default + +TODO: Write usage instructions for each cookbook. + +e.g. +Just include `kosmos-ruby` in your node's `run_list`: + +```json +{ + "name":"my_node", + "run_list": [ + "recipe[kosmos-ruby]" + ] +} +``` + +## Contributing + +TODO: (optional) If this is a public cookbook, detail the process for contributing. If this is a private cookbook, remove this section. + +e.g. +1. Fork the repository on Github +2. Create a named feature branch (like `add_component_x`) +3. Write your change +4. Write tests for your change (if applicable) +5. Run the tests, ensuring they all pass +6. Submit a Pull Request using Github + +## License and Authors + +Authors: TODO: List authors + diff --git a/site-cookbooks/kosmos-ruby/attributes/default.rb b/site-cookbooks/kosmos-ruby/attributes/default.rb new file mode 100644 index 0000000..2f7703f --- /dev/null +++ b/site-cookbooks/kosmos-ruby/attributes/default.rb @@ -0,0 +1 @@ +default['kosmos-ruby']['version'] = '2.3' diff --git a/site-cookbooks/kosmos-ruby/metadata.rb b/site-cookbooks/kosmos-ruby/metadata.rb new file mode 100644 index 0000000..2459b56 --- /dev/null +++ b/site-cookbooks/kosmos-ruby/metadata.rb @@ -0,0 +1,7 @@ +name 'kosmos-ruby' +maintainer 'Kosmos' +maintainer_email 'mail@kosmos.org' +license 'All rights reserved' +description 'Installs/Configures kosmos-ruby' +long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) +version '0.1.0' diff --git a/site-cookbooks/kosmos-ruby/recipes/default.rb b/site-cookbooks/kosmos-ruby/recipes/default.rb new file mode 100644 index 0000000..96a1c9a --- /dev/null +++ b/site-cookbooks/kosmos-ruby/recipes/default.rb @@ -0,0 +1,54 @@ +# +# Cookbook Name:: kosmos-ruby +# Recipe:: default +# +# Copyright 2017, Kosmos +# +# All rights reserved - Do Not Redistribute +# + +package_name = "ruby#{node['kosmos-ruby']['version']}" + +apt_repository 'brightbox_ruby' do + uri 'http://ppa.launchpad.net/brightbox/ruby-ng/ubuntu' + distribution node['lsb']['codename'] + components ['main'] + keyserver 'keyserver.ubuntu.com' + key '80F70E11F0F0D5F10CB20E62F5DA5F09C3173AA6' +end + +packages = [ + "ruby#{node['kosmos-ruby']['version']}", + "ruby#{node['kosmos-ruby']['version']}-dev", + "build-essential", + "libssl-dev", + "zlib1g-dev" +] + +apt_package packages do + action :install +end + +apt_package 'ruby-switch' do + action :install + notifies :run, 'execute[set default ruby]', :immediately +end + +execute 'set default ruby' do + command "ruby-switch --set #{package_name}" + action :nothing + notifies :reload, 'ohai[reload]', :immediately +end + +ohai 'reload' do + action :nothing +end + +execute 'update rubygems' do + command 'gem update --system 2.6.8' + not_if "gem --version | grep ^2.6.8$" +end + +gem_package "bundler" do + version "1.13.2" +end diff --git a/site-cookbooks/sockethub/metadata.rb b/site-cookbooks/sockethub/metadata.rb index f574a74..488e39d 100644 --- a/site-cookbooks/sockethub/metadata.rb +++ b/site-cookbooks/sockethub/metadata.rb @@ -6,8 +6,7 @@ description 'Installs/Configures sockethub' long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) version '0.1.0' -depends 'application' -depends 'application_nodejs' +depends 'application_javascript' depends 'kosmos-redis' depends 'kosmos-nodejs' depends 'kosmos-nginx' diff --git a/site-cookbooks/sockethub/recipes/default.rb b/site-cookbooks/sockethub/recipes/default.rb index 1428270..daa6b63 100644 --- a/site-cookbooks/sockethub/recipes/default.rb +++ b/site-cookbooks/sockethub/recipes/default.rb @@ -8,25 +8,45 @@ # include_recipe 'kosmos-nodejs' - include_recipe 'kosmos-redis' +package "git" -application "sockethub" do - path "/srv/sockethub" +path_to_deploy = "/opt/sockethub" +application path_to_deploy do owner "www-data" group "www-data" - action :deploy + git do + repository 'https://github.com/sockethub/sockethub.git' + revision 'v1.0.5' + end - repository 'https://github.com/sockethub/sockethub.git' - revision 'v1.0.5' + npm_install - nodejs do - entry_point '/srv/sockethub/current/bin/sockethub' - # Use our own systemd service that depends on redis-server - template 'nodejs.systemd.service.erb' - environment 'DEBUG' => '*', - 'PORT' => node['sockethub']['port'] + execute "systemctl daemon-reload" do + command "systemctl daemon-reload" + action :nothing + end + + template "/lib/systemd/system/sockethub_nodejs.service" do + source 'nodejs.systemd.service.erb' + owner 'root' + group 'root' + mode '0644' + variables( + :user => owner, + :group => group, + :app_dir => path_to_deploy, + :entry => "/usr/local/bin/node /usr/local/bin/npm start", + :environment => { 'DEBUG' => '*', + 'PORT' => node['sockethub']['port'] } + + ) + notifies :run, "execute[systemctl daemon-reload]", :delayed + notifies :restart, "service[sockethub_nodejs]", :delayed + end + + service "sockethub_nodejs" do + action [:enable, :start] end end - diff --git a/site-cookbooks/sockethub/recipes/proxy.rb b/site-cookbooks/sockethub/recipes/proxy.rb index 0663151..88025da 100644 --- a/site-cookbooks/sockethub/recipes/proxy.rb +++ b/site-cookbooks/sockethub/recipes/proxy.rb @@ -9,10 +9,13 @@ include_recipe "kosmos-base::letsencrypt" -firewall_rule 'sockethub' do - port node['sockethub']['external_port'].to_i - protocol :tcp - command :allow +unless node.chef_environment == "development" + include_recipe "firewall" + firewall_rule 'sockethub' do + port node['sockethub']['external_port'].to_i + protocol :tcp + command :allow + end end include_recipe 'kosmos-nginx' diff --git a/site-cookbooks/sockethub/templates/default/nodejs.systemd.service.erb b/site-cookbooks/sockethub/templates/default/nodejs.systemd.service.erb index 2c42623..8dc98a9 100644 --- a/site-cookbooks/sockethub/templates/default/nodejs.systemd.service.erb +++ b/site-cookbooks/sockethub/templates/default/nodejs.systemd.service.erb @@ -5,6 +5,7 @@ After=redis-server.service [Service] ExecStart=<%= @entry %> +WorkingDirectory=<%= @app_dir %> User=<%= @user %> Group=<%= @group %> <% unless @environment.empty? -%> From 7bcc5515c4fb86cf53cbabd2d654f53362c43356 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 7 Apr 2017 11:49:25 +0200 Subject: [PATCH 04/83] Update dev.kosmos.org node Disable hubot recipes for now Add Mastodon --- nodes/dev.kosmos.org.json | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/nodes/dev.kosmos.org.json b/nodes/dev.kosmos.org.json index 46364b4..448a882 100644 --- a/nodes/dev.kosmos.org.json +++ b/nodes/dev.kosmos.org.json @@ -3,14 +3,20 @@ "kosmos-base", "sockethub", "sockethub::proxy", - "kosmos-hubot", "kosmos-wordpress", "kosmos-mediawiki", - "5apps-hubot::xmpp_botka", - "5apps-hubot::xmpp_schlupp", "5apps-xmpp_server", - "kosmos-ipfs" + "kosmos-ipfs", + "kosmos-mastodon", + "kosmos-mastodon::nginx" ], + "normal": { + "postgresql": { + "password": { + "postgres": "ahbaiRaiThohngeoko8ohFij8rako4" + } + } + }, "automatic": { "ipaddress": "dev.kosmos.org" } From 8ad690cedb88af6db4e397105306494f3660ef96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 7 Apr 2017 12:06:06 +0200 Subject: [PATCH 05/83] Add development environment (used in Vagrant setup) --- environments/development.json | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 environments/development.json diff --git a/environments/development.json b/environments/development.json new file mode 100644 index 0000000..d8017c9 --- /dev/null +++ b/environments/development.json @@ -0,0 +1,10 @@ +{ + "name": "development", + "description": "development environment, for example for Vagrant", + "json_class": "Chef::Environment", + "chef_type": "environment", + "default_attributes": { + }, + "override_attributes": { + } +} From d5d3fb60c11efd862273e78c12e6bc9121be68ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 7 Apr 2017 18:16:51 +0200 Subject: [PATCH 06/83] Use nginx's official repo and improve TLS configuration These packagea are newer than the 15.04 we had. We can enable HTTP2 --- .../files/default/nginx_tls_config.conf | 14 ++++++++++++++ site-cookbooks/kosmos-nginx/metadata.rb | 1 + .../kosmos-nginx/recipes/default.rb | 19 ++++++++++++++++++- 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 site-cookbooks/kosmos-nginx/files/default/nginx_tls_config.conf diff --git a/site-cookbooks/kosmos-nginx/files/default/nginx_tls_config.conf b/site-cookbooks/kosmos-nginx/files/default/nginx_tls_config.conf new file mode 100644 index 0000000..3edc0d2 --- /dev/null +++ b/site-cookbooks/kosmos-nginx/files/default/nginx_tls_config.conf @@ -0,0 +1,14 @@ +# Improve performance +ssl_session_timeout 1d; +ssl_session_cache shared:SSL:50m; +ssl_session_tickets off; +# Disable insecure cyphers +ssl_protocols TLSv1.2; +ssl_prefer_server_ciphers on; +# From https://mozilla.github.io/server-side-tls/ssl-config-generator/ +# Oldest compatible clients: Firefox 27, Chrome 30, IE 11 on Windows 7, Edge, Opera 17, Safari 9, Android 5.0, and Java 8 +# We don't have a lot of those cyphers (using Ubuntu 15.04), but CBC is insecure: +# https://blog.cloudflare.com/yet-another-padding-oracle-in-openssl-cbc-ciphersuites/ +ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256'; +# Unique DH Group, see https://weakdh.org/sysadmin.html +ssl_dhparam /etc/ssl/private/dhparams.pem; diff --git a/site-cookbooks/kosmos-nginx/metadata.rb b/site-cookbooks/kosmos-nginx/metadata.rb index 5ccc89c..2cd518b 100644 --- a/site-cookbooks/kosmos-nginx/metadata.rb +++ b/site-cookbooks/kosmos-nginx/metadata.rb @@ -8,3 +8,4 @@ version '0.1.0' depends 'nginx' depends 'firewall' +depends 'openssl' diff --git a/site-cookbooks/kosmos-nginx/recipes/default.rb b/site-cookbooks/kosmos-nginx/recipes/default.rb index 6a17fc2..9faa21f 100644 --- a/site-cookbooks/kosmos-nginx/recipes/default.rb +++ b/site-cookbooks/kosmos-nginx/recipes/default.rb @@ -22,9 +22,26 @@ node.override['nginx']['log_formats']['json'] = <<-EOF '"ua":"$http_user_agent"}' EOF - +node.override['nginx']['repo_source'] = 'nginx' # Install from official repo +node.override['nginx']['upstream_repository'] = "http://nginx.org/packages/mainline/#{node['platform']}" include_recipe 'nginx' +# Generate Strong Diffie-Hellman Group (increases security) +# https://weakdh.org/sysadmin.html +openssl_dhparam "/etc/ssl/private/dhparams.pem" do + key_length 2048 + mode 0600 + owner 'www-data' +end + +cookbook_file "#{node['nginx']['dir']}/conf.d/tls_config.conf" do + source 'nginx_tls_config.conf' + owner 'root' + group 'root' + mode '0644' + notifies :restart, 'service[nginx]' +end + unless node.chef_environment == "development" include_recipe 'kosmos-base::firewall' From d49f28574caf637ccafea806d6ec0ae5c621e501 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 7 Apr 2017 18:19:28 +0200 Subject: [PATCH 07/83] Update openssl cookbook --- Batali | 1 + batali.manifest | 67 ++++---- cookbooks/openssl/.foodcritic | 1 + cookbooks/openssl/CHANGELOG.md | 106 +++++++++---- cookbooks/openssl/CONTRIBUTING.md | 2 + cookbooks/openssl/MAINTAINERS.md | 15 ++ cookbooks/openssl/README.md | 144 +++++++++--------- cookbooks/openssl/attributes/default.rb | 5 +- cookbooks/openssl/libraries/helpers.rb | 14 +- .../openssl/libraries/random_password.rb | 8 +- .../openssl/libraries/secure_password.rb | 4 +- cookbooks/openssl/metadata.json | 2 +- cookbooks/openssl/providers/dhparam.rb | 33 ---- cookbooks/openssl/providers/rsa_key.rb | 39 ----- cookbooks/openssl/providers/x509.rb | 104 ------------- cookbooks/openssl/recipes/default.rb | 2 +- cookbooks/openssl/recipes/upgrade.rb | 23 ++- cookbooks/openssl/resources/dhparam.rb | 34 ++++- cookbooks/openssl/resources/rsa_key.rb | 39 ++++- cookbooks/openssl/resources/x509.rb | 130 ++++++++++++++-- 20 files changed, 398 insertions(+), 375 deletions(-) create mode 100644 cookbooks/openssl/.foodcritic create mode 100644 cookbooks/openssl/CONTRIBUTING.md create mode 100644 cookbooks/openssl/MAINTAINERS.md delete mode 100644 cookbooks/openssl/providers/dhparam.rb delete mode 100644 cookbooks/openssl/providers/rsa_key.rb delete mode 100644 cookbooks/openssl/providers/x509.rb diff --git a/Batali b/Batali index f9723d0..cdd22bb 100644 --- a/Batali +++ b/Batali @@ -37,5 +37,6 @@ Batali.define do cookbook 'nodejs', '~> 3.0.0' cookbook 'ark' cookbook 'logrotate' + cookbook 'openssl', '~> 7.0.1' end diff --git a/batali.manifest b/batali.manifest index 1ed1cd4..4ae84b2 100644 --- a/batali.manifest +++ b/batali.manifest @@ -326,30 +326,38 @@ } }, { - "name": "apt", + "name": "postgresql", "dependencies": [ - + [ + "compat_resource", + ">= 12.16.3" + ], + [ + "build-essential", + ">= 2.0.0" + ], + [ + "openssl", + ">= 4.0" + ] ], - "version": "2.9.2", + "version": "6.1.1", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/apt/versions/2.9.2/download", - "version": "2.9.2" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/postgresql/versions/6.1.1/download", + "version": "6.1.1" } }, { "name": "openssl", "dependencies": [ - [ - "chef-sugar", - ">= 3.1.1" - ] + ], - "version": "4.4.0", + "version": "7.0.1", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/openssl/versions/4.4.0/download", - "version": "4.4.0" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/openssl/versions/7.0.1/download", + "version": "7.0.1" } }, { @@ -387,6 +395,18 @@ "version": "2.7.6" } }, + { + "name": "apt", + "dependencies": [ + + ], + "version": "2.9.2", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/apt/versions/2.9.2/download", + "version": "2.9.2" + } + }, { "name": "bluepill", "dependencies": [ @@ -1002,29 +1022,6 @@ "version": "2.5.4" } }, - { - "name": "postgresql", - "dependencies": [ - [ - "compat_resource", - ">= 12.16.3" - ], - [ - "build-essential", - ">= 2.0.0" - ], - [ - "openssl", - ">= 4.0" - ] - ], - "version": "6.1.1", - "source": { - "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/postgresql/versions/6.1.1/download", - "version": "6.1.1" - } - }, { "name": "omnibus_updater", "dependencies": [ diff --git a/cookbooks/openssl/.foodcritic b/cookbooks/openssl/.foodcritic new file mode 100644 index 0000000..b9f8767 --- /dev/null +++ b/cookbooks/openssl/.foodcritic @@ -0,0 +1 @@ +~FC016 diff --git a/cookbooks/openssl/CHANGELOG.md b/cookbooks/openssl/CHANGELOG.md index 4c67fbc..a65e2fe 100644 --- a/cookbooks/openssl/CHANGELOG.md +++ b/cookbooks/openssl/CHANGELOG.md @@ -1,28 +1,73 @@ -openssl Cookbook CHANGELOG -========================== +# openssl Cookbook CHANGELOG + This file is used to list changes made in each version of the openssl cookbook. -v4.4.0 (2015-08-28) -------------------- +## 7.0.1 (2017-03-21) + +- Fix compatibility with Chef 12.5.1 + +## 7.0.0 (2017-03-06) + +- Converted LWRPs to custom resources, increasing the chef-client dependency to 12.5+. This fixes the bus where each resource notified on every run even if it didn't actually update the files on disk. +- Added testing for Chef 13 +- Test with Local Delivery instead of Rake + +## 6.1.1 (2017-01-19) + +- Resolve deprecation warnings in chefspec +- Use proper ::File class and fix ^2 validation of dhparam key length +- Disable .zero? in cookstyle for now + +## 6.1.0 (2017-01-18) + +- [#37] Support for Subject Alternative Names on generated self-signed certificates +- rubocop +- Cookstyle fixes + +## 6.0.0 (2016-09-08) + +- Update the minimum chef release to 12.1 + +## 5.0.1 (2016-09-01) +- Update docs from node.normal as node.set has been deprecated +- Testing updates + +## 5.0.0 (2016-08-27) + +- Remove the need for the chef-sugar cookbook +- Remove the default['openssl']['packages'] attribute in the upgrades recipe and instead use the correct openssl packages based on platform +- Remove support for Debian 6 and Ubuntu 10.04 in the upgrade recipe +- Add support for Fedora and Suse in the upgrade recipe +- Prevent errors with unset variable in error raising within the random password helper +- Add cookstyle and resolve all warnings +- Add testing, contributing, and maintainers documentation +- Add integration testing in Travis CI with kitchen-dokken +- Add issues_url, source_url and chef_version metadata +- Update the requirements section of the README +- Update the Chefspecs to avoid errors and run using caching for faster runs +- Add issues and PR templates for Github + +## v4.4.0 (2015-08-28) + - NEW: x509 certificates are now signed via SHA-256 instead of SHA-1 - FIX: gen_dhparam error now correctly fails with TypeError instead of ArgumentError if Generator argument isn't an integer -v4.3.2 (2015-08-01) -------------------- +## v4.3.2 (2015-08-01) + - FIX: Updated changelog -v4.3 (2015-08-01) -------------------- +## v4.3 (2015-08-01) + - NEW: Add rsa_key lwrp - FIX: dhparam lwrp now correctly honors the generator parameter -v4.2 (2015-06-23) -------------------- +## v4.2 (2015-06-23) + - NEW: Add dhparam lwrp - FIX: x509 lwrp now updates resource count correctly -v4.1.2 (2015-06-20) -------------------- +## v4.1.2 (2015-06-20) + - Add Serverspec suite - Removed update suite from .kitchen.yml - Add explicit license to test cookbook recipes @@ -31,41 +76,42 @@ v4.1.2 (2015-06-20) - Add helper library - Update x509 LWRP to verify existing keys, if specified -v4.1.1 (2015-06-11) -------------------- +## v4.1.1 (2015-06-11) + - README.md fixes -v4.1.0 (2015-06-11) -------------------- +## v4.1.0 (2015-06-11) + - Add new random_password Mixin (Thanks, Seth!) - Rewritten README.md - Refactor specs - Clear Rubocop violations -v4.0.0 (2015-02-19) -------------------- +## v4.0.0 (2015-02-19) + - Reverting to Opscode module namespace -v3.0.2 (2015-12-18) -------------------- +## v3.0.2 (2015-12-18) + - Accidently released 2.0.2 as 3.0.2 - Re-namespaced `Opscode::OpenSSL::Password` module as `Chef::OpenSSL::Password` -v2.0.2 (2014-12-30) -------------------- +## v2.0.2 (2014-12-30) + - Call cert.to_pem before recipe DSL -v2.0.0 (2014-06-11) -------------------- +## v2.0.0 (2014-06-11) -- #1 - **[COOK-847](https://tickets.chef.io/browse/COOK-847)** - Add LWRP for generating self signed certs -- #4 - **[COOK-4715](https://tickets.chef.io/browse/COOK-4715)** - add upgrade recipe and complete test harness +- # 1 - **[COOK-847](https://tickets.chef.io/browse/COOK-847)** - Add LWRP for generating self signed certs + +- # 4 - **[COOK-4715](https://tickets.chef.io/browse/COOK-4715)** - add upgrade recipe and complete test harness + +## v1.1.0 -v1.1.0 ------- ### Improvement + - **[COOK-3222](https://tickets.chef.io/browse/COOK-3222)** - Allow setting length for `secure_password` -v1.0.2 ------- +## v1.0.2 + - Add name attribute to metadata diff --git a/cookbooks/openssl/CONTRIBUTING.md b/cookbooks/openssl/CONTRIBUTING.md new file mode 100644 index 0000000..ef2f2b8 --- /dev/null +++ b/cookbooks/openssl/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/openssl/MAINTAINERS.md b/cookbooks/openssl/MAINTAINERS.md new file mode 100644 index 0000000..645ed14 --- /dev/null +++ b/cookbooks/openssl/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/openssl/README.md b/cookbooks/openssl/README.md index f329acc..da19dbc 100644 --- a/cookbooks/openssl/README.md +++ b/cookbooks/openssl/README.md @@ -1,42 +1,41 @@ -OpenSSL Cookbook -================ -[![Build Status](https://travis-ci.org/opscode-cookbooks/openssl.svg?branch=master)](https://travis-ci.org/opscode-cookbooks/openssl) +# OpenSSL Cookbook + +[![Build Status](https://travis-ci.org/chef-cookbooks/openssl.svg?branch=master)](http://travis-ci.org/chef-cookbooks/openssl) [![Cookbook Version](https://img.shields.io/cookbook/v/openssl.svg)](https://supermarket.chef.io/cookbooks/openssl) This cookbook provides tools for working with the Ruby OpenSSL library. It includes: + - A library method to generate secure random passwords in recipes, using the Ruby SecureRandom library. -- An LWRP for generating RSA private keys. -- An LWRP for generating x509 certificates. -- An LWRP for generating dhparam.pem files. +- A resource for generating RSA private keys. +- A resource for generating x509 certificates. +- A resource for generating dhparam.pem files. - An attribute-driven recipe for upgrading OpenSSL packages. -Requirements ------------- +## Platforms The `random_password` mixin works on any platform with the Ruby SecureRandom module. This module is already included with Chef. -The `openssl_x509`, `openssl_rsa_key` and `openssl_dhparam` LWRPs work on any platform with the OpenSSL Ruby bindings installed. These bindings are already included with Chef. +The `openssl_x509`, `openssl_rsa_key` and `openssl_dhparam` resources work on any platform with the OpenSSL Ruby bindings installed. These bindings are already included with Chef. The `upgrade` recipe has been tested on the following platforms: -* Ubuntu 12.04, 14.04 -* Debian 7.4 -* CentOS 6.5 +- Debian / Ubuntu derivatives +- RHEL and derivatives +- Fedora +- openSUSE / SUSE Linux Enterprises -The recipe may work on other platforms or different versions of the above platforms, but this has not been tested. +## Chef -Dependencies ------------- +- Chef 12.5+ -This cookbook depends on the [Chef Sugar](http://supermarket.chef.io/cookbooks/chef-sugar/) cookbook. [Chef Sugar](http://supermarket.chef.io/cookbooks/chef-sugar/) is used to make the default attribute settings easier to reason about. (See [Attributes](#attributes)) +## Cookbooks -Attributes ----------- +- none -* `node['openssl']['packages']` - An array of packages required to use openssl. The default attributes attempt to be smart about which packages are the default, but this may need to be changed by users of the `openssl::upgrade` recipe. -* `node['openssl']['restart_services']` - An array of service resources that depend on the packages listed in the `node['openssl']['packages']` attribute. This array is empty by default, as Chef has no reasonable way to detect which applications or services are compiled against these packages. *Note* Each service listed in this array should represent a "`service`" resource specified in the recipes of the node's run list. +## Attributes -Recipes -------- +- `node['openssl']['restart_services']` - An array of service resources that depend on the openssl packages. This array is empty by default, as Chef has no reasonable way to detect which applications or services are compiled against these packages. _Note_ Each service listed in this array should represent a "`service`" resource specified in the recipes of the node's run list. + +## Recipes ### default @@ -63,8 +62,7 @@ include_recipe 'openssl::upgrade' When executed, this recipe will ensure that openssl is upgraded to the latest version, and that the `stats_collector` service is restarted to pick up the latest security fixes released in the openssl package. -Libraries & LWRPs ------------------ +## Libraries & Resources There are two mixins packaged with this cookbook. @@ -73,13 +71,14 @@ There are two mixins packaged with this cookbook. The `RandomPassword` mixin can be used to generate secure random passwords in Chef cookbooks, usually for assignment to a variable or an attribute. `random_password` uses Ruby's SecureRandom library and is customizable. #### Example Usage + ```ruby Chef::Recipe.send(:include, OpenSSLCookbook::RandomPassword) -node.set['my_secure_attribute'] = random_password -node.set_unless['my_secure_attribute'] = random_password -node.set['my_secure_attribute'] = random_password(length: 50) -node.set['my_secure_attribute'] = random_password(length: 50, mode: :base64) -node.set['my_secure_attribute'] = random_password(length: 50, mode: :base64, encoding: 'ASCII') +node.normal['my_secure_attribute'] = random_password +node.normal_unless['my_secure_attribute'] = random_password +node.normal['my_secure_attribute'] = random_password(length: 50) +node.normal['my_secure_attribute'] = random_password(length: 50, mode: :base64) +node.normal['my_secure_attribute'] = random_password(length: 50, mode: :base64, encoding: 'ASCII') ``` Note that node attributes are widely accessible. Storing unencrypted passwords in node attributes, as in this example, carries risk. @@ -89,31 +88,34 @@ Note that node attributes are widely accessible. Storing unencrypted passwords i This library should be considered deprecated and will be removed in a future version. Please use `OpenSSLCookbook::RandomPassword` instead. The documentation is kept here for historical reasons. #### ~~Example Usage~~ + ```ruby ::Chef::Recipe.send(:include, Opscode::OpenSSL::Password) -node.set_unless['my_password'] = secure_password +node.normal_unless['my_password'] = secure_password ``` ~~Note that node attributes are widely accessible. Storing unencrypted passwords in node attributes, as in this example, carries risk.~~ ### openssl_x509 -This LWRP generates self-signed, PEM-formatted x509 certificates. If no existing key is specified, the LWRP will automatically generate a passwordless key with the certificate. +This resource generates self-signed, PEM-formatted x509 certificates. If no existing key is specified, the resource will automatically generate a passwordless key with the certificate. #### Attributes -| Name | Type | Description | -| ----- | ---- | ------------ | -| `common_name` | String (Required) | Value for the `CN` certificate field. | -| `org` | String (Required) | Value for the `O` certificate field. | -| `org_unit` | String (Required) | Value for the `OU` certificate field. | -| `country` | String (Required) | Value for the `C` ssl field. | -| `expire` | Fixnum (Optional) | Value representing the number of days from _now_ through which the issued certificate cert will remain valid. The certificate will expire after this period. | -| `key_file` | String (Optional) | The path to a certificate key file on the filesystem. If the `key_file` attribute is specified, the LWRP will attempt to source a key from this location. If no key file is found, the LWRP will generate a new key file at this location. If the `key_file` attribute is not specified, the LWRP will generate a key file in the same directory as the generated certificate, with the same name as the generated certificate. -| `key_pass` | String (Optional) | The passphrase for an existing key's passphrase -| `key_length` | Fixnum (Optional) | The desired Bit Length of the generated key. _Default: 2048_ | -| `owner` | String (optional) | The owner of all files created by the LWRP. _Default: "root"_ | -| `group` | String (optional) | The group of all files created by the LWRP. _Default: "root"_ | -| `mode` | String or Fixnum (Optional) | The permission mode of all files created by the LWRP. _Default: "0400"_ | + +Name | Type | Description +------------------ | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +`common_name` | String (Required) | Value for the `CN` certificate field. +`org` | String (Required) | Value for the `O` certificate field. +`org_unit` | String (Required) | Value for the `OU` certificate field. +`country` | String (Required) | Value for the `C` ssl field. +`expire` | Fixnum (Optional) | Value representing the number of days from _now_ through which the issued certificate cert will remain valid. The certificate will expire after this period. +`subject_alt_name` | Array (Optional) | Array of _Subject Alternative Name_ entries, in format `DNS:example.com` or `IP:1.2.3.4` _Default: empty_ +`key_file` | String (Optional) | The path to a certificate key file on the filesystem. If the `key_file` attribute is specified, the resource will attempt to source a key from this location. If no key file is found, the resource will generate a new key file at this location. If the `key_file` attribute is not specified, the resource will generate a key file in the same directory as the generated certificate, with the same name as the generated certificate. +`key_pass` | String (Optional) | The passphrase for an existing key's passphrase +`key_length` | Fixnum (Optional) | The desired Bit Length of the generated key. _Default: 2048_ +`owner` | String (optional) | The owner of all files created by the resource. _Default: "root"_ +`group` | String (optional) | The group of all files created by the resource. _Default: "root"_ +`mode` | String or Fixnum (Optional) | The permission mode of all files created by the resource. _Default: "0400"_ #### Example Usage @@ -132,16 +134,17 @@ When executed, this recipe will generate a key certificate at `/etc/httpd/ssl/my ### openssl_dhparam -This LWRP generates dhparam.pem files. If a valid dhparam.pem file is found at the specified location, no new file will be created. If a file is found at the specified location but it is not a valid dhparam file, it will be overwritten. +This resource generates dhparam.pem files. If a valid dhparam.pem file is found at the specified location, no new file will be created. If a file is found at the specified location but it is not a valid dhparam file, it will be overwritten. #### Attributes -| Name | Type | Description | -| ----- | ---- | ------------ | -| `key_length` | Fixnum (Optional) | The desired Bit Length of the generated key. _Default: 2048_ | -| `generator` | Fixnum (Optional) | The desired Diffie-Hellmann generator. Can be _2_ or _5_. | -| `owner` | String (optional) | The owner of all files created by the LWRP. _Default: "root"_ | -| `group` | String (optional) | The group of all files created by the LWRP. _Default: "root"_ | -| `mode` | String or Fixnum (Optional) | The permission mode of all files created by the LWRP. _Default: "0644"_ | + +Name | Type | Description +------------ | --------------------------- | --------------------------------------------------------------------------- +`key_length` | Fixnum (Optional) | The desired Bit Length of the generated key. _Default: 2048_ +`generator` | Fixnum (Optional) | The desired Diffie-Hellmann generator. Can be _2_ or _5_. +`owner` | String (optional) | The owner of all files created by the resource. _Default: "root"_ +`group` | String (optional) | The group of all files created by the resource. _Default: "root"_ +`mode` | String or Fixnum (Optional) | The permission mode of all files created by the resource. _Default: "0644"_ #### Example Usage @@ -149,7 +152,7 @@ In this example, an administrator wishes to create a dhparam.pem file for use wi ```ruby openssl_dhparam '/etc/httpd/ssl/dhparam.pem' do - key_length 2048 + key_length 2048 generator 2 end ``` @@ -158,16 +161,17 @@ When executed, this recipe will generate a dhparam file at `/etc/httpd/ssl/dhpar ### openssl_rsa_key -This LWRP generates rsa key files. If a valid rsa key file can be opened at the specified location, no new file will be created. If the RSA key file cannot be opened, either because it does not exist or because the password to the RSA key file does not match the password in the recipe, it will be overwritten. +This resource generates rsa key files. If a valid rsa key file can be opened at the specified location, no new file will be created. If the RSA key file cannot be opened, either because it does not exist or because the password to the RSA key file does not match the password in the recipe, it will be overwritten. #### Attributes -| Name | Type | Description | -| ----- | ---- | ------------ | -| `key_length` | Fixnum (Optional) | The desired Bit Length of the generated key. _Default: 2048_ | -| `key_pass` | String (Optional) | The desired passphrase for the key. | -| `owner` | String (optional) | The owner of all files created by the LWRP. _Default: "root"_ | -| `group` | String (optional) | The group of all files created by the LWRP. _Default: "root"_ | -| `mode` | String or Fixnum (Optional) | The permission mode of all files created by the LWRP. _Default: "0644"_ | + +Name | Type | Description +------------ | --------------------------- | --------------------------------------------------------------------------- +`key_length` | Fixnum (Optional) | The desired Bit Length of the generated key. _Default: 2048_ +`key_pass` | String (Optional) | The desired passphrase for the key. +`owner` | String (optional) | The owner of all files created by the resource. _Default: "root"_ +`group` | String (optional) | The group of all files created by the resource. _Default: "root"_ +`mode` | String or Fixnum (Optional) | The permission mode of all files created by the resource. _Default: "0644"_ #### Example Usage @@ -175,25 +179,21 @@ In this example, an administrator wishes to create a new RSA private key file in ```ruby openssl_rsa_key '/etc/httpd/ssl/server.key' do - key_length 2048 + key_length 2048 end ``` When executed, this recipe will generate a passwordless RSA key file at `/etc/httpd/ssl/server.key`. +## License and Author -License and Author ------------------- - -Author:: Jesse Nelson () -Author:: Seth Vargo () -Author:: Charles Johnson () -Author:: Joshua Timberman () - -======= +Author:: Jesse Nelson ([spheromak@gmail.com](mailto:spheromak@gmail.com))
+Author:: Seth Vargo ([sethvargo@gmail.com](mailto:sethvargo@gmail.com))
+Author:: Charles Johnson ([charles@chef.io](mailto:charles@chef.io))
+Author:: Joshua Timberman ([joshua@chef.io](mailto:joshua@chef.io)) ```text -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. diff --git a/cookbooks/openssl/attributes/default.rb b/cookbooks/openssl/attributes/default.rb index d4945a3..b22f210 100644 --- a/cookbooks/openssl/attributes/default.rb +++ b/cookbooks/openssl/attributes/default.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: openssl +# Cookbook:: openssl # Attributes:: default # -# Copyright 2014, Chef Software, Inc. +# Copyright:: 2014-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. @@ -17,5 +17,4 @@ # limitations under the License. # -default['openssl']['packages'] = [] default['openssl']['restart_services'] = [] diff --git a/cookbooks/openssl/libraries/helpers.rb b/cookbooks/openssl/libraries/helpers.rb index bb81dff..4bb17d3 100644 --- a/cookbooks/openssl/libraries/helpers.rb +++ b/cookbooks/openssl/libraries/helpers.rb @@ -20,7 +20,7 @@ module OpenSSLCookbook def dhparam_pem_valid?(dhparam_pem_path) # Check if the dhparam.pem file exists # Verify the dhparam.pem file contains a key - return false unless File.exist?(dhparam_pem_path) + return false unless ::File.exist?(dhparam_pem_path) dhparam = OpenSSL::PKey::DH.new File.read(dhparam_pem_path) dhparam.params_ok? end @@ -28,21 +28,21 @@ module OpenSSLCookbook def key_file_valid?(key_file_path, key_password = nil) # Check if the key file exists # Verify the key file contains a private key - return false unless File.exist?(key_file_path) + return false unless ::File.exist?(key_file_path) key = OpenSSL::PKey::RSA.new File.read(key_file_path), key_password key.private? end # Generators def gen_dhparam(key_length, generator) - fail ArgumentError, 'Key length must be a power of 2 greater than or equal to 1024' unless key_length_valid?(key_length) - fail TypeError, 'Generator must be an integer' unless generator.is_a?(Integer) + raise ArgumentError, 'Key length must be a power of 2 greater than or equal to 1024' unless key_length_valid?(key_length) + raise TypeError, 'Generator must be an integer' unless generator.is_a?(Integer) OpenSSL::PKey::DH.new(key_length, generator) end def gen_rsa_key(key_length) - fail ArgumentError, 'Key length must be a power of 2 greater than or equal to 1024' unless key_length_valid?(key_length) + raise ArgumentError, 'Key length must be a power of 2 greater than or equal to 1024' unless key_length_valid?(key_length) OpenSSL::PKey::RSA.new(key_length) end @@ -50,8 +50,8 @@ module OpenSSLCookbook # Key manipulation helpers # Returns a pem string def encrypt_rsa_key(rsa_key, key_password) - fail TypeError, 'rsa_key must be a Ruby OpenSSL::PKey::RSA object' unless rsa_key.is_a?(OpenSSL::PKey::RSA) - fail TypeError, 'RSA key password must be a string' unless key_password.is_a?(String) + raise TypeError, 'rsa_key must be a Ruby OpenSSL::PKey::RSA object' unless rsa_key.is_a?(OpenSSL::PKey::RSA) + raise TypeError, 'RSA key password must be a string' unless key_password.is_a?(String) cipher = OpenSSL::Cipher::Cipher.new('des3') rsa_key.to_pem(cipher, key_password) diff --git a/cookbooks/openssl/libraries/random_password.rb b/cookbooks/openssl/libraries/random_password.rb index c488301..89dbee9 100644 --- a/cookbooks/openssl/libraries/random_password.rb +++ b/cookbooks/openssl/libraries/random_password.rb @@ -1,9 +1,9 @@ # -# Cookbook Name:: openssl +# Cookbook:: openssl # Library:: random_password # Author:: Seth Vargo # -# Copyright 2015, Seth Vargo +# Copyright:: 2015-2017, Seth Vargo # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -28,7 +28,7 @@ module OpenSSLCookbook end class InvalidPasswordMode < StandardError - def initialize(given, acceptable) + def initialize(given, _acceptable = nil) super <<-EOH The given password mode '#{given}' is not valid. Valid password modes are :hex, :base64, and :random_bytes! @@ -73,7 +73,7 @@ EOH when :random_bytes length else - fail InvalidPasswordMode.new(mode) + raise InvalidPasswordMode.new(mode) end SecureRandom.send(mode, length).force_encoding(encoding) diff --git a/cookbooks/openssl/libraries/secure_password.rb b/cookbooks/openssl/libraries/secure_password.rb index 75f7f50..90051da 100644 --- a/cookbooks/openssl/libraries/secure_password.rb +++ b/cookbooks/openssl/libraries/secure_password.rb @@ -1,9 +1,9 @@ # -# Cookbook Name:: openssl +# Cookbook:: openssl # Library:: secure_password # Author:: Joshua Timberman # -# Copyright 2009, Chef Software, Inc. +# Copyright:: 2009-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/openssl/metadata.json b/cookbooks/openssl/metadata.json index aef92df..6e6d604 100644 --- a/cookbooks/openssl/metadata.json +++ b/cookbooks/openssl/metadata.json @@ -1 +1 @@ -{"name":"openssl","version":"4.4.0","description":"Provides a library with a method for generating secure random passwords.","long_description":"OpenSSL Cookbook\n================\n[![Build Status](https://travis-ci.org/opscode-cookbooks/openssl.svg?branch=master)](https://travis-ci.org/opscode-cookbooks/openssl)\n\nThis cookbook provides tools for working with the Ruby OpenSSL library. It includes:\n- A library method to generate secure random passwords in recipes, using the Ruby SecureRandom library.\n- An LWRP for generating RSA private keys.\n- An LWRP for generating x509 certificates.\n- An LWRP for generating dhparam.pem files.\n- An attribute-driven recipe for upgrading OpenSSL packages.\n\nRequirements\n------------\n\nThe `random_password` mixin works on any platform with the Ruby SecureRandom module. This module is already included with Chef.\n\nThe `openssl_x509`, `openssl_rsa_key` and `openssl_dhparam` LWRPs work on any platform with the OpenSSL Ruby bindings installed. These bindings are already included with Chef.\n\nThe `upgrade` recipe has been tested on the following platforms:\n\n* Ubuntu 12.04, 14.04\n* Debian 7.4\n* CentOS 6.5\n\nThe recipe may work on other platforms or different versions of the above platforms, but this has not been tested.\n\nDependencies\n------------\n\nThis cookbook depends on the [Chef Sugar](http://supermarket.chef.io/cookbooks/chef-sugar/) cookbook. [Chef Sugar](http://supermarket.chef.io/cookbooks/chef-sugar/) is used to make the default attribute settings easier to reason about. (See [Attributes](#attributes))\n\nAttributes\n----------\n\n* `node['openssl']['packages']` - An array of packages required to use openssl. The default attributes attempt to be smart about which packages are the default, but this may need to be changed by users of the `openssl::upgrade` recipe.\n* `node['openssl']['restart_services']` - An array of service resources that depend on the packages listed in the `node['openssl']['packages']` attribute. This array is empty by default, as Chef has no reasonable way to detect which applications or services are compiled against these packages. *Note* Each service listed in this array should represent a \"`service`\" resource specified in the recipes of the node's run list.\n\nRecipes\n-------\n\n### default\n\nAn empty placeholder recipe. Takes no action.\n\n### upgrade\n\nThe upgrade recipe iterates over the list of packages in the `node['openssl']['packages']` attribute, and manages them with the `:upgrade` action. Each package will send a `:restart` notification to service resources named in the `node['openssl']['restart_services']` attribute.\n\n#### Example Usage\n\nIn this example, assume the node is running the `stats_collector` daemon, which depends on the openssl library. Imagine that a new openssl vulnerability has been disclosed, and the operating system vendor has released an update to openssl to address this vulnerability. In order to protect the node, an administrator crafts this recipe:\n\n```ruby\nnode.default['openssl']['restart_services'] = ['stats_collector']\n\n# other recipe code here...\nservice 'stats_collector' do\n action [:enable, :start]\nend\n\ninclude_recipe 'openssl::upgrade'\n```\n\nWhen executed, this recipe will ensure that openssl is upgraded to the latest version, and that the `stats_collector` service is restarted to pick up the latest security fixes released in the openssl package.\n\nLibraries & LWRPs\n-----------------\n\nThere are two mixins packaged with this cookbook.\n\n### random_password (`OpenSSLCookbook::RandomPassword`)\n\nThe `RandomPassword` mixin can be used to generate secure random passwords in Chef cookbooks, usually for assignment to a variable or an attribute. `random_password` uses Ruby's SecureRandom library and is customizable.\n\n#### Example Usage\n```ruby\nChef::Recipe.send(:include, OpenSSLCookbook::RandomPassword)\nnode.set['my_secure_attribute'] = random_password\nnode.set_unless['my_secure_attribute'] = random_password\nnode.set['my_secure_attribute'] = random_password(length: 50)\nnode.set['my_secure_attribute'] = random_password(length: 50, mode: :base64)\nnode.set['my_secure_attribute'] = random_password(length: 50, mode: :base64, encoding: 'ASCII')\n```\n\nNote that node attributes are widely accessible. Storing unencrypted passwords in node attributes, as in this example, carries risk.\n\n### ~~secure_password (`Opscode::OpenSSL::Password`)~~\n\nThis library should be considered deprecated and will be removed in a future version. Please use `OpenSSLCookbook::RandomPassword` instead. The documentation is kept here for historical reasons.\n\n#### ~~Example Usage~~\n```ruby\n::Chef::Recipe.send(:include, Opscode::OpenSSL::Password)\nnode.set_unless['my_password'] = secure_password\n```\n\n~~Note that node attributes are widely accessible. Storing unencrypted passwords in node attributes, as in this example, carries risk.~~\n\n### openssl_x509\n\nThis LWRP generates self-signed, PEM-formatted x509 certificates. If no existing key is specified, the LWRP will automatically generate a passwordless key with the certificate.\n\n#### Attributes\n| Name | Type | Description |\n| ----- | ---- | ------------ |\n| `common_name` | String (Required) | Value for the `CN` certificate field. |\n| `org` | String (Required) | Value for the `O` certificate field. |\n| `org_unit` | String (Required) | Value for the `OU` certificate field. |\n| `country` | String (Required) | Value for the `C` ssl field. |\n| `expire` | Fixnum (Optional) | Value representing the number of days from _now_ through which the issued certificate cert will remain valid. The certificate will expire after this period. |\n| `key_file` | String (Optional) | The path to a certificate key file on the filesystem. If the `key_file` attribute is specified, the LWRP will attempt to source a key from this location. If no key file is found, the LWRP will generate a new key file at this location. If the `key_file` attribute is not specified, the LWRP will generate a key file in the same directory as the generated certificate, with the same name as the generated certificate.\n| `key_pass` | String (Optional) | The passphrase for an existing key's passphrase \n| `key_length` | Fixnum (Optional) | The desired Bit Length of the generated key. _Default: 2048_ |\n| `owner` | String (optional) | The owner of all files created by the LWRP. _Default: \"root\"_ |\n| `group` | String (optional) | The group of all files created by the LWRP. _Default: \"root\"_ |\n| `mode` | String or Fixnum (Optional) | The permission mode of all files created by the LWRP. _Default: \"0400\"_ |\n\n#### Example Usage\n\nIn this example, an administrator wishes to create a self-signed x509 certificate for use with a web server. In order to create the certificate, the administrator crafts this recipe:\n\n```ruby\nopenssl_x509 '/etc/httpd/ssl/mycert.pem' do\n common_name 'www.f00bar.com'\n org 'Foo Bar'\n org_unit 'Lab'\n country 'US'\nend\n```\n\nWhen executed, this recipe will generate a key certificate at `/etc/httpd/ssl/mycert.key`. It will then use that key to generate a new certificate file at `/etc/httpd/ssl/mycert.pem`.\n\n### openssl_dhparam\n\nThis LWRP generates dhparam.pem files. If a valid dhparam.pem file is found at the specified location, no new file will be created. If a file is found at the specified location but it is not a valid dhparam file, it will be overwritten.\n\n#### Attributes\n| Name | Type | Description |\n| ----- | ---- | ------------ |\n| `key_length` | Fixnum (Optional) | The desired Bit Length of the generated key. _Default: 2048_ |\n| `generator` | Fixnum (Optional) | The desired Diffie-Hellmann generator. Can be _2_ or _5_. |\n| `owner` | String (optional) | The owner of all files created by the LWRP. _Default: \"root\"_ |\n| `group` | String (optional) | The group of all files created by the LWRP. _Default: \"root\"_ |\n| `mode` | String or Fixnum (Optional) | The permission mode of all files created by the LWRP. _Default: \"0644\"_ |\n\n#### Example Usage\n\nIn this example, an administrator wishes to create a dhparam.pem file for use with a web server. In order to create the .pem file, the administrator crafts this recipe:\n\n```ruby\nopenssl_dhparam '/etc/httpd/ssl/dhparam.pem' do\n key_length 2048 \n generator 2\nend\n```\n\nWhen executed, this recipe will generate a dhparam file at `/etc/httpd/ssl/dhparam.pem`.\n\n### openssl_rsa_key\n\nThis LWRP generates rsa key files. If a valid rsa key file can be opened at the specified location, no new file will be created. If the RSA key file cannot be opened, either because it does not exist or because the password to the RSA key file does not match the password in the recipe, it will be overwritten.\n\n#### Attributes\n| Name | Type | Description |\n| ----- | ---- | ------------ |\n| `key_length` | Fixnum (Optional) | The desired Bit Length of the generated key. _Default: 2048_ |\n| `key_pass` | String (Optional) | The desired passphrase for the key. |\n| `owner` | String (optional) | The owner of all files created by the LWRP. _Default: \"root\"_ |\n| `group` | String (optional) | The group of all files created by the LWRP. _Default: \"root\"_ |\n| `mode` | String or Fixnum (Optional) | The permission mode of all files created by the LWRP. _Default: \"0644\"_ |\n\n#### Example Usage\n\nIn this example, an administrator wishes to create a new RSA private key file in order to generate other certificates and public keys. In order to create the key file, the administrator crafts this recipe:\n\n```ruby\nopenssl_rsa_key '/etc/httpd/ssl/server.key' do\n key_length 2048 \nend\n```\n\nWhen executed, this recipe will generate a passwordless RSA key file at `/etc/httpd/ssl/server.key`.\n\n\nLicense and Author\n------------------\n\nAuthor:: Jesse Nelson () \nAuthor:: Seth Vargo () \nAuthor:: Charles Johnson () \nAuthor:: Joshua Timberman ()\n\n=======\n\n```text\nCopyright:: 2009-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":{"chef-sugar":">= 3.1.1"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{"openssl":"Empty, this cookbook provides a library, see README.md","upgrade":"Upgrade OpenSSL library and restart dependent services"}} \ No newline at end of file +{"name":"openssl","version":"7.0.1","description":"Provides a library with a method for generating secure random passwords.","long_description":"# OpenSSL Cookbook\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/openssl.svg?branch=master)](http://travis-ci.org/chef-cookbooks/openssl) [![Cookbook Version](https://img.shields.io/cookbook/v/openssl.svg)](https://supermarket.chef.io/cookbooks/openssl)\n\nThis cookbook provides tools for working with the Ruby OpenSSL library. It includes:\n\n- A library method to generate secure random passwords in recipes, using the Ruby SecureRandom library.\n- A resource for generating RSA private keys.\n- A resource for generating x509 certificates.\n- A resource for generating dhparam.pem files.\n- An attribute-driven recipe for upgrading OpenSSL packages.\n\n## Platforms\n\nThe `random_password` mixin works on any platform with the Ruby SecureRandom module. This module is already included with Chef.\n\nThe `openssl_x509`, `openssl_rsa_key` and `openssl_dhparam` resources work on any platform with the OpenSSL Ruby bindings installed. These bindings are already included with Chef.\n\nThe `upgrade` recipe has been tested on the following platforms:\n\n- Debian / Ubuntu derivatives\n- RHEL and derivatives\n- Fedora\n- openSUSE / SUSE Linux Enterprises\n\n## Chef\n\n- Chef 12.5+\n\n## Cookbooks\n\n- none\n\n## Attributes\n\n- `node['openssl']['restart_services']` - An array of service resources that depend on the openssl packages. This array is empty by default, as Chef has no reasonable way to detect which applications or services are compiled against these packages. _Note_ Each service listed in this array should represent a \"`service`\" resource specified in the recipes of the node's run list.\n\n## Recipes\n\n### default\n\nAn empty placeholder recipe. Takes no action.\n\n### upgrade\n\nThe upgrade recipe iterates over the list of packages in the `node['openssl']['packages']` attribute, and manages them with the `:upgrade` action. Each package will send a `:restart` notification to service resources named in the `node['openssl']['restart_services']` attribute.\n\n#### Example Usage\n\nIn this example, assume the node is running the `stats_collector` daemon, which depends on the openssl library. Imagine that a new openssl vulnerability has been disclosed, and the operating system vendor has released an update to openssl to address this vulnerability. In order to protect the node, an administrator crafts this recipe:\n\n```ruby\nnode.default['openssl']['restart_services'] = ['stats_collector']\n\n# other recipe code here...\nservice 'stats_collector' do\n action [:enable, :start]\nend\n\ninclude_recipe 'openssl::upgrade'\n```\n\nWhen executed, this recipe will ensure that openssl is upgraded to the latest version, and that the `stats_collector` service is restarted to pick up the latest security fixes released in the openssl package.\n\n## Libraries & Resources\n\nThere are two mixins packaged with this cookbook.\n\n### random_password (`OpenSSLCookbook::RandomPassword`)\n\nThe `RandomPassword` mixin can be used to generate secure random passwords in Chef cookbooks, usually for assignment to a variable or an attribute. `random_password` uses Ruby's SecureRandom library and is customizable.\n\n#### Example Usage\n\n```ruby\nChef::Recipe.send(:include, OpenSSLCookbook::RandomPassword)\nnode.normal['my_secure_attribute'] = random_password\nnode.normal_unless['my_secure_attribute'] = random_password\nnode.normal['my_secure_attribute'] = random_password(length: 50)\nnode.normal['my_secure_attribute'] = random_password(length: 50, mode: :base64)\nnode.normal['my_secure_attribute'] = random_password(length: 50, mode: :base64, encoding: 'ASCII')\n```\n\nNote that node attributes are widely accessible. Storing unencrypted passwords in node attributes, as in this example, carries risk.\n\n### ~~secure_password (`Opscode::OpenSSL::Password`)~~\n\nThis library should be considered deprecated and will be removed in a future version. Please use `OpenSSLCookbook::RandomPassword` instead. The documentation is kept here for historical reasons.\n\n#### ~~Example Usage~~\n\n```ruby\n::Chef::Recipe.send(:include, Opscode::OpenSSL::Password)\nnode.normal_unless['my_password'] = secure_password\n```\n\n~~Note that node attributes are widely accessible. Storing unencrypted passwords in node attributes, as in this example, carries risk.~~\n\n### openssl_x509\n\nThis resource generates self-signed, PEM-formatted x509 certificates. If no existing key is specified, the resource will automatically generate a passwordless key with the certificate.\n\n#### Attributes\n\nName | Type | Description\n------------------ | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n`common_name` | String (Required) | Value for the `CN` certificate field.\n`org` | String (Required) | Value for the `O` certificate field.\n`org_unit` | String (Required) | Value for the `OU` certificate field.\n`country` | String (Required) | Value for the `C` ssl field.\n`expire` | Fixnum (Optional) | Value representing the number of days from _now_ through which the issued certificate cert will remain valid. The certificate will expire after this period.\n`subject_alt_name` | Array (Optional) | Array of _Subject Alternative Name_ entries, in format `DNS:example.com` or `IP:1.2.3.4` _Default: empty_\n`key_file` | String (Optional) | The path to a certificate key file on the filesystem. If the `key_file` attribute is specified, the resource will attempt to source a key from this location. If no key file is found, the resource will generate a new key file at this location. If the `key_file` attribute is not specified, the resource will generate a key file in the same directory as the generated certificate, with the same name as the generated certificate.\n`key_pass` | String (Optional) | The passphrase for an existing key's passphrase\n`key_length` | Fixnum (Optional) | The desired Bit Length of the generated key. _Default: 2048_\n`owner` | String (optional) | The owner of all files created by the resource. _Default: \"root\"_\n`group` | String (optional) | The group of all files created by the resource. _Default: \"root\"_\n`mode` | String or Fixnum (Optional) | The permission mode of all files created by the resource. _Default: \"0400\"_\n\n#### Example Usage\n\nIn this example, an administrator wishes to create a self-signed x509 certificate for use with a web server. In order to create the certificate, the administrator crafts this recipe:\n\n```ruby\nopenssl_x509 '/etc/httpd/ssl/mycert.pem' do\n common_name 'www.f00bar.com'\n org 'Foo Bar'\n org_unit 'Lab'\n country 'US'\nend\n```\n\nWhen executed, this recipe will generate a key certificate at `/etc/httpd/ssl/mycert.key`. It will then use that key to generate a new certificate file at `/etc/httpd/ssl/mycert.pem`.\n\n### openssl_dhparam\n\nThis resource generates dhparam.pem files. If a valid dhparam.pem file is found at the specified location, no new file will be created. If a file is found at the specified location but it is not a valid dhparam file, it will be overwritten.\n\n#### Attributes\n\nName | Type | Description\n------------ | --------------------------- | ---------------------------------------------------------------------------\n`key_length` | Fixnum (Optional) | The desired Bit Length of the generated key. _Default: 2048_\n`generator` | Fixnum (Optional) | The desired Diffie-Hellmann generator. Can be _2_ or _5_.\n`owner` | String (optional) | The owner of all files created by the resource. _Default: \"root\"_\n`group` | String (optional) | The group of all files created by the resource. _Default: \"root\"_\n`mode` | String or Fixnum (Optional) | The permission mode of all files created by the resource. _Default: \"0644\"_\n\n#### Example Usage\n\nIn this example, an administrator wishes to create a dhparam.pem file for use with a web server. In order to create the .pem file, the administrator crafts this recipe:\n\n```ruby\nopenssl_dhparam '/etc/httpd/ssl/dhparam.pem' do\n key_length 2048\n generator 2\nend\n```\n\nWhen executed, this recipe will generate a dhparam file at `/etc/httpd/ssl/dhparam.pem`.\n\n### openssl_rsa_key\n\nThis resource generates rsa key files. If a valid rsa key file can be opened at the specified location, no new file will be created. If the RSA key file cannot be opened, either because it does not exist or because the password to the RSA key file does not match the password in the recipe, it will be overwritten.\n\n#### Attributes\n\nName | Type | Description\n------------ | --------------------------- | ---------------------------------------------------------------------------\n`key_length` | Fixnum (Optional) | The desired Bit Length of the generated key. _Default: 2048_\n`key_pass` | String (Optional) | The desired passphrase for the key.\n`owner` | String (optional) | The owner of all files created by the resource. _Default: \"root\"_\n`group` | String (optional) | The group of all files created by the resource. _Default: \"root\"_\n`mode` | String or Fixnum (Optional) | The permission mode of all files created by the resource. _Default: \"0644\"_\n\n#### Example Usage\n\nIn this example, an administrator wishes to create a new RSA private key file in order to generate other certificates and public keys. In order to create the key file, the administrator crafts this recipe:\n\n```ruby\nopenssl_rsa_key '/etc/httpd/ssl/server.key' do\n key_length 2048\nend\n```\n\nWhen executed, this recipe will generate a passwordless RSA key file at `/etc/httpd/ssl/server.key`.\n\n## License and Author\n\nAuthor:: Jesse Nelson ([spheromak@gmail.com](mailto:spheromak@gmail.com))
\nAuthor:: Seth Vargo ([sethvargo@gmail.com](mailto:sethvargo@gmail.com))
\nAuthor:: Charles Johnson ([charles@chef.io](mailto:charles@chef.io))
\nAuthor:: Joshua Timberman ([joshua@chef.io](mailto:joshua@chef.io))\n\n```text\nCopyright:: 2009-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":{},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{"openssl":"Empty, this cookbook provides a library, see README.md","upgrade":"Upgrade OpenSSL library and restart dependent services"},"source_url":"https://github.com/chef-cookbooks/openssl","issues_url":"https://github.com/chef-cookbooks/openssl/issues","chef_version":">= 12.5","ohai_version":{}} \ No newline at end of file diff --git a/cookbooks/openssl/providers/dhparam.rb b/cookbooks/openssl/providers/dhparam.rb deleted file mode 100644 index 4b6e4c3..0000000 --- a/cookbooks/openssl/providers/dhparam.rb +++ /dev/null @@ -1,33 +0,0 @@ -# -# dhparam.pem provider -# -# Author:: Charles Johnson -# - -include OpenSSLCookbook::Helpers - -use_inline_resources - -def whyrun_supported? - true -end - -action :create do - converge_by("Create a dhparam file #{@new_resource}") do - unless dhparam_pem_valid?(new_resource.name) - dhparam_content = gen_dhparam(new_resource.key_length, new_resource.generator).to_pem - - log "Generating #{new_resource.key_length} bit "\ - "dhparam file at #{new_resource.name}, this may take some time" - - file new_resource.name do - action :create - owner new_resource.owner - group new_resource.group - mode new_resource.mode - sensitive true - content dhparam_content - end - end - end -end diff --git a/cookbooks/openssl/providers/rsa_key.rb b/cookbooks/openssl/providers/rsa_key.rb deleted file mode 100644 index 0a4dd42..0000000 --- a/cookbooks/openssl/providers/rsa_key.rb +++ /dev/null @@ -1,39 +0,0 @@ -# -# dhparam.pem provider -# -# Author:: Charles Johnson -# - -include OpenSSLCookbook::Helpers - -use_inline_resources - -def whyrun_supported? - true -end - -action :create do - converge_by("Create an RSA key #{@new_resource}") do - unless key_file_valid?(new_resource.name, new_resource.key_pass) - - log "Generating #{new_resource.key_length} bit "\ - "RSA key file at #{new_resource.name}, this may take some time" - - if new_resource.key_pass - unencrypted_rsa_key = gen_rsa_key(new_resource.key_length) - rsa_key_content = encrypt_rsa_key(unencrypted_rsa_key, new_resource.key_pass) - else - rsa_key_content = gen_rsa_key(new_resource.key_length).to_pem - end - - file new_resource.name do - action :create - owner new_resource.owner - group new_resource.group - mode new_resource.mode - sensitive true - content rsa_key_content - end - end - end -end diff --git a/cookbooks/openssl/providers/x509.rb b/cookbooks/openssl/providers/x509.rb deleted file mode 100644 index 433300a..0000000 --- a/cookbooks/openssl/providers/x509.rb +++ /dev/null @@ -1,104 +0,0 @@ -# -# x509 self signed cert provider -# -# Author:: Jesse Nelson -# - -include OpenSSLCookbook::Helpers - -use_inline_resources - -def whyrun_supported? - true -end - -attr_reader :key_file, :key, :cert, :ef - -action :create do - converge_by("Create #{@new_resource}") do - unless ::File.exist? new_resource.name - create_keys - cert_content = cert.to_pem - key_content = key.to_pem - - file new_resource.name do - action :create_if_missing - mode new_resource.mode - owner new_resource.owner - group new_resource.group - sensitive true - content cert_content - end - - file new_resource.key_file do - action :create_if_missing - mode new_resource.mode - owner new_resource.owner - group new_resource.group - sensitive true - content key_content - end - new_resource.updated_by_last_action(true) - end - end -end - -protected - - # rubocop:disable Metrics/AbcSize, Style/IndentationConsistency - def key_file - unless new_resource.key_file - path, file = ::File.split(new_resource.name) - filename = ::File.basename(file, ::File.extname(file)) - new_resource.key_file path + '/' + filename + '.key' - end - new_resource.key_file - end - - def key - @key ||= if key_file_valid?(key_file, new_resource.key_pass) - OpenSSL::PKey::RSA.new ::File.read(key_file), new_resource.key_pass - else - OpenSSL::PKey::RSA.new(new_resource.key_length) - end - @key - end - - def cert - @cert ||= OpenSSL::X509::Certificate.new - end - - def gen_cert - cert - cert.subject = cert.issuer = OpenSSL::X509::Name.parse(subject) - cert.not_before = Time.now - cert.not_after = Time.now + (new_resource.expire.to_i * 24 * 60 * 60) - cert.public_key = key.public_key - cert.serial = 0x0 - cert.version = 2 - end - - def subject - @subject ||= '/C=' + new_resource.country + - '/O=' + new_resource.org + - '/OU=' + new_resource.org_unit + - '/CN=' + new_resource.common_name - end - - def extensions - [ - ef.create_extension('basicConstraints', 'CA:TRUE', true), - ef.create_extension('subjectKeyIdentifier', 'hash') - ] - end - - def create_keys - gen_cert - @ef ||= OpenSSL::X509::ExtensionFactory.new - ef.subject_certificate = cert - ef.issuer_certificate = cert - cert.extensions = extensions - cert.add_extension ef.create_extension('authorityKeyIdentifier', - 'keyid:always,issuer:always') - cert.sign key, OpenSSL::Digest::SHA256.new - end diff --git a/cookbooks/openssl/recipes/default.rb b/cookbooks/openssl/recipes/default.rb index b0465e1..0311040 100644 --- a/cookbooks/openssl/recipes/default.rb +++ b/cookbooks/openssl/recipes/default.rb @@ -2,7 +2,7 @@ # Cookbook Name:: openssl # Recipe:: default # -# Copyright 2009, 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/openssl/recipes/upgrade.rb b/cookbooks/openssl/recipes/upgrade.rb index c31923b..d9d6f4a 100644 --- a/cookbooks/openssl/recipes/upgrade.rb +++ b/cookbooks/openssl/recipes/upgrade.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: openssl +# Cookbook:: openssl # Recipe:: upgrade # -# Copyright 2015, Chef Software, Inc. +# Copyright:: 2015-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. @@ -16,22 +16,17 @@ # See the License for the specific language governing permissions and # limitations under the License. # -include_recipe 'chef-sugar' -# Attributes are set here and not in attributes/default.rb because of the -# chef-sugar dependency for the methods evaluated in the case statement. -case -when debian_before_or_at_squeeze?, ubuntu_before_or_at_lucid? - node.default['openssl']['packages'] = %w(libssl0.9.8 openssl) -when debian_after_or_at_wheezy?, ubuntu_after_or_at_precise? - node.default['openssl']['packages'] = %w(libssl1.0.0 openssl) -when rhel? - node.default['openssl']['packages'] = %w(openssl) +case node['platform_family'] +when 'debian', 'ubuntu' + packages = %w(libssl1.0.0 openssl) +when 'rhel', 'fedora', 'suse' + packages = %w(openssl) else - node.default['openssl']['packages'] = [] + packages = [] end -node['openssl']['packages'].each do |ssl_pkg| +packages.each do |ssl_pkg| package ssl_pkg do action :upgrade node['openssl']['restart_services'].each do |ssl_svc| diff --git a/cookbooks/openssl/resources/dhparam.rb b/cookbooks/openssl/resources/dhparam.rb index 1a8bd14..c3d4d97 100644 --- a/cookbooks/openssl/resources/dhparam.rb +++ b/cookbooks/openssl/resources/dhparam.rb @@ -1,10 +1,28 @@ +include OpenSSLCookbook::Helpers -actions [:create] -default_action :create +property :name, String, name_property: true +property :key_length, equal_to: [1024, 2048, 4096, 8192], default: 2048 +property :generator, equal_to: [2, 5], default: 2 +property :owner, String +property :group, String +property :mode, [Integer, String] -attribute :name, :kind_of => String, :name_attribute => true -attribute :key_length, :equal_to => [1024, 2048, 4096, 8192], :default => 2048 -attribute :generator, :equal_to => [2, 5], :default => 2 -attribute :owner, :kind_of => String -attribute :group, :kind_of => String -attribute :mode, :kind_of => [Integer, String] +action :create do + unless dhparam_pem_valid?(new_resource.name) # ~FC023 + converge_by("Create a dhparam file #{@new_resource}") do + dhparam_content = gen_dhparam(new_resource.key_length, new_resource.generator).to_pem + + log "Generating #{new_resource.key_length} bit "\ + "dhparam file at #{new_resource.name}, this may take some time" + + file new_resource.name do + action :create + owner new_resource.owner + group new_resource.group + mode new_resource.mode + sensitive true + content dhparam_content + end + end + end +end diff --git a/cookbooks/openssl/resources/rsa_key.rb b/cookbooks/openssl/resources/rsa_key.rb index f1e46bb..5b2b170 100644 --- a/cookbooks/openssl/resources/rsa_key.rb +++ b/cookbooks/openssl/resources/rsa_key.rb @@ -1,10 +1,33 @@ +include OpenSSLCookbook::Helpers -actions [:create] -default_action :create +property :name, String, name_property: true +property :key_length, equal_to: [1024, 2048, 4096, 8192], default: 2048 +property :key_pass, String +property :owner, String +property :group, String +property :mode, [Integer, String] -attribute :name, :kind_of => String, :name_attribute => true -attribute :key_length, :equal_to => [1024, 2048, 4096, 8192], :default => 2048 -attribute :key_pass, :kind_of => String, :default => nil -attribute :owner, :kind_of => String -attribute :group, :kind_of => String -attribute :mode, :kind_of => [Integer, String] +action :create do + unless key_file_valid?(new_resource.name, new_resource.key_pass) + converge_by("Create an RSA key #{@new_resource}") do + log "Generating #{new_resource.key_length} bit "\ + "RSA key file at #{new_resource.name}, this may take some time" + + if new_resource.key_pass + unencrypted_rsa_key = gen_rsa_key(new_resource.key_length) + rsa_key_content = encrypt_rsa_key(unencrypted_rsa_key, new_resource.key_pass) + else + rsa_key_content = gen_rsa_key(new_resource.key_length).to_pem + end + + file new_resource.name do + action :create + owner new_resource.owner + group new_resource.group + mode new_resource.mode + sensitive true + content rsa_key_content + end + end + end +end diff --git a/cookbooks/openssl/resources/x509.rb b/cookbooks/openssl/resources/x509.rb index 5685778..2929cbf 100644 --- a/cookbooks/openssl/resources/x509.rb +++ b/cookbooks/openssl/resources/x509.rb @@ -1,16 +1,118 @@ +include OpenSSLCookbook::Helpers -actions [:create] -default_action :create +property :name, String, name_property: true +property :owner, String +property :group, String +property :expire, Integer +property :mode, [Integer, String] +property :org, String, required: true +property :org_unit, String, required: true +property :country, String, required: true +property :common_name, String, required: true +property :subject_alt_name, Array, default: [] +property :key_file, String +property :key_pass, String +property :key_length, equal_to: [1024, 2048, 4096, 8192], default: 2048 -attribute :name, :kind_of => String, :name_attribute => true -attribute :owner, :kind_of => String -attribute :group, :kind_of => String -attribute :expire, :kind_of => Integer -attribute :mode, :kind_of => [Integer, String] -attribute :org, :kind_of => String, :required => true -attribute :org_unit, :kind_of => String, :required => true -attribute :country, :kind_of => String, :required => true -attribute :common_name, :kind_of => String, :required => true -attribute :key_file, :kind_of => String, :default => nil -attribute :key_pass, :kind_of => String, :default => nil -attribute :key_length, :equal_to => [1024, 2048, 4096, 8192], :default => 2048 +action :create do + unless ::File.exist? new_resource.name + converge_by("Create #{@new_resource}") do + create_keys + cert_content = cert.to_pem + key_content = key.to_pem + + file new_resource.name do + action :create_if_missing + mode new_resource.mode + owner new_resource.owner + group new_resource.group + sensitive true + content cert_content + end + + file new_resource.key_file do + action :create_if_missing + mode new_resource.mode + owner new_resource.owner + group new_resource.group + sensitive true + content key_content + end + end + end +end + +action_class.class_eval do + def generate_key_file + unless new_resource.key_file + path, file = ::File.split(new_resource.name) + filename = ::File.basename(file, ::File.extname(file)) + new_resource.key_file path + '/' + filename + '.key' + end + new_resource.key_file + end + + def key + @key ||= if key_file_valid?(generate_key_file, new_resource.key_pass) + OpenSSL::PKey::RSA.new ::File.read(generate_key_file), new_resource.key_pass + else + OpenSSL::PKey::RSA.new(new_resource.key_length) + end + @key + end + + def cert + @cert ||= OpenSSL::X509::Certificate.new + end + + def gen_cert + cert + cert.subject = cert.issuer = OpenSSL::X509::Name.parse(subject) + cert.not_before = Time.now + cert.not_after = Time.now + (new_resource.expire.to_i * 24 * 60 * 60) + cert.public_key = key.public_key + cert.serial = 0x0 + cert.version = 2 + end + + def subject + @subject ||= '/C=' + new_resource.country + + '/O=' + new_resource.org + + '/OU=' + new_resource.org_unit + + '/CN=' + new_resource.common_name + end + + def extensions + exts = [] + exts << @ef.create_extension('basicConstraints', 'CA:TRUE', true) + exts << @ef.create_extension('subjectKeyIdentifier', 'hash') + + unless new_resource.subject_alt_name.empty? + san = {} + counters = {} + new_resource.subject_alt_name.each do |an| + kind, value = an.split(':', 2) + counters[kind] ||= 0 + counters[kind] += 1 + san["#{kind}.#{counters[kind]}"] = value + end + @ef.config['alt_names'] = san + exts << @ef.create_extension('subjectAltName', '@alt_names') + end + + exts + end + + def create_keys + gen_cert + @ef ||= OpenSSL::X509::ExtensionFactory.new + @ef.subject_certificate = cert + @ef.issuer_certificate = cert + @ef.config = OpenSSL::Config.load(OpenSSL::Config::DEFAULT_CONFIG_FILE) + + cert.extensions = extensions + cert.add_extension @ef.create_extension('authorityKeyIdentifier', + 'keyid:always,issuer:always') + cert.sign key, OpenSSL::Digest::SHA256.new + end +end From 4e5d452aff93b4711b1c8122e22a94e2ceae11fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 7 Apr 2017 18:19:55 +0200 Subject: [PATCH 08/83] Add support for PostgreSQL backups --- site-cookbooks/backup/recipes/default.rb | 6 ++++ .../backup/templates/default/backup.rb.erb | 4 +++ .../backup/templates/default/config.rb.erb | 30 +++++++++---------- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/site-cookbooks/backup/recipes/default.rb b/site-cookbooks/backup/recipes/default.rb index f02f585..fe4a869 100644 --- a/site-cookbooks/backup/recipes/default.rb +++ b/site-cookbooks/backup/recipes/default.rb @@ -58,6 +58,12 @@ if node["backup"]["default_model"] end include_recipe 'logrotate' + if node["backup"]["mysql"] + # Install MySQL client (includes mysqldump) + mysql_client 'default' do + action :create + end + end logrotate_app 'backup' do path '/var/log/backup.log' diff --git a/site-cookbooks/backup/templates/default/backup.rb.erb b/site-cookbooks/backup/templates/default/backup.rb.erb index 23ec04f..836fbc3 100644 --- a/site-cookbooks/backup/templates/default/backup.rb.erb +++ b/site-cookbooks/backup/templates/default/backup.rb.erb @@ -16,6 +16,10 @@ KosmosBackup.new(:default, 'default backup') do <%- end -%> <%- end -%> +<%- if node["backup"]["postgresql"] -%> + database PostgreSQL +<%- end -%> + <%- if node["mongodb"] -%> <%- node["backup"]["mongodb"]["databases"].each do |db_name| -%> database MongoDB, :"<%= db_name.to_sym %>" do |db| diff --git a/site-cookbooks/backup/templates/default/config.rb.erb b/site-cookbooks/backup/templates/default/config.rb.erb index 736aa33..11c7814 100644 --- a/site-cookbooks/backup/templates/default/config.rb.erb +++ b/site-cookbooks/backup/templates/default/config.rb.erb @@ -45,11 +45,11 @@ Database::MySQL.defaults do |db| end <%- end -%> -<%- if node["backup"]["postgresql"] -%> +<%- if node["backup"]["mysql"] -%> Database::MySQL.defaults do |db| - db.host = "<%= node["backup"]["postgresql"]["host"] %>" - db.username = "<%= node["backup"]["postgresql"]["username"] %>" - db.password = "<%= node["backup"]["postgresql"]["password"] %>" + db.host = "<%= node["backup"]["mysql"]["host"] %>" + db.username = "<%= node["backup"]["mysql"]["username"] %>" + db.password = "<%= node["backup"]["mysql"]["password"] %>" db.additional_options = ['--quick', '--single-transaction'] end <%- end -%> @@ -63,17 +63,17 @@ Database::Redis.defaults do |db| end <%- if node["backup"]["postgresql"] -%> - database PostgreSQL do |db| - db.username = "" - db.password = "<%= node['postgresql']['password']['postgres'] %>" - db.host = "localhost" - db.port = 5432 - db.socket = "/tmp/pg.sock" - # When dumping all databases, `skip_tables` and `only_tables` are ignored. - db.skip_tables = ['skip', 'these', 'tables'] - db.only_tables = ['only', 'these' 'tables'] - db.additional_options = [] - end +Database::PostgreSQL.defaults do |db| + db.username = "<%= node["backup"]["postgresql"]["username"] %>" + db.password = "<%= node["backup"]["postgresql"]["password"] %>" + db.host = "<%= node["backup"]["postgresql"]["host"] %>" + db.port = 5432 + # db.socket = "/var/run/postgresql/.s.PGSQL.5432" + # When dumping all databases, `skip_tables` and `only_tables` are ignored. + db.skip_tables = [] + db.only_tables = [] + db.additional_options = [] +end <% end -%> preconfigure 'KosmosBackup' do From 6bea5b7567505d6a8cbb72b1c8ae7a1048b73ebd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 7 Apr 2017 18:20:22 +0200 Subject: [PATCH 09/83] Enable HTTP2 and HSTS --- .../templates/default/nginx_conf_xmpp.5apps.com.erb | 2 +- .../templates/default/nginx_conf_ipfs.kosmos.org.erb | 2 +- .../kosmos-mediawiki/templates/default/nginx.conf.erb | 3 ++- .../kosmos-wordpress/templates/default/nginx.conf.erb | 3 ++- .../sockethub/templates/default/nginx_conf_sockethub.erb | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/site-cookbooks/5apps-xmpp_server/templates/default/nginx_conf_xmpp.5apps.com.erb b/site-cookbooks/5apps-xmpp_server/templates/default/nginx_conf_xmpp.5apps.com.erb index db0cfa5..3b41657 100644 --- a/site-cookbooks/5apps-xmpp_server/templates/default/nginx_conf_xmpp.5apps.com.erb +++ b/site-cookbooks/5apps-xmpp_server/templates/default/nginx_conf_xmpp.5apps.com.erb @@ -1,7 +1,7 @@ server { listen 80; # For Let's Encrypt <% if File.exist?(@ssl_cert) && File.exist?(@ssl_key) -%> - listen 443 ssl spdy; + listen 443 ssl http2; <% end -%> server_name <%= @server_name %>; diff --git a/site-cookbooks/kosmos-ipfs/templates/default/nginx_conf_ipfs.kosmos.org.erb b/site-cookbooks/kosmos-ipfs/templates/default/nginx_conf_ipfs.kosmos.org.erb index 94c75a1..6fdb500 100644 --- a/site-cookbooks/kosmos-ipfs/templates/default/nginx_conf_ipfs.kosmos.org.erb +++ b/site-cookbooks/kosmos-ipfs/templates/default/nginx_conf_ipfs.kosmos.org.erb @@ -16,7 +16,7 @@ server { server { <% if File.exist?(@ssl_cert) && File.exist?(@ssl_key) -%> - listen <%= @ipfs_external_api_port %> ssl spdy; + listen <%= @ipfs_external_api_port %> ssl http2; <% else -%> listen 80; <% end -%> diff --git a/site-cookbooks/kosmos-mediawiki/templates/default/nginx.conf.erb b/site-cookbooks/kosmos-mediawiki/templates/default/nginx.conf.erb index 0154d5f..c5afe43 100644 --- a/site-cookbooks/kosmos-mediawiki/templates/default/nginx.conf.erb +++ b/site-cookbooks/kosmos-mediawiki/templates/default/nginx.conf.erb @@ -1,6 +1,6 @@ server { listen 80; - listen 443 ssl; + listen 443 ssl http2; server_name <%= @server_name %>; access_log /var/log/nginx/<%= @server_name %>.access.log; @@ -30,6 +30,7 @@ server { fastcgi_param HTTP_PROXY ""; } + add_header Strict-Transport-Security "max-age=15768000; includeSubDomains"; ssl_certificate <%= @ssl_cert %>; ssl_certificate_key <%= @ssl_key %>; } diff --git a/site-cookbooks/kosmos-wordpress/templates/default/nginx.conf.erb b/site-cookbooks/kosmos-wordpress/templates/default/nginx.conf.erb index 7c9c86e..3477c1b 100644 --- a/site-cookbooks/kosmos-wordpress/templates/default/nginx.conf.erb +++ b/site-cookbooks/kosmos-wordpress/templates/default/nginx.conf.erb @@ -1,7 +1,7 @@ server { listen 80; <% if File.exist?(@ssl_cert) && File.exist?(@ssl_key) -%> - listen <%= @server_port %> ssl spdy; + listen <%= @server_port %> ssl http2; <% end -%> server_name <%= @server_name %> <%= @server_aliases.join(" ") %>; @@ -35,6 +35,7 @@ server { } <% if File.exist?(@ssl_cert) && File.exist?(@ssl_key) -%> + add_header Strict-Transport-Security "max-age=15768000; includeSubDomains"; ssl_certificate <%= @ssl_cert %>; ssl_certificate_key <%= @ssl_key %>; <% end -%> diff --git a/site-cookbooks/sockethub/templates/default/nginx_conf_sockethub.erb b/site-cookbooks/sockethub/templates/default/nginx_conf_sockethub.erb index daf8b43..14f565b 100644 --- a/site-cookbooks/sockethub/templates/default/nginx_conf_sockethub.erb +++ b/site-cookbooks/sockethub/templates/default/nginx_conf_sockethub.erb @@ -11,7 +11,7 @@ map $http_upgrade $connection_upgrade { server { listen 80; # For Let's Encrypt <% if File.exist?(@ssl_cert) && File.exist?(@ssl_key) -%> - listen <%= @sockethub_external_port %> ssl spdy; + listen <%= @sockethub_external_port %> ssl http2; add_header Strict-Transport-Security "max-age=15768000"; <% end -%> From 99a509176018ad0fa6052752e7c77685c47981af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 7 Apr 2017 18:21:20 +0200 Subject: [PATCH 10/83] Backup the mastodon PostgreSQL database --- site-cookbooks/kosmos-mastodon/metadata.rb | 1 + site-cookbooks/kosmos-mastodon/recipes/default.rb | 13 +++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/site-cookbooks/kosmos-mastodon/metadata.rb b/site-cookbooks/kosmos-mastodon/metadata.rb index 6447a64..6f19998 100644 --- a/site-cookbooks/kosmos-mastodon/metadata.rb +++ b/site-cookbooks/kosmos-mastodon/metadata.rb @@ -13,3 +13,4 @@ depends "application_ruby" depends "application_javascript" depends "postgresql" depends "database" +depends "backup" diff --git a/site-cookbooks/kosmos-mastodon/recipes/default.rb b/site-cookbooks/kosmos-mastodon/recipes/default.rb index 694ca15..6d58d45 100644 --- a/site-cookbooks/kosmos-mastodon/recipes/default.rb +++ b/site-cookbooks/kosmos-mastodon/recipes/default.rb @@ -148,9 +148,10 @@ application mastodon_path do end end -# unless node.chef_environment == "development" -# node.override["backup"]["postgresql"]["host"] = "localhost" -# node.override["backup"]["postgresql"]["username"] = "postgres" -# node.override["backup"]["postgresql"]["password"] = node['postgresql']['password']['postgres'] -# include_recipe "backup" -# end +unless node.chef_environment == "development" + # Backup the database to S3 + node.override["backup"]["postgresql"]["host"] = "localhost" + node.override["backup"]["postgresql"]["username"] = "postgres" + node.override["backup"]["postgresql"]["password"] = node['postgresql']['password']['postgres'] + include_recipe "backup" +end From 3549b8594ad3361558afd7a0c9a8b343b30298cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 7 Apr 2017 18:26:49 +0200 Subject: [PATCH 11/83] Enable IPv6 and HTTP2 on Mastodon --- .../templates/default/nginx_conf_mastodon.erb | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/site-cookbooks/kosmos-mastodon/templates/default/nginx_conf_mastodon.erb b/site-cookbooks/kosmos-mastodon/templates/default/nginx_conf_mastodon.erb index 2f87598..7c9da59 100644 --- a/site-cookbooks/kosmos-mastodon/templates/default/nginx_conf_mastodon.erb +++ b/site-cookbooks/kosmos-mastodon/templates/default/nginx_conf_mastodon.erb @@ -4,7 +4,8 @@ map $http_upgrade $connection_upgrade { } server { - listen 80; + listen 80; # IPv4 + listen [::]:80; #IPv6 server_name <%= @server_name %>; access_log "/var/log/nginx/mastodon.access.log"; @@ -19,18 +20,13 @@ server { } server { - listen 443 ssl; + listen 443 ssl http2; #IPv4 + listen [::]:443 ssl http2; #IPv6 server_name <%= @server_name %>; access_log "/var/log/nginx/mastodon.access.log"; error_log "/var/log/nginx/mastodon.error.log"; - ssl_protocols TLSv1.2; - ssl_ciphers EECDH+AESGCM:EECDH+AES; - ssl_ecdh_curve secp384r1; - ssl_prefer_server_ciphers on; - ssl_session_cache shared:SSL:10m; - <% if File.exist?(@ssl_cert) && File.exist?(@ssl_key) -%> ssl_certificate <%= @ssl_cert %>; @@ -44,7 +40,7 @@ server { root <%= @mastodon_path %>/public; - # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains"; + add_header Strict-Transport-Security "max-age=15768000; includeSubDomains"; location / { try_files $uri @proxy; From e3bcf9b1b86e94394746aabaa6e033f0e4ded7df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 7 Apr 2017 18:27:02 +0200 Subject: [PATCH 12/83] Add reload support to mastodon-web systemd service --- .../templates/default/mastodon-web.systemd.service.erb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/site-cookbooks/kosmos-mastodon/templates/default/mastodon-web.systemd.service.erb b/site-cookbooks/kosmos-mastodon/templates/default/mastodon-web.systemd.service.erb index 879d87c..a3464dd 100644 --- a/site-cookbooks/kosmos-mastodon/templates/default/mastodon-web.systemd.service.erb +++ b/site-cookbooks/kosmos-mastodon/templates/default/mastodon-web.systemd.service.erb @@ -8,10 +8,14 @@ After=postgresql@9.4-main.service [Service] Type=simple User=<%= @user %> +PIDFile=<%= @app_dir %>/tmp/puma.pid WorkingDirectory=<%= @app_dir %> Environment="RAILS_ENV=production" Environment="PORT=3000" -ExecStart=/usr/local/bin/bundle exec puma -C config/puma.rb +ExecStart=/usr/local/bin/bundle exec puma -C config/puma.rb --pidfile <%= @app_dir %>/tmp/puma.pid +ExecStop=/usr/local/bin/bundle exec puma -C config/puma.rb --pidfile <%= @app_dir %>/tmp/puma.pid stop +ExecReload=/usr/local/bin/bundle exec pumactl -F config/puma.rb --pidfile <%= @app_dir %>/tmp/puma.pid phased-restart +ExecRestart=/usr/local/bin/bundle exec pumactl -F config/puma.rb --pidfile <%= @app_dir %>/tmp/puma.pid restart TimeoutSec=15 Restart=always From af96881daa09cd7583eaba4fef65bf0dfb70eebd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 7 Apr 2017 18:27:29 +0200 Subject: [PATCH 13/83] Add kosmos-mastodon::nginx recipe to Vagrant --- Vagrantfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Vagrantfile b/Vagrantfile index ceed2fd..8bd5b03 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -87,7 +87,7 @@ Vagrant.configure(2) do |config| # chef.add_recipe 'kosmos-wordpress' # chef.add_recipe 'sockethub' chef.add_recipe 'kosmos-mastodon' - # chef.add_recipe 'kosmos-mastodon::nginx' + chef.add_recipe 'kosmos-mastodon::nginx' # chef.add_recipe '5apps-hubot::xmpp_botka' # chef.add_recipe 'kosmos-hubot' From 4530190df6e22b04f01d94243332dcde7ea1867d Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Sat, 8 Apr 2017 16:10:43 +0100 Subject: [PATCH 14/83] Use "kosmos" branch for Mastodon deploys --- site-cookbooks/kosmos-mastodon/recipes/default.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site-cookbooks/kosmos-mastodon/recipes/default.rb b/site-cookbooks/kosmos-mastodon/recipes/default.rb index 6d58d45..1bee581 100644 --- a/site-cookbooks/kosmos-mastodon/recipes/default.rb +++ b/site-cookbooks/kosmos-mastodon/recipes/default.rb @@ -52,7 +52,7 @@ application mastodon_path do user "mastodon" group "mastodon" repository "https://github.com/67P/mastodon.git" - revision "redis_db" + revision "kosmos" end mastodon_credentials = Chef::EncryptedDataBagItem.load('credentials', 'mastodon') From 54332db8de999a44001b7ab831d964988cea6741 Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Mon, 17 Apr 2017 11:40:31 +0200 Subject: [PATCH 15/83] Use ruby-build for Mastodon, update cookbooks This uses the ruby_build provider for Mastodon, installing Ruby 2.4.1 currently. It also updates some other cookbooks and the runlists. --- Batali | 2 +- batali.manifest | 84 +++++- cookbooks/build-essential/MAINTAINERS.md | 11 +- cookbooks/build-essential/README.md | 55 +++- cookbooks/build-essential/recipes/_windows.rb | 119 +++------ cookbooks/build-essential/recipes/default.rb | 17 +- .../resources/build_essential.rb | 4 +- .../resources/xcode_command_line_tools.rb | 4 +- cookbooks/homebrew/CHANGELOG.md | 103 +++++-- cookbooks/homebrew/MAINTAINERS.md | 10 +- cookbooks/homebrew/README.md | 82 +++--- cookbooks/homebrew/attributes/default.rb | 11 +- .../homebrew/libraries/homebrew_mixin.rb | 28 +- .../homebrew/libraries/homebrew_package.rb | 102 ------- cookbooks/homebrew/libraries/matchers.rb | 17 +- cookbooks/homebrew/metadata.json | 2 +- cookbooks/homebrew/providers/cask.rb | 4 +- cookbooks/homebrew/providers/tap.rb | 4 +- cookbooks/homebrew/recipes/cask.rb | 18 +- cookbooks/homebrew/recipes/default.rb | 20 +- cookbooks/homebrew/recipes/install_casks.rb | 4 +- .../homebrew/recipes/install_formulas.rb | 8 +- cookbooks/homebrew/recipes/install_taps.rb | 4 +- cookbooks/homebrew/resources/tap.rb | 4 +- cookbooks/poise-build-essential/CHANGELOG.md | 5 + cookbooks/poise-build-essential/README.md | 85 ++++++ .../attributes/default.rb | 21 ++ .../files/halite_gem/poise_build_essential.rb | 22 ++ .../build_essential_providers.rb | 49 ++++ .../build_essential_providers/base.rb | 103 +++++++ .../build_essential_providers/debian.rb | 41 +++ .../build_essential_providers/freebsd.rb | 46 ++++ .../build_essential_providers/mac_os_x.rb | 66 +++++ .../build_essential_providers/omnios.rb | 46 ++++ .../build_essential_providers/rhel.rb | 46 ++++ .../build_essential_providers/smartos.rb | 39 +++ .../build_essential_providers/solaris.rb | 47 ++++ .../build_essential_providers/suse.rb | 43 +++ .../build_essential_providers/windows.rb | 68 +++++ .../poise_build_essential/cheftie.rb | 18 ++ .../poise_build_essential/resources.rb | 26 ++ .../resources/poise_build_essential.rb | 48 ++++ .../poise_build_essential/version.rb | 20 ++ .../libraries/default.rb | 19 ++ cookbooks/poise-build-essential/metadata.json | 1 + .../poise-build-essential/recipes/default.rb | 19 ++ cookbooks/poise-git/CHANGELOG.md | 5 + cookbooks/poise-git/README.md | 151 +++++++++++ cookbooks/poise-git/attributes/default.rb | 26 ++ .../poise-git/files/halite_gem/poise_git.rb | 24 ++ .../files/halite_gem/poise_git/cheftie.rb | 18 ++ .../poise_git/git_client_providers.rb | 36 +++ .../poise_git/git_client_providers/base.rb | 93 +++++++ .../poise_git/git_client_providers/dummy.rb | 79 ++++++ .../poise_git/git_client_providers/system.rb | 73 +++++ .../halite_gem/poise_git/git_command_mixin.rb | 37 +++ .../files/halite_gem/poise_git/resources.rb | 27 ++ .../poise_git/resources/poise_git.rb | 252 ++++++++++++++++++ .../poise_git/resources/poise_git_client.rb | 82 ++++++ .../files/halite_gem/poise_git/safe_string.rb | 25 ++ .../files/halite_gem/poise_git/version.rb | 20 ++ cookbooks/poise-git/libraries/default.rb | 19 ++ cookbooks/poise-git/metadata.json | 1 + cookbooks/poise-git/recipes/default.rb | 22 ++ cookbooks/poise-ruby-build/CHANGELOG.md | 22 ++ cookbooks/poise-ruby-build/README.md | 53 ++++ .../poise-ruby-build/attributes/default.rb | 17 ++ .../files/halite_gem/poise_ruby/ruby_build.rb | 26 ++ .../poise_ruby/ruby_build/cheftie.rb | 17 ++ .../poise_ruby/ruby_build/provider.rb | 219 +++++++++++++++ .../poise_ruby/ruby_build/version.rb | 22 ++ .../poise-ruby-build/libraries/default.rb | 19 ++ cookbooks/poise-ruby-build/metadata.json | 1 + cookbooks/seven_zip/CHANGELOG.md | 21 +- cookbooks/seven_zip/CONTRIBUTING | 29 -- cookbooks/seven_zip/LICENSE | 201 -------------- cookbooks/seven_zip/README.md | 100 +++++-- cookbooks/seven_zip/attributes/default.rb | 20 +- cookbooks/seven_zip/libraries/matchers.rb | 33 +++ cookbooks/seven_zip/metadata.json | 42 +-- cookbooks/seven_zip/metadata.rb | 10 - cookbooks/seven_zip/providers/archive.rb | 42 ++- cookbooks/seven_zip/recipes/default.rb | 20 +- cookbooks/seven_zip/resources/archive.rb | 11 +- nodes/dev.kosmos.org.json | 1 + nodes/staging.kosmos.org.json | 18 ++ site-cookbooks/kosmos-base/recipes/default.rb | 3 - site-cookbooks/kosmos-mastodon/metadata.rb | 3 +- .../kosmos-mastodon/recipes/default.rb | 35 ++- .../mastodon-sidekiq.systemd.service.erb | 2 +- .../default/mastodon-web.systemd.service.erb | 8 +- site-cookbooks/kosmos-ruby/CHANGELOG.md | 11 - site-cookbooks/kosmos-ruby/README.md | 80 ------ .../kosmos-ruby/attributes/default.rb | 1 - site-cookbooks/kosmos-ruby/metadata.rb | 7 - site-cookbooks/kosmos-ruby/recipes/default.rb | 54 ---- 96 files changed, 2830 insertions(+), 903 deletions(-) delete mode 100644 cookbooks/homebrew/libraries/homebrew_package.rb create mode 100644 cookbooks/poise-build-essential/CHANGELOG.md create mode 100644 cookbooks/poise-build-essential/README.md create mode 100644 cookbooks/poise-build-essential/attributes/default.rb create mode 100644 cookbooks/poise-build-essential/files/halite_gem/poise_build_essential.rb create mode 100644 cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers.rb create mode 100644 cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/base.rb create mode 100644 cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/debian.rb create mode 100644 cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/freebsd.rb create mode 100644 cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/mac_os_x.rb create mode 100644 cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/omnios.rb create mode 100644 cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/rhel.rb create mode 100644 cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/smartos.rb create mode 100644 cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/solaris.rb create mode 100644 cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/suse.rb create mode 100644 cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/windows.rb create mode 100644 cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/cheftie.rb create mode 100644 cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/resources.rb create mode 100644 cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/resources/poise_build_essential.rb create mode 100644 cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/version.rb create mode 100644 cookbooks/poise-build-essential/libraries/default.rb create mode 100644 cookbooks/poise-build-essential/metadata.json create mode 100644 cookbooks/poise-build-essential/recipes/default.rb create mode 100644 cookbooks/poise-git/CHANGELOG.md create mode 100644 cookbooks/poise-git/README.md create mode 100644 cookbooks/poise-git/attributes/default.rb create mode 100644 cookbooks/poise-git/files/halite_gem/poise_git.rb create mode 100644 cookbooks/poise-git/files/halite_gem/poise_git/cheftie.rb create mode 100644 cookbooks/poise-git/files/halite_gem/poise_git/git_client_providers.rb create mode 100644 cookbooks/poise-git/files/halite_gem/poise_git/git_client_providers/base.rb create mode 100644 cookbooks/poise-git/files/halite_gem/poise_git/git_client_providers/dummy.rb create mode 100644 cookbooks/poise-git/files/halite_gem/poise_git/git_client_providers/system.rb create mode 100644 cookbooks/poise-git/files/halite_gem/poise_git/git_command_mixin.rb create mode 100644 cookbooks/poise-git/files/halite_gem/poise_git/resources.rb create mode 100644 cookbooks/poise-git/files/halite_gem/poise_git/resources/poise_git.rb create mode 100644 cookbooks/poise-git/files/halite_gem/poise_git/resources/poise_git_client.rb create mode 100644 cookbooks/poise-git/files/halite_gem/poise_git/safe_string.rb create mode 100644 cookbooks/poise-git/files/halite_gem/poise_git/version.rb create mode 100644 cookbooks/poise-git/libraries/default.rb create mode 100644 cookbooks/poise-git/metadata.json create mode 100644 cookbooks/poise-git/recipes/default.rb create mode 100644 cookbooks/poise-ruby-build/CHANGELOG.md create mode 100644 cookbooks/poise-ruby-build/README.md create mode 100644 cookbooks/poise-ruby-build/attributes/default.rb create mode 100644 cookbooks/poise-ruby-build/files/halite_gem/poise_ruby/ruby_build.rb create mode 100644 cookbooks/poise-ruby-build/files/halite_gem/poise_ruby/ruby_build/cheftie.rb create mode 100644 cookbooks/poise-ruby-build/files/halite_gem/poise_ruby/ruby_build/provider.rb create mode 100644 cookbooks/poise-ruby-build/files/halite_gem/poise_ruby/ruby_build/version.rb create mode 100644 cookbooks/poise-ruby-build/libraries/default.rb create mode 100644 cookbooks/poise-ruby-build/metadata.json delete mode 100644 cookbooks/seven_zip/CONTRIBUTING delete mode 100644 cookbooks/seven_zip/LICENSE create mode 100644 cookbooks/seven_zip/libraries/matchers.rb delete mode 100644 cookbooks/seven_zip/metadata.rb create mode 100644 nodes/staging.kosmos.org.json delete mode 100644 site-cookbooks/kosmos-ruby/CHANGELOG.md delete mode 100644 site-cookbooks/kosmos-ruby/README.md delete mode 100644 site-cookbooks/kosmos-ruby/attributes/default.rb delete mode 100644 site-cookbooks/kosmos-ruby/metadata.rb delete mode 100644 site-cookbooks/kosmos-ruby/recipes/default.rb diff --git a/Batali b/Batali index cdd22bb..f4c3a18 100644 --- a/Batali +++ b/Batali @@ -14,6 +14,7 @@ Batali.define do ref: 'relax_dependencies' cookbook 'postfix' cookbook 'unattended-upgrades' + cookbook 'poise-ruby-build', '~> 1.1.0' cookbook 'application' cookbook 'application_javascript' cookbook 'application_ruby' @@ -39,4 +40,3 @@ Batali.define do cookbook 'logrotate' cookbook 'openssl', '~> 7.0.1' end - diff --git a/batali.manifest b/batali.manifest index 4ae84b2..532457c 100644 --- a/batali.manifest +++ b/batali.manifest @@ -100,11 +100,11 @@ ">= 1.1" ] ], - "version": "8.0.0", + "version": "8.0.1", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/build-essential/versions/8.0.0/download", - "version": "8.0.0" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/build-essential/versions/8.0.1/download", + "version": "8.0.1" } }, { @@ -115,11 +115,11 @@ ">= 1.2.2" ] ], - "version": "1.0.4", + "version": "2.0.2", "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/seven_zip/versions/2.0.2/download", + "version": "2.0.2" } }, { @@ -1103,16 +1103,13 @@ { "name": "homebrew", "dependencies": [ - [ - "build-essential", - ">= 2.1.2" - ] + ], - "version": "2.0.5", + "version": "3.0.0", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/homebrew/versions/2.0.5/download", - "version": "2.0.5" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/homebrew/versions/3.0.0/download", + "version": "3.0.0" } }, { @@ -1126,6 +1123,67 @@ "url": "https://supermarket.chef.io:443/api/v1/cookbooks/logrotate/versions/1.9.2/download", "version": "1.9.2" } + }, + { + "name": "poise-ruby-build", + "dependencies": [ + [ + "poise", + "~> 2.0" + ], + [ + "poise-build-essential", + "~> 1.0" + ], + [ + "poise-git", + "~> 1.0" + ], + [ + "poise-ruby", + "~> 2.1" + ] + ], + "version": "1.1.0", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/poise-ruby-build/versions/1.1.0/download", + "version": "1.1.0" + } + }, + { + "name": "poise-build-essential", + "dependencies": [ + [ + "poise", + "~> 2.6" + ] + ], + "version": "1.0.0", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/poise-build-essential/versions/1.0.0/download", + "version": "1.0.0" + } + }, + { + "name": "poise-git", + "dependencies": [ + [ + "poise", + "~> 2.6" + ], + [ + "poise-languages", + "~> 2.1" + ] + ], + "version": "1.0.0", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/poise-git/versions/1.0.0/download", + "version": "1.0.0" + } } ] } \ No newline at end of file diff --git a/cookbooks/build-essential/MAINTAINERS.md b/cookbooks/build-essential/MAINTAINERS.md index d7de891..645ed14 100644 --- a/cookbooks/build-essential/MAINTAINERS.md +++ b/cookbooks/build-essential/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 -* [Jennifer Davis](https://github.com/sigje) +* [Tim Smith](https://github.com/tas50) # Maintainers * [Jennifer Davis](https://github.com/sigje) diff --git a/cookbooks/build-essential/README.md b/cookbooks/build-essential/README.md index cee8624..ac35267 100644 --- a/cookbooks/build-essential/README.md +++ b/cookbooks/build-essential/README.md @@ -1,37 +1,45 @@ # 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] -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. +[![Cookbook Version](http://img.shields.io/cookbook/v/build-essential.svg)][cookbook] [![Build Status](https://travis-ci.org/chef-cookbooks/build-essential.svg?branch=master)](https://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. Contains a resource, 'build_essential', as as well as a default recipe that simply calls that same resource. ## Requirements + ### Platforms + - Debian/Ubuntu - RHEL/CentOS/Scientific/Amazon/Oracle -- openSUSE +- openSUSE / SUSE Enterprise Linux - SmartOS - Fedora -- Mac OS X +- Mac OS X 10.9+ - FreeBSD ### Chef -- Chef 11+ + +- Chef 12.5+ ### Cookbooks -- Suggests pkgutil for Solaris based platforms +- seven_zip +- mingw **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. - ## 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) +Attribute | Default | Description +------------------------------------------ | :---------------------------: | ----------------------------------------------------- +`node['build-essential']['compile_time']` | `false` | Execute resources at compile time +`node['build-essential']['msys2']['path']` | `#{ENV['SYSTEMDRIVE']\\msys2` | Destination for msys2 build tool chain (Windows only) ## Usage + +### Recipe Usage + +The recipe simply calls the build_essential resource, but it ideal for adding to roles or node run lists. + Include the build-essential recipe in your run list: ```sh @@ -45,7 +53,9 @@ 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. + - Set the `compile_time` attribute to true in your wrapper cookbook or role: ```ruby @@ -82,10 +92,29 @@ For RubyGems that include native C extensions you wish to use with Chef, you sho chef_gem 'gem-with-native-extension' ``` +### Resource Usage + +The cookbook includes a resource 'build_essential' that can be included in your cookbook to install the necessary build-essential packages + +Simple package installation during the client run: + +```ruby +build_essential 'some name you choose' +``` + +Package installation during the compile phase: + +```ruby +build_essential 'some name you choose' do + compile_time false +end +``` + ## License & Authors + **Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io)) -**Copyright:** 2009-2015, Chef Software, Inc. +**Copyright:** 2009-2016, Chef Software, Inc. ``` Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/cookbooks/build-essential/recipes/_windows.rb b/cookbooks/build-essential/recipes/_windows.rb index bd9c598..6d317f9 100644 --- a/cookbooks/build-essential/recipes/_windows.rb +++ b/cookbooks/build-essential/recipes/_windows.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: build-essential -# Recipe:: _mingw +# Cookbook:: build-essential +# Recipe:: _windows # -# Copyright 2016, Chef Software, Inc. +# Copyright:: 2016-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. @@ -16,97 +16,38 @@ # See the License for the specific language governing permissions and # limitations under the License. # -require 'ostruct' -include_recipe '7-zip::default' +node.default['seven_zip']['syspath'] = true +include_recipe 'seven_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 +tool_path = node['build-essential']['msys2']['path'] + +directory tool_path do + action :create + recursive true 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') + 'base-devel', # Brings down msys based bash/make/awk/patch/stuff.. + 'mingw-w64-x86_64-toolchain', # Puts 64-bit SEH mingw toolchain in msys2\mingw64 + 'mingw-w64-i686-toolchain' # Puts 32-bit DW2 mingw toolchain in msys2\ming32 ].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 + msys2_package package do + root tool_path + end +end + +# Certain build steps assume that a tar command is available on the +# system path. The default tar present in msys2\usr\bin is an msys GNU tar +# that expects forward slashes and consider ':' to be a remote tape separator +# or something weird like that. We therefore drop bat file in msys2\bin that +# redirect to the underlying executables without mucking around with +# msys2's /usr/bin itself. +{ + 'bsdtar.exe' => 'tar.bat', + 'patch.exe' => 'patch.bat', +}.each do |reference, link| + file "#{tool_path}\\bin\\#{link}" do + content "@%~dp0..\\usr\\bin\\#{reference} %*" end end diff --git a/cookbooks/build-essential/recipes/default.rb b/cookbooks/build-essential/recipes/default.rb index 199735f..11edff2 100644 --- a/cookbooks/build-essential/recipes/default.rb +++ b/cookbooks/build-essential/recipes/default.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: build-essential +# Cookbook:: build-essential # Recipe:: default # -# Copyright 2008-2016, Chef Software, Inc. +# Copyright:: 2008-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. @@ -17,13 +17,8 @@ # limitations under the License. # -begin - include_recipe "build-essential::_#{node['platform_family']}" -rescue Chef::Exceptions::RecipeNotFound - 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 +# Call the build-essential custom resource +# This can also be called directly in your cookbooks anywhere you want +build_essential 'install_packages' do + compile_time node['build-essential']['compile_time'] end diff --git a/cookbooks/build-essential/resources/build_essential.rb b/cookbooks/build-essential/resources/build_essential.rb index 5a0ea6a..76c6725 100644 --- a/cookbooks/build-essential/resources/build_essential.rb +++ b/cookbooks/build-essential/resources/build_essential.rb @@ -2,7 +2,7 @@ # Cookbook:: build-essential # resource:: build_essential # -# Copyright:: 2008-2016, Chef Software, Inc. +# Copyright:: 2008-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. @@ -26,7 +26,7 @@ action :install do case node['platform_family'] when 'debian' package %w( autoconf binutils-doc bison build-essential flex gettext ncurses-dev ) - when 'fedora', 'rhel' + when 'amazon', '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 diff --git a/cookbooks/build-essential/resources/xcode_command_line_tools.rb b/cookbooks/build-essential/resources/xcode_command_line_tools.rb index 850612e..9e7f5d8 100644 --- a/cookbooks/build-essential/resources/xcode_command_line_tools.rb +++ b/cookbooks/build-essential/resources/xcode_command_line_tools.rb @@ -2,7 +2,7 @@ # Cookbook:: build-essential # Resource:: xcode_command_line_tools # -# Copyright:: 2014-2016, Chef Software, Inc. +# Copyright:: 2014-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. @@ -44,7 +44,7 @@ action :install do end end -action_class do +action_class.class_eval do # # Determine if the XCode Command Line Tools are installed # diff --git a/cookbooks/homebrew/CHANGELOG.md b/cookbooks/homebrew/CHANGELOG.md index 0273c91..b63b898 100644 --- a/cookbooks/homebrew/CHANGELOG.md +++ b/cookbooks/homebrew/CHANGELOG.md @@ -1,7 +1,34 @@ # homebrew Cookbook CHANGELOG + This file is used to list changes made in each version of the homebrew cookbook. +## 3.0.0 (2016-12-19) + +- The homebrew package provider has been removed from this cookbook. It ships with Chef 12.0+. This cookbook now requires a minimum of Chef 12.1 or later. +- This cookbook no longer depends on build-essential as it wasn't using it directly +- Properly define the chefspec matchers +- Add chef_version metadata and remove OS X server which isn't an actual platform from ohai +- Don't grab homebrew_go script if homebrew is already installed. +- Add ability to disable sending analytics data via a new attribute +- Move testing to a test cookbook to make it easier to expand in the future. Also convert integration tests to InSpec from ServerSpec + +## 2.1.2 (2016-09-07) + +- Allow passing custom options to brew packages + +## 2.1.1 (2016-09-06) + +- Run chefspecs as OS X +- Update cask recipe to not create /opt/homebrew-cask and /opt/homebrew-cask/Caskroom +- Update tests + +## v2.1.0 (2016-03-29) + +- Make homebrew install script url configurable +- Make package_info more efficient + ## v2.0.5 (2016-01-25) + - Updated execute resources to pass in the HOME/USER environmental variables so homebrew commands are properly executed - Removed redundant code from recipes and providers - Removed brew-cask installation and the upgade execute that are no longer necessary @@ -9,22 +36,27 @@ This file is used to list changes made in each version of the homebrew cookbook. - Updated creation of /opt/homebrew-cask to be recursive in case /opt hasn't been created yet ## v2.0.4 (2016-01-20) + - Use the officially supported method of querying homebrew data vs. unsupported internal APIs - Fixed environmental variables in the homebrew command execution ## v2.0.3 (2015-12-09) + - Fixed poor name matching in determining if a cask had been installed already, which prevented some casks from installing ## v2.0.2 (2015-12-04) + - Prevents casks from installing on every chef run ## v2.0.1 (2015-12-03) + - Fixed already-installed casks breaking builds ## v2.0.0 (2015-12-01) + - Removed all Chef 10 compatibility code -- #77 Update the tap provider to properly notify on changes -- #73 Allow specifying versions (or HEAD) of formulas (see readme for usage) +- 77 Update the tap provider to properly notify on changes +- 73 Allow specifying versions (or HEAD) of formulas (see readme for usage) - Updated contributing, testing, and maintainers docs - Updated contents of chefignore and .gitignore files - Updated development dependencies in the Gemfile @@ -32,109 +64,136 @@ This file is used to list changes made in each version of the homebrew cookbook. - Added Chef standard rubocop file and resolved all warnings - Added super metadata for Supermarket - Added testing in Travis CI -- #75 Fix Chefspecs to properly run on Linux hosts (like Travis) +- 75 Fix Chefspecs to properly run on Linux hosts (like Travis) - Add Rakefile for simplified testing - Resolved all foodcritic warnings ## v1.13.0 (2015-06-23) -- #72 Massage Chef12HomebrewUser.find_homebrew_uid into username -- #69 Add options to cask + +- 72 Massage Chef12HomebrewUser.find_homebrew_uid into username +- 69 Add options to cask ## v1.12.0 (2015-01-29) -- #67 Add attribute and recipe for installing homebrew taps + +- 67 Add attribute and recipe for installing homebrew taps ## v1.11.0 (2015-01-12) -- #59 Update Homebrew Cask if auto-update attribute is true -- #52 Manage Homebrew Cask's install directories -- #56 Fix check for existing casks -- #61 Fix owner class for Chef 12 + +- 59 Update Homebrew Cask if auto-update attribute is true +- 52 Manage Homebrew Cask's install directories +- 56 Fix check for existing casks +- 61 Fix owner class for Chef 12 - Depend on build-essential cookbook 2.1.2+ to support OS X 10.10 -- #64, #66 add and fix ChefSpec tests for default recipe +- 64, #66 add and fix ChefSpec tests for default recipe ## v1.10.0 (2014-12-09) -- #55 This cookbook no longer sets its `homebrew_package` as the + +- 55 This cookbook no longer sets its `homebrew_package` as the - `package` provider for OS X when running under Chef 12 - List CHEF as the maintainer instead of Chef. ## v1.9.2 (2014-10-09) + Bug Fixes: -- #57 Update url per homebrew error: Upstream, the homebrew project + +- 57 Update url per homebrew error: Upstream, the homebrew project - has changed the URL for the installation script. All users of this - cookbook are advised to update to this version. ## v1.9.0 (2014-07-29) + Improvements: -- #35 Modernize the cask provider (use why run mode, inline resources) -- #43 Use `brew cask list` to determine if casks are installed -- #45 Add `default_action` and print warning messages on earlier + +- 35 Modernize the cask provider (use why run mode, inline resources) +- 43 Use `brew cask list` to determine if casks are installed +- 45 Add `default_action` and print warning messages on earlier - versions of Chef (10.10) New Features: -- #44 Add `:install` and `:uninstall` actions and alias previous `:cask`, + +- 44 Add `:install` and `:uninstall` actions and alias previous `:cask`, - `:uncask` actions to them Bug Fixes: -- #27 Fix name for taps adding the `/homebrew` prefix -- #28 Set `RUBYOPT` to `nil` so Chef can execute in a bundle (bundler + +- 27 Fix name for taps adding the `/homebrew` prefix +- 28 Set `RUBYOPT` to `nil` so Chef can execute in a bundle (bundler - sets `RUBYOPT` and this can cause issues when running the - underlying `brew` commands) -- #40 Fix regex for cask to match current homebrew conventions -- #42 Fix attribute for list of formulas to match the README and +- 40 Fix regex for cask to match current homebrew conventions +- 42 Fix attribute for list of formulas to match the README and - maintain backward compat for 6 day old version ## v1.8.0 (2014-07-23) + - Add recipes to install an array of formulas/casks ## v1.7.2 (2014-06-26) + - Implement attribute to control auto-update ## v1.7.0 (2014-06-26) -#38 - Add homebrew::cask recipe + +# 38 - Add homebrew::cask recipe ## v1.6.6 (2014-05-29) + - [COOK-3283] Use homebrew_owner for cask and tap - [COOK-4670] homebrew_tap provider is not idempotent - [COOK-4671] Syntax Error in README ## v1.6.4 (2014-05-08) + - Fixing cask provider correctly this time. "brew cask list" ## v1.6.2 (2014-05-08) + - Fixing typo in cask provider: 's/brew brew/brew/' ## v1.6.0 (2014-04-23) + - [COOK-3960] Added LWRP for brew cask - [COOK-4508] Add ChefSpec matchers for homebrew_tap - [COOK-4566] Guard against "HEAD only" formulae ## v1.5.4 + - [COOK-4023] Fix installer script's URL. - Fixing up style for rubocop ## v1.5.2 + - [COOK-3825] setting $HOME on homebrew_package ## v1.5.0 + ### Bug + - **[COOK-3589](https://tickets.chef.io/browse/COOK-3589)** - Add homebrew as the default package manager on OS X Server ## v1.4.0 + ### Bug + - **[COOK-3283](https://tickets.chef.io/browse/COOK-3283)** - Support running homebrew cookbook as root user, with sudo, or a non-privileged user ## v1.3.2 + - [COOK-1793] - use homebrew "go" script to install homebrew - [COOK-1821] - Discovered version using Homebrew Formula factory fails check that verifies that version is a String - [COOK-1843] - Homebrew README.md contains non-ASCII characters, triggering same issue as COOK-522 ## v1.3.0 + - [COOK-1425] - use new json output format for formula - [COOK-1578] - Use shell_out! instead of popen4 ## v1.2.0 + Chef Software has taken maintenance of this cookbook as the original author has other commitments. This is the initial release with Chef Software as maintainer. Changes in this release: + - [pull/2] - support for option passing to brew - [pull/3] - add brew upgrade and control return value from command - [pull/9] - added LWRP for "brew tap" diff --git a/cookbooks/homebrew/MAINTAINERS.md b/cookbooks/homebrew/MAINTAINERS.md index c6a51ae..645ed14 100644 --- a/cookbooks/homebrew/MAINTAINERS.md +++ b/cookbooks/homebrew/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/homebrew/README.md b/cookbooks/homebrew/README.md index 2d2aa11..b87382a 100644 --- a/cookbooks/homebrew/README.md +++ b/cookbooks/homebrew/README.md @@ -1,36 +1,29 @@ # Homebrew Cookbook + [![Build Status](https://travis-ci.org/chef-cookbooks/homebrew.svg?branch=master)](http://travis-ci.org/chef-cookbooks/homebrew) [![Cookbook Version](https://img.shields.io/cookbook/v/homebrew.svg)](https://supermarket.chef.io/cookbooks/homebrew) -This cookbook installs [Homebrew](http://mxcl.github.com/homebrew/) and under Chef 11 and earlier versions, its package provider replaces MacPorts as the _default package provider_ for the package resource on OS X systems. +This cookbook installs [Homebrew](http://brew.sh/) and provides resources for working with taps and casks -# Requirements -Chef 12: The package provider is not necessary on Chef 12, as the default [OS X package provider](https://github.com/chef/chef-rfc/blob/master/rfc016-homebrew-osx-package-provider.md) is homebrew. +## Requirements -Chef <= 11: The package provider will be set as the default provider for OS X. +### Platforms -## Prerequisites -In order for this recipe to work, your userid must own `/usr/local`. This is outside the scope of the cookbook because it's possible that you'll run the cookbook as your own user, not root and you'd have to be root to take ownership of the directory. Easiest way to get started: +- macOS -```bash -sudo chown -R `whoami`:staff /usr/local -``` +### Chef -Bear in mind that this will take ownership of the entire folder and its contents, so if you've already got stuff in there (eg MySQL owned by a `mysql` user) you'll need to be a touch more careful. This is a recommendation from the Homebrew project. +- Chef 12.1+ -**Note** This cookbook _only_ supports installing in `/usr/local`. While the Homebrew project itself allows for alternative installations, this cookbook doesn't. +### Cookbooks -## Platform -- Mac OS X (10.6+) +- none -The only platform supported by Homebrew itself at the time of this writing is Mac OS X. It should work fine on Server edition as well, and on platforms that Homebrew supports in the future. +## Attributes -## Cookbooks -- build-essential: homebrew itself doesn't work well if XCode is not installed. - -# Attributes - `node['homebrew']['owner']` - The user that will own the Homebrew installation and packages. Setting this will override the default behavior which is to use the non-privileged user that has invoked the Chef run (or the `SUDO_USER` if invoked with sudo). The default is `nil`. -- `node['homebrew']['auto-update']` - Whether the default recipe should automatically update homebrew each run or not. The default is `true` to maintain compatibility. Set to false or nil to disable. Note that disabling this feature may cause formula to not work. -- `node['homebrew']['formulas']` - An Array of formula that should be installed using homebrew by default, used only in the `homebrew::install_formulas` recipe. +- `node['homebrew']['auto-update']` - Whether the default recipe should automatically update Homebrew each run or not. The default is `true` to maintain compatibility. Set to false or nil to disable. Note that disabling this feature may cause formula to not work. +- `node['homebrew']['formulas']` - An Array of formula that should be installed using Homebrew by default, used only in the `homebrew::install_formulas` recipe. + - To install the most recent version, include just the recipe name: `- simple_formula` - To install a specific version, specify both its name and version: @@ -46,38 +39,21 @@ The only platform supported by Homebrew itself at the time of this writing is Ma head: true ``` + - To provide other options, specify both its name and options + + ``` + - name: formula-with-options + options: --with-option-1 --with-other-option + ``` + - `node['homebrew']['casks']` - An Array of casks that should be installed using brew cask by default, used only in the `homebrew::install_casks` recipe. + - `node['homebrew']['taps']` - An Array of taps that should be installed using brew tap by default, used only in the `homebrew::install_taps` recipe. -# Resources and Providers -This cookbook includes a package resource provider to use homebrew. Under Chef 12+, this is not necessary, and the code doesn't actually get used on Chef 12+. This was preserved to maintain backwards compatiblity with older versions of Chef. +## Resources (provider) -## package / homebrew\_package -This cookbook provides a package provider called `homebrew_package` which will install/remove packages using Homebrew. This becomes the default provider for `package` if your platform is Mac OS X. +### homebrew_tap -As this extends the built-in package resource/provider in Chef, it has all the resource attributes and actions available to the package resource. However, a couple notes: -- Homebrew itself doesn't have a notion of "upgrade" per se. The "upgrade" action will simply perform an install, and if the Homebrew Formula for the package is newer, it will upgrade. -- Likewise, Homebrew doesn't have a purge, but the "purge" action will act like "remove". - -### Examples - -```ruby -package 'mysql' do - action :install -end - -homebrew_package 'mysql' - -package 'mysql' do - provider Chef::Provider::Package::Homebrew -end - -package 'wireshark' do - options '--with-qt --devel' -end -``` - -### homebrew\_tap LWRP for `brew tap`, a Homebrew command used to add additional formula repositories. From the `brew` man page: ```text @@ -99,12 +75,14 @@ homebrew_tap 'homebrew/dupes' do end ``` -## homebrew\_cask +### homebrew_cask + LWRP for `brew cask`, a Homebrew-style CLI workflow for the administration of Mac applications distributed as binaries. It's implemented as a homebrew "external command" called cask. [homebrew-cask on GitHub](https://github.com/caskroom/homebrew-cask) -### Prerequisites +#### Prerequisites + You must have the homebrew-cask repository tapped. ```ruby @@ -136,11 +114,13 @@ Default action is `:cask` which installs the Application binary . Use `:uncask` [View the list of available Casks](https://github.com/caskroom/homebrew-cask/tree/master/Casks) # Usage + We strongly recommend that you put "recipe[homebrew]" in your node's run list, to ensure that it is available on the system and that Homebrew itself gets installed. Putting an explicit dependency in the metadata will cause the cookbook to be downloaded and the library loaded, thus resulting in changing the package provider on Mac OS X, so if you have systems you want to use the default (Mac Ports), they would be changed to Homebrew. The default recipe also ensures that Homebrew is installed and up to date if the auto update attribute (above) is true (default). -# License and Authors +## License and Authors + This cookbook is maintained by CHEF. The original author, maintainer and copyright holder is Graeme Mathieson. The cookbook remains licensed under the Apache License version 2. [Original blog post by Graeme](https://woss.name/articles/converging-your-home-directory-with-chef/) @@ -151,7 +131,7 @@ Author:: Joshua Timberman ([joshua@chef.io](mailto:joshua@chef.io)) ```text Copyright:: 2011, Graeme Mathieson -Copyright:: 2012-2015, 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/homebrew/attributes/default.rb b/cookbooks/homebrew/attributes/default.rb index 06d2380..67245a6 100644 --- a/cookbooks/homebrew/attributes/default.rb +++ b/cookbooks/homebrew/attributes/default.rb @@ -1,10 +1,10 @@ # # Author:: Joshua Timberman () # Author:: Graeme Mathieson () -# Cookbook Name:: homebrew +# Cookbook:: homebrew # Attributes:: default # -# Copyright 2011-2013, 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. @@ -18,9 +18,12 @@ # See the License for the specific language governing permissions and # limitations under the License. # - -default['homebrew']['owner'] = nil +# only used if auto detection fails +default['homebrew']['owner'] = nil # only used if auto detection fails default['homebrew']['auto-update'] = true default['homebrew']['casks'] = [] default['homebrew']['formulas'] = node['homebrew']['formula'] || [] default['homebrew']['taps'] = [] +default['homebrew']['installer']['url'] = 'https://raw.githubusercontent.com/Homebrew/install/master/install' +default['homebrew']['installer']['checksum'] = nil +default['homebrew']['enable-analytics'] = true diff --git a/cookbooks/homebrew/libraries/homebrew_mixin.rb b/cookbooks/homebrew/libraries/homebrew_mixin.rb index 4b802a9..e292214 100644 --- a/cookbooks/homebrew/libraries/homebrew_mixin.rb +++ b/cookbooks/homebrew/libraries/homebrew_mixin.rb @@ -1,10 +1,10 @@ # # Author:: Joshua Timberman () # Author:: Graeme Mathieson () -# Cookbook Name:: homebrew +# Cookbook:: homebrew # Libraries:: homebrew_mixin # -# Copyright 2011-2013, 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. @@ -18,26 +18,19 @@ # See the License for the specific language governing permissions and # limitations under the License. # -# Include the mixin from Chef 12 if its defined, when we get to the -# #homebrew_owner method below... + class Chef12HomebrewUser - include Chef::Mixin::HomebrewUser if defined?(Chef::Mixin::HomebrewUser) + include Chef::Mixin::HomebrewUser end module Homebrew # Homebrew module Mixin def homebrew_owner - if defined?(Chef::Mixin::HomebrewUser) - begin - require 'etc' - @homebrew_owner ||= ::Etc.getpwuid(Chef12HomebrewUser.new.find_homebrew_uid).name - rescue Chef::Exceptions::CannotDetermineHomebrewOwner - @homebrew_owner ||= calculate_owner - end - else - @homebrew_owner ||= calculate_owner - end + require 'etc' + @homebrew_owner ||= ::Etc.getpwuid(Chef12HomebrewUser.new.find_homebrew_uid).name + rescue Chef::Exceptions::CannotDetermineHomebrewOwner + @homebrew_owner ||= calculate_owner end private @@ -45,7 +38,7 @@ module Homebrew def calculate_owner owner = homebrew_owner_attr || sudo_user || current_user if owner == 'root' - fail Chef::Exceptions::User, + raise Chef::Exceptions::User, "Homebrew owner is 'root' which is not supported. " \ "To set an explicit owner, please set node['homebrew']['owner']." end @@ -65,3 +58,6 @@ module Homebrew end end end + +Chef::Resource.send(:include, Homebrew::Mixin) +Chef::Recipe.send(:include, Homebrew::Mixin) diff --git a/cookbooks/homebrew/libraries/homebrew_package.rb b/cookbooks/homebrew/libraries/homebrew_package.rb deleted file mode 100644 index cda2bcf..0000000 --- a/cookbooks/homebrew/libraries/homebrew_package.rb +++ /dev/null @@ -1,102 +0,0 @@ -# -# Author:: Joshua Timberman () -# Author:: Graeme Mathieson () -# Cookbook Name:: homebrew -# Libraries:: homebrew_package -# -# Copyright 2011-2013, 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 libraries are unconditionally included if the cookbook is -# present on a node. This approach should avoid creating this class if -# the node already has Chef::Provider::Package::Homebrew, such as with -# Chef 12. -# https://github.com/chef/chef-rfc/blob/master/rfc016-homebrew-osx-package-provider.md -unless defined?(Chef::Provider::Package::Homebrew) && Chef::Platform.find('mac_os_x', nil)[:package] == Chef::Provider::Package::Homebrew - require 'chef/provider/package' - require 'chef/resource/package' - require 'chef/platform' - require 'chef/mixin/shell_out' - - class Chef - class Provider - class Package - # Package - class Homebrew < Package - # Homebrew packagex - include Chef::Mixin::ShellOut - include ::Homebrew::Mixin - - def load_current_resource - @current_resource = Chef::Resource::Package.new(@new_resource.name) - @current_resource.package_name(@new_resource.package_name) - @current_resource.version(current_installed_version) - - @current_resource - end - - def install_package(name, _version) - brew('install', @new_resource.options, name) - end - - def upgrade_package(name, _version) - brew('upgrade', name) - end - - def remove_package(name, _version) - brew('uninstall', @new_resource.options, name) - end - - # Homebrew doesn't really have a notion of purging, so just remove. - def purge_package(name, version) - @new_resource.options = ((@new_resource.options || '') << ' --force').strip - remove_package(name, version) - end - - protected - - def brew(*args) - get_response_from_command("brew #{args.join(' ')}") - end - - def current_installed_version - versions = package_info['installed'].map { |v| v['version'] } - versions.join(' ') unless versions.empty? - end - - def candidate_version - package_info['versions']['stable'] ? package_info['versions']['stable'].to_s : package_info['versions'].find { |_k, v| v if v.is_a?(String) } - end - - def package_info - require 'json' - JSON.parse(brew('info', @new_resource.package_name, '--json=v1'))[0] - end - - def get_response_from_command(command) - require 'etc' - home_dir = Etc.getpwnam(homebrew_owner).dir - - Chef::Log.debug "Executing '#{command}' as #{homebrew_owner}" - output = shell_out!(command, user: homebrew_owner, environment: { 'USER' => homebrew_owner, 'HOME' => home_dir, 'RUBYOPT' => nil }) - output.stdout - end - end - end - end - end - - Chef::Platform.set platform: :mac_os_x_server, resource: :package, provider: Chef::Provider::Package::Homebrew - Chef::Platform.set platform: :mac_os_x, resource: :package, provider: Chef::Provider::Package::Homebrew -end diff --git a/cookbooks/homebrew/libraries/matchers.rb b/cookbooks/homebrew/libraries/matchers.rb index 2679528..67d1d88 100644 --- a/cookbooks/homebrew/libraries/matchers.rb +++ b/cookbooks/homebrew/libraries/matchers.rb @@ -1,20 +1,5 @@ if defined?(ChefSpec) - - def install_homebrew_package(pkg) - ChefSpec::Matchers::ResourceMatcher.new(:homebrew_package, :install, pkg) - end - - def upgrade_homebrew_package(pkg) - ChefSpec::Matchers::ResourceMatcher.new(:homebrew_package, :upgrade, pkg) - end - - def remove_homebrew_package(pkg) - ChefSpec::Matchers::ResourceMatcher.new(:homebrew_package, :remove, pkg) - end - - def purge_homebrew_package(pkg) - ChefSpec::Matchers::ResourceMatcher.new(:homebrew_package, :purge, pkg) - end + ChefSpec.define_matcher :homebrew_package def tap_homebrew_tap(tap) ChefSpec::Matchers::ResourceMatcher.new(:homebrew_tap, :tap, tap) diff --git a/cookbooks/homebrew/metadata.json b/cookbooks/homebrew/metadata.json index 0163800..e69fd81 100644 --- a/cookbooks/homebrew/metadata.json +++ b/cookbooks/homebrew/metadata.json @@ -1 +1 @@ -{"name":"homebrew","version":"2.0.5","description":"Install Homebrew, and use it as the OS X package provider on Chef versions =< 11","long_description":"# Homebrew Cookbook\n[![Build Status](https://travis-ci.org/chef-cookbooks/homebrew.svg?branch=master)](http://travis-ci.org/chef-cookbooks/homebrew) [![Cookbook Version](https://img.shields.io/cookbook/v/homebrew.svg)](https://supermarket.chef.io/cookbooks/homebrew)\n\nThis cookbook installs [Homebrew](http://mxcl.github.com/homebrew/) and under Chef 11 and earlier versions, its package provider replaces MacPorts as the _default package provider_ for the package resource on OS X systems.\n\n# Requirements\nChef 12: The package provider is not necessary on Chef 12, as the default [OS X package provider](https://github.com/chef/chef-rfc/blob/master/rfc016-homebrew-osx-package-provider.md) is homebrew.\n\nChef <= 11: The package provider will be set as the default provider for OS X.\n\n## Prerequisites\nIn order for this recipe to work, your userid must own `/usr/local`. This is outside the scope of the cookbook because it's possible that you'll run the cookbook as your own user, not root and you'd have to be root to take ownership of the directory. Easiest way to get started:\n\n```bash\nsudo chown -R `whoami`:staff /usr/local\n```\n\nBear in mind that this will take ownership of the entire folder and its contents, so if you've already got stuff in there (eg MySQL owned by a `mysql` user) you'll need to be a touch more careful. This is a recommendation from the Homebrew project.\n\n**Note** This cookbook _only_ supports installing in `/usr/local`. While the Homebrew project itself allows for alternative installations, this cookbook doesn't.\n\n## Platform\n- Mac OS X (10.6+)\n\nThe only platform supported by Homebrew itself at the time of this writing is Mac OS X. It should work fine on Server edition as well, and on platforms that Homebrew supports in the future.\n\n## Cookbooks\n- build-essential: homebrew itself doesn't work well if XCode is not installed.\n\n# Attributes\n- `node['homebrew']['owner']` - The user that will own the Homebrew installation and packages. Setting this will override the default behavior which is to use the non-privileged user that has invoked the Chef run (or the `SUDO_USER` if invoked with sudo). The default is `nil`.\n- `node['homebrew']['auto-update']` - Whether the default recipe should automatically update homebrew each run or not. The default is `true` to maintain compatibility. Set to false or nil to disable. Note that disabling this feature may cause formula to not work.\n- `node['homebrew']['formulas']` - An Array of formula that should be installed using homebrew by default, used only in the `homebrew::install_formulas` recipe.\n - To install the most recent version, include just the recipe name: `- simple_formula`\n - To install a specific version, specify both its name and version:\n\n ```\n - name: special-version-formula\n version: 1.2.3\n ```\n\n - To install the HEAD of a formula, specify both its name and `head: true`:\n\n ```\n - name: head-tracking-formula\n head: true\n ```\n\n- `node['homebrew']['casks']` - An Array of casks that should be installed using brew cask by default, used only in the `homebrew::install_casks` recipe.\n- `node['homebrew']['taps']` - An Array of taps that should be installed using brew tap by default, used only in the `homebrew::install_taps` recipe.\n\n# Resources and Providers\nThis cookbook includes a package resource provider to use homebrew. Under Chef 12+, this is not necessary, and the code doesn't actually get used on Chef 12+. This was preserved to maintain backwards compatiblity with older versions of Chef.\n\n## package / homebrew\\_package\nThis cookbook provides a package provider called `homebrew_package` which will install/remove packages using Homebrew. This becomes the default provider for `package` if your platform is Mac OS X.\n\nAs this extends the built-in package resource/provider in Chef, it has all the resource attributes and actions available to the package resource. However, a couple notes:\n- Homebrew itself doesn't have a notion of \"upgrade\" per se. The \"upgrade\" action will simply perform an install, and if the Homebrew Formula for the package is newer, it will upgrade.\n- Likewise, Homebrew doesn't have a purge, but the \"purge\" action will act like \"remove\".\n\n### Examples\n\n```ruby\npackage 'mysql' do\n action :install\nend\n\nhomebrew_package 'mysql'\n\npackage 'mysql' do\n provider Chef::Provider::Package::Homebrew\nend\n\npackage 'wireshark' do\n options '--with-qt --devel'\nend\n```\n\n### homebrew\\_tap\nLWRP for `brew tap`, a Homebrew command used to add additional formula repositories. From the `brew` man page:\n\n```text\ntap [tap]\n Tap a new formula repository from GitHub, or list existing taps.\n\n tap is of the form user/repo, e.g. brew tap homebrew/dupes.\n```\n\nDefault action is `:tap` which enables the repository. Use `:untap` to disable a tapped repository.\n\n#### Examples\n\n```ruby\nhomebrew_tap 'homebrew/dupes'\n\nhomebrew_tap 'homebrew/dupes' do\n action :untap\nend\n```\n\n## homebrew\\_cask\nLWRP for `brew cask`, a Homebrew-style CLI workflow for the administration of Mac applications distributed as binaries. It's implemented as a homebrew \"external command\" called cask.\n\n[homebrew-cask on GitHub](https://github.com/caskroom/homebrew-cask)\n\n### Prerequisites\nYou must have the homebrew-cask repository tapped.\n\n```ruby\nhomebrew_tap 'caskroom/cask'\n```\n\nAnd then install the homebrew cask package before using this LWRP.\n\n```ruby\npackage \"brew-cask\" do\n action :install\n end\n```\n\nYou can include the `homebrew::cask` recipe to do this.\n\n### Examples\n\n```ruby\nhomebrew_cask \"google-chrome\"\n\nhomebrew_cask \"google-chrome\" do\n action :uncask\nend\n```\n\nDefault action is `:cask` which installs the Application binary . Use `:uncask` to uninstall a an Application.\n\n[View the list of available Casks](https://github.com/caskroom/homebrew-cask/tree/master/Casks)\n\n# Usage\nWe strongly recommend that you put \"recipe[homebrew]\" in your node's run list, to ensure that it is available on the system and that Homebrew itself gets installed. Putting an explicit dependency in the metadata will cause the cookbook to be downloaded and the library loaded, thus resulting in changing the package provider on Mac OS X, so if you have systems you want to use the default (Mac Ports), they would be changed to Homebrew.\n\nThe default recipe also ensures that Homebrew is installed and up to date if the auto update attribute (above) is true (default).\n\n# License and Authors\nThis cookbook is maintained by CHEF. The original author, maintainer and copyright holder is Graeme Mathieson. The cookbook remains licensed under the Apache License version 2.\n\n[Original blog post by Graeme](https://woss.name/articles/converging-your-home-directory-with-chef/)\n\nAuthor:: Graeme Mathieson ([mathie@woss.name](mailto:mathie@woss.name))\n\nAuthor:: Joshua Timberman ([joshua@chef.io](mailto:joshua@chef.io))\n\n```text\nCopyright:: 2011, Graeme Mathieson\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":{"mac_os_x":">= 0.0.0","mac_os_x_server":">= 0.0.0"},"dependencies":{"build-essential":">= 2.1.2"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{"homebrew":"Install Homebrew"}} \ No newline at end of file +{"name":"homebrew","version":"3.0.0","description":"Install Homebrew and includes resources for working with taps and casks","long_description":"# Homebrew Cookbook\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/homebrew.svg?branch=master)](http://travis-ci.org/chef-cookbooks/homebrew) [![Cookbook Version](https://img.shields.io/cookbook/v/homebrew.svg)](https://supermarket.chef.io/cookbooks/homebrew)\n\nThis cookbook installs [Homebrew](http://brew.sh/) and provides resources for working with taps and casks\n\n## Requirements\n\n### Platforms\n\n- macOS\n\n### Chef\n\n- Chef 12.1+\n\n### Cookbooks\n\n- none\n\n## Attributes\n\n- `node['homebrew']['owner']` - The user that will own the Homebrew installation and packages. Setting this will override the default behavior which is to use the non-privileged user that has invoked the Chef run (or the `SUDO_USER` if invoked with sudo). The default is `nil`.\n- `node['homebrew']['auto-update']` - Whether the default recipe should automatically update Homebrew each run or not. The default is `true` to maintain compatibility. Set to false or nil to disable. Note that disabling this feature may cause formula to not work.\n- `node['homebrew']['formulas']` - An Array of formula that should be installed using Homebrew by default, used only in the `homebrew::install_formulas` recipe.\n\n - To install the most recent version, include just the recipe name: `- simple_formula`\n - To install a specific version, specify both its name and version:\n\n ```\n - name: special-version-formula\n version: 1.2.3\n ```\n\n - To install the HEAD of a formula, specify both its name and `head: true`:\n\n ```\n - name: head-tracking-formula\n head: true\n ```\n\n - To provide other options, specify both its name and options\n\n ```\n - name: formula-with-options\n options: --with-option-1 --with-other-option\n ```\n\n- `node['homebrew']['casks']` - An Array of casks that should be installed using brew cask by default, used only in the `homebrew::install_casks` recipe.\n\n- `node['homebrew']['taps']` - An Array of taps that should be installed using brew tap by default, used only in the `homebrew::install_taps` recipe.\n\n## Resources (provider)\n\n### homebrew_tap\n\nLWRP for `brew tap`, a Homebrew command used to add additional formula repositories. From the `brew` man page:\n\n```text\ntap [tap]\n Tap a new formula repository from GitHub, or list existing taps.\n\n tap is of the form user/repo, e.g. brew tap homebrew/dupes.\n```\n\nDefault action is `:tap` which enables the repository. Use `:untap` to disable a tapped repository.\n\n#### Examples\n\n```ruby\nhomebrew_tap 'homebrew/dupes'\n\nhomebrew_tap 'homebrew/dupes' do\n action :untap\nend\n```\n\n### homebrew_cask\n\nLWRP for `brew cask`, a Homebrew-style CLI workflow for the administration of Mac applications distributed as binaries. It's implemented as a homebrew \"external command\" called cask.\n\n[homebrew-cask on GitHub](https://github.com/caskroom/homebrew-cask)\n\n#### Prerequisites\n\nYou must have the homebrew-cask repository tapped.\n\n```ruby\nhomebrew_tap 'caskroom/cask'\n```\n\nAnd then install the homebrew cask package before using this LWRP.\n\n```ruby\npackage \"brew-cask\" do\n action :install\n end\n```\n\nYou can include the `homebrew::cask` recipe to do this.\n\n### Examples\n\n```ruby\nhomebrew_cask \"google-chrome\"\n\nhomebrew_cask \"google-chrome\" do\n action :uncask\nend\n```\n\nDefault action is `:cask` which installs the Application binary . Use `:uncask` to uninstall a an Application.\n\n[View the list of available Casks](https://github.com/caskroom/homebrew-cask/tree/master/Casks)\n\n# Usage\n\nWe strongly recommend that you put \"recipe[homebrew]\" in your node's run list, to ensure that it is available on the system and that Homebrew itself gets installed. Putting an explicit dependency in the metadata will cause the cookbook to be downloaded and the library loaded, thus resulting in changing the package provider on Mac OS X, so if you have systems you want to use the default (Mac Ports), they would be changed to Homebrew.\n\nThe default recipe also ensures that Homebrew is installed and up to date if the auto update attribute (above) is true (default).\n\n## License and Authors\n\nThis cookbook is maintained by CHEF. The original author, maintainer and copyright holder is Graeme Mathieson. The cookbook remains licensed under the Apache License version 2.\n\n[Original blog post by Graeme](https://woss.name/articles/converging-your-home-directory-with-chef/)\n\nAuthor:: Graeme Mathieson ([mathie@woss.name](mailto:mathie@woss.name))\n\nAuthor:: Joshua Timberman ([joshua@chef.io](mailto:joshua@chef.io))\n\n```text\nCopyright:: 2011, Graeme Mathieson\nCopyright:: 2012-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":{"mac_os_x":">= 0.0.0"},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{"homebrew":"Install Homebrew"}} \ No newline at end of file diff --git a/cookbooks/homebrew/providers/cask.rb b/cookbooks/homebrew/providers/cask.rb index 822fff3..dc7126a 100644 --- a/cookbooks/homebrew/providers/cask.rb +++ b/cookbooks/homebrew/providers/cask.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: homebrew +# Cookbook:: homebrew # Providers:: cask # -# Copyright 2011-2015, 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/homebrew/providers/tap.rb b/cookbooks/homebrew/providers/tap.rb index f82002d..fd04df8 100644 --- a/cookbooks/homebrew/providers/tap.rb +++ b/cookbooks/homebrew/providers/tap.rb @@ -1,10 +1,10 @@ # # Author:: Joshua Timberman () # Author:: Graeme Mathieson () -# Cookbook Name:: homebrew +# Cookbook:: homebrew # Providers:: tap # -# Copyright 2011-2015, 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/homebrew/recipes/cask.rb b/cookbooks/homebrew/recipes/cask.rb index ec4a1f1..38148e6 100644 --- a/cookbooks/homebrew/recipes/cask.rb +++ b/cookbooks/homebrew/recipes/cask.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: homebrew +# Cookbook:: homebrew # Recipes:: cask # -# Copyright 2014-2015, 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. @@ -16,23 +16,11 @@ # See the License for the specific language governing permissions and # limitations under the License. # -Chef::Resource.send(:include, Homebrew::Mixin) homebrew_tap 'caskroom/cask' directory '/Library/Caches/Homebrew/Casks' do owner homebrew_owner - mode 00775 + mode '775' only_if { ::Dir.exist?('/Library/Caches/Homebrew') } end - -directory '/opt/homebrew-cask' do - owner homebrew_owner - mode 00775 - recursive true -end - -directory '/opt/homebrew-cask/Caskroom' do - owner homebrew_owner - mode 00775 -end diff --git a/cookbooks/homebrew/recipes/default.rb b/cookbooks/homebrew/recipes/default.rb index d0caa8a..feab10e 100644 --- a/cookbooks/homebrew/recipes/default.rb +++ b/cookbooks/homebrew/recipes/default.rb @@ -1,10 +1,10 @@ # # Author:: Joshua Timberman () # Author:: Graeme Mathieson () -# Cookbook Name:: homebrew +# Cookbook:: homebrew # Recipe:: default # -# Copyright 2011-2015, 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. @@ -19,16 +19,15 @@ # limitations under the License. # -Chef::Resource.send(:include, Homebrew::Mixin) -Chef::Recipe.send(:include, Homebrew::Mixin) - homebrew_go = "#{Chef::Config[:file_cache_path]}/homebrew_go" Chef::Log.debug("Homebrew owner is '#{homebrew_owner}'") remote_file homebrew_go do - source 'https://raw.githubusercontent.com/Homebrew/install/master/install' - mode 00755 + source node['homebrew']['installer']['url'] + checksum node['homebrew']['installer']['checksum'] unless node['homebrew']['installer']['checksum'].nil? + mode '755' + not_if { ::File.exist? '/usr/local/bin/brew' } end execute 'install homebrew' do @@ -38,6 +37,13 @@ execute 'install homebrew' do not_if { ::File.exist? '/usr/local/bin/brew' } end +execute 'set analytics' do + environment lazy { { 'HOME' => ::Dir.home(homebrew_owner), 'USER' => homebrew_owner } } + user homebrew_owner + command "/usr/local/bin/brew analytics #{node['homebrew']['enable-analytics'] ? 'on' : 'off'}" + only_if { shell_out('/usr/local/bin/brew analytics state', user: homebrew_owner).stdout.include?('enabled') != node['homebrew']['enable-analytics'] } +end + if node['homebrew']['auto-update'] package 'git' do not_if 'which git' diff --git a/cookbooks/homebrew/recipes/install_casks.rb b/cookbooks/homebrew/recipes/install_casks.rb index 8da97ca..3635e17 100644 --- a/cookbooks/homebrew/recipes/install_casks.rb +++ b/cookbooks/homebrew/recipes/install_casks.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: homebrew +# Cookbook:: homebrew # Recipe:: install_casks # -# Copyright 2014-2015, 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/homebrew/recipes/install_formulas.rb b/cookbooks/homebrew/recipes/install_formulas.rb index ac37e7d..ca13679 100644 --- a/cookbooks/homebrew/recipes/install_formulas.rb +++ b/cookbooks/homebrew/recipes/install_formulas.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: homebrew +# Cookbook:: homebrew # Recipes:: install_casks # -# Copyright 2014-2015, 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,8 +21,10 @@ include_recipe 'homebrew' node['homebrew']['formulas'].each do |formula| if formula.class == Chef::Node::ImmutableMash + formula_options = formula.fetch(:options, '') + formula_options += ' --HEAD' if formula.fetch(:head, false) package formula.fetch(:name) do - options '--HEAD' if formula.fetch(:head, false) + options formula_options.strip version formula['version'] if formula.fetch(:version, false) end else diff --git a/cookbooks/homebrew/recipes/install_taps.rb b/cookbooks/homebrew/recipes/install_taps.rb index 9dac2bc..950165c 100644 --- a/cookbooks/homebrew/recipes/install_taps.rb +++ b/cookbooks/homebrew/recipes/install_taps.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: homebrew +# Cookbook:: homebrew # Recipes:: install_taps # -# 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. diff --git a/cookbooks/homebrew/resources/tap.rb b/cookbooks/homebrew/resources/tap.rb index 1592f30..f7a8c99 100644 --- a/cookbooks/homebrew/resources/tap.rb +++ b/cookbooks/homebrew/resources/tap.rb @@ -1,10 +1,10 @@ # # Author:: Joshua Timberman () # Author:: Graeme Mathieson () -# Cookbook Name:: homebrew +# Cookbook:: homebrew # Resources:: tap # -# Copyright 2011-2013, 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/poise-build-essential/CHANGELOG.md b/cookbooks/poise-build-essential/CHANGELOG.md new file mode 100644 index 0000000..2e62ba5 --- /dev/null +++ b/cookbooks/poise-build-essential/CHANGELOG.md @@ -0,0 +1,5 @@ +# Poise-Build-Essential Changelog + +## v1.0.0 + +* Initial release! diff --git a/cookbooks/poise-build-essential/README.md b/cookbooks/poise-build-essential/README.md new file mode 100644 index 0000000..fd9979f --- /dev/null +++ b/cookbooks/poise-build-essential/README.md @@ -0,0 +1,85 @@ +# Poise-Build-Essential Cookbook + +[![Build Status](https://img.shields.io/travis/poise/poise-build-essential.svg)](https://travis-ci.org/poise/poise-build-essential) +[![Gem Version](https://img.shields.io/gem/v/poise-build-essential.svg)](https://rubygems.org/gems/poise-build-essential) +[![Cookbook Version](https://img.shields.io/cookbook/v/poise-build-essential.svg)](https://supermarket.chef.io/cookbooks/poise-build-essential) +[![Coverage](https://img.shields.io/codecov/c/github/poise/poise-build-essential.svg)](https://codecov.io/github/poise/poise-build-essential) +[![Gemnasium](https://img.shields.io/gemnasium/poise/poise-build-essential.svg)](https://gemnasium.com/poise/poise-build-essential) +[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) + +A [Chef](https://www.chef.io/) cookbook to install a C compiler and build tools.. + +## Quick Start + +To install a C compiler: + +```ruby +include_recipe 'poise-build-essential' +``` + +Or to install using a resource and at compile time: + +```ruby +poise_build_essential 'build_essential' do + action :nothing +end.run_action(:install) +``` + +## Recipes + +* `poise-build-essential::default` – Install a C compiler and build tools. + +## Attributes + +* `node['poise-build-essential']['action']` – Action to use. One of install, + upgrade, or remove. *(default: install)* +* `node['poise-build-essential']['allow_unsupported_platform']` – Whether or not + to raise an error on unsupported platforms. *(default: false)* + +## Resources + +### `poise_build_essential` + +The `poise_build_essential` resource installs a C compiler and build tools. + +```ruby +poise_build_essential 'build_essential' do + allow_unsupported_platform true +end +``` + +#### Actions + +* `:install` – Install a C compiler. *(default)* +* `:upgrade` – Install a C compiler using `package action :ugprade` rules. +* `:remove` – Remove a C compiler. + +#### Properties + +* `allow_unsupported_platform` – Whether or not to raise an error on unsupported + platforms. *(default: false)* + +## Sponsors + +Development sponsored by [SAP](https://www.sap.com/). + +The Poise test server infrastructure is sponsored by [Rackspace](https://rackspace.com/). + +## License + +Some code copyright 2008-2017, Chef Software, Inc. Used under the terms of the +Apache License, Version 2.0. + +Copyright 2017, Noah Kantrowitz + +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/poise-build-essential/attributes/default.rb b/cookbooks/poise-build-essential/attributes/default.rb new file mode 100644 index 0000000..0b97ec0 --- /dev/null +++ b/cookbooks/poise-build-essential/attributes/default.rb @@ -0,0 +1,21 @@ +# +# Copyright 2017, Noah Kantrowitz +# +# 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. +# + +# Action to use. One of install, upgrade, or remove. +default['poise-build-essential']['action'] = 'install' + +# Whether or not to raise an error on unsupported platforms. +default['poise-build-essential']['allow_unsupported_platform'] = false diff --git a/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential.rb b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential.rb new file mode 100644 index 0000000..85106af --- /dev/null +++ b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential.rb @@ -0,0 +1,22 @@ +# +# Copyright 2017, Noah Kantrowitz +# +# 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 PoiseBuildEssential + autoload :BuildEssentialProviders, 'poise_build_essential/build_essential_providers' + autoload :Resources, 'poise_build_essential/resources' + autoload :VERSION, 'poise_build_essential/version' +end diff --git a/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers.rb b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers.rb new file mode 100644 index 0000000..d8cd687 --- /dev/null +++ b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers.rb @@ -0,0 +1,49 @@ +# +# Copyright 2017, Noah Kantrowitz +# +# 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/platform/provider_priority_map' + +require 'poise_build_essential/build_essential_providers/debian' +require 'poise_build_essential/build_essential_providers/freebsd' +require 'poise_build_essential/build_essential_providers/mac_os_x' +require 'poise_build_essential/build_essential_providers/omnios' +require 'poise_build_essential/build_essential_providers/rhel' +require 'poise_build_essential/build_essential_providers/smartos' +require 'poise_build_essential/build_essential_providers/solaris' +require 'poise_build_essential/build_essential_providers/suse' +# require 'poise_build_essential/build_essential_providers/windows' + + +module PoiseBuildEssential + # Inversion providers for the poise_build_essential resource. + # + # @since 1.0.0 + module BuildEssentialProviders + # Set up priority maps + Chef::Platform::ProviderPriorityMap.instance.priority(:poise_build_essential, [ + PoiseBuildEssential::BuildEssentialProviders::Debian, + PoiseBuildEssential::BuildEssentialProviders::FreeBSD, + PoiseBuildEssential::BuildEssentialProviders::MacOSX, + PoiseBuildEssential::BuildEssentialProviders::OmniOS, + PoiseBuildEssential::BuildEssentialProviders::RHEL, + PoiseBuildEssential::BuildEssentialProviders::SmartOS, + PoiseBuildEssential::BuildEssentialProviders::Solaris, + PoiseBuildEssential::BuildEssentialProviders::SUSE, + # PoiseBuildEssential::BuildEssentialProviders::Windows, + PoiseBuildEssential::BuildEssentialProviders::Base, + ]) + end +end diff --git a/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/base.rb b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/base.rb new file mode 100644 index 0000000..7c6e912 --- /dev/null +++ b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/base.rb @@ -0,0 +1,103 @@ +# +# Copyright 2017, Noah Kantrowitz +# +# 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/provider' +require 'poise' + + +module PoiseBuildEssential + module BuildEssentialProviders + # The provider base class for `poise_build_essential`. + # + # @see PoiseBuildEssential::Resources::PoiseBuildEssential::Resource + # @provides poise_build_essential + class Base < Chef::Provider + include Poise + provides(:poise_build_essential) + + # The `install` action for the `poise_build_essential` resource. + # + # @return [void] + def action_install + notifying_block do + install_build_essential + end + end + + # The `upgrade` action for the `poise_build_essential` resource. + # + # @return [void] + def action_upgrade + notifying_block do + upgrade_build_essential + end + end + + # The `remove` action for the `poise_build_essential` resource. + # + # @return [void] + def action_remove + notifying_block do + remove_build_essential + end + end + + private + + # Install C compiler and build tools. Must be implemented by subclasses. + # + # @abstract + def install_build_essential + unsupported_platform("Unknown platform for poise_build_eseential: #{node['platform']} (#{node['platform_family']})") + # Return an array so upgrade/remove also work. + [] + end + + # Upgrade C compiler and build tools. Must be implemented by subclasses. + # + # @abstract + def upgrade_build_essential + install_build_essential.tap do |installed| + Array(installed).each {|r| r.action(:upgrade) } + end + end + + # Uninstall C compiler and build tools. Must be implemented by subclasses. + # + # @abstract + def remove_build_essential + install_build_essential.tap do |installed| + Array(installed).each {|r| r.action(:remove) } + end + end + + # Helper method for either warning about an unsupported platform or raising + # an exception. + # + # @api private + # @param msg [String] Error message to display. + # @return [void] + def unsupported_platform(msg) + if new_resource.allow_unsupported_platform + Chef::Log.warn(msg) + else + raise RuntimeError.new(msg) + end + end + + end + end +end diff --git a/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/debian.rb b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/debian.rb new file mode 100644 index 0000000..9fd0bd9 --- /dev/null +++ b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/debian.rb @@ -0,0 +1,41 @@ +# +# Copyright 2008-2017, Chef Software, Inc. +# Copyright 2017, Noah Kantrowitz +# +# 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 'poise_build_essential/build_essential_providers/base' + + +module PoiseBuildEssential + module BuildEssentialProviders + # A provider for `poise_build_essential` to install on Debian platforms. + # + # @see PoiseBuildEssential::Resources::PoiseBuildEssential::Resource + # @provides poise_build_essential + class Debian < Base + provides(:poise_build_essential, platform_family: 'debian') + + private + + # (see Base#install_build_essential) + def install_build_essential + package %w{autoconf binutils-doc bison build-essential flex gettext ncurses-dev} + end + + end + end +end + + diff --git a/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/freebsd.rb b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/freebsd.rb new file mode 100644 index 0000000..d462c2b --- /dev/null +++ b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/freebsd.rb @@ -0,0 +1,46 @@ +# +# Copyright 2008-2017, Chef Software, Inc. +# Copyright 2017, Noah Kantrowitz +# +# 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 'poise_build_essential/build_essential_providers/base' + + +module PoiseBuildEssential + module BuildEssentialProviders + # A provider for `poise_build_essential` to install on FreeBSD platforms. + # + # @see PoiseBuildEssential::Resources::PoiseBuildEssential::Resource + # @provides poise_build_essential + class FreeBSD < Base + provides(:poise_build_essential, platform_family: 'freebsd') + + private + + # (see Base#install_build_essential) + def install_build_essential + pkgs = %w{devel/gmake devel/autoconf devel/m4 devel/gettext} + # Only install gcc on freebsd 9.x - 10 uses clang. + if node['platform_version'].to_i <= 9 + pkgs << 'lang/gcc49' + end + pkgs.map {|name| package name } + end + + end + end +end + + diff --git a/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/mac_os_x.rb b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/mac_os_x.rb new file mode 100644 index 0000000..ab2849c --- /dev/null +++ b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/mac_os_x.rb @@ -0,0 +1,66 @@ +# +# Copyright 2008-2017, Chef Software, Inc. +# Copyright 2017, Noah Kantrowitz +# +# 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 'poise_build_essential/build_essential_providers/base' + + +module PoiseBuildEssential + module BuildEssentialProviders + # A provider for `poise_build_essential` to install on macOS platforms. + # + # @see PoiseBuildEssential::Resources::PoiseBuildEssential::Resource + # @provides poise_build_essential + class MacOSX < Base + provides(:poise_build_essential, platform_family: 'mac_os_x') + + private + + # (see Base#install_build_essential) + def install_build_essential + # 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 +# 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 + not_if 'pkgutil --pkgs=com.apple.pkg.CLTools_Executables' + end + end + + # (see Base#upgrade_build_essential) + def upgrade_build_essential + # Make upgrade the same as install on Mac. + install_build_essential + end + + # (see Base#remove_build_essential) + def remove_build_essential + # Not sure how to do this, ignoring for now. + raise NotImplementedError + end + + end + end +end diff --git a/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/omnios.rb b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/omnios.rb new file mode 100644 index 0000000..3a22af0 --- /dev/null +++ b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/omnios.rb @@ -0,0 +1,46 @@ +# +# Copyright 2008-2017, Chef Software, Inc. +# Copyright 2017, Noah Kantrowitz +# +# 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 'poise_build_essential/build_essential_providers/base' + + +module PoiseBuildEssential + module BuildEssentialProviders + # A provider for `poise_build_essential` to install on OmniOS platforms. + # + # @see PoiseBuildEssential::Resources::PoiseBuildEssential::Resource + # @provides poise_build_essential + class OmniOS < Base + provides(:poise_build_essential, platform_family: 'omnios') + + private + + # (see Base#install_build_essential) + def install_build_essential + # 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" + + %w{developer/gcc48 developer/object-file developer/linker + developer/library/lint developer/build/gnu-make system/header + system/library/math/header-math}.map {|name| package name } + end + + end + end +end diff --git a/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/rhel.rb b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/rhel.rb new file mode 100644 index 0000000..65052a5 --- /dev/null +++ b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/rhel.rb @@ -0,0 +1,46 @@ +# +# Copyright 2008-2017, Chef Software, Inc. +# Copyright 2017, Noah Kantrowitz +# +# 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 'poise_build_essential/build_essential_providers/base' + + +module PoiseBuildEssential + module BuildEssentialProviders + # A provider for `poise_build_essential` to install on RedHat and Fedora platforms. + # + # @see PoiseBuildEssential::Resources::PoiseBuildEssential::Resource + # @provides poise_build_essential + class RHEL < Base + provides(:poise_build_essential, platform_family: %w{rhel fedora}) + + private + + # (see Base#install_build_essential) + def install_build_essential + pkgs = %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 + if node['platform_family'] == 'rhel' && node['platform_version'].to_i < 6 + pkgs += %w{gcc44 gcc44-c++} + end + package pkgs + end + + end + end +end + + diff --git a/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/smartos.rb b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/smartos.rb new file mode 100644 index 0000000..8f45af1 --- /dev/null +++ b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/smartos.rb @@ -0,0 +1,39 @@ +# +# Copyright 2008-2017, Chef Software, Inc. +# Copyright 2017, Noah Kantrowitz +# +# 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 'poise_build_essential/build_essential_providers/base' + + +module PoiseBuildEssential + module BuildEssentialProviders + # A provider for `poise_build_essential` to install on SmartOS platforms. + # + # @see PoiseBuildEssential::Resources::PoiseBuildEssential::Resource + # @provides poise_build_essential + class SmartOS < Base + provides(:poise_build_essential, platform_family: 'smartos') + + private + + # (see Base#install_build_essential) + def install_build_essential + %w{autoconf binutils build-essential gcc47 gmake pkg-config}.map {|name| package name } + end + + end + end +end diff --git a/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/solaris.rb b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/solaris.rb new file mode 100644 index 0000000..2ef2b50 --- /dev/null +++ b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/solaris.rb @@ -0,0 +1,47 @@ +# +# Copyright 2008-2017, Chef Software, Inc. +# Copyright 2017, Noah Kantrowitz +# +# 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 'poise_build_essential/build_essential_providers/base' + + +module PoiseBuildEssential + module BuildEssentialProviders + # A provider for `poise_build_essential` to install on Solaris platforms. + # + # @see PoiseBuildEssential::Resources::PoiseBuildEssential::Resource + # @provides poise_build_essential + class Solaris < Base + provides(:poise_build_essential, platform_family: 'solaris2') + + private + + # (see Base#install_build_essential) + def install_build_essential + if node['platform_version'].to_f < 5.11 + unsupported_platform('poise_build_essential does not support Solaris before 11. You will need to install SUNWbison, SUNWgcc, SUNWggrp, SUNWgmake, and SUNWgtar from the Solaris DVD') + return [] + end + + # lock because we don't use gcc 5 yet. + [package('gcc') { version '4.8.2'} ] + \ + %w{autoconf automake bison gnu-coreutils flex gcc-3 gnu-grep gnu-make + gnu-patch gnu-tar make pkg-config ucb}.map {|name| package name } + end + + end + end +end diff --git a/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/suse.rb b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/suse.rb new file mode 100644 index 0000000..b734631 --- /dev/null +++ b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/suse.rb @@ -0,0 +1,43 @@ +# +# Copyright 2008-2017, Chef Software, Inc. +# Copyright 2017, Noah Kantrowitz +# +# 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 'poise_build_essential/build_essential_providers/base' + + +module PoiseBuildEssential + module BuildEssentialProviders + # A provider for `poise_build_essential` to install on SUSE platforms. + # + # @see PoiseBuildEssential::Resources::PoiseBuildEssential::Resource + # @provides poise_build_essential + class SUSE < Base + provides(:poise_build_essential, platform_family: 'suse') + + private + + # (see Base#install_build_essential) + def install_build_essential + pkgs = %w{autoconf bison flex gcc gcc-c++ kernel-default-devel make m4} + if node['platform_version'].to_i < 12 + pkgs += %w{gcc48 gcc48-c++} + end + package pkgs + end + + end + end +end diff --git a/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/windows.rb b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/windows.rb new file mode 100644 index 0000000..67251db --- /dev/null +++ b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/build_essential_providers/windows.rb @@ -0,0 +1,68 @@ +# +# Copyright 2008-2017, Chef Software, Inc. +# Copyright 2017, Noah Kantrowitz +# +# 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 'poise_build_essential/build_essential_providers/base' + + +module PoiseBuildEssential + module BuildEssentialProviders + # A provider for `poise_build_essential` to install on Windows platforms. + # + # @see PoiseBuildEssential::Resources::PoiseBuildEssential::Resource + # @provides poise_build_essential + class Windows < Base + provides(:poise_build_essential, platform_family: 'windows') + + private + + # (see Base#install_build_essential) + def install_build_essential + install_build_essential_packages + end + + # (see Base#upgrade_build_essential) + def upgrade_build_essential + # Upgrade and install are the same on Windows. (?) + install_build_essential + end + + # (see Base#remove_build_essential) + def remove_build_essential + raise NotImplementedError + end + + # Install MSYS2 packages needed for the build environment. + # + # @api private + # @return [Array] + def install_build_essential_packages + # TODO This probably won't work on 32-bit right now, fix that. + [ + 'base-devel', # Brings down msys based bash/make/awk/patch/stuff. + 'mingw-w64-x86_64-toolchain', # Puts 64-bit SEH mingw toolchain in msys2\mingw64. + 'mingw-w64-i686-toolchain' # Puts 32-bit DW2 mingw toolchain in msys2\ming32. + ].map do |pkg_group| + # The pacman package provider doesn't support groups, so going old-school. + poise_msys2_execute "pacman --sync #{pkg_group}" do + command ['pacman', '--sync', '--noconfirm', '--noprogressbar', '--needed', pkg_group] + end + end + end + + end + end +end diff --git a/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/cheftie.rb b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/cheftie.rb new file mode 100644 index 0000000..c771207 --- /dev/null +++ b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/cheftie.rb @@ -0,0 +1,18 @@ +# +# Copyright 2017, Noah Kantrowitz +# +# 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 'poise_build_essential/resources' +require 'poise_build_essential/build_essential_providers' diff --git a/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/resources.rb b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/resources.rb new file mode 100644 index 0000000..25c75d3 --- /dev/null +++ b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/resources.rb @@ -0,0 +1,26 @@ +# +# Copyright 2017, Noah Kantrowitz +# +# 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 'poise_build_essential/resources/poise_build_essential' + + +module PoiseBuildEssential + # Chef resources and providers for poise-build-essential. + # + # @since 1.0.0 + module Resources + end +end diff --git a/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/resources/poise_build_essential.rb b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/resources/poise_build_essential.rb new file mode 100644 index 0000000..e5e08cc --- /dev/null +++ b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/resources/poise_build_essential.rb @@ -0,0 +1,48 @@ +# +# Copyright 2017, Noah Kantrowitz +# +# 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' +require 'poise' + + +module PoiseBuildEssential + module Resources + # (see PoiseBuildEssential::Resource) + # @since 1.0.0 + module PoiseBuildEssential + # A `poise_build_essential` resource to install a C compiler and build tools. + # + # @provides poise_build_essential + # @action install + # @action upgrade + # @action uninstall + # @example + # poise_build_essential 'build-essential' + class Resource < Chef::Resource + include Poise + provides(:poise_build_essential) + actions(:install, :upgrade, :remove) + + # @!attribute allow_unsupported_platform + # Whether or not to raise an error on unsupported platforms. + # @return [Boolean] + attribute(:allow_unsupported_platform, kind_of: [TrueClass, FalseClass], default: lazy { node['poise-build-essential']['allow_unsupported_platform'] }) + end + + # Providers can be found under build_essential_providers/. + end + end +end diff --git a/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/version.rb b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/version.rb new file mode 100644 index 0000000..58a1c80 --- /dev/null +++ b/cookbooks/poise-build-essential/files/halite_gem/poise_build_essential/version.rb @@ -0,0 +1,20 @@ +# +# Copyright 2017, Noah Kantrowitz +# +# 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 PoiseBuildEssential + VERSION = '1.0.0' +end diff --git a/cookbooks/poise-build-essential/libraries/default.rb b/cookbooks/poise-build-essential/libraries/default.rb new file mode 100644 index 0000000..4b0a953 --- /dev/null +++ b/cookbooks/poise-build-essential/libraries/default.rb @@ -0,0 +1,19 @@ +# +# Copyright 2017, Noah Kantrowitz +# +# 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. +# + +raise 'Halite is not compatible with no_lazy_load false, please set no_lazy_load true in your Chef configuration file.' unless Chef::Config[:no_lazy_load] +$LOAD_PATH << File.expand_path('../../files/halite_gem', __FILE__) +require "poise_build_essential/cheftie" diff --git a/cookbooks/poise-build-essential/metadata.json b/cookbooks/poise-build-essential/metadata.json new file mode 100644 index 0000000..c1ddba6 --- /dev/null +++ b/cookbooks/poise-build-essential/metadata.json @@ -0,0 +1 @@ +{"name":"poise-build-essential","version":"1.0.0","description":"A Chef cookbook to install a C compiler and build tools.","long_description":"# Poise-Build-Essential Cookbook\n\n[![Build Status](https://img.shields.io/travis/poise/poise-build-essential.svg)](https://travis-ci.org/poise/poise-build-essential)\n[![Gem Version](https://img.shields.io/gem/v/poise-build-essential.svg)](https://rubygems.org/gems/poise-build-essential)\n[![Cookbook Version](https://img.shields.io/cookbook/v/poise-build-essential.svg)](https://supermarket.chef.io/cookbooks/poise-build-essential)\n[![Coverage](https://img.shields.io/codecov/c/github/poise/poise-build-essential.svg)](https://codecov.io/github/poise/poise-build-essential)\n[![Gemnasium](https://img.shields.io/gemnasium/poise/poise-build-essential.svg)](https://gemnasium.com/poise/poise-build-essential)\n[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)\n\nA [Chef](https://www.chef.io/) cookbook to install a C compiler and build tools..\n\n## Quick Start\n\nTo install a C compiler:\n\n```ruby\ninclude_recipe 'poise-build-essential'\n```\n\nOr to install using a resource and at compile time:\n\n```ruby\npoise_build_essential 'build_essential' do\n action :nothing\nend.run_action(:install)\n```\n\n## Recipes\n\n* `poise-build-essential::default` – Install a C compiler and build tools.\n\n## Attributes\n\n* `node['poise-build-essential']['action']` – Action to use. One of install,\n upgrade, or remove. *(default: install)*\n* `node['poise-build-essential']['allow_unsupported_platform']` – Whether or not\n to raise an error on unsupported platforms. *(default: false)*\n\n## Resources\n\n### `poise_build_essential`\n\nThe `poise_build_essential` resource installs a C compiler and build tools.\n\n```ruby\npoise_build_essential 'build_essential' do\n allow_unsupported_platform true\nend\n```\n\n#### Actions\n\n* `:install` – Install a C compiler. *(default)*\n* `:upgrade` – Install a C compiler using `package action :ugprade` rules.\n* `:remove` – Remove a C compiler.\n\n#### Properties\n\n* `allow_unsupported_platform` – Whether or not to raise an error on unsupported\n platforms. *(default: false)*\n\n## Sponsors\n\nDevelopment sponsored by [SAP](https://www.sap.com/).\n\nThe Poise test server infrastructure is sponsored by [Rackspace](https://rackspace.com/).\n\n## License\n\nSome code copyright 2008-2017, Chef Software, Inc. Used under the terms of the\nApache License, Version 2.0.\n\nCopyright 2017, Noah Kantrowitz\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","maintainer":"Noah Kantrowitz","maintainer_email":"noah@coderanger.net","license":"Apache 2.0","platforms":{},"dependencies":{"poise":"~> 2.6"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{},"source_url":"https://github.com/poise/poise-build-essential","issues_url":"https://github.com/poise/poise-build-essential/issues","chef_version":[["< 14",">= 12.1"]],"ohai_version":[]} \ No newline at end of file diff --git a/cookbooks/poise-build-essential/recipes/default.rb b/cookbooks/poise-build-essential/recipes/default.rb new file mode 100644 index 0000000..9c89821 --- /dev/null +++ b/cookbooks/poise-build-essential/recipes/default.rb @@ -0,0 +1,19 @@ +# +# Copyright 2017, Noah Kantrowitz +# +# 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. +# + +poise_build_essential 'build_essential' do + action node['poise-build-essential']['action'].to_sym +end diff --git a/cookbooks/poise-git/CHANGELOG.md b/cookbooks/poise-git/CHANGELOG.md new file mode 100644 index 0000000..d037b8c --- /dev/null +++ b/cookbooks/poise-git/CHANGELOG.md @@ -0,0 +1,5 @@ +# Poise-Git Changelog + +## v1.0.0 + +* Initial release! diff --git a/cookbooks/poise-git/README.md b/cookbooks/poise-git/README.md new file mode 100644 index 0000000..2d8a6e0 --- /dev/null +++ b/cookbooks/poise-git/README.md @@ -0,0 +1,151 @@ +# Poise-Git Cookbook + +[![Build Status](https://img.shields.io/travis/poise/poise-git.svg)](https://travis-ci.org/poise/poise-git) +[![Gem Version](https://img.shields.io/gem/v/poise-git.svg)](https://rubygems.org/gems/poise-git) +[![Cookbook Version](https://img.shields.io/cookbook/v/poise-git.svg)](https://supermarket.chef.io/cookbooks/poise-git) +[![Coverage](https://img.shields.io/codecov/c/github/poise/poise-git.svg)](https://codecov.io/github/poise/poise-git) +[![Gemnasium](https://img.shields.io/gemnasium/poise/poise-git.svg)](https://gemnasium.com/poise/poise-git) +[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) + +A [Chef](https://www.chef.io/) cookbook to manage [Git](https://git-scm.com/). + +## Quick Start + +To install Git and clone a repository using a deploy key from a data bag: + +```ruby +poise_git '/srv/myapp' do + repository 'git@github.com:example/myapp.git' + deploy_key data_bag_item('keys', 'myapp')['key'] +end +``` + +To install Git and clone a repository using a deploy key that already exists on +disk: + +```ruby +poise_git '/srv/myapp' do + repository 'git@github.com:example/myapp.git' + deploy_key '/path/to/mykey.pem' +end +``` + +## Recipes + +* `poise-git::default` – Install Git. + +## Attributes + +* `node['poise-git']['default_recipe']` – Recipe used by `poise_git` to install + Git if not already available. *(default: poise-git)* +* `node['poise-git']['provider']` – Default provider for `poise_git_client` resource + instances. *(default: auto)* +* `node['poise-git']['recipe'][*]` – All subkeys of `'recipe'` will be passed + as properties to the `poise_git_client` resource before installation when using + the `poise-git::default` recipe. + +## Resources + +### `poise_git` + +The `poise_git` resource extends the core `git` resource, adding a `deploy_key` +property to use SSH deploy keys automatically. + +```ruby +poise_git '/srv/myapp' do + repository 'git@github.com:example/myapp.git' + deploy_key 'mysecretkey' +end +``` + +The `poise_git` resource supports all the same actions and properties as the +core `git` resource. + +The `deploy_key` property can either be passed the absolute path to an existing +SSH key file, or the raw SSH private key text. + +### `poise_git_client` + +The `poise_git_client` resource installs Git. + +```ruby +poise_git_client 'git' +``` + +#### Actions + +* `:install` – Install Git. *(default)* +* `:uninstall` – Uninstall Git. + +#### Properties + +* `version` – Version of Git to install. If a partial version is given, use the + latest available version matching that prefix. *(name property)* + +#### Provider Options + +The `poise_git_client` resource uses provide options for per-provider configuration. See +[the poise-service documentation](https://github.com/poise/poise-service#service-options) +for more information on using provider options. + +## Git Client Providers + +### `system` + +The `system` provider installs Git using system packages. This is currently +only tested on platforms using `apt-get` and `yum` (Debian, Ubuntu, RHEL, CentOS +Amazon Linux, and Fedora) and is a default provider on those platforms. It may +work on other platforms but is untested. + +```ruby +poise_git_client 'git' do + provider :system +end +``` + +#### Options + +* `package_name` – Override auto-detection of the package name. +* `package_upgrade` – Install using action `:upgrade`. *(default: false)* +* `package_version` – Override auto-detection of the package version. + +### `dummy` + +The `dummy` provider supports using the `poise_git_client` resource with ChefSpec +or other testing frameworks to not actually install Git. It is used by default under +ChefSpec. It can also be used to manage the Git installation externally from +this cookbook. + +```ruby +poise_git_client 'git' do + provider :dummy + options git_binary: '/path/to/git' +end +``` + +#### Provider Options + +* `git_binary` – Path to the `git` executable. *(default: /git)* +* `git_environment` – Hash of environment variables to use with this Git. *(default: {})* + +## Sponsors + +Development sponsored by [SAP](https://www.sap.com/). + +The Poise test server infrastructure is sponsored by [Rackspace](https://rackspace.com/). + +## License + +Copyright 2015-2017, Noah Kantrowitz + +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/poise-git/attributes/default.rb b/cookbooks/poise-git/attributes/default.rb new file mode 100644 index 0000000..ae15453 --- /dev/null +++ b/cookbooks/poise-git/attributes/default.rb @@ -0,0 +1,26 @@ +# +# Copyright 2017, Noah Kantrowitz +# +# 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. +# + +# Default recipe to use to install git. +default['poise-git']['default_recipe'] = 'poise-git' + +# Default inversion options. +default['poise-git']['provider'] = 'auto' +default['poise-git']['options'] = {} + +# Attributes for recipe[poise-git]. All values are nil because the actual +# defaults live in the resource. +default['poise-git']['recipe']['version'] = nil diff --git a/cookbooks/poise-git/files/halite_gem/poise_git.rb b/cookbooks/poise-git/files/halite_gem/poise_git.rb new file mode 100644 index 0000000..9da6e6a --- /dev/null +++ b/cookbooks/poise-git/files/halite_gem/poise_git.rb @@ -0,0 +1,24 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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 PoiseGit + autoload :GitClientProviders, 'poise_git/git_client_providers' + autoload :GitCommandMixin, 'poise_git/git_command_mixin' + autoload :Resources, 'poise_git/resources' + autoload :SafeString, 'poise_git/safe_string' + autoload :VERSION, 'poise_git/version' +end diff --git a/cookbooks/poise-git/files/halite_gem/poise_git/cheftie.rb b/cookbooks/poise-git/files/halite_gem/poise_git/cheftie.rb new file mode 100644 index 0000000..54b295f --- /dev/null +++ b/cookbooks/poise-git/files/halite_gem/poise_git/cheftie.rb @@ -0,0 +1,18 @@ +# +# Copyright 2017, Noah Kantrowitz +# +# 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 'poise_git/resources' +require 'poise_git/git_client_providers' diff --git a/cookbooks/poise-git/files/halite_gem/poise_git/git_client_providers.rb b/cookbooks/poise-git/files/halite_gem/poise_git/git_client_providers.rb new file mode 100644 index 0000000..552a035 --- /dev/null +++ b/cookbooks/poise-git/files/halite_gem/poise_git/git_client_providers.rb @@ -0,0 +1,36 @@ +# +# Copyright 2017, Noah Kantrowitz +# +# 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/platform/provider_priority_map' + +require 'poise_git/git_client_providers/dummy' +require 'poise_git/git_client_providers/system' + + +module PoiseGit + # Inversion providers for the poise_git resource. + # + # @since 1.0.0 + module GitClientProviders + autoload :Base, 'poise_git/git_client_providers/base' + + # Set up priority maps + Chef::Platform::ProviderPriorityMap.instance.priority(:poise_git_client, [ + PoiseGit::GitClientProviders::Dummy, + PoiseGit::GitClientProviders::System, + ]) + end +end diff --git a/cookbooks/poise-git/files/halite_gem/poise_git/git_client_providers/base.rb b/cookbooks/poise-git/files/halite_gem/poise_git/git_client_providers/base.rb new file mode 100644 index 0000000..fdc370c --- /dev/null +++ b/cookbooks/poise-git/files/halite_gem/poise_git/git_client_providers/base.rb @@ -0,0 +1,93 @@ +# +# Copyright 2017, Noah Kantrowitz +# +# 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/provider' +require 'poise' + + +module PoiseGit + module GitClientProviders + # The provider base class for `poise_git_client`. + # + # @see PoiseGit::Resources::PoiseGitClient::Resource + # @provides poise_git_client + class Base < Chef::Provider + include Poise(inversion: :poise_git_client) + provides(:poise_git_client) + + # Set default inversion options. + # + # @api private + def self.default_inversion_options(node, new_resource) + super.merge({ + version: new_resource.version, + }) + end + + # The `install` action for the `poise_git_client` resource. + # + # @return [void] + def action_install + notifying_block do + install_git + end + end + + # The `uninstall` action for the `poise_git_client` resource. + # + # @return [void] + def action_uninstall + notifying_block do + uninstall_git + end + end + + # The path to the `git` binary. This is an output property. + # + # @abstract + # @return [String] + def git_binary + raise NotImplementedError + end + + # The environment variables for this Git. This is an output property. + # + # @return [Hash] + def git_environment + {} + end + + private + + # Install git. + # + # @abstract + # @return [void] + def install_git + raise NotImplementedError + end + + # Uninstall git. + # + # @abstract + # @return [void] + def uninstall_git + raise NotImplementedError + end + + end + end +end diff --git a/cookbooks/poise-git/files/halite_gem/poise_git/git_client_providers/dummy.rb b/cookbooks/poise-git/files/halite_gem/poise_git/git_client_providers/dummy.rb new file mode 100644 index 0000000..39f1194 --- /dev/null +++ b/cookbooks/poise-git/files/halite_gem/poise_git/git_client_providers/dummy.rb @@ -0,0 +1,79 @@ +# +# Copyright 2017, Noah Kantrowitz +# +# 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 'poise_git/git_client_providers/base' + + +module PoiseGit + module GitClientProviders + # Inversion provider for the `poise_git_client` resource to use a fake Git, + # for use in unit tests. + # + # @since 1.0.0 + # @see PoiseGit::Resources::PoiseGitClient::Resource + # @provides poise_git_client + class Dummy < Base + provides(:dummy) + + # Enable by default on ChefSpec. + # + # @api private + def self.provides_auto?(node, _resource) + node.platform?('chefspec') + end + + # Manual overrides for dummy data. + # + # @api private + def self.default_inversion_options(node, resource) + super.merge({ + git_binary: '/git', + git_environment: nil, + }) + end + + # The `install` action for the `poise_git_client` resource. + # + # @return [void] + def action_install + # This space left intentionally blank. + end + + # The `uninstall` action for the `poise_git_client` resource. + # + # @return [void] + def action_uninstall + # This space left intentionally blank. + end + + # Path to the non-existent Git. + # + # @return [String] + def git_binary + options['git_binary'] + end + + # Environment for the non-existent Git. + # + # @return [String] + def git_environment + options['git_environment'] || super + end + + end + end +end + diff --git a/cookbooks/poise-git/files/halite_gem/poise_git/git_client_providers/system.rb b/cookbooks/poise-git/files/halite_gem/poise_git/git_client_providers/system.rb new file mode 100644 index 0000000..812039d --- /dev/null +++ b/cookbooks/poise-git/files/halite_gem/poise_git/git_client_providers/system.rb @@ -0,0 +1,73 @@ +# +# Copyright 2017, Noah Kantrowitz +# +# 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 'poise_languages' + +require 'poise_git/git_client_providers/base' + + +module PoiseGit + module GitClientProviders + # A provider for `poise_git_client` to install from distro packages. + # + # @since 1.0.0 + # @see PoiseGit::Resources::PoiseGitClient::Resource + # @provides poise_git_client + class System < Base + include PoiseLanguages::System::Mixin + provides(:system) + packages('git', { + omnios: {default: %w{developer/versioning/git}}, + smartos: {default: %w{scmgit}}, + }) + + # Output value for the Git binary we are installing. + def git_binary + # What should this be for OmniOS and SmartOS? + "/usr/bin/git" + end + + private + + # Install git from system packages. + # + # @return [void] + def install_git + install_system_packages do + # Unlike language-ish packages, we don't need a headers package. + dev_package false + end + end + + # Remove git from system packages. + # + # @return [void] + def uninstall_git + uninstall_system_packages do + # Unlike language-ish packages, we don't need a headers package. + dev_package false + end + end + + def system_package_candidates(version) + # This is kind of silly, could use a refactor in the mixin but just + # moving on for right now. + node.value_for_platform(self.class.packages) || %w{git} + end + + end + end +end diff --git a/cookbooks/poise-git/files/halite_gem/poise_git/git_command_mixin.rb b/cookbooks/poise-git/files/halite_gem/poise_git/git_command_mixin.rb new file mode 100644 index 0000000..7e1d3f0 --- /dev/null +++ b/cookbooks/poise-git/files/halite_gem/poise_git/git_command_mixin.rb @@ -0,0 +1,37 @@ +# +# Copyright 2017, Noah Kantrowitz +# +# 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 'poise/utils' +require 'poise_languages' + + +module PoiseGit + # Mixin for resources and providers which run Git commands. + # + # @since 1.0.0 + module GitCommandMixin + include Poise::Utils::ResourceProviderMixin + + # Mixin for resources which run Git commands. + module Resource + include PoiseLanguages::Command::Mixin::Resource(:git, runtime: :poise_git_client) + end + + module Provider + include PoiseLanguages::Command::Mixin::Provider(:git) + end + end +end diff --git a/cookbooks/poise-git/files/halite_gem/poise_git/resources.rb b/cookbooks/poise-git/files/halite_gem/poise_git/resources.rb new file mode 100644 index 0000000..ce7f5ab --- /dev/null +++ b/cookbooks/poise-git/files/halite_gem/poise_git/resources.rb @@ -0,0 +1,27 @@ +# +# Copyright 2017, Noah Kantrowitz +# +# 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 'poise_git/resources/poise_git_client' +require 'poise_git/resources/poise_git' + + +module PoiseGit + # Chef resources and providers for poise-git. + # + # @since 1.0.0 + module Resources + end +end diff --git a/cookbooks/poise-git/files/halite_gem/poise_git/resources/poise_git.rb b/cookbooks/poise-git/files/halite_gem/poise_git/resources/poise_git.rb new file mode 100644 index 0000000..9eb621d --- /dev/null +++ b/cookbooks/poise-git/files/halite_gem/poise_git/resources/poise_git.rb @@ -0,0 +1,252 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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' +require 'zlib' + +require 'chef/provider/git' +require 'chef/resource/git' +require 'poise' + +require 'poise_git/git_command_mixin' +require 'poise_git/safe_string' + + +module PoiseGit + module Resources + # (see PoiseGit::Resource) + # @since 1.0.0 + module PoiseGit + # A `poise_git` resource to manage Python installations using pip. + # + # @provides poise_git + # @action checkout + # @action export + # @action sync + # @example + # poise_git '/srv/myapp' do + # repository 'https://...' + # deploy_key data_bag_item('deploy_keys', 'myapp')['key'] + # end + class Resource < Chef::Resource::Git + include Poise + include ::PoiseGit::GitCommandMixin + provides(:poise_git) + # Manually create matchers because #actions is unreliable. + %i{checkout export sync}.each do |action| + Poise::Helpers::ChefspecMatchers.create_matcher(:poise_git, action) + end + + # @api private + def initialize(*args) + super + # Because the superclass declares this, we have to as well. Should be + # removable at some point when Chef makes everything use the provider + # resolver system instead. + @resource_name = :poise_git if defined?(@resource_name) && @resource_name + @provider = ::PoiseGit::Resources::PoiseGit::Provider if defined?(@provider) && @provider + end + + # @!attribute strict_ssh + # Enable strict SSH host key checking. Defaults to false. + # @return [Boolean] + attribute(:strict_ssh, equal_to: [true, false], default: false) + + # @!attribute deploy_key + # SSH deploy key as either a string value or a path to a key file. + # @return [String] + def deploy_key(val=nil) + # Use a SafeString for literal deploy keys so they aren't shown. + val = SafeString.new(val) if val && !deploy_key_is_local?(val) + set_or_return(:deploy_key, val, kind_of: String) + end + + # Default SSH wrapper path. + # + # @api private + # @return [String] + def ssh_wrapper_path + @ssh_wrapper_path ||= "#{Chef::Config[:file_cache_path]}/poise_git_wrapper_#{Zlib.crc32(name)}" + end + + # Guess if the deploy key is a local path or literal value. + # + # @api private + # @param key [String, nil] Key value to check. Defaults to self.key. + # @return [Boolean] + def deploy_key_is_local?(key=nil) + key ||= deploy_key + # Try to be mindful of Windows-y paths here even though they almost + # certainly won't actually work later on with ssh. + key && key =~ /\A(\/|[a-zA-Z]:)/ + end + + # Path to deploy key. + # + # @api private + # @return [String] + def deploy_key_path + @deploy_key_path ||= if deploy_key_is_local? + deploy_key + else + "#{Chef::Config[:file_cache_path]}/poise_git_deploy_#{Zlib.crc32(name)}" + end + end + + # Hook to force the git install via recipe if needed. + def after_created + if !parent_git && node['poise-git']['default_recipe'] + # Use the default recipe to give us a parent the next time we ask. + run_context.include_recipe(node['poise-git']['default_recipe']) + # Force it to re-expand the cache next time. + @parent_git = nil + end + super + end + + end + + # The default provider for the `poise_git` resource. + # + # @see Resource + class Provider < Chef::Provider::Git + include Poise + include ::PoiseGit::GitCommandMixin + provides(:poise_git) + + # @api private + def initialize(*args) + super + # Set the SSH wrapper path in a late-binding kind of way. This better + # supports situations where the user doesn't exist until Chef converges. + new_resource.ssh_wrapper(new_resource.ssh_wrapper_path) if new_resource.deploy_key + end + + # Hack our special login in before load_current_resource runs because that + # needs access to the git remote. + # + # @api private + def load_current_resource + create_deploy_key if new_resource.deploy_key + super + end + + # Like {#load_current_resource}, make sure git is installed since we might + # need it depending on the version of Chef. + # + # @api private + def define_resource_requirements + create_deploy_key if new_resource.deploy_key + super + end + + private + + # Install git and set up the deploy key if needed. Safe to call multiple + # times if needed. + # + # @api private + # @return [void] + def create_deploy_key + return if @create_deploy_key + Chef::Log.debug("[#{new_resource}] Creating deploy key") + old_why_run = Chef::Config[:why_run] + begin + # Forcibly disable why run support so these will always run, since + # we need to be able to talk to the git remote even just for the + # whyrun checks. + Chef::Config[:why_run] = false + notifying_block do + write_deploy_key + write_ssh_wrapper + end + ensure + Chef::Config[:why_run] = old_why_run + end + @create_deploy_key = true + end + + # Copy the deploy key to a file if needed. + # + # @api private + # @return [void] + def write_deploy_key + # Check if we have a local path or some actual content + return if new_resource.deploy_key_is_local? + file new_resource.deploy_key_path do + owner new_resource.user + group new_resource.group + mode '600' + content new_resource.deploy_key + sensitive true + end + end + + # Create the SSH wrapper script. + # + # @api private + # @return [void] + def write_ssh_wrapper + # Write out the GIT_SSH script, it should already be enabled above + file new_resource.ssh_wrapper_path do + owner new_resource.user + group new_resource.group + mode '700' + content %Q{#!/bin/sh\n/usr/bin/env ssh #{'-o "StrictHostKeyChecking=no" ' unless new_resource.strict_ssh}-i "#{new_resource.deploy_key_path}" $@\n} + end + end + + # Patch back in the `#git` from the git provider. This otherwise conflicts + # with the `#git` defined by the DSL, which gets included in such a way + # that the DSL takes priority. + # + # @api private + def git(*args, &block) + self.class.superclass.instance_method(:git).bind(self).call(*args, &block) + end + + # Trick all shell_out related things in the base class in to using + # my git_shell_out instead. + # + # @api private + def shell_out(*cmd, **options) + if @shell_out_hack_inner + # This is the real call. + super + else + # This ia call we want to intercept and send to our method. + begin + @shell_out_hack_inner = true + # Remove nils and flatten for compat with how core uses this method. + cmd.compact! + cmd.flatten! + # Reparse the command to get a clean array. + cmd = Shellwords.split(cmd.join(' ')) + # We'll add the git command back in ourselves. + cmd.shift if cmd.first == 'git' + # Push the yak stack. + git_shell_out(*cmd, **options) + ensure + @shell_out_hack_inner = false + end + end + end + + end + + end + end +end diff --git a/cookbooks/poise-git/files/halite_gem/poise_git/resources/poise_git_client.rb b/cookbooks/poise-git/files/halite_gem/poise_git/resources/poise_git_client.rb new file mode 100644 index 0000000..0a83d4f --- /dev/null +++ b/cookbooks/poise-git/files/halite_gem/poise_git/resources/poise_git_client.rb @@ -0,0 +1,82 @@ +# +# Copyright 2017, Noah Kantrowitz +# +# 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' +require 'poise' + + +module PoiseGit + module Resources + # (see PoiseGitClient::Resource) + # @since 1.0.0 + module PoiseGitClient + # A `poise_git_client` resource to install a C compiler and build tools. + # + # @provides poise_git_client + # @action install + # @action uninstall + # @example + # poise_git_client 'git' + class Resource < Chef::Resource + include Poise(inversion: true, container: true) + provides(:poise_git_client) + actions(:install, :uninstall) + + # @!attribute version + # Version of Git to install. The version is prefix-matched so `'2'` + # will install the most recent Git 2.x, and so on. + # @return [String] + # @example Install any version + # poise_git_client 'any' do + # version '' + # end + # @example Install Git 2 + # poise_git_client '2' + attribute(:version, kind_of: String, default: lazy { default_version }) + + # The path to the `git` binary for this Git installation. This is + # an output property. + # + # @return [String] + # @example + # execute "#{resources('poise_git_client[git]').git_binary} init" + def git_binary + provider_for_action(:git_binary).git_binary + end + + # The environment variables for this Git installation. This is an + # output property. + # + # @return [Hash] + def git_environment + provider_for_action(:git_environment).git_environment + end + + private + + # Default value for the version property. Trims an optional `git-` from + # the resource name. + # + # @return [String] + def default_version + name[/^(git-?)?(.*)$/, 2] || '' + end + end + + # Providers can be found under git_client_providers/. + end + end +end diff --git a/cookbooks/poise-git/files/halite_gem/poise_git/safe_string.rb b/cookbooks/poise-git/files/halite_gem/poise_git/safe_string.rb new file mode 100644 index 0000000..347e54f --- /dev/null +++ b/cookbooks/poise-git/files/halite_gem/poise_git/safe_string.rb @@ -0,0 +1,25 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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 PoiseGit + # A string that won't be shown in Chef error output + class SafeString < String + def to_text + '"suppressed sensitive value"' + end + end +end diff --git a/cookbooks/poise-git/files/halite_gem/poise_git/version.rb b/cookbooks/poise-git/files/halite_gem/poise_git/version.rb new file mode 100644 index 0000000..f998a84 --- /dev/null +++ b/cookbooks/poise-git/files/halite_gem/poise_git/version.rb @@ -0,0 +1,20 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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 PoiseGit + VERSION = '1.0.0' +end diff --git a/cookbooks/poise-git/libraries/default.rb b/cookbooks/poise-git/libraries/default.rb new file mode 100644 index 0000000..b2f6163 --- /dev/null +++ b/cookbooks/poise-git/libraries/default.rb @@ -0,0 +1,19 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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. +# + +raise 'Halite is not compatible with no_lazy_load false, please set no_lazy_load true in your Chef configuration file.' unless Chef::Config[:no_lazy_load] +$LOAD_PATH << File.expand_path('../../files/halite_gem', __FILE__) +require "poise_git/cheftie" diff --git a/cookbooks/poise-git/metadata.json b/cookbooks/poise-git/metadata.json new file mode 100644 index 0000000..610553d --- /dev/null +++ b/cookbooks/poise-git/metadata.json @@ -0,0 +1 @@ +{"name":"poise-git","version":"1.0.0","description":"A Chef cookbook for installing and using Git.","long_description":"# Poise-Git Cookbook\n\n[![Build Status](https://img.shields.io/travis/poise/poise-git.svg)](https://travis-ci.org/poise/poise-git)\n[![Gem Version](https://img.shields.io/gem/v/poise-git.svg)](https://rubygems.org/gems/poise-git)\n[![Cookbook Version](https://img.shields.io/cookbook/v/poise-git.svg)](https://supermarket.chef.io/cookbooks/poise-git)\n[![Coverage](https://img.shields.io/codecov/c/github/poise/poise-git.svg)](https://codecov.io/github/poise/poise-git)\n[![Gemnasium](https://img.shields.io/gemnasium/poise/poise-git.svg)](https://gemnasium.com/poise/poise-git)\n[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)\n\nA [Chef](https://www.chef.io/) cookbook to manage [Git](https://git-scm.com/).\n\n## Quick Start\n\nTo install Git and clone a repository using a deploy key from a data bag:\n\n```ruby\npoise_git '/srv/myapp' do\n repository 'git@github.com:example/myapp.git'\n deploy_key data_bag_item('keys', 'myapp')['key']\nend\n```\n\nTo install Git and clone a repository using a deploy key that already exists on\ndisk:\n\n```ruby\npoise_git '/srv/myapp' do\n repository 'git@github.com:example/myapp.git'\n deploy_key '/path/to/mykey.pem'\nend\n```\n\n## Recipes\n\n* `poise-git::default` – Install Git.\n\n## Attributes\n\n* `node['poise-git']['default_recipe']` – Recipe used by `poise_git` to install\n Git if not already available. *(default: poise-git)*\n* `node['poise-git']['provider']` – Default provider for `poise_git_client` resource\n instances. *(default: auto)*\n* `node['poise-git']['recipe'][*]` – All subkeys of `'recipe'` will be passed\n as properties to the `poise_git_client` resource before installation when using\n the `poise-git::default` recipe.\n\n## Resources\n\n### `poise_git`\n\nThe `poise_git` resource extends the core `git` resource, adding a `deploy_key`\nproperty to use SSH deploy keys automatically.\n\n```ruby\npoise_git '/srv/myapp' do\n repository 'git@github.com:example/myapp.git'\n deploy_key 'mysecretkey'\nend\n```\n\nThe `poise_git` resource supports all the same actions and properties as the\ncore `git` resource.\n\nThe `deploy_key` property can either be passed the absolute path to an existing\nSSH key file, or the raw SSH private key text.\n\n### `poise_git_client`\n\nThe `poise_git_client` resource installs Git.\n\n```ruby\npoise_git_client 'git'\n```\n\n#### Actions\n\n* `:install` – Install Git. *(default)*\n* `:uninstall` – Uninstall Git.\n\n#### Properties\n\n* `version` – Version of Git to install. If a partial version is given, use the\n latest available version matching that prefix. *(name property)*\n\n#### Provider Options\n\nThe `poise_git_client` resource uses provide options for per-provider configuration. See\n[the poise-service documentation](https://github.com/poise/poise-service#service-options)\nfor more information on using provider options.\n\n## Git Client Providers\n\n### `system`\n\nThe `system` provider installs Git using system packages. This is currently\nonly tested on platforms using `apt-get` and `yum` (Debian, Ubuntu, RHEL, CentOS\nAmazon Linux, and Fedora) and is a default provider on those platforms. It may\nwork on other platforms but is untested.\n\n```ruby\npoise_git_client 'git' do\n provider :system\nend\n```\n\n#### Options\n\n* `package_name` – Override auto-detection of the package name.\n* `package_upgrade` – Install using action `:upgrade`. *(default: false)*\n* `package_version` – Override auto-detection of the package version.\n\n### `dummy`\n\nThe `dummy` provider supports using the `poise_git_client` resource with ChefSpec\nor other testing frameworks to not actually install Git. It is used by default under\nChefSpec. It can also be used to manage the Git installation externally from\nthis cookbook.\n\n```ruby\npoise_git_client 'git' do\n provider :dummy\n options git_binary: '/path/to/git'\nend\n```\n\n#### Provider Options\n\n* `git_binary` – Path to the `git` executable. *(default: /git)*\n* `git_environment` – Hash of environment variables to use with this Git. *(default: {})*\n\n## Sponsors\n\nDevelopment sponsored by [SAP](https://www.sap.com/).\n\nThe Poise test server infrastructure is sponsored by [Rackspace](https://rackspace.com/).\n\n## License\n\nCopyright 2015-2017, Noah Kantrowitz\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","maintainer":"Noah Kantrowitz","maintainer_email":"noah@coderanger.net","license":"Apache 2.0","platforms":{},"dependencies":{"poise":"~> 2.6","poise-languages":"~> 2.1"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{},"source_url":"https://github.com/poise/poise-git","issues_url":"https://github.com/poise/poise-git/issues","chef_version":[["< 14",">= 12.1"]],"ohai_version":[]} \ No newline at end of file diff --git a/cookbooks/poise-git/recipes/default.rb b/cookbooks/poise-git/recipes/default.rb new file mode 100644 index 0000000..a884efe --- /dev/null +++ b/cookbooks/poise-git/recipes/default.rb @@ -0,0 +1,22 @@ +# +# Copyright 2017, Noah Kantrowitz +# +# 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. +# + +poise_git_client 'git' do + node['poise-git']['recipe'].each do |key, value| + # Skip nils, use false if you want to disable something. + send(key, value) unless value.nil? + end +end diff --git a/cookbooks/poise-ruby-build/CHANGELOG.md b/cookbooks/poise-ruby-build/CHANGELOG.md new file mode 100644 index 0000000..e4fbf98 --- /dev/null +++ b/cookbooks/poise-ruby-build/CHANGELOG.md @@ -0,0 +1,22 @@ +# Poise-Ruby-Build Changelog + +## v1.1.0 + +* Chef 13 support. +* Switch to `poise-git` and `poise-build-essential` rather than the traditional + cookbooks to ensure support for older Chef and clean up lingering bugs. + +## v1.0.2 + +* Fix a typo that prevented uninstalling `ruby_build` runtimes. +* Ensure bzip2 is installed as some minimal Linux images do not include it. + +## v1.0.1 + +* Install bundler in the same way as other `ruby_runtime` providers. +* New integration test harness. + +## v1.0.0 + +* Initial release! + diff --git a/cookbooks/poise-ruby-build/README.md b/cookbooks/poise-ruby-build/README.md new file mode 100644 index 0000000..05d13a1 --- /dev/null +++ b/cookbooks/poise-ruby-build/README.md @@ -0,0 +1,53 @@ +# Poise-Ruby-Build Cookbook + +[![Build Status](https://img.shields.io/travis/poise/poise-ruby-build.svg)](https://travis-ci.org/poise/poise-ruby-build) +[![Gem Version](https://img.shields.io/gem/v/poise-ruby-build.svg)](https://rubygems.org/gems/poise-ruby-build) +[![Cookbook Version](https://img.shields.io/cookbook/v/poise-ruby-build.svg)](https://supermarket.chef.io/cookbooks/poise-ruby-build) +[![Coverage](https://img.shields.io/codecov/c/github/poise/poise-ruby-build.svg)](https://codecov.io/github/poise/poise-ruby-build) +[![Gemnasium](https://img.shields.io/gemnasium/poise/poise-ruby-build.svg)](https://gemnasium.com/poise/poise-ruby-build) +[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) + +A [ruby-build](https://github.com/sstephenson/ruby-build) provider for the +[poise-ruby cookbook](https://github.com/poise/poise-ruby). + +## Provider + +The `ruby_build` provider uses [ruby-build](https://github.com/sstephenson/ruby-build) +to compile and install Ruby. + +```ruby +ruby_runtime 'myapp' do + provider :ruby_build + version '2.1' +end +``` + +### Options + +* `install_doc` – Install documentation with Ruby. *(default: false)* +* `install_repo` – Git URI to clone to install ruby-build. *(default: https://github.com/sstephenson/ruby-build.git)* +* `install_rev` – Git revision to clone to install ruby-build. *(default: master)* +* `prefix` – Base path for install ruby-build and rubies. *(default: /opt/ruby_build)* +* `version` – Override the Ruby version. + +## Sponsors + +Development sponsored by [Bloomberg](http://www.bloomberg.com/company/technology/). + +The Poise test server infrastructure is sponsored by [Rackspace](https://rackspace.com/). + +## License + +Copyright 2015-2017, Noah Kantrowitz + +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/poise-ruby-build/attributes/default.rb b/cookbooks/poise-ruby-build/attributes/default.rb new file mode 100644 index 0000000..1bf8521 --- /dev/null +++ b/cookbooks/poise-ruby-build/attributes/default.rb @@ -0,0 +1,17 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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. +# + +default['poise-ruby']['provider'] = 'ruby_build' diff --git a/cookbooks/poise-ruby-build/files/halite_gem/poise_ruby/ruby_build.rb b/cookbooks/poise-ruby-build/files/halite_gem/poise_ruby/ruby_build.rb new file mode 100644 index 0000000..342d461 --- /dev/null +++ b/cookbooks/poise-ruby-build/files/halite_gem/poise_ruby/ruby_build.rb @@ -0,0 +1,26 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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 PoiseRuby + # A plugin for poise-ruby to compile Ruby using ruby-build. + # + # @since 1.0.0 + module RubyBuild + autoload :Provider, 'poise_ruby/ruby_build/provider' + autoload :VERSION, 'poise_ruby/ruby_build/version' + end +end diff --git a/cookbooks/poise-ruby-build/files/halite_gem/poise_ruby/ruby_build/cheftie.rb b/cookbooks/poise-ruby-build/files/halite_gem/poise_ruby/ruby_build/cheftie.rb new file mode 100644 index 0000000..32fd6ca --- /dev/null +++ b/cookbooks/poise-ruby-build/files/halite_gem/poise_ruby/ruby_build/cheftie.rb @@ -0,0 +1,17 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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 'poise_ruby/ruby_build/provider' diff --git a/cookbooks/poise-ruby-build/files/halite_gem/poise_ruby/ruby_build/provider.rb b/cookbooks/poise-ruby-build/files/halite_gem/poise_ruby/ruby_build/provider.rb new file mode 100644 index 0000000..9cf45d6 --- /dev/null +++ b/cookbooks/poise-ruby-build/files/halite_gem/poise_ruby/ruby_build/provider.rb @@ -0,0 +1,219 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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/mixin/shell_out' + +require 'poise_ruby/ruby_providers/base' + + +module PoiseRuby + module RubyBuild + # Inversion provider for `ruby_runtime` to install via ruby-build. + # + # @since 1.0.0 + # @provides ruby_build + class Provider < PoiseRuby::RubyProviders::Base + include Chef::Mixin::ShellOut + provides(:ruby_build) + + # Add default options for ruby-build. + # + # @param node [Chef::Node] Node to load from. + # @param resource [Chef::Resource] Resource to load from. + # @return [Hash] + def self.default_inversion_options(node, resource) + super.merge({ + install_doc: false, + install_repo: 'https://github.com/sstephenson/ruby-build.git', + install_rev: 'master', + prefix: '/opt/ruby_build', + }) + end + + # Path to the compiled Ruby binary. + # + # @return [String] + def ruby_binary + ::File.join(options['prefix'], 'builds', new_resource.name, 'bin', 'ruby') + end + + # Find the full definition name to use with ruby-build. This is based on + # prefix matching from the `ruby-build --definitions` output. Only + # public because sigh scoping. + # + # @!visibility private + # @return [String] + def ruby_definition + @ruby_definition ||= begin + cmd = shell_out!([::File.join(options['prefix'], 'install', options['install_rev'], 'bin', 'ruby-build'), '--definitions']) + version_prefix = options['version'] + # Default for '', look for MRI 2.x. + version_prefix = '2' if version_prefix == '' + # Find the last line that starts with the target version. + cmd.stdout.split(/\n/).reverse.find {|line| line.start_with?(version_prefix) } || options['version'] + end + end + + private + + # Path to the version record file. Should contain the actual version of + # Ruby installed in this folder. + # + # @return [String] + def version_file + ::File.join(options['prefix'], 'builds', new_resource.name, 'VERSION') + end + + # Installs ruby-build and then uses that to install Ruby. + # + # @return [void] + def install_ruby + # We assume that if the version_file exists, ruby-build is already + # installed. Calling #ruby_definition will shell out to ruby-build. + if ::File.exists?(version_file) && IO.read(version_file) == ruby_definition + # All set, bail out. + return + end + + converge_by("Installing Ruby #{options['version'].empty? ? new_resource.name : options['version']} via ruby-build") do + notifying_block do + create_prefix_directory + create_install_directory + create_builds_directory + install_ruby_build + install_dependencies + # Possible failed install or a version change. Wipe the existing build. + # If we weren't going to rebuild, we would have bailed out already. + uninstall_ruby + end + # Second converge has ruby-build installed so using #ruby_definition + # is safe. + notifying_block do + build_ruby + create_version_file + end + end + end + + # Create the base prefix directory. + # + # @return [Chef::Resource::Directory] + def create_prefix_directory + directory options['prefix'] do + owner 'root' + group 'root' + mode '755' + end + end + + # Create the directory to hold ruby-build installations. + # + # @return [Chef::Resource::Directory] + def create_install_directory + directory ::File.join(options['prefix'], 'install') do + owner 'root' + group 'root' + mode '755' + end + end + + # Create the directory to hold compiled rubies. + # + # @return [Chef::Resource::Directory] + def create_builds_directory + directory ::File.join(options['prefix'], 'builds') do + owner 'root' + group 'root' + mode '755' + end + end + + # Clone ruby-build from GitHub or a similar git server. Will also install + # git via the `git` cookbook unless `no_dependencies` is set. + # + # @return [Chef::Resource::Git] + def install_ruby_build + poise_git ::File.join(options['prefix'], 'install', options['install_rev']) do + repository options['install_repo'] + revision options['install_rev'] + user 'root' + end + end + + # Install dependency packages needed to compile Ruby. A no-op if + # `no_dependencies` is set. + # + # @return [Chef::Resource::Package] + def install_dependencies + return if options['no_dependencies'] + poise_build_essential 'build_essential' + unless options['version'].start_with?('jruby') + pkgs = node.value_for_platform_family( + debian: %w{libreadline6-dev zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev libxml2-dev libxslt1-dev}, + rhel: %w{tar bzip2 readline-devel zlib-devel libffi-devel openssl-devel libxml2-devel libxslt-devel}, + suse: %w{zlib-devel libffi-devel sqlite3-devel libxml2-devel libxslt-devel}, + ) + package pkgs if pkgs + end + end + + + # Compile Ruby using ruby-build. + # + # @return [Chef::Resource::Execute] + def build_ruby + # Figure out the argument to disable docs + disable_docs = if options['install_doc'] + nil + elsif options['version'].start_with?('rbx') + nil # Doesn't support? + elsif options['version'].start_with?('ree') + '--no-dev-docs' + else + '--disable-install-doc' + end + + execute 'ruby-build install' do + command [::File.join(options['prefix'], 'install', options['install_rev'], 'bin', 'ruby-build'), ruby_definition, ::File.join(options['prefix'], 'builds', new_resource.name)] + user 'root' + environment 'RUBY_CONFIGURE_OPTS' => disable_docs if disable_docs + end + end + + # Write out the concrete version to the VERSION file. + # + # @return [Chef::Resource::File] + def create_version_file + file version_file do + owner 'root' + group 'root' + mode '644' + content ruby_definition + end + end + + # Delete the compiled Ruby, but leave ruby-build installed as it may be + # shared by other resources. + # + # @return [Chef::Resource::Directory] + def uninstall_ruby + directory ::File.join(options['prefix'], 'builds', new_resource.name) do + action :delete + end + end + end + end +end diff --git a/cookbooks/poise-ruby-build/files/halite_gem/poise_ruby/ruby_build/version.rb b/cookbooks/poise-ruby-build/files/halite_gem/poise_ruby/ruby_build/version.rb new file mode 100644 index 0000000..2b51c09 --- /dev/null +++ b/cookbooks/poise-ruby-build/files/halite_gem/poise_ruby/ruby_build/version.rb @@ -0,0 +1,22 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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 PoiseRuby + module RubyBuild + VERSION = '1.1.0' + end +end diff --git a/cookbooks/poise-ruby-build/libraries/default.rb b/cookbooks/poise-ruby-build/libraries/default.rb new file mode 100644 index 0000000..2788808 --- /dev/null +++ b/cookbooks/poise-ruby-build/libraries/default.rb @@ -0,0 +1,19 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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. +# + +raise 'Halite is not compatible with no_lazy_load false, please set no_lazy_load true in your Chef configuration file.' unless Chef::Config[:no_lazy_load] +$LOAD_PATH << File.expand_path('../../files/halite_gem', __FILE__) +require "poise_ruby/ruby_build/cheftie" diff --git a/cookbooks/poise-ruby-build/metadata.json b/cookbooks/poise-ruby-build/metadata.json new file mode 100644 index 0000000..49d9350 --- /dev/null +++ b/cookbooks/poise-ruby-build/metadata.json @@ -0,0 +1 @@ +{"name":"poise-ruby-build","version":"1.1.0","description":"A Chef cookbook for managing Ruby installations using ruby-build.","long_description":"# Poise-Ruby-Build Cookbook\n\n[![Build Status](https://img.shields.io/travis/poise/poise-ruby-build.svg)](https://travis-ci.org/poise/poise-ruby-build)\n[![Gem Version](https://img.shields.io/gem/v/poise-ruby-build.svg)](https://rubygems.org/gems/poise-ruby-build)\n[![Cookbook Version](https://img.shields.io/cookbook/v/poise-ruby-build.svg)](https://supermarket.chef.io/cookbooks/poise-ruby-build)\n[![Coverage](https://img.shields.io/codecov/c/github/poise/poise-ruby-build.svg)](https://codecov.io/github/poise/poise-ruby-build)\n[![Gemnasium](https://img.shields.io/gemnasium/poise/poise-ruby-build.svg)](https://gemnasium.com/poise/poise-ruby-build)\n[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)\n\nA [ruby-build](https://github.com/sstephenson/ruby-build) provider for the\n[poise-ruby cookbook](https://github.com/poise/poise-ruby).\n\n## Provider\n\nThe `ruby_build` provider uses [ruby-build](https://github.com/sstephenson/ruby-build)\nto compile and install Ruby.\n\n```ruby\nruby_runtime 'myapp' do\n provider :ruby_build\n version '2.1'\nend\n```\n\n### Options\n\n* `install_doc` – Install documentation with Ruby. *(default: false)*\n* `install_repo` – Git URI to clone to install ruby-build. *(default: https://github.com/sstephenson/ruby-build.git)*\n* `install_rev` – Git revision to clone to install ruby-build. *(default: master)*\n* `prefix` – Base path for install ruby-build and rubies. *(default: /opt/ruby_build)*\n* `version` – Override the Ruby version.\n\n## Sponsors\n\nDevelopment sponsored by [Bloomberg](http://www.bloomberg.com/company/technology/).\n\nThe Poise test server infrastructure is sponsored by [Rackspace](https://rackspace.com/).\n\n## License\n\nCopyright 2015-2017, Noah Kantrowitz\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","maintainer":"Noah Kantrowitz","maintainer_email":"noah@coderanger.net","license":"Apache 2.0","platforms":{},"dependencies":{"poise":"~> 2.0","poise-build-essential":"~> 1.0","poise-git":"~> 1.0","poise-ruby":"~> 2.1"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{},"source_url":"https://github.com/poise/poise-ruby-build","issues_url":"https://github.com/poise/poise-ruby-build/issues","chef_version":[["< 14",">= 12.1"]],"ohai_version":[]} \ No newline at end of file diff --git a/cookbooks/seven_zip/CHANGELOG.md b/cookbooks/seven_zip/CHANGELOG.md index 4270da1..0a24ae3 100644 --- a/cookbooks/seven_zip/CHANGELOG.md +++ b/cookbooks/seven_zip/CHANGELOG.md @@ -2,11 +2,28 @@ seven_zip Cookbook CHANGELOG ======================== This file is used to list changes made in each version of the seven_zip cookbook. +v2.0.2 +------ +- Add timeout to extract action on seven\_zip resource and configurable default\_extract_timeout attribute. + +v2.0.1 +------ +- [GH Issue 21 - NoMethodError: Undefined method or attribute `kernel' on `node'](https://github.com/daptiv/seven_zip/issues/21). + +v2.0.0 +------ +- [Upgrade to 7-Zip 15.14](https://github.com/daptiv/seven_zip/pull/9). +- [7-Zip now installed to the default MSI location by default](https://github.com/daptiv/seven_zip/pull/11). +- [7z.exe is located using the Windows registry unless the home attribute is explicitly set](https://github.com/daptiv/seven_zip/pull/10). +- [7-Zip is only added to the Windows PATH if the syspath attribute is set](https://github.com/daptiv/seven_zip/pull/11). +- [Installation idempotence check was fixed](https://github.com/daptiv/seven_zip/pull/14), package name was corrected. +- [TravisCI build added](https://github.com/daptiv/seven_zip/pull/12). +- [ServerSpec tests added](https://github.com/daptiv/seven_zip/pull/9) +- [Document Archive LRWP](https://github.com/daptiv/seven_zip/pull/6) v1.0.2 ------ -### Improvement -- **[COOK-3476](https://tickets.opscode.com/browse/COOK-3476)** - Upgrade to 7-zip 9.22 +- [COOK-3476 - Upgrade to 7-zip 9.22](https://tickets.opscode.com/browse/COOK-3476) 1.0.0 ----- diff --git a/cookbooks/seven_zip/CONTRIBUTING b/cookbooks/seven_zip/CONTRIBUTING deleted file mode 100644 index 89ac873..0000000 --- a/cookbooks/seven_zip/CONTRIBUTING +++ /dev/null @@ -1,29 +0,0 @@ -If you would like to contribute, please open a ticket in JIRA: - -* http://tickets.opscode.com - -Create the ticket in the COOK project and use the cookbook name as the -component. - -For all code contributions, we ask that contributors sign a -contributor license agreement (CLA). Instructions may be found here: - -* http://wiki.opscode.com/display/chef/How+to+Contribute - -When contributing changes to individual cookbooks, please do not -modify the version number in the metadata.rb. Also please do not -update the CHANGELOG.md for a new version. Not all changes to a -cookbook may be merged and released in the same versions. Opscode will -handle the version updates during the release process. You are welcome -to correct typos or otherwise make updates to documentation in the -README. - -If a contribution adds new platforms or platform versions, indicate -such in the body of the commit message(s), and update the relevant -COOK ticket. When writing commit messages, it is helpful for others if -you indicate the COOK ticket. For example: - - git commit -m '[COOK-1041] Updated pool resource to correctly delete.' - -In the ticket itself, it is also helpful if you include log output of -a successful Chef run, but this is not absolutely required. diff --git a/cookbooks/seven_zip/LICENSE b/cookbooks/seven_zip/LICENSE deleted file mode 100644 index 11069ed..0000000 --- a/cookbooks/seven_zip/LICENSE +++ /dev/null @@ -1,201 +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/seven_zip/README.md b/cookbooks/seven_zip/README.md index 6aba5ad..db2e6cf 100644 --- a/cookbooks/seven_zip/README.md +++ b/cookbooks/seven_zip/README.md @@ -1,40 +1,98 @@ -seven_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). +[![Cookbook Version](http://img.shields.io/cookbook/v/seven_zip.svg)](https://supermarket.chef.io/cookbooks/seven_zip) +[![Build status](https://ci.appveyor.com/api/projects/status/y1lsnlkd2b3q6gfd/branch/master?svg=true)](https://ci.appveyor.com/project/ChefWindowsCookbooks65871/seven-zip/branch/master) +# seven_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). This cookbook replaces the older [7-zip cookbook](https://github.com/sneal/7-zip). -Requirements ------------- -### Platform +# Requirements +## Platforms - Windows XP - Windows Vista -- Windows Server 2003 R2 - Windows 7 +- Windows 8, 8.1 +- Windows 10 +- Windows Server 2003 R2 - Windows Server 2008 (R1, R2) -- Windows 8 -- Windows Server 2012 +- Windows Server 2012 (R1, R2) -### Cookbooks +## Chef +- Chef >= 11.6 + +## Cookbooks - windows +# Attributes +## Optional + + + + + + + + + + + + + + + + + + + + + + + + + +
KeyTypeDescriptionDefault
['seven_zip']['home']String7-Zip installation directory.
['seven_zip']['syspath']BooleanIf true, adds 7-zip directory to system PATH environment variable.
['seven_zip']['default_extract_timeout']IntegerThe default timeout for an extract operation in seconds. This can be overridden by a resource attribute.600
-Attributes ----------- -- `node['seven_zip']['home']` - location to install 7-zip files to. default is `%SYSTEMDRIVE%\7-zip` +# Usage +## default +Add `seven_zip::default` to your run\_list which will download and install 7-zip for the current Windows platform. -Usage ------ -### default -Downloads and installs 7-zip to the location specified by `node['seven_zip']['home']`. Also ensures `node['seven_zip']['home']` is in the system path. +# Resource/Provider +## seven_zip_archive +Extracts a 7-zip compatible archive (iso, zip, 7z etc) to the specified destination directory. +#### Actions +- `:extract` - Extract a 7-zip compatible archive -License & Authors ------------------ -- Author:: Seth Chisamore () +#### Attribute Parameters +- `path` - Name attribute. The destination to extract to. +- `source` - The file path to the archive to extract. +- `overwrite` - Defaults to false. If true, the destination files will be overwritten. +- `checksum` - The archive file checksum. +- `timeout` - The extract action timeout in seconds, defaults to `node['seven_zip']['default_extract_timeout']`. + +#### Examples +Extract 7-zip source files to `C:\seven_zip_source`. + +```ruby +seven_zip_archive 'seven_zip_source' do + path 'C:\seven_zip_source' + source 'http://www.7-zip.org/a/7z1514-src.7z' + overwrite true + checksum '3713aed72728eae8f6649e4803eba0b3676785200c76df6269034c520df4bbd5' + timeout 30 +end +``` + +# Recipes +## default + +Installs 7-zip and adds it to your system PATH. + +# License & Authors +- Author:: Seth Chisamore () +- Author:: Shawn Neal () ```text -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/seven_zip/attributes/default.rb b/cookbooks/seven_zip/attributes/default.rb index 31a36fa..9c6bf77 100644 --- a/cookbooks/seven_zip/attributes/default.rb +++ b/cookbooks/seven_zip/attributes/default.rb @@ -1,9 +1,9 @@ # -# Author:: Seth Chisamore () +# Author:: Seth Chisamore () # Cookbook Name:: seven_zip # Attribute:: default # -# Copyright:: Copyright (c) 2011 Opscode, Inc. +# Copyright:: Copyright (c) 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. @@ -18,14 +18,14 @@ # limitations under the License. # -if kernel['machine'] =~ /x86_64/ - default['seven_zip']['url'] = "http://www.7-zip.org/a/7z920-x64.msi" - default['seven_zip']['checksum'] = "62df458bc521001cd9a947643a84810ecbaa5a16b5c8e87d80df8e34c4a16fe2" - default['seven_zip']['package_name'] = "7z920-x64.msi" +if node['kernel']['machine'] == 'x86_64' + default['seven_zip']['url'] = 'http://www.7-zip.org/a/7z1514-x64.msi' + default['seven_zip']['checksum'] = 'cefe1a9092d8a6be68468c33910d6206b40e934fb63cab686c5cccf369fbf712' + default['seven_zip']['package_name'] = '7-Zip 15.14 (x64 edition)' else - default['seven_zip']['url'] = "http://www.7-zip.org/a/7z920.msi" - default['seven_zip']['checksum'] = "fe4807b4698ec89f82de7d85d32deaa4c772fc871537e31fb0fccf4473455cb8" - default['seven_zip']['package_name'] = "7z920.msi" + default['seven_zip']['url'] = 'http://www.7-zip.org/a/7z1514.msi' + default['seven_zip']['checksum'] = 'eaf58e29941d8ca95045946949d75d9b5455fac167df979a7f8e4a6bf2d39680' + default['seven_zip']['package_name'] = '7-Zip 15.14' end -default['seven_zip']['home'] = "#{ENV['SYSTEMDRIVE']}\\7-zip" +default['seven_zip']['default_extract_timeout'] = 600 diff --git a/cookbooks/seven_zip/libraries/matchers.rb b/cookbooks/seven_zip/libraries/matchers.rb new file mode 100644 index 0000000..765fa19 --- /dev/null +++ b/cookbooks/seven_zip/libraries/matchers.rb @@ -0,0 +1,33 @@ +# +# Author:: Shawn Neal () +# Cookbook Name:: visualstudio +# +# Copyright 2015, Shawn Neal +# +# 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 defined?(ChefSpec) + chefspec_version = Gem.loaded_specs['chefspec'].version + define_method = if chefspec_version < Gem::Version.new('4.1.0') + ChefSpec::Runner.method(:define_runner_method) + else + ChefSpec.method(:define_matcher) + end + + define_method.call :seven_zip_archive + + def extract_seven_zip_archive(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:seven_zip_archive, :extract, resource_name) + end +end diff --git a/cookbooks/seven_zip/metadata.json b/cookbooks/seven_zip/metadata.json index 5540f6a..fd153ed 100644 --- a/cookbooks/seven_zip/metadata.json +++ b/cookbooks/seven_zip/metadata.json @@ -1,41 +1 @@ -{ - "name": "seven_zip", - "description": "Installs/Configures the 7-zip file archiver", - "long_description": "seven_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['seven_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['seven_zip']['home']`. Also ensures `node['seven_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": { - - }, - "version": "1.0.4", - "source_url": "", - "issues_url": "" -} +{"name":"seven_zip","version":"2.0.2","description":"Installs/Configures the 7-zip file archiver","long_description":"[![Cookbook Version](http://img.shields.io/cookbook/v/seven_zip.svg)](https://supermarket.chef.io/cookbooks/seven_zip)\n[![Build status](https://ci.appveyor.com/api/projects/status/y1lsnlkd2b3q6gfd/branch/master?svg=true)](https://ci.appveyor.com/project/ChefWindowsCookbooks65871/seven-zip/branch/master)\n\n# seven_zip Cookbook\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). This cookbook replaces the older [7-zip cookbook](https://github.com/sneal/7-zip).\n\n# Requirements\n## Platforms\n- Windows XP\n- Windows Vista\n- Windows 7\n- Windows 8, 8.1\n- Windows 10\n- Windows Server 2003 R2\n- Windows Server 2008 (R1, R2)\n- Windows Server 2012 (R1, R2)\n\n## Chef\n- Chef >= 11.6\n\n## Cookbooks\n- windows\n\n# Attributes\n## Optional\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
KeyTypeDescriptionDefault
['seven_zip']['home']String7-Zip installation directory.
['seven_zip']['syspath']BooleanIf true, adds 7-zip directory to system PATH environment variable.
['seven_zip']['default_extract_timeout']IntegerThe default timeout for an extract operation in seconds. This can be overridden by a resource attribute.600
\n\n# Usage\n## default\n\nAdd `seven_zip::default` to your run\\_list which will download and install 7-zip for the current Windows platform. \n\n# Resource/Provider\n## seven_zip_archive\nExtracts a 7-zip compatible archive (iso, zip, 7z etc) to the specified destination directory.\n\n#### Actions\n- `:extract` - Extract a 7-zip compatible archive\n\n#### Attribute Parameters\n- `path` - Name attribute. The destination to extract to.\n- `source` - The file path to the archive to extract.\n- `overwrite` - Defaults to false. If true, the destination files will be overwritten.\n- `checksum` - The archive file checksum.\n- `timeout` - The extract action timeout in seconds, defaults to `node['seven_zip']['default_extract_timeout']`.\n\n#### Examples\nExtract 7-zip source files to `C:\\seven_zip_source`.\n\n```ruby\nseven_zip_archive 'seven_zip_source' do\n path 'C:\\seven_zip_source'\n source 'http://www.7-zip.org/a/7z1514-src.7z'\n overwrite true\n checksum '3713aed72728eae8f6649e4803eba0b3676785200c76df6269034c520df4bbd5'\n timeout 30\nend\n```\n\n# Recipes\n## default\n\nInstalls 7-zip and adds it to your system PATH.\n\n# License & Authors\n- Author:: Seth Chisamore ()\n- Author:: Shawn Neal ()\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":"Shawn Neal","maintainer_email":"sneal@sneal.net","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/seven_zip/metadata.rb b/cookbooks/seven_zip/metadata.rb deleted file mode 100644 index 2c5305d..0000000 --- a/cookbooks/seven_zip/metadata.rb +++ /dev/null @@ -1,10 +0,0 @@ -name "seven_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.4" -supports "windows" - -depends "windows", ">= 1.2.2" diff --git a/cookbooks/seven_zip/providers/archive.rb b/cookbooks/seven_zip/providers/archive.rb index 2b5653c..ea67fde 100644 --- a/cookbooks/seven_zip/providers/archive.rb +++ b/cookbooks/seven_zip/providers/archive.rb @@ -1,5 +1,5 @@ # -# Author:: Shawn Neal () +# Author:: Shawn Neal () # Cookbook Name:: seven_zip # Provider:: archive # @@ -28,21 +28,41 @@ def whyrun_supported? true end +use_inline_resources + action :extract do converge_by("Extract #{@new_resource.source} => #{@new_resource.path} (overwrite=#{@new_resource.overwrite})") do - FileUtils.mkdir_p(@new_resource.path) unless Dir.exists?(@new_resource.path) + FileUtils.mkdir_p(@new_resource.path) unless Dir.exist?(@new_resource.path) local_source = cached_file(@new_resource.source, @new_resource.checksum) - cmd = "#{seven_zip_exe} x" - cmd << " -y" if @new_resource.overwrite - cmd << " -o#{win_friendly_path(@new_resource.path)}" - cmd << " #{local_source}" + cmd = "\"#{seven_zip_exe}\" x" + cmd << ' -y' if @new_resource.overwrite + cmd << " -o\"#{win_friendly_path(@new_resource.path)}\"" + cmd << " \"#{local_source}\"" Chef::Log.debug(cmd) - shell_out!(cmd) + shell_out!(cmd, timeout: extract_timeout) end end - -def seven_zip_exe() - Chef::Log.debug("seven zip home: #{node['seven_zip']['home']}") - win_friendly_path(::File.join(node['seven_zip']['home'], '7z.exe')) +def seven_zip_exe + path = if node['seven_zip']['home'] + node['seven_zip']['home'] + else + seven_zip_exe_from_registry + end + Chef::Log.debug("Using 7-zip home: #{path}") + win_friendly_path(::File.join(path, '7z.exe')) +end + +def seven_zip_exe_from_registry + require 'win32/registry' + # Read path from recommended Windows App Paths registry location + # docs: https://msdn.microsoft.com/en-us/library/windows/desktop/ee872121 + ::Win32::Registry::HKEY_LOCAL_MACHINE.open( + 'SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\7zFM.exe', + ::Win32::Registry::KEY_READ + ).read_s('Path') +end + +def extract_timeout + @new_resource.timeout || node['seven_zip']['default_extract_timeout'] end diff --git a/cookbooks/seven_zip/recipes/default.rb b/cookbooks/seven_zip/recipes/default.rb index 299f556..c8900ad 100644 --- a/cookbooks/seven_zip/recipes/default.rb +++ b/cookbooks/seven_zip/recipes/default.rb @@ -1,9 +1,9 @@ # -# Author:: Seth Chisamore () +# Author:: Seth Chisamore () # Cookbook Name:: seven_zip # 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. @@ -21,11 +21,21 @@ windows_package node['seven_zip']['package_name'] do source node['seven_zip']['url'] checksum node['seven_zip']['checksum'] - options "INSTALLDIR=\"#{node['seven_zip']['home']}\"" + options "INSTALLDIR=\"#{node['seven_zip']['home']}\"" if node['seven_zip']['home'] action :install end # update path -windows_path "#{node['seven_zip']['home']}" do +windows_path 'seven_zip' do + path lazy { + if node['seven_zip']['home'] + node['seven_zip']['home'] + else + ::Win32::Registry::HKEY_LOCAL_MACHINE.open( + 'SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\7zFM.exe', + ::Win32::Registry::KEY_READ + ).read_s('Path') + end + } action :add -end +end if node['seven_zip']['syspath'] diff --git a/cookbooks/seven_zip/resources/archive.rb b/cookbooks/seven_zip/resources/archive.rb index cc36eed..0a6eeb3 100644 --- a/cookbooks/seven_zip/resources/archive.rb +++ b/cookbooks/seven_zip/resources/archive.rb @@ -1,5 +1,5 @@ # -# Author:: Shawn Neal () +# Author:: Shawn Neal () # Cookbook Name:: seven_zip # Resource:: archive # @@ -22,7 +22,8 @@ default_action :extract actions :extract -attribute :path, :kind_of => String, :name_attribute => true -attribute :source, :kind_of => String -attribute :overwrite, :kind_of => [ TrueClass, FalseClass ], :default => false -attribute :checksum, :kind_of => String +attribute :path, kind_of: String, name_attribute: true +attribute :source, kind_of: String +attribute :overwrite, kind_of: [TrueClass, FalseClass], default: false +attribute :checksum, kind_of: String +attribute :timeout, kind_of: Integer diff --git a/nodes/dev.kosmos.org.json b/nodes/dev.kosmos.org.json index 448a882..8a1f561 100644 --- a/nodes/dev.kosmos.org.json +++ b/nodes/dev.kosmos.org.json @@ -1,6 +1,7 @@ { "run_list": [ "kosmos-base", + "kosmos-redis", "sockethub", "sockethub::proxy", "kosmos-wordpress", diff --git a/nodes/staging.kosmos.org.json b/nodes/staging.kosmos.org.json new file mode 100644 index 0000000..8e90f77 --- /dev/null +++ b/nodes/staging.kosmos.org.json @@ -0,0 +1,18 @@ +{ + "run_list": [ + "kosmos-base", + "kosmos-redis", + "kosmos-mastodon", + "kosmos-mastodon::nginx" + ], + "normal": { + "postgresql": { + "password": { + "postgres": "thiscrapaintsafecuznocrypto" + } + } + }, + "automatic": { + "ipaddress": "staging.kosmos.org" + } +} diff --git a/site-cookbooks/kosmos-base/recipes/default.rb b/site-cookbooks/kosmos-base/recipes/default.rb index d5a69f9..b6d7484 100644 --- a/site-cookbooks/kosmos-base/recipes/default.rb +++ b/site-cookbooks/kosmos-base/recipes/default.rb @@ -17,9 +17,6 @@ package 'mailutils' node.override['unattended-upgrades']['admin_email'] = 'ops@5apps.com' include_recipe 'unattended-upgrades' -package 'ruby2.1' -package 'ruby2.1-dev' - package 'mosh' # Searches data bag "users" for groups attribute "sysadmin". diff --git a/site-cookbooks/kosmos-mastodon/metadata.rb b/site-cookbooks/kosmos-mastodon/metadata.rb index 6f19998..40bf21c 100644 --- a/site-cookbooks/kosmos-mastodon/metadata.rb +++ b/site-cookbooks/kosmos-mastodon/metadata.rb @@ -8,7 +8,8 @@ version '0.1.0' depends "kosmos-nginx" depends "kosmos-nodejs" -depends "kosmos-ruby" +depends "kosmos-redis" +depends "poise-ruby-build" depends "application_ruby" depends "application_javascript" depends "postgresql" diff --git a/site-cookbooks/kosmos-mastodon/recipes/default.rb b/site-cookbooks/kosmos-mastodon/recipes/default.rb index 1bee581..40b4eef 100644 --- a/site-cookbooks/kosmos-mastodon/recipes/default.rb +++ b/site-cookbooks/kosmos-mastodon/recipes/default.rb @@ -8,7 +8,7 @@ # include_recipe "kosmos-nodejs" -include_recipe "kosmos-ruby" +# include_recipe "kosmos-ruby" node.override['postgresql']['enable_pgdg_apt'] = false include_recipe "postgresql::server" include_recipe "postgresql::ruby" @@ -52,7 +52,7 @@ application mastodon_path do user "mastodon" group "mastodon" repository "https://github.com/67P/mastodon.git" - revision "kosmos" + revision "staging" end mastodon_credentials = Chef::EncryptedDataBagItem.load('credentials', 'mastodon') @@ -83,6 +83,11 @@ application mastodon_path do recursive true end + ruby_runtime do + provider :ruby_build + version '2.4.1' + end + bundle_install do user "mastodon" deployment true @@ -109,9 +114,10 @@ application mastodon_path do source "mastodon-web.systemd.service.erb" variables user: user, app_dir: mastodon_path, - port: node["kosmos-mastodon"]["puma_port"] + port: node["kosmos-mastodon"]["puma_port"], + bundle_path: '/opt/ruby_build/builds/opt/mastodon/bin/bundle' notifies :run, "execute[systemctl daemon-reload]", :delayed - notifies :restart, "service[mastodon-web]", :delayed + # notifies :restart, "service[mastodon-web]", :delayed end service "mastodon-web" do @@ -123,9 +129,10 @@ application mastodon_path do template "/lib/systemd/system/mastodon-sidekiq.service" do source "mastodon-sidekiq.systemd.service.erb" variables user: user, - app_dir: mastodon_path + app_dir: mastodon_path, + bundle_path: '/opt/ruby_build/builds/opt/mastodon/bin/bundle' notifies :run, "execute[systemctl daemon-reload]", :delayed - notifies :restart, "service[mastodon-sidekiq]", :delayed + # notifies :restart, "service[mastodon-sidekiq]", :delayed end service "mastodon-sidekiq" do @@ -140,7 +147,7 @@ application mastodon_path do app_dir: mastodon_path, port: node["kosmos-mastodon"]["streaming_port"] notifies :run, "execute[systemctl daemon-reload]", :delayed - notifies :restart, "service[mastodon-streaming]", :delayed + # notifies :restart, "service[mastodon-streaming]", :delayed end service "mastodon-streaming" do @@ -148,10 +155,10 @@ application mastodon_path do end end -unless node.chef_environment == "development" - # Backup the database to S3 - node.override["backup"]["postgresql"]["host"] = "localhost" - node.override["backup"]["postgresql"]["username"] = "postgres" - node.override["backup"]["postgresql"]["password"] = node['postgresql']['password']['postgres'] - include_recipe "backup" -end +# unless node.chef_environment == "development" +# # Backup the database to S3 +# node.override["backup"]["postgresql"]["host"] = "localhost" +# node.override["backup"]["postgresql"]["username"] = "postgres" +# node.override["backup"]["postgresql"]["password"] = node['postgresql']['password']['postgres'] +# include_recipe "backup" +# end diff --git a/site-cookbooks/kosmos-mastodon/templates/default/mastodon-sidekiq.systemd.service.erb b/site-cookbooks/kosmos-mastodon/templates/default/mastodon-sidekiq.systemd.service.erb index 86a3759..8346649 100644 --- a/site-cookbooks/kosmos-mastodon/templates/default/mastodon-sidekiq.systemd.service.erb +++ b/site-cookbooks/kosmos-mastodon/templates/default/mastodon-sidekiq.systemd.service.erb @@ -9,7 +9,7 @@ User=<%= @user %> WorkingDirectory=<%= @app_dir %> Environment="RAILS_ENV=production" Environment="DB_POOL=5" -ExecStart=/usr/local/bin/bundle exec sidekiq -c 5 -q default -q mailers -q pull -q push +ExecStart=<%= @bundle_path %> exec sidekiq -c 5 -q default -q mailers -q pull -q push TimeoutSec=15 Restart=always diff --git a/site-cookbooks/kosmos-mastodon/templates/default/mastodon-web.systemd.service.erb b/site-cookbooks/kosmos-mastodon/templates/default/mastodon-web.systemd.service.erb index a3464dd..5e8e5e9 100644 --- a/site-cookbooks/kosmos-mastodon/templates/default/mastodon-web.systemd.service.erb +++ b/site-cookbooks/kosmos-mastodon/templates/default/mastodon-web.systemd.service.erb @@ -12,10 +12,10 @@ PIDFile=<%= @app_dir %>/tmp/puma.pid WorkingDirectory=<%= @app_dir %> Environment="RAILS_ENV=production" Environment="PORT=3000" -ExecStart=/usr/local/bin/bundle exec puma -C config/puma.rb --pidfile <%= @app_dir %>/tmp/puma.pid -ExecStop=/usr/local/bin/bundle exec puma -C config/puma.rb --pidfile <%= @app_dir %>/tmp/puma.pid stop -ExecReload=/usr/local/bin/bundle exec pumactl -F config/puma.rb --pidfile <%= @app_dir %>/tmp/puma.pid phased-restart -ExecRestart=/usr/local/bin/bundle exec pumactl -F config/puma.rb --pidfile <%= @app_dir %>/tmp/puma.pid restart +ExecStart=<%= @bundle_path %> exec puma -C config/puma.rb --pidfile <%= @app_dir %>/tmp/puma.pid +ExecStop=<%= @bundle_path %> exec puma -C config/puma.rb --pidfile <%= @app_dir %>/tmp/puma.pid stop +ExecReload=<%= @bundle_path %> exec pumactl -F config/puma.rb --pidfile <%= @app_dir %>/tmp/puma.pid phased-restart +ExecRestart=<%= @bundle_path %> exec pumactl -F config/puma.rb --pidfile <%= @app_dir %>/tmp/puma.pid restart TimeoutSec=15 Restart=always diff --git a/site-cookbooks/kosmos-ruby/CHANGELOG.md b/site-cookbooks/kosmos-ruby/CHANGELOG.md deleted file mode 100644 index e0c9479..0000000 --- a/site-cookbooks/kosmos-ruby/CHANGELOG.md +++ /dev/null @@ -1,11 +0,0 @@ -# kosmos-ruby CHANGELOG - -This file is used to list changes made in each version of the kosmos-ruby cookbook. - -## 0.1.0 -- [your_name] - Initial release of kosmos-ruby - -- - - -Check the [Markdown Syntax Guide](http://daringfireball.net/projects/markdown/syntax) for help with Markdown. - -The [Github Flavored Markdown page](http://github.github.com/github-flavored-markdown/) describes the differences between markdown on github and standard markdown. diff --git a/site-cookbooks/kosmos-ruby/README.md b/site-cookbooks/kosmos-ruby/README.md deleted file mode 100644 index 2daaba1..0000000 --- a/site-cookbooks/kosmos-ruby/README.md +++ /dev/null @@ -1,80 +0,0 @@ -# kosmos-ruby Cookbook - -TODO: Enter the cookbook description here. - -e.g. -This cookbook makes your favorite breakfast sandwich. - -## Requirements - -TODO: List your cookbook requirements. Be sure to include any requirements this cookbook has on platforms, libraries, other cookbooks, packages, operating systems, etc. - -e.g. -### Platforms - -- SandwichOS - -### Chef - -- Chef 12.0 or later - -### Cookbooks - -- `toaster` - kosmos-ruby needs toaster to brown your bagel. - -## Attributes - -TODO: List your cookbook attributes here. - -e.g. -### kosmos-ruby::default - - - - - - - - - - - - - - -
KeyTypeDescriptionDefault
['kosmos-ruby']['bacon']Booleanwhether to include bacontrue
- -## Usage - -### kosmos-ruby::default - -TODO: Write usage instructions for each cookbook. - -e.g. -Just include `kosmos-ruby` in your node's `run_list`: - -```json -{ - "name":"my_node", - "run_list": [ - "recipe[kosmos-ruby]" - ] -} -``` - -## Contributing - -TODO: (optional) If this is a public cookbook, detail the process for contributing. If this is a private cookbook, remove this section. - -e.g. -1. Fork the repository on Github -2. Create a named feature branch (like `add_component_x`) -3. Write your change -4. Write tests for your change (if applicable) -5. Run the tests, ensuring they all pass -6. Submit a Pull Request using Github - -## License and Authors - -Authors: TODO: List authors - diff --git a/site-cookbooks/kosmos-ruby/attributes/default.rb b/site-cookbooks/kosmos-ruby/attributes/default.rb deleted file mode 100644 index 2f7703f..0000000 --- a/site-cookbooks/kosmos-ruby/attributes/default.rb +++ /dev/null @@ -1 +0,0 @@ -default['kosmos-ruby']['version'] = '2.3' diff --git a/site-cookbooks/kosmos-ruby/metadata.rb b/site-cookbooks/kosmos-ruby/metadata.rb deleted file mode 100644 index 2459b56..0000000 --- a/site-cookbooks/kosmos-ruby/metadata.rb +++ /dev/null @@ -1,7 +0,0 @@ -name 'kosmos-ruby' -maintainer 'Kosmos' -maintainer_email 'mail@kosmos.org' -license 'All rights reserved' -description 'Installs/Configures kosmos-ruby' -long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -version '0.1.0' diff --git a/site-cookbooks/kosmos-ruby/recipes/default.rb b/site-cookbooks/kosmos-ruby/recipes/default.rb deleted file mode 100644 index 96a1c9a..0000000 --- a/site-cookbooks/kosmos-ruby/recipes/default.rb +++ /dev/null @@ -1,54 +0,0 @@ -# -# Cookbook Name:: kosmos-ruby -# Recipe:: default -# -# Copyright 2017, Kosmos -# -# All rights reserved - Do Not Redistribute -# - -package_name = "ruby#{node['kosmos-ruby']['version']}" - -apt_repository 'brightbox_ruby' do - uri 'http://ppa.launchpad.net/brightbox/ruby-ng/ubuntu' - distribution node['lsb']['codename'] - components ['main'] - keyserver 'keyserver.ubuntu.com' - key '80F70E11F0F0D5F10CB20E62F5DA5F09C3173AA6' -end - -packages = [ - "ruby#{node['kosmos-ruby']['version']}", - "ruby#{node['kosmos-ruby']['version']}-dev", - "build-essential", - "libssl-dev", - "zlib1g-dev" -] - -apt_package packages do - action :install -end - -apt_package 'ruby-switch' do - action :install - notifies :run, 'execute[set default ruby]', :immediately -end - -execute 'set default ruby' do - command "ruby-switch --set #{package_name}" - action :nothing - notifies :reload, 'ohai[reload]', :immediately -end - -ohai 'reload' do - action :nothing -end - -execute 'update rubygems' do - command 'gem update --system 2.6.8' - not_if "gem --version | grep ^2.6.8$" -end - -gem_package "bundler" do - version "1.13.2" -end From 08529c3344c99e974620f8c33f6c5637c72bfc27 Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Mon, 17 Apr 2017 11:42:05 +0200 Subject: [PATCH 16/83] Update nodejs --- site-cookbooks/kosmos-nodejs/recipes/default.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/site-cookbooks/kosmos-nodejs/recipes/default.rb b/site-cookbooks/kosmos-nodejs/recipes/default.rb index 3630bd6..993b455 100644 --- a/site-cookbooks/kosmos-nodejs/recipes/default.rb +++ b/site-cookbooks/kosmos-nodejs/recipes/default.rb @@ -7,6 +7,6 @@ # All rights reserved - Do Not Redistribute # -node.override['nodejs']['version'] = '6.9.4' -node.override['nodejs']['source']['checksum'] = 'c51d7c61db40455d57428abcadc7eb0f0a08a8878cb1d8ea3c1e211c54532c35' +node.override['nodejs']['version'] = '6.10.2' +node.override['nodejs']['source']['checksum'] = '80aa11333da99813973a99646e2113c6be5b63f665c0731ed14ecb94cbe846b6' include_recipe 'nodejs::nodejs_from_source' From 521f48a21ec7f8ed7c9f199bfc9b02f671362e30 Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Mon, 17 Apr 2017 11:47:00 +0200 Subject: [PATCH 17/83] Add docker config for Vagrant --- Vagrantfile | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/Vagrantfile b/Vagrantfile index 8bd5b03..d73b11d 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -15,11 +15,18 @@ Vagrant.configure(2) do |config| config.vm.box = "bento/ubuntu-15.04" - config.vm.provider "virtualbox" do |vb| + config.vm.provider :virtualbox do |vb| # Customize the amount of memory on the VM: vb.memory = "1024" end + config.vm.provider :docker do |d, override| + d.image = "nishidayuya/docker-vagrant-ubuntu:xenial" + d.has_ssh = true + override.vm.box = nil + override.ssh.port = 22 + end + # Disable automatic box update checking. If you disable this, then # boxes will only be checked for updates when the user runs # `vagrant box outdated`. This is not recommended. @@ -75,13 +82,19 @@ Vagrant.configure(2) do |config| # sudo apt-get install -y apache2 # SHELL + # Install latest Chef via Omnibus + # Needs `vagrant plugin install vagrant-omnibus` + if Vagrant.has_plugin?("vagrant-omnibus") + config.omnibus.chef_version = "12.19.36" + end + config.vm.provision :chef_zero do |chef| - chef.cookbooks_path = ['./cookbooks', './site-cookbooks'] - chef.data_bags_path = './data_bags' - chef.roles_path = './roles' + chef.cookbooks_path = ['cookbooks', 'site-cookbooks'] + chef.data_bags_path = 'data_bags' + chef.roles_path = 'roles' chef.node_name = "vagrant-node" - chef.nodes_path = './nodes' - chef.environments_path = './environments' + chef.nodes_path = 'nodes' + chef.environments_path = 'environments' chef.encrypted_data_bag_secret_key_path = '.chef/encrypted_data_bag_secret' chef.environment = 'development' # chef.add_recipe 'kosmos-wordpress' From 0cf22f7f71fe2df674560a3494e23fee50cdbd4b Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Mon, 17 Apr 2017 16:12:06 +0200 Subject: [PATCH 18/83] Use server name from attribute everywhere --- site-cookbooks/kosmos-mastodon/recipes/default.rb | 4 ++-- site-cookbooks/kosmos-mastodon/recipes/nginx.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/site-cookbooks/kosmos-mastodon/recipes/default.rb b/site-cookbooks/kosmos-mastodon/recipes/default.rb index 40b4eef..9e8e9bf 100644 --- a/site-cookbooks/kosmos-mastodon/recipes/default.rb +++ b/site-cookbooks/kosmos-mastodon/recipes/default.rb @@ -64,13 +64,13 @@ application mastodon_path do group "mastodon" variables redis_db: 1, redis_actioncable_db: 2, - domain: "kosmos.social", + domain: node["kosmos-mastodon"]["server_name"], paperclip_secret: mastodon_credentials['paperclip_secret'], secret_key_base: mastodon_credentials['secret_key_base'], otp_secret: mastodon_credentials['otp_secret'], smtp_login: mastodon_credentials['smtp_user_name'], smtp_password: mastodon_credentials['smtp_password'], - smtp_from_address: "mail@kosmos.social", + smtp_from_address: "mail@#{node["kosmos-mastodon"]["server_name"]}", s3_bucket: "kosmos-social", aws_access_key_id: mastodon_credentials['aws_access_key_id'], aws_secret_access_key: mastodon_credentials['aws_secret_access_key'], diff --git a/site-cookbooks/kosmos-mastodon/recipes/nginx.rb b/site-cookbooks/kosmos-mastodon/recipes/nginx.rb index 8f314a6..c7db150 100644 --- a/site-cookbooks/kosmos-mastodon/recipes/nginx.rb +++ b/site-cookbooks/kosmos-mastodon/recipes/nginx.rb @@ -38,7 +38,7 @@ end unless node.chef_environment == "development" include_recipe "kosmos-base::letsencrypt" - execute "letsencrypt cert for kosmos.social" do + execute "letsencrypt cert for #{server_name}" do command "./certbot-auto certonly --webroot --agree-tos --email ops@5apps.com --webroot-path /var/www/mastodon -d #{server_name} -n" cwd "/usr/local/certbot" not_if { File.exist? "/etc/letsencrypt/live/#{server_name}/fullchain.pem" } From d090dc08c998e876f304362e2bb9c1b11f5c0555 Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Mon, 17 Apr 2017 16:12:24 +0200 Subject: [PATCH 19/83] Add server name for staging node --- nodes/staging.kosmos.org.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nodes/staging.kosmos.org.json b/nodes/staging.kosmos.org.json index 8e90f77..f0670e9 100644 --- a/nodes/staging.kosmos.org.json +++ b/nodes/staging.kosmos.org.json @@ -10,6 +10,9 @@ "password": { "postgres": "thiscrapaintsafecuznocrypto" } + }, + "kosmos-mastodon": { + "server_name": "staging.kosmos.social" } }, "automatic": { From 764746a00936652fd14de5b4c360e40b243539a4 Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Mon, 17 Apr 2017 16:15:41 +0200 Subject: [PATCH 20/83] Remove obsolete commented code --- site-cookbooks/kosmos-mastodon/recipes/default.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/site-cookbooks/kosmos-mastodon/recipes/default.rb b/site-cookbooks/kosmos-mastodon/recipes/default.rb index 9e8e9bf..e2fa7ca 100644 --- a/site-cookbooks/kosmos-mastodon/recipes/default.rb +++ b/site-cookbooks/kosmos-mastodon/recipes/default.rb @@ -8,7 +8,6 @@ # include_recipe "kosmos-nodejs" -# include_recipe "kosmos-ruby" node.override['postgresql']['enable_pgdg_apt'] = false include_recipe "postgresql::server" include_recipe "postgresql::ruby" From fe44b29b62362f54ab94bc6c5e681159416f654e Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Mon, 17 Apr 2017 16:52:59 +0200 Subject: [PATCH 21/83] Use kosmos branch for Mastodon --- site-cookbooks/kosmos-mastodon/recipes/default.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site-cookbooks/kosmos-mastodon/recipes/default.rb b/site-cookbooks/kosmos-mastodon/recipes/default.rb index e2fa7ca..3d301d1 100644 --- a/site-cookbooks/kosmos-mastodon/recipes/default.rb +++ b/site-cookbooks/kosmos-mastodon/recipes/default.rb @@ -51,7 +51,7 @@ application mastodon_path do user "mastodon" group "mastodon" repository "https://github.com/67P/mastodon.git" - revision "staging" + revision "kosmos" end mastodon_credentials = Chef::EncryptedDataBagItem.load('credentials', 'mastodon') From ead7db5eaf6aa04cd2c19697bf1bb03b3185226e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 21 Apr 2017 12:53:06 +0200 Subject: [PATCH 22/83] Only do backups when not in development environment --- site-cookbooks/kosmos-redis/recipes/default.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/site-cookbooks/kosmos-redis/recipes/default.rb b/site-cookbooks/kosmos-redis/recipes/default.rb index 8c6dd06..53587c8 100644 --- a/site-cookbooks/kosmos-redis/recipes/default.rb +++ b/site-cookbooks/kosmos-redis/recipes/default.rb @@ -10,5 +10,8 @@ node.override['redis']['unixsocket'] = '' include_recipe 'redis::server' -node.override["backup"]["redis"]["databases"] = ["dump"] -include_recipe "backup" +unless node.chef_environment == "development" + # Backup the database to S3 + node.override["backup"]["redis"]["databases"] = ["dump"] + include_recipe "backup" +end From e98b887665ba75ef73bda543d9bea40e17667b7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 21 Apr 2017 12:53:37 +0200 Subject: [PATCH 23/83] Add missing dependency on mysql, only install mysql client when needed --- site-cookbooks/backup/metadata.rb | 1 + site-cookbooks/backup/recipes/default.rb | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/site-cookbooks/backup/metadata.rb b/site-cookbooks/backup/metadata.rb index 957763d..5cd3ae7 100644 --- a/site-cookbooks/backup/metadata.rb +++ b/site-cookbooks/backup/metadata.rb @@ -7,3 +7,4 @@ version "0.5.0" name "backup" depends 'logrotate' +depends 'mysql' diff --git a/site-cookbooks/backup/recipes/default.rb b/site-cookbooks/backup/recipes/default.rb index fe4a869..6272a7c 100644 --- a/site-cookbooks/backup/recipes/default.rb +++ b/site-cookbooks/backup/recipes/default.rb @@ -58,7 +58,7 @@ if node["backup"]["default_model"] end include_recipe 'logrotate' - if node["backup"]["mysql"] + unless node["backup"]["mysql"]["databases"].empty? # Install MySQL client (includes mysqldump) mysql_client 'default' do action :create From 208d6de94d6e978ffe2f71d69fa5e4fee194450b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 21 Apr 2017 12:54:16 +0200 Subject: [PATCH 24/83] Add dependency on redis and do backups again --- site-cookbooks/kosmos-mastodon/recipes/default.rb | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/site-cookbooks/kosmos-mastodon/recipes/default.rb b/site-cookbooks/kosmos-mastodon/recipes/default.rb index 3d301d1..d10b36f 100644 --- a/site-cookbooks/kosmos-mastodon/recipes/default.rb +++ b/site-cookbooks/kosmos-mastodon/recipes/default.rb @@ -8,6 +8,7 @@ # include_recipe "kosmos-nodejs" +include_recipe "kosmos-redis" node.override['postgresql']['enable_pgdg_apt'] = false include_recipe "postgresql::server" include_recipe "postgresql::ruby" @@ -154,10 +155,10 @@ application mastodon_path do end end -# unless node.chef_environment == "development" -# # Backup the database to S3 -# node.override["backup"]["postgresql"]["host"] = "localhost" -# node.override["backup"]["postgresql"]["username"] = "postgres" -# node.override["backup"]["postgresql"]["password"] = node['postgresql']['password']['postgres'] -# include_recipe "backup" -# end +unless node.chef_environment == "development" + # Backup the database to S3 + node.override["backup"]["postgresql"]["host"] = "localhost" + node.override["backup"]["postgresql"]["username"] = "postgres" + node.override["backup"]["postgresql"]["password"] = node['postgresql']['password']['postgres'] + include_recipe "backup" +end From 871f59dd8c1fbfb90717e577ce324b7479e1ba06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Thu, 27 Apr 2017 13:24:31 +0200 Subject: [PATCH 25/83] Enable the XMPP schlupp and botka recipes again --- nodes/dev.kosmos.org.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nodes/dev.kosmos.org.json b/nodes/dev.kosmos.org.json index 8a1f561..566ed85 100644 --- a/nodes/dev.kosmos.org.json +++ b/nodes/dev.kosmos.org.json @@ -7,6 +7,8 @@ "kosmos-wordpress", "kosmos-mediawiki", "5apps-xmpp_server", + "5apps-hubot::xmpp_schlupp", + "5apps-hubot::xmpp_botka", "kosmos-ipfs", "kosmos-mastodon", "kosmos-mastodon::nginx" From 2e5b27f8482e1ead05ec558aad575042126e2afa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Thu, 27 Apr 2017 13:34:53 +0200 Subject: [PATCH 26/83] Enable Freenode's botka and hal8000 again --- nodes/dev.kosmos.org.json | 1 + 1 file changed, 1 insertion(+) diff --git a/nodes/dev.kosmos.org.json b/nodes/dev.kosmos.org.json index 566ed85..4824f75 100644 --- a/nodes/dev.kosmos.org.json +++ b/nodes/dev.kosmos.org.json @@ -6,6 +6,7 @@ "sockethub::proxy", "kosmos-wordpress", "kosmos-mediawiki", + "kosmos-hubot", "5apps-xmpp_server", "5apps-hubot::xmpp_schlupp", "5apps-hubot::xmpp_botka", From 34653dc7d6fc4a8d6534e169c2efdd214660b174 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 28 Apr 2017 10:23:04 +0200 Subject: [PATCH 27/83] Add GitHub token and deploy a feature branch for now --- data_bags/credentials/5apps_schlupp_xmpp.json | 30 +++++++++++-------- .../5apps-hubot/recipes/xmpp_schlupp.rb | 5 ++-- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/data_bags/credentials/5apps_schlupp_xmpp.json b/data_bags/credentials/5apps_schlupp_xmpp.json index 731c1be..52b7adb 100644 --- a/data_bags/credentials/5apps_schlupp_xmpp.json +++ b/data_bags/credentials/5apps_schlupp_xmpp.json @@ -1,38 +1,44 @@ { "id": "5apps_schlupp_xmpp", "password": { - "encrypted_data": "qeK3ExmdWLlP1nbdpp7PK2mZ8rfdfp+XGhy2a/13LhWDYs2ZfU86fddWTi6k\njoMk\n", - "iv": "egW+wXfvOlZ0EcW8QxyxrA==\n", + "encrypted_data": "vdpA+JHaQryqZcoFkEdny7+InZDz99xV8iu/LKU8YGFBYXdWXts4sfH4WyVg\nbTfM\n", + "iv": "WHfrC1kzs6/xKXwuwlwPqw==\n", "version": 1, "cipher": "aes-256-cbc" }, "webhook_token": { - "encrypted_data": "R00gYs07sVFN3nIUno8zWb0cBU2k/sValcoiPhciRKHWjnw7tUG6uz6CgiPy\n5R8Y\n", - "iv": "9uMP9CSu7/2kyY+EAMONJw==\n", + "encrypted_data": "9Ir6EU4vbA49+L0zUxaEBxSCF7Wzx20/vg40YSM6hVrH2Mg7ZF5bprdni4mP\n1KmI\n", + "iv": "6g9kOLaeb1cmhp7wlC1XPg==\n", "version": 1, "cipher": "aes-256-cbc" }, "rs_logger_token": { - "encrypted_data": "4dIzQMef+4GePMeyPCeYIBOwISGrPcwispyimNY+Y1xEx+fYUTkvg4FrzME5\n0v69zxCFb7iz1Ul5O5Krliz3wg==\n", - "iv": "2XVJyhTClvb1BY3m4Pmj2Q==\n", + "encrypted_data": "KRwgLSHbfwiLMI4sV9ZWP5VnT/kWFe89WGbsYLYAPSseOYFrvH+YEH0A1sB/\nS6aafrCsK+q5WawLSmfTg8DOtw==\n", + "iv": "5asejj0oTTKWVgDdpBmbmg==\n", "version": 1, "cipher": "aes-256-cbc" }, "rs_ops_token": { - "encrypted_data": "TdYwqunwYxNYFMd9YbtePuiop1STQkPf4MU+bXVd3GLB6VbtSvvqgj0NJ/U3\nerx0ZrNhWWX1BOmaF0/YkSKWaQ==\n", - "iv": "K7K+ARH7TMExCDMybPHCqA==\n", + "encrypted_data": "GkfRyCO6Ctj2Tls4HFOTHt/y+3a6rrd84+siDr6c8+1ydsOT7vA+hDP7fHvq\nU8JnDca/Pd7yRMLACV4fdY0dQQ==\n", + "iv": "ES0LLnsEaC2SgHr7Rv1wFw==\n", "version": 1, "cipher": "aes-256-cbc" }, "deploy_key": { - "encrypted_data": "dSfJC9T78mBkZQDx3GmWx0piLHCcLwGj/50WLElnUFThRwPKlMdOR/xk/6ZO\nhXQ68axjx8Y7Xok3DkfgmKfT/2zX8HCTAwPekApUtwOoBIUTqgtLuqscRfra\nvrEs7j5Jgw2lBQF++ZAiM39uOc0JtnoxvXukiLAC0U1qtg5mxh/2C3hUubPp\n4dVrtmXq0ucQ4JnX8xs5kEVwKq5WUN4ZRUFLY+Hw78Z0HRy+BPh0+X4BR7wb\nlW2F+ojEJbJtuSs7ndSxlJ+5Uk4ZpD7cJb6qM3lwOLY05S8GVkjdi8FgAI0C\nzHD+0Fz5DjFVl2xcGUreUi5E2Pej+U1V+CpW8AL9+8LMkZ3bde6G8+TUASDl\nqXSBkX3pt4p/84PWc1I5JHpDJJ7nVHKuazcSpD5etoMPEXoLPVXTTYLLLR2J\neOLC1m04v7SpO8d0rozdjCcbj2fWT1hC1KfNnzPKmuRsEXXYdoQHOTjdg1Bq\nsNJAkCdLN5C0vP2zu1ug1Wk4XbFvK77a5u30icaLz+7fgBiAc1EKnTymCOwi\neFJLczcxb6jHK8edBNRaGVF8q2IP7n6fW2LqcqaufB6zOj4VPAC8ih4k8xZx\nKaAr9zzXli9QY9FepWJw9y45GYjJCwE5p7tLeerGypVJh6yF99xcs+NsAnmm\nwghL4HMUiRvH/+4q07U1JvxYduoesVBjL6yu6wKxDiOZkHO2Tq8HIxk8tA2G\nq9dPuogkRBtqC7xgmru5iX5/9hsILfUQs+Xg5i9+4T3ucH5mFzGBuv91z4uh\njHlEcCiBEReg2UrAK8FSyEVEo2ywqD/3CEejdRJSuZJ/b5HC6Tm/HvVtSnWl\n+v9J+7raddcPyuDt2rXIl2xyA3zrg0/oL2rg1KaQeTlgo4TYudjX5YzWhfoO\n9wXz3i2Na2HF87KMghVn0mE7MMvby1cRtIa5kkDHftLUwl/Fw5IVB5nT6VbR\nZcC6xM7ZYXBKgfa4cf8TaNHKq2Jmlvyxg+KWx+8UJhM1U2E/snljyoTT6aHR\nqjZB7SwqUPAAyIC1xv3xfljEgD04DzgqeS3A3bNkaF71Pnw2aXyryJeq6A0U\nmrkDTq+3Zf4XUqi1mTJXPP3uPmPmDB1dIMKZ5Bu1mxIvy1mL2B3Lrn5IG9/j\nD8BpUuDxg2406HdfUT4pyddqrDrX2p8WDDzFY1NCwQNAtLM3GXDt6VHntVHG\nEIiQksU5ubxPqkGJPToL3VlCKkGlcwv46g/h/rqcnuHX2oEvgFMZ4icC5yJ4\nVX1onZJmKC4fox4LY52kGQtVXoQkRbr3pcvpqfJaYXy8l/DOIp3Bh5wqEjjS\n/ULfDg6u/a/s+E6Witd76sL9FSe0R7lOBAS0ufQX+yc8dS52uf3g3Xj68d07\nCFpel61vwEk2mQG00SLgb+/o5QGsLi9Z2TbDiFxONj7y3cy+3fmeyUgymcyI\nUl9YN2Zcj7XV3n9/GjMZF0bXbJ5yLVw4amUlZha4/0cJb+i/ftOMmdAUJr6d\nAj9xrDNxJ85WcyOIYf9+1lMzCMwUt221K8eiDABD74LjUHIzJwKZ3uSf5v3F\nWPco5j5Ze27FcDxJ1mMCzuTBpSXjRQsubrdbHGSrFZi4yM9qcS+VfVkto1YN\nvDgOvIYd+PWQZBp4SCXP/trbAgawVd/i2gHl4KR8sx1cVdxwuefJ8zHgZyOl\nd8q+uQFaoX9nFm05ASlKL5PbZYA9dkaAulCYNGaOt8xzWAmA+7lDtwulpBcd\nbwdsTRcmt3vN2kgZduK6RQnMClYal4bF4rMuDE96WZdlLFefPleqP4W4g4pD\nVHg0zGSQRMZjZhPACBWX2kczZ1YW2RxgMRRdksxStUfKfrOMJ3YwHkwos+SU\nz5Q04Og3LFbq5XPu+JXFLNUpbsc6xKU+M7/a1s+oa/yu/0MoHDPiB0Ea29Am\nmKlXHhkeeXjSMJe3XKPFzUEuwhBhygR5JjfxoTEC9aL2MNU3Q5RHQYToXsBm\nwImrxwR9yWjmaY+Zn8A2UNHftQ92BlRt2WSFobBNOUX0FN66WCL2/9dFxett\nj+l7ueLJ0xT03+I5peA9PsSUMKQIX52CJUqrd+rvEGstUfHNBStCx1AEWz/O\ncZscVs+4tv3ytS6NkJ68PkxAIaWoH/+w+8UhNpev/pkSCsxTs86Wcvlm8hFg\nuxeyCQ/xogGBfeNFUecPdnjfsC8zpgKmIzRmROhwauNDP+S98LDmqGJ9s5Ix\nCVYLUaI3rh4n89tJzcoUK4ar7aOH51HUIDahcILxV3S3xvS2wqzl3zcXj1pG\nKrwgw/+Kxu/YHt/l5IytIp4d\n", - "iv": "NU7HOiRXhEDSaBA+fH3AvQ==\n", + "encrypted_data": "JuNDHLnOVwMUCvjkFVheR8eb+8gCqKe/eywGjppdLwAgHQdJlnMeqbyGDTes\njJeuildjKXrsuSfcMO+JP4Q53ZrL3V7pAHKHC3Ck7y9DZ78cZNgdJazsm/Ov\niQ++ZjZTDXFJLi8X9IwI9W4O+gAxycyA3C17Jtr1M/2EHHLBB/K/WvCzRIAi\ncCeOxPMCa5bwaeVXj5z1FRYezhbGIGyF/ddXU1knSwtxk0zRT3FhRcOVj/iw\n6nx5c+YEf38Qg+jM7IEi60wgBeT1g6U5jARKUN3GUR3chtDI43KKFB0h0nlv\nnNc/p/FXk6XeGebrdJElSbCiH0bH1E/KHicP7jCTARVuyx67WZRHAEzEuVbd\nUtbHy+KF0eqTVKuLABQaiqpiGjlYi+4xlr4NwKwqzfo7qGYUNn2JJ4lLicyW\nBbf+jxYBRt4g9+NtSiAdtA7y5/o3GKMMzDxs+H6H2yrFnXLlpzk/1fXT+Vmg\nxPQ3rPW2FsPTFmuRr9QtbjSfKtIyyrUC8lGWJHR4T6fEe1TDVDASs80e15Cx\nKyKoJzToIGi4iXwproDsEyWH9gIutNuhT7Qerg+gJVFpid4k6Iqugt4sNrGH\nV68MNt5mHihsGCeZO0YTl6b/kvk63rcbl1jBqA7iayfjuKekM3p5Dmp6tbpA\nluF+hHC0vdUFyFHB4keW8a4FlsQxyOAlSxNxkKXaeHgssd7pouHN/KdlrWax\nZGxOclGMqARqa3VzExgEGFaavSBB+4eHfECHgYGeREXYREDzr7ZrDcLGOh2J\nd+NiP+rb9zut61qPdRanZQV3KuA2iRBo+kDLxFaPAgHvVjeEOVRga1P8zJXE\n3gwqAbZUWOd9jkl8XtDGHM2lmLxiqv2LPhU2VubCJWWFhzfOLjntbPqeLLKC\nq+9ddzpxyJb7+0PEpMX/J+kEh5aQVlPgxnCZzPFf+Hj+I083tWxIqwD+lujN\nQduZ2GaF56/i2bRCIE5nfrcQf05OLIhb+BZkMw9haW850Jf/b3doVyyekyVw\nJxMY8qDZB9YcvrPrFmdThTkPDMiZOCTu5k18YNl4trqtv20S6+J2sMvN3FjE\n0LkqDTy3jYlH6cis7aiZhpQi9zusCczQepBOnBrqCfiVKkNeGmoXCFl0DYc3\nwYUZyluFGB3bkc97T9uOn1n6arHs/0O2yXWk5AZIiExf0NS/bcOGMJeeIByr\nK3NLWPdLK280AqzRqjg7ZeO3iD2HUfRpjU5MXiTau/5ttKoNIwgKjDVzSOvi\nB850ph4l6owXmQz14/JQrAWLswyLL37euK2FYtPMGEqzBdwg+lwWQK4nDw17\n9pN/3yBlPDC5NAfi51C9vEyxDuchAoekeXIjEQauSaxelDH7m+4ytKcR8P1Y\nGqlrxax+6SpA//JHvqzJcgfX/G7FwSE1WB7jES2jVo8jQJN+y15ZRglPCkAl\nISSR6pEug50nmmKK02S1jtGjRS5r/rzZh4ZIWUwMBX0lxcXyYEoEDjZptTF6\n6iOkgwr1EC4s2XujcOOoj0EUmGfdS5EFDakymmM8T/xOGZ4/HzVjlXC5y0ZE\nrbhwJ2DhYQgmLSe3Ih8xSKxbmVdNCU5nzm9A4EB2FvFac244CfRcbGeTz9HA\nRKi7Kf3HLcSWMYJm4W+Dz88Kl8R3b4vTVmfy6BZevBnO8dleCeAh0Me6DWaq\nJM6jRsABxxuF/hpaLf0kDYbfkdoDvpxHcVkFNqYnSfM0JP969nRyb+kRnUCJ\npVKYGUVKvo3xgOFgK7qV/d/MP6GCu8H9LG6CEdBRnC9Ahof5RBuJIzlntqwo\nIjq33pfdJaVXbuAUyTBekzsYbQtlo0kzUxBNt3hFnK7MbEKhlXbMjqmn/JA5\nbcKc2IpMrAaX5FC88k5OgJKl7OObDyuKMEZI7lSR/iV0wIWpJEW8sFZtchEc\njcp17jD+n5MlJ9ezm9Bm2/XBCDcy46kPG4hsXZ/RbRJ5x349xp0VimLr0lVB\ni83eyPeM8LnTKNmoxk8b+q0GXzefJZJBePtI6hZkmtKTxkzLmORaOUYYUV/A\nJy7vdgktl6G9qGPl3q16eGLBv8Is/0iOvSUhKsF21Zd0rO3plhCP4g67iT6R\np00ANOPqpkDIksNrpBPeM5DBpxAn1I4t1XejL3AIgyHI9zJZ34JymkFLL9OR\n+Ar8e3PXrDSdlYqBF8GZYYsjOoCxLthZXMvhaubT8Z1B4KrKHdYYRBoJ2A+0\nxhcpfPBHSz/KQPR+zOGU11acCD8lcNHv+Bn2J/mbjqKqth8PmZijtzSE+52t\nNirK6cK/bWZzRjN/W6nJ9PrO\n", + "iv": "JSVBvNn1cvdCQYAAFv1f4g==\n", "version": 1, "cipher": "aes-256-cbc" }, "airtable_api_key": { - "encrypted_data": "Hwg8ABWrUCj5aNQfYLi/nLv6VsdAGgCvaZ6JYzj51c1dFO+rIelwGYYcxcbC\nnIx4\n", - "iv": "7fqdsRG7WZSHD9U3HtcmZA==\n", + "encrypted_data": "WOQ/IJwVSiu5cUumLZcBE5dyKCxojHpBVFEVFcWax9jHvcLgIz2d7U/X1XeI\nZJ6W\n", + "iv": "67fXeOD2OTRhWeG5YsqdRg==\n", + "version": 1, + "cipher": "aes-256-cbc" + }, + "github_token": { + "encrypted_data": "KDZ3TzVjX05aeL9dyCeIuEa3XpItIduovEpEu+eDRA+eyCW1Yg5mdBARLoqO\n8elA0sO9EYrxJAo/o6tE+rLmFw==\n", + "iv": "BXflyLpEh5eZtiU1pEJPzA==\n", "version": 1, "cipher": "aes-256-cbc" } diff --git a/site-cookbooks/5apps-hubot/recipes/xmpp_schlupp.rb b/site-cookbooks/5apps-hubot/recipes/xmpp_schlupp.rb index 3d5227a..8f4aeac 100644 --- a/site-cookbooks/5apps-hubot/recipes/xmpp_schlupp.rb +++ b/site-cookbooks/5apps-hubot/recipes/xmpp_schlupp.rb @@ -39,7 +39,7 @@ application schlupp_xmpp_path do git "git@gitlab.com:5apps/schlupp.git" do user "hubot" group "hubot" - revision "master" + revision "feature/add_staging_label" deploy_key schlupp_xmpp_data_bag_item['deploy_key'] end @@ -92,7 +92,8 @@ application schlupp_xmpp_path do "REDIS_URL" => "redis://localhost:6379/5apps_schlupp_xmpp", "RS_OPS_TOKEN" => schlupp_xmpp_data_bag_item['rs_ops_token'], "WEBHOOK_TOKEN" => schlupp_xmpp_data_bag_item['webhook_token'], - "AIRTABLE_API_KEY" => schlupp_xmpp_data_bag_item['airtable_api_key'] } + "AIRTABLE_API_KEY" => schlupp_xmpp_data_bag_item['airtable_api_key'], + "GITHUB_TOKEN" => schlupp_xmpp_data_bag_item['github_token'] } ) notifies :run, "execute[systemctl daemon-reload]", :delayed From 5d1d4832dfab7e89c6b98ed48ff85ca886673cd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 28 Apr 2017 11:58:45 +0200 Subject: [PATCH 28/83] Move repository to its own attribute --- site-cookbooks/5apps-hubot/recipes/xmpp_schlupp.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/site-cookbooks/5apps-hubot/recipes/xmpp_schlupp.rb b/site-cookbooks/5apps-hubot/recipes/xmpp_schlupp.rb index 8f4aeac..f344b37 100644 --- a/site-cookbooks/5apps-hubot/recipes/xmpp_schlupp.rb +++ b/site-cookbooks/5apps-hubot/recipes/xmpp_schlupp.rb @@ -36,9 +36,10 @@ application schlupp_xmpp_path do owner "hubot" group "hubot" - git "git@gitlab.com:5apps/schlupp.git" do + git do user "hubot" group "hubot" + repository "git@gitlab.com:5apps/schlupp.git" revision "feature/add_staging_label" deploy_key schlupp_xmpp_data_bag_item['deploy_key'] end From 4fb5390f9babe20c28184492fae673887554bbb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 28 Apr 2017 11:59:11 +0200 Subject: [PATCH 29/83] Update cookbooks * Replace old nginx cookbook with new chef_nginx cookbooks * Update application cookbook --- Batali | 8 +- batali.manifest | 413 +++++------- cookbooks/7-zip/CHANGELOG.md | 13 - cookbooks/7-zip/README.md | 50 -- cookbooks/7-zip/attributes/default.rb | 31 - cookbooks/7-zip/metadata.json | 31 - cookbooks/7-zip/metadata.rb | 10 - cookbooks/7-zip/recipes/default.rb | 31 - cookbooks/application/CHANGELOG.md | 7 +- cookbooks/application/README.md | 13 +- .../files/halite_gem/poise_application.rb | 2 +- .../poise_application/app_file_mixin.rb | 9 +- .../halite_gem/poise_application/app_mixin.rb | 2 +- .../halite_gem/poise_application/cheftie.rb | 2 +- .../halite_gem/poise_application/error.rb | 2 +- .../halite_gem/poise_application/resources.rb | 3 +- .../resources/application.rb | 2 +- .../resources/application_cookbook_file.rb | 2 +- .../resources/application_directory.rb | 50 ++ .../resources/application_file.rb | 2 +- .../resources/application_template.rb | 2 +- .../poise_application/service_mixin.rb | 2 +- .../halite_gem/poise_application/utils.rb | 2 +- .../halite_gem/poise_application/version.rb | 4 +- cookbooks/application/libraries/default.rb | 2 +- cookbooks/application/metadata.json | 2 +- cookbooks/bluepill/.foodcritic | 1 - cookbooks/bluepill/CHANGELOG.md | 87 --- cookbooks/bluepill/README.md | 111 ---- cookbooks/bluepill/attributes/default.rb | 44 -- cookbooks/bluepill/libraries/matchers.rb | 33 - cookbooks/bluepill/metadata.json | 1 - cookbooks/bluepill/providers/service.rb | 172 ----- cookbooks/bluepill/recipes/default.rb | 45 -- cookbooks/bluepill/recipes/rsyslog.rb | 28 - cookbooks/bluepill/resources/service.rb | 27 - .../default/bluepill_init.fedora.erb | 34 - .../default/bluepill_init.freebsd.erb | 32 - .../templates/default/bluepill_init.lsb.erb | 37 -- .../templates/default/bluepill_init.rhel.erb | 34 - .../default/bluepill_rsyslog.conf.erb | 1 - cookbooks/build-essential/.foodcritic | 3 +- cookbooks/build-essential/CHANGELOG.md | 97 +++ .../build-essential/attributes/default.rb | 6 +- .../build-essential/libraries/_msys_helper.rb | 15 - .../build-essential/libraries/matchers.rb | 4 + cookbooks/build-essential/libraries/timing.rb | 124 ---- .../libraries/xcode_command_line_tools.rb | 212 ------ cookbooks/build-essential/metadata.json | 2 +- .../build-essential/providers/msys_archive.rb | 102 --- cookbooks/build-essential/recipes/_debian.rb | 28 - cookbooks/build-essential/recipes/_fedora.rb | 32 - cookbooks/build-essential/recipes/_freebsd.rb | 25 - cookbooks/build-essential/recipes/_omnios.rb | 33 - cookbooks/build-essential/recipes/_smartos.rb | 27 - .../build-essential/recipes/_solaris2.rb | 48 -- cookbooks/build-essential/recipes/_suse.rb | 29 - .../build-essential/resources/msys_archive.rb | 7 - cookbooks/chef_nginx/.foodcritic | 1 + cookbooks/chef_nginx/CHANGELOG.md | 628 ++++++++++++++++++ .../{bluepill => chef_nginx}/CONTRIBUTING.md | 0 .../{bluepill => chef_nginx}/MAINTAINERS.md | 9 +- cookbooks/chef_nginx/README.md | 367 ++++++++++ .../attributes/auth_request.rb | 8 +- .../attributes/default.rb | 37 +- .../{nginx => chef_nginx}/attributes/devel.rb | 8 +- .../{nginx => chef_nginx}/attributes/echo.rb | 8 +- .../{nginx => chef_nginx}/attributes/geoip.rb | 16 +- .../attributes/headers_more.rb | 8 +- .../{nginx => chef_nginx}/attributes/lua.rb | 12 +- .../{nginx => chef_nginx}/attributes/naxsi.rb | 8 +- .../attributes/openssl_source.rb | 6 +- .../attributes/pagespeed.rb | 8 +- .../attributes/passenger.rb | 19 +- .../attributes/rate_limiting.rb | 4 +- .../{nginx => chef_nginx}/attributes/repo.rb | 22 +- cookbooks/chef_nginx/attributes/set_misc.rb | 8 + .../attributes/socketproxy.rb | 5 + .../attributes/source.rb | 19 +- .../attributes/status.rb | 4 +- .../attributes/syslog.rb | 5 +- .../attributes/upload_progress.rb | 4 +- cookbooks/chef_nginx/files/default/mime.types | 134 ++++ .../files/default/naxsi_core.rules | 0 cookbooks/chef_nginx/libraries/helpers.rb | 38 ++ .../libraries/matchers.rb} | 34 +- cookbooks/chef_nginx/metadata.json | 1 + .../recipes/authorized_ips.rb | 7 +- .../{nginx => chef_nginx}/recipes/commons.rb | 10 +- .../recipes/commons_conf.rb | 13 +- .../recipes/commons_dir.rb | 15 +- .../recipes/commons_script.rb | 6 +- .../{nginx => chef_nginx}/recipes/default.rb | 13 +- .../recipes/headers_more_module.rb | 11 +- .../recipes/http_auth_request_module.rb | 7 +- .../recipes/http_echo_module.rb | 7 +- .../recipes/http_geoip_module.rb | 24 +- .../recipes/http_gzip_static_module.rb | 7 +- .../recipes/http_mp4_module.rb | 0 .../recipes/http_perl_module.rb | 4 +- .../recipes/http_realip_module.rb | 7 +- .../recipes/http_spdy_module.rb | 4 +- .../recipes/http_ssl_module.rb | 4 +- .../recipes/http_stub_status_module.rb | 9 +- .../recipes/http_v2_module.rb} | 11 +- .../{nginx => chef_nginx}/recipes/ipv6.rb | 4 +- .../{nginx => chef_nginx}/recipes/lua.rb | 21 +- .../recipes/naxsi_module.rb | 10 +- .../recipes/ngx_devel_module.rb | 7 +- .../recipes/ngx_lua_module.rb | 13 +- .../recipes/ohai_plugin.rb | 18 +- .../recipes/openssl_source.rb | 7 +- cookbooks/chef_nginx/recipes/package.rb | 53 ++ .../recipes/pagespeed_module.rb | 20 +- .../recipes/passenger.rb | 21 +- .../{nginx => chef_nginx}/recipes/repo.rb | 28 +- .../recipes/repo_passenger.rb | 20 +- .../{nginx => chef_nginx}/recipes/set_misc.rb | 7 +- .../recipes/socketproxy.rb | 9 +- .../{nginx => chef_nginx}/recipes/source.rb | 137 ++-- .../recipes/syslog_module.rb | 40 +- .../recipes/upload_progress_module.rb | 10 +- cookbooks/chef_nginx/resources/site.rb | 81 +++ .../templates/debian/nginx.init.erb | 2 +- .../templates/default/default-site.erb | 0 .../default/modules/authorized_ip.erb | 0 .../default/modules/http_geoip.conf.erb | 0 .../default/modules/http_gzip_static.conf.erb | 0 .../default/modules/http_realip.conf.erb | 6 +- .../default/modules/nginx_status.erb | 4 + .../default/modules/passenger.conf.erb | 4 + .../default/modules/socketproxy.conf.erb | 0 .../default/modules/upload_progress.erb | 0 .../templates/default/nginx-upstart.conf.erb | 16 +- .../templates/default/nginx.conf.erb | 14 +- .../templates/default/nginx.init.erb | 0 .../templates/default/nginx.service.erb | 13 + .../templates/default/nginx.sysconfig.erb | 0 .../templates/default/nxdissite.erb | 0 .../templates/default/nxensite.erb | 0 .../default/plugins/ohai-nginx.rb.erb | 82 +++ .../templates/default/sv-nginx-log-run.erb | 0 .../templates/default/sv-nginx-run.erb | 0 .../templates/ubuntu/nginx.init.erb | 2 +- cookbooks/dmg/.foodcritic | 4 - cookbooks/dmg/CHANGELOG.md | 17 + cookbooks/dmg/README.md | 10 +- cookbooks/dmg/attributes/default.rb | 20 - cookbooks/dmg/libraries/matchers.rb | 2 +- cookbooks/dmg/metadata.json | 2 +- cookbooks/dmg/providers/package.rb | 95 --- cookbooks/dmg/recipes/default.rb | 6 +- cookbooks/dmg/resources/package.rb | 99 ++- cookbooks/mediawiki/metadata.rb | 4 +- cookbooks/mediawiki/recipes/nginx.rb | 2 +- cookbooks/nginx/CHANGELOG.md | 435 ------------ cookbooks/nginx/README.md | 521 --------------- cookbooks/nginx/attributes/set_misc.rb | 8 - cookbooks/nginx/definitions/nginx_site.rb | 50 -- cookbooks/nginx/files/default/mime.types | 78 --- cookbooks/nginx/libraries/matchers.rb | 20 - cookbooks/nginx/metadata.json | 351 ---------- cookbooks/nginx/metadata.rb | 125 ---- cookbooks/nginx/recipes/package.rb | 52 -- .../nginx/templates/default/nginx.pill.erb | 15 - .../templates/default/plugins/nginx.rb.erb | 66 -- .../nginx/templates/gentoo/nginx.init.erb | 87 --- cookbooks/nginx/templates/suse/nginx.init.erb | 115 ---- cookbooks/ohai/.foodcritic | 2 + cookbooks/ohai/CHANGELOG.md | 95 +++ cookbooks/ohai/MAINTAINERS.md | 10 +- cookbooks/ohai/README.md | 117 +++- cookbooks/ohai/attributes/default.rb | 31 - cookbooks/ohai/files/default/plugins/README | 1 - cookbooks/ohai/libraries/matchers.rb | 38 +- cookbooks/ohai/metadata.json | 2 +- cookbooks/ohai/providers/hint.rb | 46 -- cookbooks/ohai/recipes/default.rb | 38 +- cookbooks/ohai/resources/hint.rb | 58 +- cookbooks/ohai/resources/plugin.rb | 117 ++++ cookbooks/packagecloud/.gitignore | 19 - cookbooks/packagecloud/.kitchen.yml | 79 --- cookbooks/packagecloud/.rubocop.yml | 28 - cookbooks/packagecloud/.travis.yml | 7 - cookbooks/packagecloud/Berksfile | 5 - cookbooks/packagecloud/CHANGELOG.md | 18 - cookbooks/packagecloud/Gemfile | 16 - cookbooks/packagecloud/LICENSE | 13 - cookbooks/packagecloud/README.md | 91 --- cookbooks/packagecloud/Rakefile | 47 -- cookbooks/packagecloud/THANKS | 6 - cookbooks/packagecloud/Thorfile | 5 - cookbooks/packagecloud/Vagrantfile | 85 --- cookbooks/packagecloud/attributes/default.rb | 8 - cookbooks/packagecloud/chefignore | 98 --- cookbooks/packagecloud/libraries/helper.rb | 43 -- cookbooks/packagecloud/libraries/matcher.rb | 7 - cookbooks/packagecloud/metadata.json | 48 -- cookbooks/packagecloud/metadata.rb | 9 - cookbooks/packagecloud/providers/repo.rb | 224 ------- cookbooks/packagecloud/resources/repo.rb | 11 - .../packagecloud/templates/default/apt.erb | 2 - .../packagecloud/templates/default/yum.erb | 15 - cookbooks/rsyslog/CHANGELOG.md | 193 ------ cookbooks/rsyslog/README.md | 276 -------- cookbooks/rsyslog/attributes/default.rb | 131 ---- cookbooks/rsyslog/libraries/helpers.rb | 25 - cookbooks/rsyslog/metadata.json | 1 - cookbooks/rsyslog/providers/file_input.rb | 44 -- cookbooks/rsyslog/recipes/client.rb | 87 --- cookbooks/rsyslog/recipes/default.rb | 89 --- cookbooks/rsyslog/recipes/server.rb | 44 -- cookbooks/rsyslog/resources/file_input.rb | 28 - .../default/35-server-per-host.conf.erb | 62 -- .../templates/default/49-relp.conf.erb | 10 - .../templates/default/49-remote.conf.erb | 30 - .../templates/default/50-default.conf.erb | 6 - .../templates/default/file-input.conf.erb | 15 - .../templates/default/omnios-manifest.xml.erb | 30 - .../templates/default/rsyslog.conf.erb | 117 ---- .../templates/smartos/50-default.conf.erb | 18 - cookbooks/runit/CHANGELOG.md | 232 ------- cookbooks/runit/README.md | 439 ------------ cookbooks/runit/attributes/default.rb | 62 -- cookbooks/runit/files/default/runit.seed | 1 - cookbooks/runit/files/default/runsvdir | 0 cookbooks/runit/files/ubuntu-6.10/runsvdir | 6 - cookbooks/runit/files/ubuntu-7.04/runsvdir | 7 - cookbooks/runit/files/ubuntu-7.10/runsvdir | 7 - cookbooks/runit/files/ubuntu-8.04/runsvdir | 7 - cookbooks/runit/libraries/default.rb | 0 cookbooks/runit/libraries/helpers.rb | 198 ------ cookbooks/runit/libraries/matchers.rb | 69 -- .../runit/libraries/provider_runit_service.rb | 348 ---------- .../runit/libraries/resource_runit_service.rb | 267 -------- cookbooks/runit/metadata.json | 49 -- cookbooks/runit/metadata.rb | 15 - cookbooks/runit/recipes/default.rb | 91 --- cookbooks/runit/templates/debian/init.d.erb | 66 -- .../runit/templates/default/log-config.erb | 24 - .../runit/templates/gentoo/runit-start.sh.erb | 32 - cookbooks/wordpress/metadata.rb | 4 +- cookbooks/wordpress/recipes/nginx.rb | 2 +- cookbooks/yum-epel/CHANGELOG.md | 36 +- cookbooks/yum-epel/MAINTAINERS.md | 4 +- cookbooks/yum-epel/README.md | 20 +- cookbooks/yum-epel/attributes/default.rb | 9 +- .../yum-epel/attributes/epel-debuginfo.rb | 8 +- cookbooks/yum-epel/attributes/epel-source.rb | 8 +- .../attributes/epel-testing-debuginfo.rb | 8 +- .../attributes/epel-testing-source.rb | 7 +- cookbooks/yum-epel/attributes/epel-testing.rb | 14 +- cookbooks/yum-epel/attributes/epel.rb | 9 +- cookbooks/yum-epel/metadata.json | 2 +- cookbooks/yum-epel/recipes/default.rb | 47 +- cookbooks/zypper/CHANGELOG.md | 25 + cookbooks/zypper/README.md | 126 ++++ cookbooks/zypper/attributes/default.rb | 1 + cookbooks/zypper/libraries/matchers.rb | 12 + cookbooks/zypper/metadata.json | 1 + cookbooks/zypper/providers/repo.rb | 68 ++ cookbooks/zypper/recipes/default.rb | 30 + cookbooks/zypper/recipes/smt_client.rb | 50 ++ cookbooks/zypper/resources/repo.rb | 8 + 264 files changed, 3050 insertions(+), 8605 deletions(-) delete mode 100644 cookbooks/7-zip/CHANGELOG.md delete mode 100644 cookbooks/7-zip/README.md delete mode 100644 cookbooks/7-zip/attributes/default.rb delete mode 100644 cookbooks/7-zip/metadata.json delete mode 100644 cookbooks/7-zip/metadata.rb delete mode 100644 cookbooks/7-zip/recipes/default.rb create mode 100644 cookbooks/application/files/halite_gem/poise_application/resources/application_directory.rb delete mode 100644 cookbooks/bluepill/.foodcritic delete mode 100644 cookbooks/bluepill/CHANGELOG.md delete mode 100644 cookbooks/bluepill/README.md delete mode 100644 cookbooks/bluepill/attributes/default.rb delete mode 100644 cookbooks/bluepill/libraries/matchers.rb delete mode 100644 cookbooks/bluepill/metadata.json delete mode 100644 cookbooks/bluepill/providers/service.rb delete mode 100644 cookbooks/bluepill/recipes/default.rb delete mode 100644 cookbooks/bluepill/recipes/rsyslog.rb delete mode 100644 cookbooks/bluepill/resources/service.rb delete mode 100644 cookbooks/bluepill/templates/default/bluepill_init.fedora.erb delete mode 100644 cookbooks/bluepill/templates/default/bluepill_init.freebsd.erb delete mode 100644 cookbooks/bluepill/templates/default/bluepill_init.lsb.erb delete mode 100644 cookbooks/bluepill/templates/default/bluepill_init.rhel.erb delete mode 100644 cookbooks/bluepill/templates/default/bluepill_rsyslog.conf.erb delete mode 100644 cookbooks/build-essential/libraries/_msys_helper.rb delete mode 100644 cookbooks/build-essential/libraries/timing.rb delete mode 100644 cookbooks/build-essential/libraries/xcode_command_line_tools.rb delete mode 100644 cookbooks/build-essential/providers/msys_archive.rb delete mode 100644 cookbooks/build-essential/recipes/_debian.rb delete mode 100644 cookbooks/build-essential/recipes/_fedora.rb delete mode 100644 cookbooks/build-essential/recipes/_freebsd.rb delete mode 100644 cookbooks/build-essential/recipes/_omnios.rb delete mode 100644 cookbooks/build-essential/recipes/_smartos.rb delete mode 100644 cookbooks/build-essential/recipes/_solaris2.rb delete mode 100644 cookbooks/build-essential/recipes/_suse.rb delete mode 100644 cookbooks/build-essential/resources/msys_archive.rb create mode 100644 cookbooks/chef_nginx/.foodcritic create mode 100644 cookbooks/chef_nginx/CHANGELOG.md rename cookbooks/{bluepill => chef_nginx}/CONTRIBUTING.md (100%) rename cookbooks/{bluepill => chef_nginx}/MAINTAINERS.md (56%) create mode 100644 cookbooks/chef_nginx/README.md rename cookbooks/{nginx => chef_nginx}/attributes/auth_request.rb (74%) rename cookbooks/{nginx => chef_nginx}/attributes/default.rb (83%) rename cookbooks/{nginx => chef_nginx}/attributes/devel.rb (78%) rename cookbooks/{nginx => chef_nginx}/attributes/echo.rb (77%) rename cookbooks/{nginx => chef_nginx}/attributes/geoip.rb (69%) rename cookbooks/{nginx => chef_nginx}/attributes/headers_more.rb (76%) rename cookbooks/{nginx => chef_nginx}/attributes/lua.rb (70%) rename cookbooks/{nginx => chef_nginx}/attributes/naxsi.rb (77%) rename cookbooks/{nginx => chef_nginx}/attributes/openssl_source.rb (86%) rename cookbooks/{nginx => chef_nginx}/attributes/pagespeed.rb (53%) rename cookbooks/{nginx => chef_nginx}/attributes/passenger.rb (77%) rename cookbooks/{nginx => chef_nginx}/attributes/rate_limiting.rb (92%) rename cookbooks/{nginx => chef_nginx}/attributes/repo.rb (59%) create mode 100644 cookbooks/chef_nginx/attributes/set_misc.rb rename cookbooks/{nginx => chef_nginx}/attributes/socketproxy.rb (89%) rename cookbooks/{nginx => chef_nginx}/attributes/source.rb (69%) rename cookbooks/{nginx => chef_nginx}/attributes/status.rb (91%) rename cookbooks/{nginx => chef_nginx}/attributes/syslog.rb (92%) rename cookbooks/{nginx => chef_nginx}/attributes/upload_progress.rb (94%) create mode 100644 cookbooks/chef_nginx/files/default/mime.types rename cookbooks/{nginx => chef_nginx}/files/default/naxsi_core.rules (100%) create mode 100644 cookbooks/chef_nginx/libraries/helpers.rb rename cookbooks/{build-essential/recipes/_rhel.rb => chef_nginx/libraries/matchers.rb} (53%) create mode 100644 cookbooks/chef_nginx/metadata.json rename cookbooks/{nginx => chef_nginx}/recipes/authorized_ips.rb (88%) rename cookbooks/{nginx => chef_nginx}/recipes/commons.rb (76%) rename cookbooks/{nginx => chef_nginx}/recipes/commons_conf.rb (81%) rename cookbooks/{nginx => chef_nginx}/recipes/commons_dir.rb (75%) rename cookbooks/{nginx => chef_nginx}/recipes/commons_script.rb (87%) rename cookbooks/{nginx => chef_nginx}/recipes/default.rb (71%) rename cookbooks/{nginx => chef_nginx}/recipes/headers_more_module.rb (80%) rename cookbooks/{nginx => chef_nginx}/recipes/http_auth_request_module.rb (93%) rename cookbooks/{nginx => chef_nginx}/recipes/http_echo_module.rb (92%) rename cookbooks/{nginx => chef_nginx}/recipes/http_geoip_module.rb (86%) rename cookbooks/{nginx => chef_nginx}/recipes/http_gzip_static_module.rb (88%) rename cookbooks/{nginx => chef_nginx}/recipes/http_mp4_module.rb (100%) rename cookbooks/{nginx => chef_nginx}/recipes/http_perl_module.rb (93%) rename cookbooks/{nginx => chef_nginx}/recipes/http_realip_module.rb (91%) rename cookbooks/{nginx => chef_nginx}/recipes/http_spdy_module.rb (92%) rename cookbooks/{nginx => chef_nginx}/recipes/http_ssl_module.rb (92%) rename cookbooks/{nginx => chef_nginx}/recipes/http_stub_status_module.rb (86%) rename cookbooks/{build-essential/recipes/_mac_os_x.rb => chef_nginx/recipes/http_v2_module.rb} (76%) rename cookbooks/{nginx => chef_nginx}/recipes/ipv6.rb (92%) rename cookbooks/{nginx => chef_nginx}/recipes/lua.rb (79%) rename cookbooks/{nginx => chef_nginx}/recipes/naxsi_module.rb (89%) rename cookbooks/{nginx => chef_nginx}/recipes/ngx_devel_module.rb (92%) rename cookbooks/{nginx => chef_nginx}/recipes/ngx_lua_module.rb (87%) rename cookbooks/{nginx => chef_nginx}/recipes/ohai_plugin.rb (70%) rename cookbooks/{nginx => chef_nginx}/recipes/openssl_source.rb (92%) create mode 100644 cookbooks/chef_nginx/recipes/package.rb rename cookbooks/{nginx => chef_nginx}/recipes/pagespeed_module.rb (78%) rename cookbooks/{nginx => chef_nginx}/recipes/passenger.rb (70%) rename cookbooks/{nginx => chef_nginx}/recipes/repo.rb (61%) rename cookbooks/{nginx => chef_nginx}/recipes/repo_passenger.rb (75%) rename cookbooks/{nginx => chef_nginx}/recipes/set_misc.rb (88%) rename cookbooks/{nginx => chef_nginx}/recipes/socketproxy.rb (73%) rename cookbooks/{nginx => chef_nginx}/recipes/source.rb (54%) rename cookbooks/{nginx => chef_nginx}/recipes/syslog_module.rb (71%) rename cookbooks/{nginx => chef_nginx}/recipes/upload_progress_module.rb (89%) create mode 100644 cookbooks/chef_nginx/resources/site.rb rename cookbooks/{nginx => chef_nginx}/templates/debian/nginx.init.erb (98%) rename cookbooks/{nginx => chef_nginx}/templates/default/default-site.erb (100%) rename cookbooks/{nginx => chef_nginx}/templates/default/modules/authorized_ip.erb (100%) rename cookbooks/{nginx => chef_nginx}/templates/default/modules/http_geoip.conf.erb (100%) rename cookbooks/{nginx => chef_nginx}/templates/default/modules/http_gzip_static.conf.erb (100%) rename cookbooks/{nginx => chef_nginx}/templates/default/modules/http_realip.conf.erb (58%) rename cookbooks/{nginx => chef_nginx}/templates/default/modules/nginx_status.erb (86%) rename cookbooks/{nginx => chef_nginx}/templates/default/modules/passenger.conf.erb (76%) rename cookbooks/{nginx => chef_nginx}/templates/default/modules/socketproxy.conf.erb (100%) rename cookbooks/{nginx => chef_nginx}/templates/default/modules/upload_progress.erb (100%) rename cookbooks/{nginx => chef_nginx}/templates/default/nginx-upstart.conf.erb (74%) rename cookbooks/{nginx => chef_nginx}/templates/default/nginx.conf.erb (88%) rename cookbooks/{nginx => chef_nginx}/templates/default/nginx.init.erb (100%) create mode 100644 cookbooks/chef_nginx/templates/default/nginx.service.erb rename cookbooks/{nginx => chef_nginx}/templates/default/nginx.sysconfig.erb (100%) rename cookbooks/{nginx => chef_nginx}/templates/default/nxdissite.erb (100%) rename cookbooks/{nginx => chef_nginx}/templates/default/nxensite.erb (100%) create mode 100644 cookbooks/chef_nginx/templates/default/plugins/ohai-nginx.rb.erb rename cookbooks/{nginx => chef_nginx}/templates/default/sv-nginx-log-run.erb (100%) rename cookbooks/{nginx => chef_nginx}/templates/default/sv-nginx-run.erb (100%) rename cookbooks/{nginx => chef_nginx}/templates/ubuntu/nginx.init.erb (98%) delete mode 100644 cookbooks/dmg/.foodcritic delete mode 100644 cookbooks/dmg/attributes/default.rb delete mode 100644 cookbooks/dmg/providers/package.rb delete mode 100644 cookbooks/nginx/CHANGELOG.md delete mode 100644 cookbooks/nginx/README.md delete mode 100644 cookbooks/nginx/attributes/set_misc.rb delete mode 100644 cookbooks/nginx/definitions/nginx_site.rb delete mode 100644 cookbooks/nginx/files/default/mime.types delete mode 100644 cookbooks/nginx/libraries/matchers.rb delete mode 100644 cookbooks/nginx/metadata.json delete mode 100644 cookbooks/nginx/metadata.rb delete mode 100644 cookbooks/nginx/recipes/package.rb delete mode 100644 cookbooks/nginx/templates/default/nginx.pill.erb delete mode 100644 cookbooks/nginx/templates/default/plugins/nginx.rb.erb delete mode 100644 cookbooks/nginx/templates/gentoo/nginx.init.erb delete mode 100644 cookbooks/nginx/templates/suse/nginx.init.erb create mode 100644 cookbooks/ohai/.foodcritic delete mode 100644 cookbooks/ohai/attributes/default.rb delete mode 100644 cookbooks/ohai/files/default/plugins/README delete mode 100644 cookbooks/ohai/providers/hint.rb create mode 100644 cookbooks/ohai/resources/plugin.rb delete mode 100644 cookbooks/packagecloud/.gitignore delete mode 100644 cookbooks/packagecloud/.kitchen.yml delete mode 100644 cookbooks/packagecloud/.rubocop.yml delete mode 100644 cookbooks/packagecloud/.travis.yml delete mode 100644 cookbooks/packagecloud/Berksfile delete mode 100644 cookbooks/packagecloud/CHANGELOG.md delete mode 100644 cookbooks/packagecloud/Gemfile delete mode 100644 cookbooks/packagecloud/LICENSE delete mode 100644 cookbooks/packagecloud/README.md delete mode 100644 cookbooks/packagecloud/Rakefile delete mode 100644 cookbooks/packagecloud/THANKS delete mode 100644 cookbooks/packagecloud/Thorfile delete mode 100644 cookbooks/packagecloud/Vagrantfile delete mode 100644 cookbooks/packagecloud/attributes/default.rb delete mode 100644 cookbooks/packagecloud/chefignore delete mode 100644 cookbooks/packagecloud/libraries/helper.rb delete mode 100644 cookbooks/packagecloud/libraries/matcher.rb delete mode 100644 cookbooks/packagecloud/metadata.json delete mode 100644 cookbooks/packagecloud/metadata.rb delete mode 100644 cookbooks/packagecloud/providers/repo.rb delete mode 100644 cookbooks/packagecloud/resources/repo.rb delete mode 100644 cookbooks/packagecloud/templates/default/apt.erb delete mode 100644 cookbooks/packagecloud/templates/default/yum.erb delete mode 100644 cookbooks/rsyslog/CHANGELOG.md delete mode 100644 cookbooks/rsyslog/README.md delete mode 100644 cookbooks/rsyslog/attributes/default.rb delete mode 100644 cookbooks/rsyslog/libraries/helpers.rb delete mode 100644 cookbooks/rsyslog/metadata.json delete mode 100644 cookbooks/rsyslog/providers/file_input.rb delete mode 100644 cookbooks/rsyslog/recipes/client.rb delete mode 100644 cookbooks/rsyslog/recipes/default.rb delete mode 100644 cookbooks/rsyslog/recipes/server.rb delete mode 100644 cookbooks/rsyslog/resources/file_input.rb delete mode 100644 cookbooks/rsyslog/templates/default/35-server-per-host.conf.erb delete mode 100644 cookbooks/rsyslog/templates/default/49-relp.conf.erb delete mode 100644 cookbooks/rsyslog/templates/default/49-remote.conf.erb delete mode 100644 cookbooks/rsyslog/templates/default/50-default.conf.erb delete mode 100644 cookbooks/rsyslog/templates/default/file-input.conf.erb delete mode 100644 cookbooks/rsyslog/templates/default/omnios-manifest.xml.erb delete mode 100644 cookbooks/rsyslog/templates/default/rsyslog.conf.erb delete mode 100644 cookbooks/rsyslog/templates/smartos/50-default.conf.erb delete mode 100644 cookbooks/runit/CHANGELOG.md delete mode 100644 cookbooks/runit/README.md delete mode 100644 cookbooks/runit/attributes/default.rb delete mode 100644 cookbooks/runit/files/default/runit.seed delete mode 100644 cookbooks/runit/files/default/runsvdir delete mode 100644 cookbooks/runit/files/ubuntu-6.10/runsvdir delete mode 100644 cookbooks/runit/files/ubuntu-7.04/runsvdir delete mode 100644 cookbooks/runit/files/ubuntu-7.10/runsvdir delete mode 100644 cookbooks/runit/files/ubuntu-8.04/runsvdir delete mode 100644 cookbooks/runit/libraries/default.rb delete mode 100644 cookbooks/runit/libraries/helpers.rb delete mode 100644 cookbooks/runit/libraries/matchers.rb delete mode 100644 cookbooks/runit/libraries/provider_runit_service.rb delete mode 100644 cookbooks/runit/libraries/resource_runit_service.rb delete mode 100644 cookbooks/runit/metadata.json delete mode 100644 cookbooks/runit/metadata.rb delete mode 100644 cookbooks/runit/recipes/default.rb delete mode 100644 cookbooks/runit/templates/debian/init.d.erb delete mode 100644 cookbooks/runit/templates/default/log-config.erb delete mode 100644 cookbooks/runit/templates/gentoo/runit-start.sh.erb create mode 100644 cookbooks/zypper/CHANGELOG.md create mode 100644 cookbooks/zypper/README.md create mode 100644 cookbooks/zypper/attributes/default.rb create mode 100644 cookbooks/zypper/libraries/matchers.rb create mode 100644 cookbooks/zypper/metadata.json create mode 100644 cookbooks/zypper/providers/repo.rb create mode 100644 cookbooks/zypper/recipes/default.rb create mode 100644 cookbooks/zypper/recipes/smt_client.rb create mode 100644 cookbooks/zypper/resources/repo.rb diff --git a/Batali b/Batali index f4c3a18..2e8ac02 100644 --- a/Batali +++ b/Batali @@ -14,11 +14,11 @@ Batali.define do ref: 'relax_dependencies' cookbook 'postfix' cookbook 'unattended-upgrades' - cookbook 'poise-ruby-build', '~> 1.1.0' - cookbook 'application' + cookbook 'poise-ruby-build', '~> 1.1.0' + cookbook 'application', '~> 5.2.0' cookbook 'application_javascript' cookbook 'application_ruby' - cookbook 'application_git' + cookbook 'application_git', '~> 1.1.0' # 1.2.0 doesn't work with knife-solo cookbook 'users' cookbook 'sudo' cookbook 'hostname' @@ -27,7 +27,7 @@ Batali.define do ref: 'v0.5.6' cookbook 'ufw' cookbook 'firewall' - cookbook 'nginx' + cookbook 'chef_nginx' cookbook 'build-essential' cookbook 'mysql' cookbook 'postgresql', '~> 6.1' diff --git a/batali.manifest b/batali.manifest index 532457c..b6dcb72 100644 --- a/batali.manifest +++ b/batali.manifest @@ -21,7 +21,7 @@ "> 0" ], [ - "nginx", + "chef_nginx", "> 0" ], [ @@ -33,10 +33,10 @@ "> 0" ] ], - "version": "0.2.0", + "version": "0.3.0", "source": { "url": "https://github.com/67P/mediawiki-cookbook.git", - "ref": "41d3c5129b5a6cd9c473e99339885bc1feac5d57", + "ref": "8da675abc28b1b1ccf00d32df8a1923208e762c9", "type": "Batali::Source::Git", "subdirectory": null } @@ -361,107 +361,34 @@ } }, { - "name": "nginx", + "name": "chef_nginx", "dependencies": [ - [ - "apt", - "~> 2.2" - ], - [ - "bluepill", - "~> 2.3" - ], [ "build-essential", - "~> 2.0" + ">= 0.0.0" ], [ "ohai", - "~> 2.0" - ], - [ - "runit", - "~> 1.2" + ">= 4.1.0" ], [ "yum-epel", - "~> 0.3" - ] - ], - "version": "2.7.6", - "source": { - "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/nginx/versions/2.7.6/download", - "version": "2.7.6" - } - }, - { - "name": "apt", - "dependencies": [ - - ], - "version": "2.9.2", - "source": { - "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/apt/versions/2.9.2/download", - "version": "2.9.2" - } - }, - { - "name": "bluepill", - "dependencies": [ + ">= 0.0.0" + ], [ - "rsyslog", - ">= 2.0" - ] - ], - "version": "2.4.3", - "source": { - "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/bluepill/versions/2.4.3/download", - "version": "2.4.3" - } - }, - { - "name": "rsyslog", - "dependencies": [ - - ], - "version": "2.2.0", - "source": { - "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/rsyslog/versions/2.2.0/download", - "version": "2.2.0" - } - }, - { - "name": "build-essential", - "dependencies": [ + "compat_resource", + ">= 12.16.3" + ], [ - "7-zip", + "zypper", ">= 0.0.0" ] ], - "version": "2.4.0", + "version": "6.0.2", "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" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/chef_nginx/versions/6.0.2/download", + "version": "6.0.2" } }, { @@ -469,53 +396,23 @@ "dependencies": [ ], - "version": "2.1.0", + "version": "5.0.4", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/ohai/versions/2.1.0/download", - "version": "2.1.0" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/ohai/versions/5.0.4/download", + "version": "5.0.4" } }, { - "name": "runit", - "dependencies": [ - [ - "packagecloud", - ">= 0.0.0" - ] - ], - "version": "1.7.6", - "source": { - "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/runit/versions/1.7.6/download", - "version": "1.7.6" - } - }, - { - "name": "packagecloud", + "name": "zypper", "dependencies": [ ], - "version": "0.2.0", + "version": "0.4.0", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/packagecloud/versions/0.2.0/download", - "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" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/zypper/versions/0.4.0/download", + "version": "0.4.0" } }, { @@ -564,6 +461,18 @@ "version": "0.3.1" } }, + { + "name": "apt", + "dependencies": [ + + ], + "version": "2.9.2", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/apt/versions/2.9.2/download", + "version": "2.9.2" + } + }, { "name": "php-fpm", "dependencies": [ @@ -624,8 +533,8 @@ ">= 0.3.1" ], [ - "nginx", - "~> 2.7.4" + "chef_nginx", + "> 0" ], [ "php-fpm", @@ -636,10 +545,10 @@ "~> 0.7" ] ], - "version": "3.0.0", + "version": "3.1.0", "source": { "url": "https://github.com/67P/wordpress-cookbook.git", - "ref": "d6401db517476e6f3ab36aa92dfc0f5ed6a8a264", + "ref": "a80b8a17fb823a01b769f690349d745c40fff04c", "type": "Batali::Source::Git", "subdirectory": null } @@ -696,22 +605,30 @@ } }, { - "name": "application", + "name": "poise-ruby-build", "dependencies": [ [ "poise", - "~> 2.4" + "~> 2.0" ], [ - "poise-service", + "poise-build-essential", "~> 1.0" + ], + [ + "poise-git", + "~> 1.0" + ], + [ + "poise-ruby", + "~> 2.1" ] ], - "version": "5.1.0", + "version": "1.1.0", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/application/versions/5.1.0/download", - "version": "5.1.0" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/poise-ruby-build/versions/1.1.0/download", + "version": "1.1.0" } }, { @@ -726,6 +643,112 @@ "version": "2.7.2" } }, + { + "name": "poise-build-essential", + "dependencies": [ + [ + "poise", + "~> 2.6" + ] + ], + "version": "1.0.0", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/poise-build-essential/versions/1.0.0/download", + "version": "1.0.0" + } + }, + { + "name": "poise-git", + "dependencies": [ + [ + "poise", + "~> 2.6" + ], + [ + "poise-languages", + "~> 2.1" + ] + ], + "version": "1.0.0", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/poise-git/versions/1.0.0/download", + "version": "1.0.0" + } + }, + { + "name": "poise-languages", + "dependencies": [ + [ + "poise", + "~> 2.5" + ], + [ + "poise-archive", + "~> 1.0" + ] + ], + "version": "2.1.0", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/poise-languages/versions/2.1.0/download", + "version": "2.1.0" + } + }, + { + "name": "poise-archive", + "dependencies": [ + [ + "poise", + "~> 2.6" + ] + ], + "version": "1.4.0", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/poise-archive/versions/1.4.0/download", + "version": "1.4.0" + } + }, + { + "name": "poise-ruby", + "dependencies": [ + [ + "poise", + "~> 2.0" + ], + [ + "poise-languages", + "~> 2.0" + ] + ], + "version": "2.2.0", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/poise-ruby/versions/2.2.0/download", + "version": "2.2.0" + } + }, + { + "name": "application", + "dependencies": [ + [ + "poise", + "~> 2.4" + ], + [ + "poise-service", + "~> 1.0" + ] + ], + "version": "5.2.0", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/application/versions/5.2.0/download", + "version": "5.2.0" + } + }, { "name": "poise-service", "dependencies": [ @@ -787,40 +810,6 @@ "version": "1.1.0" } }, - { - "name": "poise-languages", - "dependencies": [ - [ - "poise", - "~> 2.5" - ], - [ - "poise-archive", - "~> 1.0" - ] - ], - "version": "2.1.0", - "source": { - "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/poise-languages/versions/2.1.0/download", - "version": "2.1.0" - } - }, - { - "name": "poise-archive", - "dependencies": [ - [ - "poise", - "~> 2.6" - ] - ], - "version": "1.4.0", - "source": { - "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/poise-archive/versions/1.4.0/download", - "version": "1.4.0" - } - }, { "name": "application_ruby", "dependencies": [ @@ -848,25 +837,6 @@ "version": "4.0.1" } }, - { - "name": "poise-ruby", - "dependencies": [ - [ - "poise", - "~> 2.0" - ], - [ - "poise-languages", - "~> 2.0" - ] - ], - "version": "2.2.0", - "source": { - "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/poise-ruby/versions/2.2.0/download", - "version": "2.2.0" - } - }, { "name": "application_git", "dependencies": [ @@ -918,11 +888,11 @@ "dependencies": [ ], - "version": "3.1.0", + "version": "4.0.0", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/dmg/versions/3.1.0/download", - "version": "3.1.0" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/dmg/versions/4.0.0/download", + "version": "4.0.0" } }, { @@ -1123,67 +1093,6 @@ "url": "https://supermarket.chef.io:443/api/v1/cookbooks/logrotate/versions/1.9.2/download", "version": "1.9.2" } - }, - { - "name": "poise-ruby-build", - "dependencies": [ - [ - "poise", - "~> 2.0" - ], - [ - "poise-build-essential", - "~> 1.0" - ], - [ - "poise-git", - "~> 1.0" - ], - [ - "poise-ruby", - "~> 2.1" - ] - ], - "version": "1.1.0", - "source": { - "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/poise-ruby-build/versions/1.1.0/download", - "version": "1.1.0" - } - }, - { - "name": "poise-build-essential", - "dependencies": [ - [ - "poise", - "~> 2.6" - ] - ], - "version": "1.0.0", - "source": { - "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/poise-build-essential/versions/1.0.0/download", - "version": "1.0.0" - } - }, - { - "name": "poise-git", - "dependencies": [ - [ - "poise", - "~> 2.6" - ], - [ - "poise-languages", - "~> 2.1" - ] - ], - "version": "1.0.0", - "source": { - "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/poise-git/versions/1.0.0/download", - "version": "1.0.0" - } } ] } \ No newline at end of file diff --git a/cookbooks/7-zip/CHANGELOG.md b/cookbooks/7-zip/CHANGELOG.md deleted file mode 100644 index 183bcf7..0000000 --- a/cookbooks/7-zip/CHANGELOG.md +++ /dev/null @@ -1,13 +0,0 @@ -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 deleted file mode 100644 index 4bfd6be..0000000 --- a/cookbooks/7-zip/README.md +++ /dev/null @@ -1,50 +0,0 @@ -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 deleted file mode 100644 index adc1903..0000000 --- a/cookbooks/7-zip/attributes/default.rb +++ /dev/null @@ -1,31 +0,0 @@ -# -# 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 deleted file mode 100644 index 98ab32d..0000000 --- a/cookbooks/7-zip/metadata.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "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 deleted file mode 100644 index fa83e9f..0000000 --- a/cookbooks/7-zip/metadata.rb +++ /dev/null @@ -1,10 +0,0 @@ -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/7-zip/recipes/default.rb b/cookbooks/7-zip/recipes/default.rb deleted file mode 100644 index 155cbb6..0000000 --- a/cookbooks/7-zip/recipes/default.rb +++ /dev/null @@ -1,31 +0,0 @@ -# -# Author:: Seth Chisamore () -# Cookbook Name:: 7-zip -# Recipe:: 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. -# - -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/application/CHANGELOG.md b/cookbooks/application/CHANGELOG.md index 1a4498d..74c8643 100644 --- a/cookbooks/application/CHANGELOG.md +++ b/cookbooks/application/CHANGELOG.md @@ -1,8 +1,13 @@ # Application Changelog +## v5.2.0 + +* Add `application_directory` resource. +* Chef 13 compatibility. + ## v5.1.0 -* Add `application_cookbook_file`, `application_file`, and `application_template resources. +* Add `application_cookbook_file`, `application_file`, and `application_template` resources. ## v5.0.0 diff --git a/cookbooks/application/README.md b/cookbooks/application/README.md index 6089ca3..3696a6e 100644 --- a/cookbooks/application/README.md +++ b/cookbooks/application/README.md @@ -137,9 +137,9 @@ end * `action_on_update_immediately` – Run the `action_on_update` notification with `:immediately`. *(default: false)* -### `application_cookbook_file`, `application_file`, `application_template` +### `application_cookbook_file`, `application_directory`, `application_file`, `application_template` -The `application_cookbook_file`, `application_file`, and `application_template` +The `application_cookbook_file`, `application_directory`, `application_file`, and `application_template` resources extend the core Chef resources to take some application-level configuration in to account: @@ -148,6 +148,7 @@ application '/opt/myapp' do template 'myapp.conf' do source 'myapp.conf.erb' end + directory 'logs' end ``` @@ -163,9 +164,9 @@ Some test recipes are available as examples for common application frameworks: * [Sinatra](https://github.com/poise/application_ruby/blob/master/test/cookbooks/application_ruby_test/recipes/sinatra.rb) * [Rails](https://github.com/poise/application_ruby/blob/master/test/cookbooks/application_ruby_test/recipes/rails.rb) -* [Flask](https://github.com/poise/application_python/blob/master/test/cookbooks/application_python_test/recipes/flask.rb) -* [Django](https://github.com/poise/application_python/blob/master/test/cookbooks/application_python_test/recipes/django.rb) -* [Express](https://github.com/poise/application_javascript/blob/master/test/cookbooks/application_javascript_test/recipes/express.rb) +* [Flask](https://github.com/poise/application_python/blob/master/test/cookbook/recipes/flask.rb) +* [Django](https://github.com/poise/application_python/blob/master/test/cookbook/recipes/django.rb) +* [Express](https://github.com/poise/application_javascript/blob/master/test/cookbook/recipes/express.rb) ## Upgrading From 4.x @@ -244,7 +245,7 @@ The Poise test server infrastructure is sponsored by [Rackspace](https://rackspa ## License -Copyright 2015, Noah Kantrowitz +Copyright 2015-2016, Noah Kantrowitz 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/application/files/halite_gem/poise_application.rb b/cookbooks/application/files/halite_gem/poise_application.rb index 13c9825..8d771c4 100644 --- a/cookbooks/application/files/halite_gem/poise_application.rb +++ b/cookbooks/application/files/halite_gem/poise_application.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2016, Noah Kantrowitz # # 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/application/files/halite_gem/poise_application/app_file_mixin.rb b/cookbooks/application/files/halite_gem/poise_application/app_file_mixin.rb index 9f4a377..8ad14a9 100644 --- a/cookbooks/application/files/halite_gem/poise_application/app_file_mixin.rb +++ b/cookbooks/application/files/halite_gem/poise_application/app_file_mixin.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2016, Noah Kantrowitz # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -48,10 +48,13 @@ module PoiseApplication # @return [String, Integer] attribute(:group, kind_of: [String, Integer, NilClass], default: lazy { parent && parent.group }) - # @!attribute user + # @!attribute owner # Override the default user to be the app owner if unspecified. # @return [String, Integer] - attribute(:user, kind_of: [String, Integer, NilClass], default: lazy { parent && parent.owner }) + attribute(:owner, kind_of: [String, Integer, NilClass], default: lazy { parent && parent.owner }) + + # For the forgetful. + alias_method :user, :owner end module Provider diff --git a/cookbooks/application/files/halite_gem/poise_application/app_mixin.rb b/cookbooks/application/files/halite_gem/poise_application/app_mixin.rb index 7ce3d53..611d1f8 100644 --- a/cookbooks/application/files/halite_gem/poise_application/app_mixin.rb +++ b/cookbooks/application/files/halite_gem/poise_application/app_mixin.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2016, Noah Kantrowitz # # 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/application/files/halite_gem/poise_application/cheftie.rb b/cookbooks/application/files/halite_gem/poise_application/cheftie.rb index 622ba83..52e47b2 100644 --- a/cookbooks/application/files/halite_gem/poise_application/cheftie.rb +++ b/cookbooks/application/files/halite_gem/poise_application/cheftie.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2016, Noah Kantrowitz # # 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/application/files/halite_gem/poise_application/error.rb b/cookbooks/application/files/halite_gem/poise_application/error.rb index 4156956..ed43760 100644 --- a/cookbooks/application/files/halite_gem/poise_application/error.rb +++ b/cookbooks/application/files/halite_gem/poise_application/error.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2016, Noah Kantrowitz # # 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/application/files/halite_gem/poise_application/resources.rb b/cookbooks/application/files/halite_gem/poise_application/resources.rb index 4797a80..31129bd 100644 --- a/cookbooks/application/files/halite_gem/poise_application/resources.rb +++ b/cookbooks/application/files/halite_gem/poise_application/resources.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2016, Noah Kantrowitz # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ require 'poise_application/resources/application' require 'poise_application/resources/application_cookbook_file' +require 'poise_application/resources/application_directory' require 'poise_application/resources/application_file' require 'poise_application/resources/application_template' diff --git a/cookbooks/application/files/halite_gem/poise_application/resources/application.rb b/cookbooks/application/files/halite_gem/poise_application/resources/application.rb index e0efbf2..524a124 100644 --- a/cookbooks/application/files/halite_gem/poise_application/resources/application.rb +++ b/cookbooks/application/files/halite_gem/poise_application/resources/application.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2016, Noah Kantrowitz # # 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/application/files/halite_gem/poise_application/resources/application_cookbook_file.rb b/cookbooks/application/files/halite_gem/poise_application/resources/application_cookbook_file.rb index bcb6830..aeb6ead 100644 --- a/cookbooks/application/files/halite_gem/poise_application/resources/application_cookbook_file.rb +++ b/cookbooks/application/files/halite_gem/poise_application/resources/application_cookbook_file.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2016, Noah Kantrowitz # # 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/application/files/halite_gem/poise_application/resources/application_directory.rb b/cookbooks/application/files/halite_gem/poise_application/resources/application_directory.rb new file mode 100644 index 0000000..a32bef5 --- /dev/null +++ b/cookbooks/application/files/halite_gem/poise_application/resources/application_directory.rb @@ -0,0 +1,50 @@ +# +# Copyright 2015-2016, Noah Kantrowitz +# +# 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 'poise_application/app_file_mixin' + + +module PoiseApplication + module Resources + # (see ApplicationDirectory::Resource) + # @since 5.1.0 + module ApplicationDirectory + # An `application_directory` resource to manage Chef files inside and + # Application cookbook deployment. + # + # @provides application_directory + # @action create + # @action delete + # @example + # application '/srv/myapp' do + # directory 'logs' + # end + class Resource < Chef::Resource::Directory + include PoiseApplication::AppFileMixin + provides(:application_directory) + actions(:create, :delete) + subclass_providers! + + def initialize(*args) + super + # For older Chef. + @resource_name = :application_directory + end + end + + end + end +end diff --git a/cookbooks/application/files/halite_gem/poise_application/resources/application_file.rb b/cookbooks/application/files/halite_gem/poise_application/resources/application_file.rb index a766088..95eac83 100644 --- a/cookbooks/application/files/halite_gem/poise_application/resources/application_file.rb +++ b/cookbooks/application/files/halite_gem/poise_application/resources/application_file.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2016, Noah Kantrowitz # # 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/application/files/halite_gem/poise_application/resources/application_template.rb b/cookbooks/application/files/halite_gem/poise_application/resources/application_template.rb index 27e7f0b..dff0151 100644 --- a/cookbooks/application/files/halite_gem/poise_application/resources/application_template.rb +++ b/cookbooks/application/files/halite_gem/poise_application/resources/application_template.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2016, Noah Kantrowitz # # 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/application/files/halite_gem/poise_application/service_mixin.rb b/cookbooks/application/files/halite_gem/poise_application/service_mixin.rb index 176fb29..0649159 100644 --- a/cookbooks/application/files/halite_gem/poise_application/service_mixin.rb +++ b/cookbooks/application/files/halite_gem/poise_application/service_mixin.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2016, Noah Kantrowitz # # 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/application/files/halite_gem/poise_application/utils.rb b/cookbooks/application/files/halite_gem/poise_application/utils.rb index cc3f874..0a93c77 100644 --- a/cookbooks/application/files/halite_gem/poise_application/utils.rb +++ b/cookbooks/application/files/halite_gem/poise_application/utils.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2016, Noah Kantrowitz # # 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/application/files/halite_gem/poise_application/version.rb b/cookbooks/application/files/halite_gem/poise_application/version.rb index bb3f482..02c4411 100644 --- a/cookbooks/application/files/halite_gem/poise_application/version.rb +++ b/cookbooks/application/files/halite_gem/poise_application/version.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2016, Noah Kantrowitz # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -16,5 +16,5 @@ module PoiseApplication - VERSION = '5.1.0' + VERSION = '5.2.0' end diff --git a/cookbooks/application/libraries/default.rb b/cookbooks/application/libraries/default.rb index ebf4f00..21614d8 100644 --- a/cookbooks/application/libraries/default.rb +++ b/cookbooks/application/libraries/default.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2016, Noah Kantrowitz # # 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/application/metadata.json b/cookbooks/application/metadata.json index a491ee2..02fb71f 100644 --- a/cookbooks/application/metadata.json +++ b/cookbooks/application/metadata.json @@ -1 +1 @@ -{"name":"application","version":"5.1.0","description":"A Chef cookbook for deploying application code.","long_description":"# Application cookbook\n\n[![Build Status](https://img.shields.io/travis/poise/application.svg)](https://travis-ci.org/poise/application)\n[![Gem Version](https://img.shields.io/gem/v/poise-application.svg)](https://rubygems.org/gems/poise-application)\n[![Cookbook Version](https://img.shields.io/cookbook/v/application.svg)](https://supermarket.chef.io/cookbooks/application)\n[![Coverage](https://img.shields.io/codeclimate/coverage/github/poise/application.svg)](https://codeclimate.com/github/poise/application)\n[![Gemnasium](https://img.shields.io/gemnasium/poise/application.svg)](https://gemnasium.com/poise/application)\n[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)\n\nA [Chef](https://www.chef.io/) cookbook to deploy applications.\n\n## Getting Started\n\nThe application cookbook provides a central framework to deploy applications\nusing Chef. Generally this will be web applications using things like Rails,\nDjango, or NodeJS, but the framework makes no specific assumptions. The core\n`application` resource provides DSL support and helpers, but the heavy lifting\nis all done in specific plugins detailed below. Each deployment starts with\nan `application` resource:\n\n```ruby\napplication '/path/to/deploy' do\n owner 'root'\n group 'root'\n\n # ...\nend\n```\n\nThe `application` resource uses the Poise subresource system for plugins. This\nmeans you configure the steps of the deployment like normal recipe code inside\nthe `application` resource, with a few special additions:\n\n```ruby\napplication '/path/to/deploy' do\n # Application resource properties.\n owner 'root'\n group 'root'\n\n # Subresources, like normal recipe code.\n package 'ruby'\n git '/path/to/deploy' do\n repository 'https://github.com/example/myapp.git'\n end\n application_rails '/path/to/deploy' do\n database 'mysql://dbhost/myapp'\n end\nend\n```\n\nWhen evaluating the recipe inside the `application` resource, it first checks\nfor `application_#{resource}`, as well as looking for an LWRP of the same name\nin any cookbook starting with `application_`. This means that a resource named\n`application_foo` can be used as `foo` inside the `application` resource:\n\n```ruby\napplication '/path/to/deploy' do\n owner 'root'\n group 'root'\n\n rails '/path/to/deploy' do\n database 'mysql://dbhost/myapp'\n end\nend\n```\n\nAdditionally if a resource inside the `application` block doesn't have a name,\nit uses the same name as the application resource itself:\n\n```ruby\napplication '/path/to/deploy' do\n owner 'root'\n group 'root'\n\n rails do\n database 'mysql://dbhost/myapp'\n end\nend\n```\n\nOther than those two special features, the recipe code inside the `application`\nresource is processed just like any other recipe.\n\n## Available Plugins\n\n* [`application_git`](https://github.com/poise/application_git) – Deploy\n application code from a git repository.\n* [`application_ruby`](https://github.com/poise/application_ruby) – Manage Ruby\n deployments, such as Rails or Sinatra applications.\n* [`application_python`](https://github.com/poise/application_python) – Manage\n Python deployments, such as Django or Flask applications.\n* [`application_javascript`](https://github.com/poise/application_javascript) –\n Manage server-side JavaScript deployments using Node.js or io.js.\n* `application_java` – *Coming soon!*\n* `application_go` – *Coming soon!*\n* `application_erlang` – *Coming soon!*\n\n## Requirements\n\nChef 12 or newer is required.\n\n## Resources\n\n### `application`\n\nThe `application` resource has top-level configuration properties for each\ndeployment and acts as a container for other deployment plugin resources.\n\n```ruby\napplication '/opt/test_sinatra' do\n git 'https://github.com/example/my_sinatra_app.git'\n bundle_install do\n deployment true\n end\n unicorn do\n port 9000\n end\nend\n```\n\n#### Actions\n\n* `:deploy` – Deploy the application. *(default)*\n* `:start` - Run `:start` on all subresources that support it.\n* `:stop` - Run `:stop` on all subresources that support it.\n* `:restart` - Run `:restart` on all subresources that support it.\n* `:reload` - Run `:reload` on all subresources that support it.\n\n#### Properties\n\n* `path` – Path to deploy the application to. *(name attribute)*\n* `environment` – Environment variables for all application deployment steps.\n* `group` – System group to deploy the application as.\n* `owner` – System user to deploy the application as.\n* `action_on_update` – Action to run on the application resource when any\n subresource is updated. *(default: restart)*\n* `action_on_update_immediately` – Run the `action_on_update` notification with\n `:immediately`. *(default: false)*\n\n### `application_cookbook_file`, `application_file`, `application_template`\n\nThe `application_cookbook_file`, `application_file`, and `application_template`\nresources extend the core Chef resources to take some application-level\nconfiguration in to account:\n\n```ruby\napplication '/opt/myapp' do\n template 'myapp.conf' do\n source 'myapp.conf.erb'\n end\nend\n```\n\nIf the resource name is a relative path, it will be expanded relative to the\napplication path. If an owner or group is declared for the application, those\nwill be the default user and group for the resource.\n\nAll other actions and properties are the same as the similar resource in core Chef.\n\n## Examples\n\nSome test recipes are available as examples for common application frameworks:\n\n* [Sinatra](https://github.com/poise/application_ruby/blob/master/test/cookbooks/application_ruby_test/recipes/sinatra.rb)\n* [Rails](https://github.com/poise/application_ruby/blob/master/test/cookbooks/application_ruby_test/recipes/rails.rb)\n* [Flask](https://github.com/poise/application_python/blob/master/test/cookbooks/application_python_test/recipes/flask.rb)\n* [Django](https://github.com/poise/application_python/blob/master/test/cookbooks/application_python_test/recipes/django.rb)\n* [Express](https://github.com/poise/application_javascript/blob/master/test/cookbooks/application_javascript_test/recipes/express.rb)\n\n## Upgrading From 4.x\n\nWhile the overall design of the revamped application resource is similar to the\n4.x version, some changes will need to be made. The `name` property no longer\nexists, with the name attribute being used as the path to the deployment.\nThe `packages` property has been removed as this is more easily handled via\nnormal recipe code.\n\nThe SCM-related properties like `repository` and `revision` are now handled by\nnormal plugins. If you were deploying from a private git repository you will\nlikely want to use the `application_git` cookbook, otherwise just use the\nbuilt-in `git` or `svn` resources as per normal.\n\nThe properties related to the `deploy` resource like `strategy` and `symlinks`\nhave been removed. The `deploy` resource is no longer used so these aren't\nrelevant. As a side effect of this, you'll likely want to point the upgraded\ndeployment at a new folder or manually clean the `current` and `shared` folders\nfrom the existing folder. The pseudo-Capistrano layout used by the `deploy`\nresource has few benefits in a config-managed world and introduced a lot of\ncomplexity and moving pieces that are no longer required.\n\nWith the removal of the `deploy` resource, the callback properties and commands\nare no longer used as well. Subresources no longer use the complex\nactions-as-callbacks arrangement as existed before, instead following normal\nChef recipe flow. Individual subresources may need to be tweaked to work with\nnewer versions of the cookbooks they come from, though most have stayed similar\nin overall approach.\n\n## Database Migrations and Chef\n\nSeveral of the web application deployment plugins include optional support to\nrun database migrations from Chef. For \"toy\" applications where the app and\ndatabase run together on a single machine, this is fine and is a nice time\nsaver. For anything more complex I highly recommend not running database\nmigrations from Chef. Some initial operations like creating the database and/or\ndatabase user are more reasonable as they tend to be done only once and by their\nnature the application does not yet have users so some level of eventual\nconsistency is more acceptable. With migrations on a production application, I\nencourage using Chef and the application cookbooks to handle deploying the code\nand writing configuration files, but use something more specific to run the\nactual migration task. [Fabric](http://www.fabfile.org/),\n[Capistrano](http://capistranorb.com/), and [Rundeck](http://rundeck.org/) are\nall good choices for this orchestration tooling.\n\nMigrations can generally be applied idempotently but they have unique\nconstraints (pun definitely intended) that make them tricky in a Chef-like,\nconvergence-based system. First and foremost is that many table alterations\nlock the table for updating for at least some period of time. That can mean that\nwhile staging the new code or configuration data can happen within a window, the\nmigration itself needs to be run in careful lockstep with the rest of the\ndeployment process (eg. moving things in and out of load balancers). Beyond\nthat, while most web frameworks have internal idempotence checks for migrations,\nrunning the process on two servers at the same time can have unexpected effects.\n\nOverall migrations are best thought of as a procedural step rather than a\ndeclaratively modeled piece of the system.\n\n## Application Signals and Updates\n\nThe `application` resource exposes `start`, `stop`, `restart`, and `reload`\nactions which will dispatch to any subresources attached to the application.\nThis allows for generic application-level restart or reload signals that will\nwork with any type of deployment.\n\nAdditionally the `action_on_update` property is used to set a default\nnotification so any subresource that updates will trigger an application\nrestart or reload. This can be disabled by setting `action_on_update false` if\nyou want to take manual control of service restarts.\n\n## Sponsors\n\nDevelopment sponsored by [Chef Software](https://www.chef.io/), [Symonds & Son](http://symondsandson.com/), and [Orion](https://www.orionlabs.co/).\n\nThe Poise test server infrastructure is sponsored by [Rackspace](https://rackspace.com/).\n\n## License\n\nCopyright 2015, Noah Kantrowitz\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","maintainer":"Noah Kantrowitz","maintainer_email":"noah@coderanger.net","license":"Apache 2.0","platforms":{},"dependencies":{"poise":"~> 2.4","poise-service":"~> 1.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{}} \ No newline at end of file +{"name":"application","version":"5.2.0","description":"A Chef cookbook for deploying application code.","long_description":"# Application cookbook\n\n[![Build Status](https://img.shields.io/travis/poise/application.svg)](https://travis-ci.org/poise/application)\n[![Gem Version](https://img.shields.io/gem/v/poise-application.svg)](https://rubygems.org/gems/poise-application)\n[![Cookbook Version](https://img.shields.io/cookbook/v/application.svg)](https://supermarket.chef.io/cookbooks/application)\n[![Coverage](https://img.shields.io/codeclimate/coverage/github/poise/application.svg)](https://codeclimate.com/github/poise/application)\n[![Gemnasium](https://img.shields.io/gemnasium/poise/application.svg)](https://gemnasium.com/poise/application)\n[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)\n\nA [Chef](https://www.chef.io/) cookbook to deploy applications.\n\n## Getting Started\n\nThe application cookbook provides a central framework to deploy applications\nusing Chef. Generally this will be web applications using things like Rails,\nDjango, or NodeJS, but the framework makes no specific assumptions. The core\n`application` resource provides DSL support and helpers, but the heavy lifting\nis all done in specific plugins detailed below. Each deployment starts with\nan `application` resource:\n\n```ruby\napplication '/path/to/deploy' do\n owner 'root'\n group 'root'\n\n # ...\nend\n```\n\nThe `application` resource uses the Poise subresource system for plugins. This\nmeans you configure the steps of the deployment like normal recipe code inside\nthe `application` resource, with a few special additions:\n\n```ruby\napplication '/path/to/deploy' do\n # Application resource properties.\n owner 'root'\n group 'root'\n\n # Subresources, like normal recipe code.\n package 'ruby'\n git '/path/to/deploy' do\n repository 'https://github.com/example/myapp.git'\n end\n application_rails '/path/to/deploy' do\n database 'mysql://dbhost/myapp'\n end\nend\n```\n\nWhen evaluating the recipe inside the `application` resource, it first checks\nfor `application_#{resource}`, as well as looking for an LWRP of the same name\nin any cookbook starting with `application_`. This means that a resource named\n`application_foo` can be used as `foo` inside the `application` resource:\n\n```ruby\napplication '/path/to/deploy' do\n owner 'root'\n group 'root'\n\n rails '/path/to/deploy' do\n database 'mysql://dbhost/myapp'\n end\nend\n```\n\nAdditionally if a resource inside the `application` block doesn't have a name,\nit uses the same name as the application resource itself:\n\n```ruby\napplication '/path/to/deploy' do\n owner 'root'\n group 'root'\n\n rails do\n database 'mysql://dbhost/myapp'\n end\nend\n```\n\nOther than those two special features, the recipe code inside the `application`\nresource is processed just like any other recipe.\n\n## Available Plugins\n\n* [`application_git`](https://github.com/poise/application_git) – Deploy\n application code from a git repository.\n* [`application_ruby`](https://github.com/poise/application_ruby) – Manage Ruby\n deployments, such as Rails or Sinatra applications.\n* [`application_python`](https://github.com/poise/application_python) – Manage\n Python deployments, such as Django or Flask applications.\n* [`application_javascript`](https://github.com/poise/application_javascript) –\n Manage server-side JavaScript deployments using Node.js or io.js.\n* `application_java` – *Coming soon!*\n* `application_go` – *Coming soon!*\n* `application_erlang` – *Coming soon!*\n\n## Requirements\n\nChef 12 or newer is required.\n\n## Resources\n\n### `application`\n\nThe `application` resource has top-level configuration properties for each\ndeployment and acts as a container for other deployment plugin resources.\n\n```ruby\napplication '/opt/test_sinatra' do\n git 'https://github.com/example/my_sinatra_app.git'\n bundle_install do\n deployment true\n end\n unicorn do\n port 9000\n end\nend\n```\n\n#### Actions\n\n* `:deploy` – Deploy the application. *(default)*\n* `:start` - Run `:start` on all subresources that support it.\n* `:stop` - Run `:stop` on all subresources that support it.\n* `:restart` - Run `:restart` on all subresources that support it.\n* `:reload` - Run `:reload` on all subresources that support it.\n\n#### Properties\n\n* `path` – Path to deploy the application to. *(name attribute)*\n* `environment` – Environment variables for all application deployment steps.\n* `group` – System group to deploy the application as.\n* `owner` – System user to deploy the application as.\n* `action_on_update` – Action to run on the application resource when any\n subresource is updated. *(default: restart)*\n* `action_on_update_immediately` – Run the `action_on_update` notification with\n `:immediately`. *(default: false)*\n\n### `application_cookbook_file`, `application_directory`, `application_file`, `application_template`\n\nThe `application_cookbook_file`, `application_directory`, `application_file`, and `application_template`\nresources extend the core Chef resources to take some application-level\nconfiguration in to account:\n\n```ruby\napplication '/opt/myapp' do\n template 'myapp.conf' do\n source 'myapp.conf.erb'\n end\n directory 'logs'\nend\n```\n\nIf the resource name is a relative path, it will be expanded relative to the\napplication path. If an owner or group is declared for the application, those\nwill be the default user and group for the resource.\n\nAll other actions and properties are the same as the similar resource in core Chef.\n\n## Examples\n\nSome test recipes are available as examples for common application frameworks:\n\n* [Sinatra](https://github.com/poise/application_ruby/blob/master/test/cookbooks/application_ruby_test/recipes/sinatra.rb)\n* [Rails](https://github.com/poise/application_ruby/blob/master/test/cookbooks/application_ruby_test/recipes/rails.rb)\n* [Flask](https://github.com/poise/application_python/blob/master/test/cookbook/recipes/flask.rb)\n* [Django](https://github.com/poise/application_python/blob/master/test/cookbook/recipes/django.rb)\n* [Express](https://github.com/poise/application_javascript/blob/master/test/cookbook/recipes/express.rb)\n\n## Upgrading From 4.x\n\nWhile the overall design of the revamped application resource is similar to the\n4.x version, some changes will need to be made. The `name` property no longer\nexists, with the name attribute being used as the path to the deployment.\nThe `packages` property has been removed as this is more easily handled via\nnormal recipe code.\n\nThe SCM-related properties like `repository` and `revision` are now handled by\nnormal plugins. If you were deploying from a private git repository you will\nlikely want to use the `application_git` cookbook, otherwise just use the\nbuilt-in `git` or `svn` resources as per normal.\n\nThe properties related to the `deploy` resource like `strategy` and `symlinks`\nhave been removed. The `deploy` resource is no longer used so these aren't\nrelevant. As a side effect of this, you'll likely want to point the upgraded\ndeployment at a new folder or manually clean the `current` and `shared` folders\nfrom the existing folder. The pseudo-Capistrano layout used by the `deploy`\nresource has few benefits in a config-managed world and introduced a lot of\ncomplexity and moving pieces that are no longer required.\n\nWith the removal of the `deploy` resource, the callback properties and commands\nare no longer used as well. Subresources no longer use the complex\nactions-as-callbacks arrangement as existed before, instead following normal\nChef recipe flow. Individual subresources may need to be tweaked to work with\nnewer versions of the cookbooks they come from, though most have stayed similar\nin overall approach.\n\n## Database Migrations and Chef\n\nSeveral of the web application deployment plugins include optional support to\nrun database migrations from Chef. For \"toy\" applications where the app and\ndatabase run together on a single machine, this is fine and is a nice time\nsaver. For anything more complex I highly recommend not running database\nmigrations from Chef. Some initial operations like creating the database and/or\ndatabase user are more reasonable as they tend to be done only once and by their\nnature the application does not yet have users so some level of eventual\nconsistency is more acceptable. With migrations on a production application, I\nencourage using Chef and the application cookbooks to handle deploying the code\nand writing configuration files, but use something more specific to run the\nactual migration task. [Fabric](http://www.fabfile.org/),\n[Capistrano](http://capistranorb.com/), and [Rundeck](http://rundeck.org/) are\nall good choices for this orchestration tooling.\n\nMigrations can generally be applied idempotently but they have unique\nconstraints (pun definitely intended) that make them tricky in a Chef-like,\nconvergence-based system. First and foremost is that many table alterations\nlock the table for updating for at least some period of time. That can mean that\nwhile staging the new code or configuration data can happen within a window, the\nmigration itself needs to be run in careful lockstep with the rest of the\ndeployment process (eg. moving things in and out of load balancers). Beyond\nthat, while most web frameworks have internal idempotence checks for migrations,\nrunning the process on two servers at the same time can have unexpected effects.\n\nOverall migrations are best thought of as a procedural step rather than a\ndeclaratively modeled piece of the system.\n\n## Application Signals and Updates\n\nThe `application` resource exposes `start`, `stop`, `restart`, and `reload`\nactions which will dispatch to any subresources attached to the application.\nThis allows for generic application-level restart or reload signals that will\nwork with any type of deployment.\n\nAdditionally the `action_on_update` property is used to set a default\nnotification so any subresource that updates will trigger an application\nrestart or reload. This can be disabled by setting `action_on_update false` if\nyou want to take manual control of service restarts.\n\n## Sponsors\n\nDevelopment sponsored by [Chef Software](https://www.chef.io/), [Symonds & Son](http://symondsandson.com/), and [Orion](https://www.orionlabs.co/).\n\nThe Poise test server infrastructure is sponsored by [Rackspace](https://rackspace.com/).\n\n## License\n\nCopyright 2015-2016, Noah Kantrowitz\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","maintainer":"Noah Kantrowitz","maintainer_email":"noah@coderanger.net","license":"Apache-2.0","platforms":{"aix":">= 0.0.0","amazon":">= 0.0.0","arch":">= 0.0.0","centos":">= 0.0.0","chefspec":">= 0.0.0","debian":">= 0.0.0","dragonfly4":">= 0.0.0","fedora":">= 0.0.0","freebsd":">= 0.0.0","gentoo":">= 0.0.0","ios_xr":">= 0.0.0","mac_os_x":">= 0.0.0","nexus":">= 0.0.0","omnios":">= 0.0.0","openbsd":">= 0.0.0","opensuse":">= 0.0.0","oracle":">= 0.0.0","raspbian":">= 0.0.0","redhat":">= 0.0.0","slackware":">= 0.0.0","smartos":">= 0.0.0","solaris2":">= 0.0.0","suse":">= 0.0.0","ubuntu":">= 0.0.0","windows":">= 0.0.0"},"dependencies":{"poise":"~> 2.4","poise-service":"~> 1.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{},"source_url":"https://github.com/poise/application","issues_url":"https://github.com/poise/application/issues","chef_version":[["< 14",">= 12"]],"ohai_version":[]} \ No newline at end of file diff --git a/cookbooks/bluepill/.foodcritic b/cookbooks/bluepill/.foodcritic deleted file mode 100644 index 6c2ff5a..0000000 --- a/cookbooks/bluepill/.foodcritic +++ /dev/null @@ -1 +0,0 @@ -~FC059 diff --git a/cookbooks/bluepill/CHANGELOG.md b/cookbooks/bluepill/CHANGELOG.md deleted file mode 100644 index 655cf05..0000000 --- a/cookbooks/bluepill/CHANGELOG.md +++ /dev/null @@ -1,87 +0,0 @@ -# bluepill Cookbook CHANGELOG -This file is used to list changes made in each version of the bluepill cookbook. - -## 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) -- 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 -- Added .kitchen.yml file with vagrant based testing for local testing and moved the cloud based kitchen to .kitchen.cloud.yml -- Add Travis CI config -- Added rubocop config -- Updated Berksfile to 3.X format and removed yum cookbook that wasn't used -- Updated contributing.md and added testing.md documentation -- Updated development and testing dependencies in the Gemfile -- Added maintainers.md and .toml and added Rake task for generating the MD file -- Opscode -> Chef Software everywhere -- Added Travis and cookbook version badges to the readme -- Add rake file to easy testing -- Resolved all Rubocop warnings -- Added a chefignore file and added additional files to the gitignore -- Added source_url and issues_url metadata for Supermarket - -## v2.3.2 -- Never actually released - -## v2.3.1 -### New Feature -- **[COOK-3705](https://tickets.chef.io/browse/COOK-3705)** - Add init.d script with LSB style - -## v2.3.0 -### Improvement -- **[COOK-3503](https://tickets.chef.io/browse/COOK-3503)** - Add why-run support - -## v2.2.2 -- [COOK-2507] - stringify language attributes - -## v2.2.0 -- [COOK-547] - Add `load` action to provider to reload services when template changes. - -## 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 -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 -- [COOK-1730] - Add ability to specify which version of bluepill to install - -## v1.1.0 -- [COOK-1592] - use mixlib-shellout instead of execute, add test-kitchen - -## v1.0.6 -- [COOK-1304] - support amazon linux -- [COOK-1427] - resolve foodcritic warnings - -## v1.0.4 -- [COOK-1106] - fix chkconfig loader for CentOS 5 -- [COOK-1107] - use integer for GID instead of string - -## v1.0.2 -- [COOK-1043] - Bluepill cookbook fails on OS X because it tries to use root group - -## v1.0.0 -- [COOK-943] - add init script for freebsd - -## v0.3.0 -- [COOK-867] - enable bluepill service on RHEL family -- [COOK-550] - add freebsd support - -## v0.2.2 -- Fixes COOK-524, COOK-632 diff --git a/cookbooks/bluepill/README.md b/cookbooks/bluepill/README.md deleted file mode 100644 index 68bfebc..0000000 --- a/cookbooks/bluepill/README.md +++ /dev/null @@ -1,111 +0,0 @@ -# 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 -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 12+ - -### Cookbooks -- none - -## 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. - -# 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 -service 'my_app' do - provider bluepill_service - action [:enable, :load, :start] -end - -bluepill_service 'my_app' do - action [:enable, :load, :start] -end -``` - -The load action should probably always be specified, to ensure that if bluepill isn't running already it gets started. The - -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 -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. - -Example pill template resource and .erb file: - -```ruby -template '/etc/bluepill/my_app.pill' do - source 'my_app.pill.erb' -end - -Bluepill.application('my_app') do |app| - app.process('my_app') do |process| - process.pid_file = '/var/run/my_app.pid' - process.start_command = '/usr/bin/my_app' - end -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: - -- enable_bluepill_service -- load_bluepill_service -- reload_bluepill_service -- start_bluepill_service -- disable_bluepill_service -- stop_bluepill_service -- restart_bluepill_service - -### 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. - -``` -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/bluepill/attributes/default.rb b/cookbooks/bluepill/attributes/default.rb deleted file mode 100644 index abbff66..0000000 --- a/cookbooks/bluepill/attributes/default.rb +++ /dev/null @@ -1,44 +0,0 @@ -# Cookbook Name:: bluepill -# Attributes:: default -# -# Copyright 2010-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. - -default['bluepill']['bin'] = "#{node['languages']['ruby']['bin_dir']}/bluepill" -default['bluepill']['logfile'] = '/var/log/bluepill.log' -default['bluepill']['pid_dir'] = '/var/run/bluepill' -default['bluepill']['state_dir'] = '/var/lib/bluepill' -default['bluepill']['group'] = 0 -default['bluepill']['use_rsyslog'] = false - -case node['platform_family'] -when 'arch' - default['bluepill']['init_dir'] = '/etc/rc.d' - default['bluepill']['conf_dir'] = '/etc/bluepill' - default['bluepill']['defaults_dir'] = '/etc/default' -when 'freebsd' - default['bluepill']['init_dir'] = '/usr/local/etc/rc.d' - default['bluepill']['conf_dir'] = '/usr/local/etc/bluepill' - default['bluepill']['defaults_dir'] = '/etc/defaults' -else - default['bluepill']['init_dir'] = '/etc/init.d' - default['bluepill']['conf_dir'] = '/etc/bluepill' -end - -case node['platform_family'] -when 'fedora', 'rhel' - default['bluepill']['defaults_dir'] = '/etc/sysconfig' -when 'debian' - default['bluepill']['defaults_dir'] = '/etc/default' -end diff --git a/cookbooks/bluepill/libraries/matchers.rb b/cookbooks/bluepill/libraries/matchers.rb deleted file mode 100644 index da9fe67..0000000 --- a/cookbooks/bluepill/libraries/matchers.rb +++ /dev/null @@ -1,33 +0,0 @@ -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 deleted file mode 100644 index 9446821..0000000 --- a/cookbooks/bluepill/metadata.json +++ /dev/null @@ -1 +0,0 @@ -{"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/bluepill/providers/service.rb b/cookbooks/bluepill/providers/service.rb deleted file mode 100644 index 45e55f1..0000000 --- a/cookbooks/bluepill/providers/service.rb +++ /dev/null @@ -1,172 +0,0 @@ -# -# Cookbook Name:: bluepill -# Provider:: service -# -# Copyright 2010-2015, Chef Software, Inc. -# Copyright 2012, Heavy Water Operations, 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 'chef/mixin/shell_out' -require 'chef/mixin/language' - -include Chef::Mixin::ShellOut - -def whyrun_supported? - true -end - -action :enable do - config_file = ::File.join(node['bluepill']['conf_dir'], - "#{new_resource.service_name}.pill") - unless @current_resource.enabled - converge_by("enable #{@new_resource}") do - link "#{node['bluepill']['init_dir']}/#{new_resource.service_name}" do - to node['bluepill']['bin'] - only_if { ::File.exist?(config_file) } - end - template_suffix = case node['platform_family'] - when 'rhel', 'fedora', 'freebsd' then node['platform_family'] - when 'debian' then 'lsb' - end - - template "#{node['bluepill']['init_dir']}/bluepill-#{new_resource.service_name}" do - source "bluepill_init.#{template_suffix}.erb" - cookbook 'bluepill' - owner 'root' - group node['bluepill']['group'] - mode '0755' - variables( - service_name: new_resource.service_name, - config_file: config_file - ) - end if template_suffix - - service "bluepill-#{new_resource.service_name}" do - action [:enable] - end - end - end -end - -action :load do - unless @current_resource.running - converge_by("load #{@new_resource}") do - shell_out!(load_command) - end - end -end - -action :reload do - converge_by("reload #{@new_resource}") do - shell_out!(stop_command) if @current_resource.running - shell_out!(load_command) - end -end - -action :start do - unless @current_resource.running - converge_by("start #{@new_resource}") do - shell_out!(start_command) - end - end -end - -action :disable do - if @current_resource.enabled - converge_by("disable #{@new_resource}") do - file "#{node['bluepill']['conf_dir']}/#{new_resource.service_name}.pill" do - action :delete - end - link "#{node['bluepill']['init_dir']}/#{new_resource.service_name}" do - action :delete - end - end - end -end - -action :stop do - if @current_resource.running - converge_by("stop #{@new_resource}") do - shell_out!(stop_command) - end - end -end - -action :restart do - if @current_resource.running - converge_by("restart #{@new_resource}") do - Chef::Log.debug "Restarting #{new_resource.service_name}" - shell_out!(restart_command) - Chef::Log.debug "Restarted #{new_resource.service_name}" - end - end -end - -def load_current_resource - @current_resource = Chef::Resource::BluepillService.new(new_resource.name) - @current_resource.service_name(new_resource.service_name) - - Chef::Log.debug("Checking status of service #{new_resource.service_name}") - - determine_current_status! - - @current_resource -end - -protected - -def status_command - "#{node['bluepill']['bin']} #{new_resource.service_name} status" -end - -def load_command - "#{node['bluepill']['bin']} load #{node['bluepill']['conf_dir']}/#{new_resource.service_name}.pill" -end - -def start_command - "#{node['bluepill']['bin']} #{new_resource.service_name} start" -end - -def stop_command - "#{node['bluepill']['bin']} #{new_resource.service_name} stop" -end - -def restart_command - "#{node['bluepill']['bin']} #{new_resource.service_name} restart" -end - -def determine_current_status! - service_running? - service_enabled? -end - -def service_running? - if shell_out(status_command).exitstatus == 0 - @current_resource.running true - Chef::Log.debug("#{new_resource} is running") - end -rescue Mixlib::ShellOut::ShellCommandFailed, SystemCallError - @current_resource.running false - nil -end - -def service_enabled? - if ::File.exist?("#{node['bluepill']['conf_dir']}/#{new_resource.service_name}.pill") && - ::File.symlink?("#{node['bluepill']['init_dir']}/#{new_resource.service_name}") - @current_resource.enabled true - else - @current_resource.enabled false - end -end diff --git a/cookbooks/bluepill/recipes/default.rb b/cookbooks/bluepill/recipes/default.rb deleted file mode 100644 index 0ef7b4a..0000000 --- a/cookbooks/bluepill/recipes/default.rb +++ /dev/null @@ -1,45 +0,0 @@ -# -# Cookbook Name:: bluepill -# Recipe:: default -# -# Copyright 2010-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. -# - -gem_package 'i18n' - -gem_package 'bluepill' do - version node['bluepill']['version'] if node['bluepill']['version'] -end - -[ - node['bluepill']['conf_dir'], - node['bluepill']['pid_dir'], - node['bluepill']['state_dir'] -].each do |dir| - directory dir do - recursive true - owner 'root' - group node['bluepill']['group'] - end -end - -file node['bluepill']['logfile'] do - owner 'root' - group node['bluepill']['group'] - mode '0755' - action :create_if_missing -end - -include_recipe 'bluepill::rsyslog' if node['bluepill']['use_rsyslog'] diff --git a/cookbooks/bluepill/recipes/rsyslog.rb b/cookbooks/bluepill/recipes/rsyslog.rb deleted file mode 100644 index ea7ad77..0000000 --- a/cookbooks/bluepill/recipes/rsyslog.rb +++ /dev/null @@ -1,28 +0,0 @@ -# -# Cookbook Name:: bluepill -# Recipe:: rsyslog -# -# Copyright 2010-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. -# - -include_recipe 'rsyslog::default' - -template '/etc/rsyslog.d/bluepill.conf' do - owner 'root' - group 'root' - mode '0644' - source 'bluepill_rsyslog.conf.erb' - notifies :restart, "service[#{node['rsyslog']['service_name']}]" -end diff --git a/cookbooks/bluepill/resources/service.rb b/cookbooks/bluepill/resources/service.rb deleted file mode 100644 index af93fe4..0000000 --- a/cookbooks/bluepill/resources/service.rb +++ /dev/null @@ -1,27 +0,0 @@ -# -# Cookbook Name:: bluepill -# Resource:: service -# -# Copyright 2010-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. -# - -actions :start, :stop, :enable, :disable, :load, :restart, :reload -default_action :start - -attribute :service_name, name_attribute: true -attribute :enabled, default: false -attribute :running, default: false -attribute :variables, kind_of: Hash -attribute :supports, default: { restart: true, status: true } diff --git a/cookbooks/bluepill/templates/default/bluepill_init.fedora.erb b/cookbooks/bluepill/templates/default/bluepill_init.fedora.erb deleted file mode 100644 index 2731a17..0000000 --- a/cookbooks/bluepill/templates/default/bluepill_init.fedora.erb +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/sh -# -# Author: Jamie Winsor () -# -# chkconfig: 345 99 1 -# Description: Bluepill loader for <%= @service_name %> -# Provides: <%= @service_name %> -# Default-Start: 3 4 5 -# Default-Stop: 0 1 2 6 - -BLUEPILL_BIN=<%= node['bluepill']['bin'] %> -BLUEPILL_CONFIG=<%= @config_file %> -SERVICE_NAME=<%= @service_name %> - -[ -r <%= node['bluepill']['defaults_dir'] %>/$SERVICE_NAME ] && . <%= node['bluepill']['defaults_dir'] %>/$SERVICE_NAME - -case "$1" in - start) - echo "Loading bluepill configuration for $SERVICE_NAME " - $BLUEPILL_BIN load $BLUEPILL_CONFIG - ;; - stop) - $BLUEPILL_BIN $SERVICE_NAME stop - $BLUEPILL_BIN $SERVICE_NAME quit - ;; - restart) - $0 stop - $0 start - ;; - *) - echo "Usage: $0 {start|stop|restart}" - exit 1 - ;; -esac diff --git a/cookbooks/bluepill/templates/default/bluepill_init.freebsd.erb b/cookbooks/bluepill/templates/default/bluepill_init.freebsd.erb deleted file mode 100644 index 697e407..0000000 --- a/cookbooks/bluepill/templates/default/bluepill_init.freebsd.erb +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh -## -# PROVIDE: named -# REQUIRE: SERVERS cleanvar -# KEYWORD: shutdown -# - -. /etc/rc.subr - -name="<%= @service_name %>" -rcvar=`set_rcvar` - -# Set some defaults -<%= @service_name %>_enable=${<%= @service_name %>_enable:-"NO"} - -pidfile="/var/run/<%= @service_name %>.pid" -command="/usr/local/bin/bluepill" - -start_precmd="${command} load <%= node['bluepill']['conf_dir'] %>/<%= @service_name %>.pill" -start_cmd="${command} ${name} start" - -status_cmd="${command} ${name} status" - -stop_cmd="${command} ${name} stop" -stop_postcmd="${command} ${name} quit" - -[ -r <%= node['bluepill']['defaults_dir'] %>/$name ] && . <%= node['bluepill']['defaults_dir'] %>/$name -load_rc_config ${name} - -PATH="${PATH}:/usr/local/bin" - -run_rc_command "$1" diff --git a/cookbooks/bluepill/templates/default/bluepill_init.lsb.erb b/cookbooks/bluepill/templates/default/bluepill_init.lsb.erb deleted file mode 100644 index cd8b95f..0000000 --- a/cookbooks/bluepill/templates/default/bluepill_init.lsb.erb +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh -# -### BEGIN INIT INFO -# Provides: <%= @service_name %> -# Required-Start: -# Required-Stop: -# Defalt-Start: 2 3 4 5 -# Default-Stop: 0 1 2 6 -# Description: Bluepill loader for <%= @service_name %> -### END INIT INFO - -BLUEPILL_BIN=<%= node['bluepill']['bin'] %> -BLUEPILL_CONFIG=<%= @config_file %> -SERVICE_NAME=<%= @service_name %> - -[ -r <%= node['bluepill']['defaults_dir'] %>/$SERVICE_NAME ] && . <%= node['bluepill']['defaults_dir'] %>/$SERVICE_NAME - -case "$1" in - start) - echo "Loading bluepill configuration for $SERVICE_NAME " - $BLUEPILL_BIN load $BLUEPILL_CONFIG - ;; - stop) - $BLUEPILL_BIN $SERVICE_NAME stop - $BLUEPILL_BIN $SERVICE_NAME quit - ;; - restart) - $BLUEPILL_BIN $SERVICE_NAME restart - ;; - status) - $BLUEPILL_BIN $SERVICE_NAME status - ;; - *) - echo "Usage: $0 {start|stop|restart}" - exit 1 - ;; -esac diff --git a/cookbooks/bluepill/templates/default/bluepill_init.rhel.erb b/cookbooks/bluepill/templates/default/bluepill_init.rhel.erb deleted file mode 100644 index 2731a17..0000000 --- a/cookbooks/bluepill/templates/default/bluepill_init.rhel.erb +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/sh -# -# Author: Jamie Winsor () -# -# chkconfig: 345 99 1 -# Description: Bluepill loader for <%= @service_name %> -# Provides: <%= @service_name %> -# Default-Start: 3 4 5 -# Default-Stop: 0 1 2 6 - -BLUEPILL_BIN=<%= node['bluepill']['bin'] %> -BLUEPILL_CONFIG=<%= @config_file %> -SERVICE_NAME=<%= @service_name %> - -[ -r <%= node['bluepill']['defaults_dir'] %>/$SERVICE_NAME ] && . <%= node['bluepill']['defaults_dir'] %>/$SERVICE_NAME - -case "$1" in - start) - echo "Loading bluepill configuration for $SERVICE_NAME " - $BLUEPILL_BIN load $BLUEPILL_CONFIG - ;; - stop) - $BLUEPILL_BIN $SERVICE_NAME stop - $BLUEPILL_BIN $SERVICE_NAME quit - ;; - restart) - $0 stop - $0 start - ;; - *) - echo "Usage: $0 {start|stop|restart}" - exit 1 - ;; -esac diff --git a/cookbooks/bluepill/templates/default/bluepill_rsyslog.conf.erb b/cookbooks/bluepill/templates/default/bluepill_rsyslog.conf.erb deleted file mode 100644 index 6a13f39..0000000 --- a/cookbooks/bluepill/templates/default/bluepill_rsyslog.conf.erb +++ /dev/null @@ -1 +0,0 @@ -local6.* <%= node["bluepill"]["logfile"] %> diff --git a/cookbooks/build-essential/.foodcritic b/cookbooks/build-essential/.foodcritic index be0967f..b9f8767 100644 --- a/cookbooks/build-essential/.foodcritic +++ b/cookbooks/build-essential/.foodcritic @@ -1,2 +1 @@ -~FC052 -~FC057 +~FC016 diff --git a/cookbooks/build-essential/CHANGELOG.md b/cookbooks/build-essential/CHANGELOG.md index 229366d..6a94d15 100644 --- a/cookbooks/build-essential/CHANGELOG.md +++ b/cookbooks/build-essential/CHANGELOG.md @@ -2,6 +2,103 @@ This file is used to list changes made in each version of the build-essential cookbook. +## 8.0.1 (2017-04-14) + +- Test with local delivery and not Rake +- Ensure compatibility with Chef 12.5 +- Update apache2 license string +- Ensure compatibility with Amazon Linux on Chef 13 + +## 8.0.0 (2017-02-14) + +- Require 12.5 or later and remove compat_resource cookbook dependency + +## 7.0.3 (2016-12-22) + +- Require the latest compat_resource +- Cookstyle fixes + +## 7.0.2 (2016-11-07) + +- Fix softwareupdate issue from -v to --verbose + +## 7.0.1 (2016-10-06) + +- Install gcc 4.8 on SUSE < 12 + +## 7.0.0 (2016-09-30) + +- Remove support for OS X < 10.9 and add support for OS X 10.12 +- Refactor the xcode installer resource as a custom resource that does not require updates for each new OS X update +- Use a test recipe with apt_update to avoid needing apt + +## 6.0.6 (2016-09-19) + +- Remove chef 11 compatibility in the metadata +- Solaris 11 needs both make and gnu make + +## 6.0.5 (2016-09-07) + +- Testing updates +- Require the latest compat_resource + +## 6.0.4 (2016-08-19) + +- Install CLTools from dmg with -allowUntrusted on old OSX +- Switch to cookstyle for ruby linting +- Add OS X hosts to the kitchen config +- Remove chefdk included gems from the Gemfile +- Better handle kitchen failures in the Rakefile +- Perform all unit/linting in a single travis job + +## v6.0.3 (2016-07-26) + +- Fix how gcc version specified for Solaris 11 + +## v6.0.2 (2016-07-22) + +- Properly warn on Solaris 10 +- Specify the verson of gcc to install on Solaris 11 + +## v6.0.1 (2016-07-19) + +- Clarify that this cookbook actually required Chef 12.1 or later not 12.0 or later +- Add chef_version metadata + +## v6.0.0 (2016-06-03) + +This cookbook now uses the new msys2 based compiler toolchain on windows. Both 32-bit DW2 and 64-bit SEH based toolchains are available based on the gcc 5.3x series compiler. By default these are located in C:\msys2\mingw32 and C:\msys2\mingw64 + +## v5.0.0 (2016-06-03) + +The cookbook now ships with a 12.5+ style custom resource 'build_essential' which performs the same work that the existing default.rb recipe. The default.rb recipe has been converted to consume that resource to provide backwards compatibility for users that use build-essential::default in their run lists or cookbooks. In converting to this custom resource support for EOL omnios has been removed and warning messages for Solaris 10 users have been removed. See the readme for usage information on the new resource. + +## v4.0.0 (2016-05-12) + +### Breaking change + +This cookbook now requires Chef 12 or later as it includes the new mingw cookbook for installing Windows compilers. Mingw includes 12.5 style custom resources, which will fail to compile on Chef 11\. If you are not running Chef 12 you'll need to pin to 3.x in your environment. + +## v3.2.0 (2016-03-25) + +This version backs out a change in the 3.0 release which attempted to install the version of kernel-devel for the current running kernel on RHEL systems. This change had several unintended consequences and we believe the best solution is to back to change out until a better solution for the original problem is developed. Several of the issues could be resolved by code updates to build-essential, but not all, which complicates rolling forward vs. a roll back. The change caused issues which Chefspec runs on cookbooks where build-essential is a dependency as Fauxhai, used by Chefspec, does not mock out node['virtualization']. Fauxhai is being updated to mock out node['virtualization'], but we'd like to make sure a ChefDK release ships with this new Fauxhai before depending on that change. + +## v3.1.0 (2016-03-23) + +- Install GCC 4.8 if running on OmniOS >= 151008 + +## v3.0.0 (2016-03-23) + +- Install GCC 4.9 on FreeBSD < 10 +- Install the version of kernel-devel that matches the running Kernel on RHEL +- Remove suggests 'pkgutil' from the metadata as suggests does nothing +- Properly warn the user that build-essential does not support Solaris 10 instead of just silently continuing on +- Updated specs to run against more recent OS releases +- Removed the warning for OmniOS users from the Readme as the upstream issue has been resolved +- Switch from 7-zip to seven_zip cookbook as 7-zip has been deprecated +- Add 7-zip to the system path on Windows hosts so the recipe will work out of the box +- Switch from the deprecated 7-zip cookbook to seven_zip + ## v2.4.0 (2016-03-21) - Add gettext package to RHEL / FreeBSD to match other platforms diff --git a/cookbooks/build-essential/attributes/default.rb b/cookbooks/build-essential/attributes/default.rb index 21189fd..e2bf233 100644 --- a/cookbooks/build-essential/attributes/default.rb +++ b/cookbooks/build-essential/attributes/default.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: build-essential +# Cookbook:: build-essential # Attributes:: default # -# Copyright 2008-2016, Chef Software, Inc. +# Copyright:: 2008-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,4 +18,4 @@ # default['build-essential']['compile_time'] = false -default['build-essential']['msys']['path'] = "#{ENV['SYSTEMDRIVE']}\\msys" +default['build-essential']['msys2']['path'] = "#{ENV['SYSTEMDRIVE']}\\msys2" diff --git a/cookbooks/build-essential/libraries/_msys_helper.rb b/cookbooks/build-essential/libraries/_msys_helper.rb deleted file mode 100644 index e7f60af..0000000 --- a/cookbooks/build-essential/libraries/_msys_helper.rb +++ /dev/null @@ -1,15 +0,0 @@ -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/matchers.rb b/cookbooks/build-essential/libraries/matchers.rb index fcc5305..d4d1bd4 100644 --- a/cookbooks/build-essential/libraries/matchers.rb +++ b/cookbooks/build-essential/libraries/matchers.rb @@ -2,4 +2,8 @@ if defined?(ChefSpec) def install_xcode_command_line_tools(resource_name) ChefSpec::Matchers::ResourceMatcher.new(:xcode_command_line_tools, :install, resource_name) end + + def install_build_essential(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:build_essential, :install, resource_name) + end end diff --git a/cookbooks/build-essential/libraries/timing.rb b/cookbooks/build-essential/libraries/timing.rb deleted file mode 100644 index 654a8dd..0000000 --- a/cookbooks/build-essential/libraries/timing.rb +++ /dev/null @@ -1,124 +0,0 @@ -# -# Cookbook Name:: build-essential -# Library:: timing -# -# 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. -# - -# -# This module is used to clean up the recipe DSL and "potentially" execute -# resources at compile time (depending on the value of an attribute). -# -# This library is only for use within the build-essential cookbook. Resources -# inside the potentially_at_compile_time block will not fire notifications in -# some situations. This is fixable, but since none of the resources in this -# cookbook actually use notifications, it is not worth the added technical debt. -# -# TL;DR Don't use this DSL method outside of this cookbook. -# -module BuildEssential - module Timing - # - # Potentially evaluate the given block at compile time, depending on the - # value of the +node['build-essential']['compile_time']+ attribute. - # - # @example - # potentially_at_compile_time do - # package 'apache2' - # end - # - # @param [Proc] block - # the thing to eval - # - def potentially_at_compile_time(&block) - if compile_time? - CompileTime.new(self).evaluate(&block) - else - instance_eval(&block) - end - end - - private - - # - # Checks if the DSL should be evaluated at compile time. - # - # @return [true, false] - # - def compile_time? - check_for_old_attributes! - !!node['build-essential']['compile_time'] - end - - # - # Checks for the presence of the "old" attributes. - # - # @todo Remove in 2.0.0 - # - # @return [void] - # - def check_for_old_attributes! - unless node['build_essential'].nil? - Chef::Log.warn <<-EOH -node['build_essential'] has been changed to node['build-essential'] to match the -cookbook name and community standards. I have gracefully converted the attribute -for you, but this warning and conversion will be removed in the next major -release of the build-essential cookbook. -EOH - node.default['build-essential'] = node['build_essential'] - end - - unless node['build-essential']['compiletime'].nil? - Chef::Log.warn <<-EOH -node['build-essential']['compiletime'] has been deprecated. Please use -node['build-essential']['compile_time'] instead. I have gracefully converted the -attribute for you, but this warning and conversion will be removed in the next -major release of the build-essential cookbook. -EOH - node.default['build-essential']['compile_time'] = node['build-essential']['compiletime'] - end - end - - # - # A class graciously borrowed from Chef Sugar for evaluating a resource at - # compile time in a block. - # - class CompileTime - def initialize(recipe) - @recipe = recipe - end - - def evaluate(&block) - instance_eval(&block) - end - - def method_missing(m, *args, &block) - resource = @recipe.send(m, *args, &block) - if resource.is_a?(Chef::Resource) - actions = Array(resource.action) - resource.action(:nothing) - - actions.each do |action| - resource.run_action(action) - end - end - resource - end - end - end -end - -# Include the timing module into the main recipe DSL -Chef::Recipe.send(:include, BuildEssential::Timing) diff --git a/cookbooks/build-essential/libraries/xcode_command_line_tools.rb b/cookbooks/build-essential/libraries/xcode_command_line_tools.rb deleted file mode 100644 index 30d4511..0000000 --- a/cookbooks/build-essential/libraries/xcode_command_line_tools.rb +++ /dev/null @@ -1,212 +0,0 @@ -# -# Cookbook Name:: build-essential -# Library:: 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. -# - -class Chef - class Resource::XcodeCommandLineTools < Resource::LWRPBase - def self.resource_name - :xcode_command_line_tools - end - - actions :install - default_action :install - - def initialize(name, run_context = nil) - super - - # => 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', '10.11' - Provider::XcodeCommandLineToolsFromSoftwareUpdate - else - Chef::Log.warn <<-EOH -OSX #{node['platform_version']} is not an officially supported platform for the -build-essential cookbook. I am going to try and install the command line tools -from Software Update, but there is a high probability that it will fail... - -If you have tested and verified OSX #{node['platform_version']} and you are sick -of seeing this warning in your Chef Client runs, please submit a Pull Request to -https://github.com/chef-cookbooks/build-essential and add this version of OSX -to provider list. -EOH - Provider::XcodeCommandLineToolsFromSoftwareUpdate - end - end - end -end - -# -# This is a legacy provider for installing OSX from DMGs. It only supports OSX -# versions 10.7 and 10.8 and will (hopefully) be deprecated in the future. It -# downloads a remote .dmg file, mounts it, installs it, and unmounts it -# automatically. In later versions of OSX, the operating system handles this for -# the end user. -# -class Chef - class Provider::XcodeCommandLineToolsFromDmg < Provider::LWRPBase - action(:install) do - if installed? - Chef::Log.debug("#{new_resource} already installed - skipping") - else - converge_by("Install #{new_resource}") do - download - attach - install - detach - end - end - end - - private - - # - # Determine if the XCode Command Line Tools are installed - # - # @return [true, false] - # - def installed? - cmd = Mixlib::ShellOut.new('pkgutil --pkgs=com.apple.pkg.DeveloperToolsCLI') - cmd.run_command - cmd.error! - true - rescue Mixlib::ShellOut::ShellCommandFailed - false - end - - # - # The path where the dmg should be cached on disk. - # - # @return [String] - # - def dmg_cache_path - ::File.join(Chef::Config[:file_cache_path], 'osx-command-line-tools.dmg') - end - - # - # The path where the dmg should be downloaded from. This is intentionally - # not a configurable object by the end user. If you do not like where we - # are downloading XCode from - too bad. - # - # @return [String] - # - def dmg_remote_source - case node['platform_version'].to_f - when 10.7 - 'http://devimages.apple.com/downloads/xcode/command_line_tools_for_xcode_os_x_lion_april_2013.dmg' - when 10.8 - 'http://devimages.apple.com/downloads/xcode/command_line_tools_for_xcode_os_x_mountain_lion_march_2014.dmg' - else - raise "Unknown DMG download URL for OSX #{node['platform_version']}" - end - end - - # - # The path where the volume should be mounted. - # - # @return [String] - # - def mount_path - ::File.join(Chef::Config[:file_cache_path], 'osx-command-line-tools') - end - - # - # Action: download the remote dmg. - # - # @return [void] - # - def download - remote_file = Resource::RemoteFile.new(dmg_cache_path, run_context) - remote_file.source(dmg_remote_source) - remote_file.backup(false) - remote_file.run_action(:create) - end - - # - # Action: attach the dmg (basically, double-click on it) - # - # @return [void] - # - def attach - execute %(hdiutil attach "#{dmg_cache_path}" -mountpoint "#{mount_path}") - end - - # - # Action: install the package inside the dmg - # - # @return [void] - # - def install - execute %|installer -package "$(find '#{mount_path}' -name *.mpkg)" -target "/"| - end - - # - # Action: detach the dmg (basically, drag it to eject on the dock) - # - # @return [void] - # - def detach - execute %(hdiutil detach "#{mount_path}") - end - end -end - -class Chef - class Provider::XcodeCommandLineToolsFromSoftwareUpdate < Provider::LWRPBase - 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" -v - EOH - # rubocop:enable Metrics/LineLength - end - end - end - end - - private - - # - # 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 -end diff --git a/cookbooks/build-essential/metadata.json b/cookbooks/build-essential/metadata.json index 9803c84..9478641 100644 --- a/cookbooks/build-essential/metadata.json +++ b/cookbooks/build-essential/metadata.json @@ -1 +1 @@ -{"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 +{"name":"build-essential","version":"8.0.1","description":"Installs C compiler / build tools","long_description":"# build-essential Cookbook\n\n[![Cookbook Version](http://img.shields.io/cookbook/v/build-essential.svg)][cookbook] [![Build Status](https://travis-ci.org/chef-cookbooks/build-essential.svg?branch=master)](https://travis-ci.org/chef-cookbooks/build-essential)\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. Contains a resource, 'build_essential', as as well as a default recipe that simply calls that same resource.\n\n## Requirements\n\n### Platforms\n\n- Debian/Ubuntu\n- RHEL/CentOS/Scientific/Amazon/Oracle\n- openSUSE / SUSE Enterprise Linux\n- SmartOS\n- Fedora\n- Mac OS X 10.9+\n- FreeBSD\n\n### Chef\n\n- Chef 12.5+\n\n### Cookbooks\n\n- seven_zip\n- mingw\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## Attributes\n\nAttribute | Default | Description\n------------------------------------------ | :---------------------------: | -----------------------------------------------------\n`node['build-essential']['compile_time']` | `false` | Execute resources at compile time\n`node['build-essential']['msys2']['path']` | `#{ENV['SYSTEMDRIVE']\\\\msys2` | Destination for msys2 build tool chain (Windows only)\n\n## Usage\n\n### Recipe Usage\n\nThe recipe simply calls the build_essential resource, but it ideal for adding to roles or node run lists.\n\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\n\nFor RubyGems that include native C extensions you wish to use with Chef, you should do the following.\n\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### Resource Usage\n\nThe cookbook includes a resource 'build_essential' that can be included in your cookbook to install the necessary build-essential packages\n\nSimple package installation during the client run:\n\n```ruby\nbuild_essential 'some name you choose'\n```\n\nPackage installation during the compile phase:\n\n```ruby\nbuild_essential 'some name you choose' do\n compile_time false\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/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.9.0","mac_os_x_server":">= 10.9.0","opensuse":">= 0.0.0","opensuseleap":">= 0.0.0","oracle":">= 0.0.0","redhat":">= 0.0.0","scientific":">= 0.0.0","smartos":">= 0.0.0","solaris":">= 0.0.0","suse":">= 0.0.0","ubuntu":">= 0.0.0","windows":">= 0.0.0","zlinux":">= 0.0.0"},"dependencies":{"seven_zip":">= 0.0.0","mingw":">= 1.1"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"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","chef_version":[[">= 12.5"]],"ohai_version":[]} \ No newline at end of file diff --git a/cookbooks/build-essential/providers/msys_archive.rb b/cookbooks/build-essential/providers/msys_archive.rb deleted file mode 100644 index 08f8be9..0000000 --- a/cookbooks/build-essential/providers/msys_archive.rb +++ /dev/null @@ -1,102 +0,0 @@ -# -# 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 deleted file mode 100644 index ded2d85..0000000 --- a/cookbooks/build-essential/recipes/_debian.rb +++ /dev/null @@ -1,28 +0,0 @@ -# -# Cookbook Name:: build-essential -# Recipe:: debian -# -# 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. -# - -potentially_at_compile_time do - package 'autoconf' - package 'binutils-doc' - package 'bison' - package 'build-essential' - package 'flex' - package 'gettext' - package 'ncurses-dev' -end diff --git a/cookbooks/build-essential/recipes/_fedora.rb b/cookbooks/build-essential/recipes/_fedora.rb deleted file mode 100644 index 296df5c..0000000 --- a/cookbooks/build-essential/recipes/_fedora.rb +++ /dev/null @@ -1,32 +0,0 @@ -# -# Cookbook Name:: build-essential -# Recipe:: fedora -# -# 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. -# - -potentially_at_compile_time do - package 'autoconf' - package 'bison' - package 'flex' - package 'gcc' - package 'gcc-c++' - package 'gettext' - package 'kernel-devel' - package 'make' - package 'm4' - package 'ncurses-devel' - package 'patch' -end diff --git a/cookbooks/build-essential/recipes/_freebsd.rb b/cookbooks/build-essential/recipes/_freebsd.rb deleted file mode 100644 index 350571e..0000000 --- a/cookbooks/build-essential/recipes/_freebsd.rb +++ /dev/null @@ -1,25 +0,0 @@ -# -# Cookbook Name:: build-essential -# Recipe:: freebsd -# -# 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. -# - -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/_omnios.rb b/cookbooks/build-essential/recipes/_omnios.rb deleted file mode 100644 index 13e0c16..0000000 --- a/cookbooks/build-essential/recipes/_omnios.rb +++ /dev/null @@ -1,33 +0,0 @@ -# -# Cookbook Name:: build-essential -# Recipe:: omnios -# -# 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. -# 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. -# - -potentially_at_compile_time do - package 'developer/gcc47' - 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' -end - -# 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" diff --git a/cookbooks/build-essential/recipes/_smartos.rb b/cookbooks/build-essential/recipes/_smartos.rb deleted file mode 100644 index 7005484..0000000 --- a/cookbooks/build-essential/recipes/_smartos.rb +++ /dev/null @@ -1,27 +0,0 @@ -# -# Cookbook Name:: build-essential -# Recipe:: smartos -# -# 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. -# - -potentially_at_compile_time do - package 'autoconf' - package 'binutils' - package 'build-essential' - package 'gcc47' - package 'gmake' - package 'pkg-config' -end diff --git a/cookbooks/build-essential/recipes/_solaris2.rb b/cookbooks/build-essential/recipes/_solaris2.rb deleted file mode 100644 index 00c845d..0000000 --- a/cookbooks/build-essential/recipes/_solaris2.rb +++ /dev/null @@ -1,48 +0,0 @@ -# -# Cookbook Name:: build-essential -# Recipe:: solaris2 -# -# 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. -# 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. -# - -case node['platform_version'].to_f -when 5.10 - # You should install the following packages from the Solaris 10 DVD: - # - # SUNWbison - # SUNWgcc - # SUNWggrp - # SUNWgmake - # SUNWgtar - # -when 5.11 - potentially_at_compile_time do - package 'autoconf' - package 'automake' - package 'bison' - package 'gnu-coreutils' - package 'flex' - package 'gcc' - package 'gcc-3' - package 'gnu-grep' - package 'gnu-make' - package 'gnu-patch' - package 'gnu-tar' - package 'pkg-config' - package 'ucb' - end -else - 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 deleted file mode 100644 index f66bf46..0000000 --- a/cookbooks/build-essential/recipes/_suse.rb +++ /dev/null @@ -1,29 +0,0 @@ -# -# Cookbook Name:: build-essential -# Recipe:: suse -# -# 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. -# - -potentially_at_compile_time do - package 'autoconf' - package 'bison' - package 'flex' - package 'gcc' - package 'gcc-c++' - package 'kernel-default-devel' - package 'make' - package 'm4' -end diff --git a/cookbooks/build-essential/resources/msys_archive.rb b/cookbooks/build-essential/resources/msys_archive.rb deleted file mode 100644 index fe95391..0000000 --- a/cookbooks/build-essential/resources/msys_archive.rb +++ /dev/null @@ -1,7 +0,0 @@ -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/chef_nginx/.foodcritic b/cookbooks/chef_nginx/.foodcritic new file mode 100644 index 0000000..b9f8767 --- /dev/null +++ b/cookbooks/chef_nginx/.foodcritic @@ -0,0 +1 @@ +~FC016 diff --git a/cookbooks/chef_nginx/CHANGELOG.md b/cookbooks/chef_nginx/CHANGELOG.md new file mode 100644 index 0000000..944141f --- /dev/null +++ b/cookbooks/chef_nginx/CHANGELOG.md @@ -0,0 +1,628 @@ +# nginx Cookbook CHANGELOG + +This file is used to list changes made in each version of the nginx cookbook. + +## 6.0.2 (2017-04-27) + +- Resolve name conflicts in the resource + +## 6.0.1 (2017-04-04) + +- double quotes are unnecessary in lua configure flags + +## 6.0.0 (2017-03-25) + +### Breaking change + +- Support for Runit as an init system has been removed. If you require runit you will need to pin to the 5.X cookbook release. We highly recommend using either systemd or upstart instead of Runit. + +### Other changes + +- Install nginx 1.10.3 for source based installs +- Remove freebsd cookbook from testing as it’s not necessary anymore +- Bump OpenSSL to 1.0.2k + +## 5.1.3 (2017-03-24) + +- Update apache2 license string +- Add image/svg+xml to gzip_files defaults +- support `worker_shutdown_timeout` released in 1.11.11 + +## 5.1.2 (2017-03-14) + +- Setup LD options to include /usr/local/lib for libluajit in search path and bump the lua version + +## 5.1.1 (2017-03-02) + +- Add WantedBy to systemd service file so it starts at boot +- Avoid a warning in nginx_site by moving the template check outside the resource +- Allow nginx_site to specify template as an array of templates + +## 5.1.0 (2017-03-01) + +- Support the load_module directive +- Test with Local Delivery and not Rake +- Remove EOL platforms from the kitchen configs + +## 5.0.7 (2017-02-12) + +- Fix Opsworks compatibility +- Resolve a Chef 13 deprecation warning + +## 5.0.6 (2017-01-16) + +- Rebuild shared library cache after installing luajit + +## 5.0.5 (2017-01-09) + +- Fix typo in the pagespeed recipe + +## 5.0.4 (2017-01-04) + +- Avoid deprecation warnings by only defining nginx service once + +## 5.0.3 (2017-01-03) + +- Add ability to write passenger log to another location +- Properly disable the default site with nginx.org packages + +## 5.0.2 (2016-12-22) +- Requite the latest compat_resource + +## 5.0.1 (2016-12-13) + +- Use multipackage in pagespeed module recipe to speed up installs +- Simplify the distro repo setup logic to ensure we're using the correct repos under all conditions. Previously the upstream repo was being missed on Suse systems +- Determine pidfile location correctly via a helper so we correctly set pidfiles when using Upstream packages on Ubuntu 14.04 / 16.04. This involved removing the attribute for the pidfile location, which may cause issues if you relied on that attribute. +- Testing improvements to make sure all suites run and the suites are testing the correct conditions + +## 5.0.0 (2016-12-07) + +### Breaking changes + +- Default to the upstream nginx.org repo for package installs. The official nginx repo gives an improved experience over outdated distro releases. This can be disabled via attribute if you'd like to remain on the distro packages. + +### Other changes + +- Add a deprecation warning when using runit +- Rewrite the readme usage section +- Better document how to compile modules + +## 4.0.2 (2016-12-01) +- Default to openssl 1.0.2j with source installs +- Add cookbook property to the nginx_site resource to allow using templates defined in other cookbooks +- Prevent default docroot index.html on bad url in status +- Readme improvements + +## 4.0.1 (2016-10-31) +- Fix a version check in the realip recipe +- Align the config with the default config a bit +- Fix the ChefSpec matchers now that nginx_site is a custom resource + +## 4.0.0 (2016-10-31) + +### Breaking changes + +The nginx_site definition is now a custom_resource. This improves the overall experience and allows for notifications and reporting on resource updates. It does change the behavior in some circumstances however. Previously to disable a site you would set 'enable false' on your definition. This will still function, but will result in a deprecation warning. Instead you should use 'action :disable' since this is a real resource now. + +### Other changes + +- Avoid splitting on compile params in the ohai plugin, which resulted in some source installs attempting to install on every Chef run. +- Expanded testing and improved kitchen suite setup +- Improved documentation of attributes and cookbook usage + +## 3.2.0 (2016-10-28) + +- Reload nginx on site change + +## 3.1.2 (2016-10-24) + +- [GH-26] Remove guard on package[nginx] resource +- Fix pcre packages on RHEL that prevented pagespeed module compilation + +## 3.1.1 (2016-09-21) + +- Raise on error vs. Chef::Appliation.fatal +- Require compat_resource with notification fixes + +## 3.1.0 (2016-09-14) + +- Resolve FC023 warnings +- FreeBSD fixes +- Fail hard on unsupported platforms in the source recipe +- Install 'ca-certificates' packages with passenger +- Add `passenger_show_version_in_header` config +- Remove chef 11 compatibility +- Replace apt/yum deps with compat_resource +- Fix specs for freebsd source installs +- Remove apt recipe from the repo_passenger recipe +- Switch to += operator as << also incorrectly replaces text in root. + +## 3.0.0 (2016-08-18) + +### Breaking changes + +Ideally we'd offer perfect backwards compatibility forever, but in order to maintain the cookbook going forward we've evaluated the current scope of the cookbook and removed lesser used functionality that added code complexity. + +- The minimum chef-client version is now 12.1 or later, which will enables support for Ohai 7+ plugins, the ohai_plugin custom resource, and automatic init system discovery. +- Support for Gentoo has been removed. Gentoo lacks an official Chef package and there is no Bento image to use for Test Kitchen integration tests. +- Support for the bluepill init system has been removed. Usage of this init system has declined, and supporting it added a cookbook dependency as well as code complexity. +- Ubuntu source installs will no longer default to runit, and will instead use either Upstart or Systemd depending on the release of Ubuntu. You can still force the use of runit by setting default['nginx']['init_style'] to 'runit'. Runit was used historically before reliable init systems were shipped with Ubuntu. Both Upstart and Systemd have the concept of restarting on failure, which was the main reason for choosing Runit over sys-v init. + +### Other changes + +- Don't setup the YUM EPEL repo on Fedora as it's not needed +- Systemd based platforms will now use systemd by default for source installs +- Retry downloads of the nginx source file as the mirror sometimes fails to load +- Download the nginx source from the secure nginx.org site +- Updated the Ohai plugin to avoid deprecation notices and function better on non us-en locale systems +- Install source install pre-reqs using multi-package which speeds up Chef runs +- Add testing in Travis with Kitchen Dokken for full integration testing of each PR +- Add integration test on Chef 12.1 as well as the latest Chef to ensure compatibility with the oldest release we support +- Remove installation of apt-transport-https and instead increase the apt dependency to >= 2.9.1 which includes the installation of apt-transport-https +- Don't try to setup the nginx.org repo on Fedora as this will fail +- Better log when trying to setup repositories on unsupported platforms +- Fixed source_url and issue_url in the metadata to point to the correct URLs +- Removed Chef 10 compatibility code +- Chefspec platform updates and minor fixes +- Replace all usage of node.set with node.normal to avoid deprecation notices +- Remove the suse init script that isn't used anymore +- Speed up the specs with caching +- Move test attributes and runlists out the kitchen.yml files and into a test cookbook + +## 2.9.0 (2016-08-12) + +- Add support for Suse Nginx.org packages + +## v2.8.0 (2016-08-12) + +This is the first release of the nginx codebase under the chef_nginx namespace. We've chosen to bring this cookbook under the direction of the Community Cookbook Team, in order to ship a working 2.X release. The cookbook name has been changed, but all attributes are the same and compatibility has been maintained. After this 2.8.0 release we will release 3.0 as a Chef 12+ version of the cookbook and then work to add additional custom resources for managing nginx with wrapper cookbooks. Expect regular releases as we march towards a resource driven model. + +- Removed the restrictive version constraints for cookbook dependencies that prevented users from utilizing new functionality. Ohai has been pinned to < 4.0 to allow for Chef 11 compatibility, but other cookbooks have no upper limit +- Updated all modules in the source install to their latest releases +- Removed the GeoIP database checksums as these files are constantly updates and this causes Chef run failures +- Updated OpenSSL for source installs to 1.0.1t +- Updated the source install of Nginx to version 1.10.1 +- Updated the ohai recipe to install a Ohai 7+ compatible plugin on systems running Ohai 7+ +- Fixed installation of Passenger version 5.X+ +- Added a http_v2_module recipe +- Replaced node.set usage with node.normal to avoid deprecation warnings +- Removed the apt version pin in the Berkfile that wasn't necessary and constrained the apt version +- Removed the lua-devel package install from the lua recipe that failed chef runs and wasn't necessary +- Removed duplicate packages from the source module installs +- Added a dependency on the yum cookbook which was missing from the metadata +- Updated the mime.types file and added the charset_types configuration option to the nginx config +- Added source_url, issue_url, and chef_version metadata +- Fixed the pid file attribute logic for Ubuntu 16.04 +- Removed the Contributing doc that was for contributing to Opscode cookbooks +- Updated all test dependencies in the Gemfile +- Removed default user/group/mode declarations from resources for simplicity +- Updated documentation for dependencies in the README +- Added a chefignore file to limit the cookbook files that are uploaded to the chef server and speed up cookbook syncs to nodes +- Added additional platforms to the Test Kitchen config and removed the .kitchen.cloud.yml file +- Switched integration tests to Inspec and fixed several non-functional tests +- Switched from Rubocop to Cookstyle and resolved all warnings +- Added the standard Chef Rakefile for simplified testing +- Updated Chefspecs to avoid constant deprecation warnings and converge using chef-zero on a newer Debian 8 system +- Switch Travis CI testing to use ChefDK instead of RVM/Gem installs +- Removed testing dependencies from the Gemfile as testing should be performed via ChefDK. Release gems are still in the Gemfile as they are not shipped with ChefDK +- Added a maintainers.md doc and updated the contributing/testing docs to point to the Chef docs +- Removed Guard as guard-foodcritic doesn't support the latest release which makes guard incompatible with ChefDK + +## v2.7.6 (2015-03-17) + +- Bugfix sites do not need a .conf suffix anymore, [#338][@runningman84] + +## v2.7.5 (2015-03-17) + +**NOTE** As of this release, this cookbook in its current format is deprecated, and only critical bugs and fixes will be added. A complete rewrite is in progress, so we appreciate your patience while we sort things out. The amount of change included here + +- Fix nginx 1.4.4 archive checksum to prevent redownload, [#305][@irontoby] +- Allow setting an empty string to prevent additional repos, [#243][@miketheman] +- Use correct `mime.types` for javascript, [#259][@dwradcliffe] +- Fix `headers_more` module for source installs, [#279], [@josh-padnick] & [@miketheman] +- Remove `libtool` from `geoip` and update download paths & checksums, [@miketheman] +- Fix unquoted URL with params failing geoip module build (and tests!), [#294][@karsten-bruckmann] & [@miketheman] +- Fix typo in `source.rb`, [#205][@gregkare] +- Test updates: ChefSpec, test-kitchen. Lots of help by [@jujugrrr] +- Toolchain updates for testing +- Adds support for `tcp_nopush`, `tcp_nodelay` [@shtouff] + +After merging a ton of pull requests, here's a brief changelog. Click each to read more. + +- Merge pull request [#335] from [@stevenolen] +- Merge pull request [#332] from [@monsterstrike] +- Merge pull request [#331] from [@jalberto] +- Merge pull request [#327] from [@nkadel-skyhook] +- Merge pull request [#326] from [@bchrobot] +- Merge pull request [#325] from [@CanOfSpam3bug324] +- Merge pull request [#321] from [@jalberto] +- Merge pull request [#318] from [@evertrue] +- Merge pull request [#314] from [@bkw] +- Merge pull request [#312] from [@thomasmeeus] +- Merge pull request [#310] from [@morr] +- Merge pull request [#305] from [@irontoby] +- Merge pull request [#302] from [@auth0] +- Merge pull request [#298] from [@Mytho] +- Merge pull request [#269] from [@yveslaroche] +- Merge pull request [#259] from [@dwradcliffe] +- Merge pull request [#254] from [@evertrue] +- Merge pull request [#252] from [@gkra] +- Merge pull request [#249] from [@whatcould] +- Merge pull request [#240] from [@jcoleman] +- Merge pull request [#236] from [@adepue] +- Merge pull request [#230] from [@n1koo] +- Merge pull request [#225] from [@thommay] +- Merge pull request [#223] from [@firmhouse] +- Merge pull request [#220] from [@evertrue] +- Merge pull request [#219] from [@evertrue] +- Merge pull request [#204] from [@usertesting] +- Merge pull request [#200] from [@ffuenf] +- Merge pull request [#188] from [@larkin] +- Merge pull request [#184] from [@tvdinner] +- Merge pull request [#183] from [@jenssegers] +- Merge pull request [#174] from [@9minutesnooze] + + + +## v2.7.4 (2014-06-06) + +- [COOK-4703] Default openssl version to 1.0.1h to address CVE-2014-0224 + +## v2.7.2 (2014-05-27) + +- [COOK-4658] - Nginx::socketproxy if the context is blank or nonexistent, the location in the config file has a double slash at the beginning +- [COOK-4644] - add support to nginx::repo for Amazon Linux +- Allow .kitchen.cloud.yml to use an environment variable for the EC2 Availability Zone + +## v2.7.0 (2014-05-15) + +- [COOK-4643] - Update metadata lock on ohai +- [COOK-4588] - Give more love to FreeBSD +- [COOK-4601] - Add proxy type: Socket + +## v2.6.2 (2014-04-09) + +[COOK-4527] - set default openssl source version to 1.0.1g to address CVE-2014-0160 aka Heartbleed + +## v2.6.0 (2014-04-08) + +- Reverting COOK-4323 + +## v2.5.0 (2014-03-27) + +- [COOK-4323] - Need a resource to easily configure available sites (vhosts) + +## v2.4.4 (2014-03-13) + +- Updating for build-essential 2.0 + +## v2.4.2 (2014-02-28) + +Fixing bad commit from COOK-4330 + +## v2.4.1 (2014-02-27) + +- [COOK-4345] - nginx default recipe include install type recipe directly + +## v2.4.0 (2014-02-27) + +- [COOK-4380] - kitchen.yml platform listings for ubuntu-10.04 and ubuntu-12.04 are missing the dot +- [COOK-4330] - Bump nginx version for security issues (CVE-2013-0337, CVE-2013-4547) + +## v2.3.0 (2014-02-25) + +- **[COOK-4293](https://tickets.chef.io/browse/COOK-4293)** - Update testing Gems in nginx and fix a rubocop warnings +- **[COOK-4237] - Nginx version incorrectly parsed on Ubuntu 13 +- **[COOK-3866] - Nginx default site folder + +## v2.2.2 (2014-01-23) + +[COOK-3672] - Add gzip_static option + +## v2.2.0 + +No changes. Version bump for toolchain + +## v2.1.0 + +[COOK-3923] - Enable the list of packages installed by nginx::passenger to be configurable [COOK-3672] - Nginx should support the gzip_static option Updating for yum ~> 3.0 Fixing up style for rubocop Updating test-kitchen harness + +## v2.0.8 + +fixing metadata version error. locking to 3.0 + +## v2.0.6 + +Locking yum dependency to '< 3' + +## v2.0.4 + +### Bug + +- **[COOK-3808](https://tickets.chef.io/browse/COOK-3808)** - nginx::passenger run fails because of broken installation of package dependencies +- **[COOK-3779](https://tickets.chef.io/browse/COOK-3779)** - Build in master fails due to rubocop error + +## v2.0.2 + +### Bug + +- **[COOK-3808](https://tickets.chef.io/browse/COOK-3808)** - nginx::passenger run fails because of broken installation of package dependencies +- **[COOK-3779](https://tickets.chef.io/browse/COOK-3779)** - Build in master fails due to rubocop error + +## v2.0.0 + +### Improvement + +- **[COOK-3733](https://tickets.chef.io/browse/COOK-3733)** - Add RPM key names and GPG checking +- **[COOK-3687](https://tickets.chef.io/browse/COOK-3687)** - Add support for `http_perl` +- **[COOK-3603](https://tickets.chef.io/browse/COOK-3603)** - Add a recipe for using custom openssl +- **[COOK-3602](https://tickets.chef.io/browse/COOK-3602)** - Use an attribute for the status module port +- **[COOK-3549](https://tickets.chef.io/browse/COOK-3549)** - Refactor custom modules support +- **[COOK-3521](https://tickets.chef.io/browse/COOK-3521)** - Add support for `http_auth_request` +- **[COOK-3520](https://tickets.chef.io/browse/COOK-3520)** - Add support for `spdy` +- **[COOK-3185](https://tickets.chef.io/browse/COOK-3185)** - Add `gzip_*` attributes +- **[COOK-2712](https://tickets.chef.io/browse/COOK-2712)** - Update `upload_progress` version to 0.9.0 + +### Bug + +- **[COOK-3686](https://tickets.chef.io/browse/COOK-3686)** - Remove deprecated 'passenger_use_global_queue' directive +- **[COOK-3626](https://tickets.chef.io/browse/COOK-3626)** - Parameterize hardcoded path to helper scripts +- **[COOK-3571](https://tickets.chef.io/browse/COOK-3571)** - Reloda ohai plugin after installation +- **[COOK-3428](https://tickets.chef.io/browse/COOK-3428)** - Fix an issue where access logs are not disabled when the `disable_access_log` attribute is set to `true` +- **[COOK-3322](https://tickets.chef.io/browse/COOK-3322)** - Fix an issue where `nginx::ohai_plugin` fails when using source recipe +- **[COOK-3241](https://tickets.chef.io/browse/COOK-3241)** - Fix an issue where`nginx::ohai_plugin` fails unless using source recipe + +### New Feature + +- **[COOK-3605](https://tickets.chef.io/browse/COOK-3605)** - Add Lua module + +## v1.8.0 + +### Bug + +- **[COOK-3397](https://tickets.chef.io/browse/COOK-3397)** - Fix user from nginx package on Gentoo +- **[COOK-2968](https://tickets.chef.io/browse/COOK-2968)** - Fix foodcritic failure +- **[COOK-2723](https://tickets.chef.io/browse/COOK-2723)** - Remove duplicate passenger `max_pool_size` + +### Improvement + +- **[COOK-3186](https://tickets.chef.io/browse/COOK-3186)** - Add `client_body_buffer_size` and `server_tokens attributes` +- **[COOK-3080](https://tickets.chef.io/browse/COOK-3080)** - Add rate-limiting support +- **[COOK-2927](https://tickets.chef.io/browse/COOK-2927)** - Add support for `real_ip_recursive` directive +- **[COOK-2925](https://tickets.chef.io/browse/COOK-2925)** - Fix ChefSpec converge +- **[COOK-2724](https://tickets.chef.io/browse/COOK-2724)** - Automatically create directory for PID file +- **[COOK-2472](https://tickets.chef.io/browse/COOK-2472)** - Bump nginx version to 1.2.9 +- **[COOK-2312](https://tickets.chef.io/browse/COOK-2312)** - Add additional `mine_types` to the `gzip_types` value + +### New Feature + +- **[COOK-3183](https://tickets.chef.io/browse/COOK-3183)** - Allow inclusion in extra-cookbook modules + +## v1.7.0 + +### Improvement + +- [COOK-3030]: The repo_source attribute should allow you to not add any additional repositories to your node + +### Sub-task + +- [COOK-2738]: move nginx::passenger attributes to `nginx/attributes/passenger.rb` + +## v1.6.0 + +### Task + +- [COOK-2409]: update nginx::source recipe for new `runit_service` resource +- [COOK-2877]: update nginx cookbook test-kitchen support to 1.0 (alpha) + +### Improvement + +- [COOK-1976]: nginx source should be able to configure binary path +- [COOK-2622]: nginx: add upstart support +- [COOK-2725]: add "configtest" subcommand in initscript + +### Bug + +- [COOK-2398]: nginx_site definition cannot be used to manage the default site +- [COOK-2493]: Resources in nginx::source recipe always use 1.2.6 version, even overriding version attribute +- [COOK-2531]: Remove usage of non-existant attribute "description" for `apt_repository` +- [COOK-2665]: nginx::source install with custom sbin_path breaks ohai data + +## v1.4.0 + +- [COOK-2183] - Install nginx package from nginxyum repo +- [COOK-2311] - headers-more should be updated to the latest version +- [COOK-2455] - Support sendfile option (nginx.conf) + +## v1.3.0 + +- [COOK-1979] - Passenger module requires curl-dev(el) +- [COOK-2219] - Support `proxy_read_timeout` (in nginx.conf) +- [COOK-2220] - Support `client_max_body_size` (in nginx.conf) +- [COOK-2280] - Allow custom timing of nginx_site's reload notification +- [COOK-2304] - nginx cookbook should install 1.2.6 not 1.2.3 for source installs +- [COOK-2309] - checksums for geoip files need to be updated in nginx +- [COOK-2310] - Checksum in the `nginx::upload_progress` recipe is not correct +- [COOK-2314] - nginx::passenger: Install the latest version of passenger +- [COOK-2327] - nginx: passenger recipe should find ruby via Ohai +- [COOK-2328] - nginx: Update mime.types file to the latest +- [COOK-2329] - nginx: Update naxsi rules to the current + +## v1.2.0 + +- [COOK-1752] - Add headers more module to the nginx cookbook +- [COOK-2209] - nginx source recipe should create web user before creating directories +- [COOK-2221] - make nginx::source compatible with gentoo +- [COOK-2267] - add version for runit recommends + +## v1.1.4 + +- [COOK-2168] - specify package name as an attribute + +## v1.1.2 + +- [COOK-1766] - Nginx Source Recipe Rebuilding Source at Every Run +- [COOK-1910] - Add IPv6 module +- [COOK-1966] - nginx cookbook should let you set `gzip_vary` and `gzip_buffers` in nginx.conf +- [COOK-1969]- - nginx::passenger module not included due to use of symbolized `:nginx_configure_flags` +- [COOK-1971] - Template passenger.conf.erb configures key `passenger_max_pool_size` 2 times +- [COOK-1972] - nginx::source compile_nginx_source reports success in spite of failed compilation +- [COOK-1975] - nginx::passenger requires rake gem +- [COOK-1979] - Passenger module requires curl-dev(el) +- [COOK-2080] - Restart nginx on source compilation + +## v1.1.0 + +- [COOK-1263] - Nginx log (and possibly other) directory creations should be recursive +- [COOK-1515] - move creation of `node['nginx']['dir']` out of commons.rb +- [COOK-1523] - nginx `http_geoip_module` requires libtoolize +- [COOK-1524] - nginx checksums are md5 +- [COOK-1641] - add "use", "`multi_accept`" and "`worker_rlimit_nofile`" to nginx cookbook +- [COOK-1683] - Nginx fails Windows nodes just by being required in metadata +- [COOK-1735] - Support Amazon Linux in nginx::source recipe +- [COOK-1753] - Add ability for nginx::passenger recipe to configure more Passenger global settings +- [COOK-1754] - Allow group to be set in nginx.conf file +- [COOK-1770] - nginx cookbook fails on servers that don't have a "cpu" attribute +- [COOK-1781] - Use 'sv' to reload nginx when using runit +- [COOK-1789] - stop depending on bluepill, runit and yum. they are not required by nginx cookbook +- [COOK-1791] - add name attribute to metadata +- [COOK-1837] - nginx::passenger doesn't work on debian family +- [COOK-1956] - update naxsi version due to incompatibility with newer nginx + +## v1.0.2 + +- [COOK-1636] - relax the version constraint on ohai + +## v1.0.0 + +- [COOK-913] - defaults for gzip cause warning on service restart +- [COOK-1020] - duplicate MIME type +- [COOK-1269] - add passenger module support through new recipe +- [COOK-1306] - increment nginx version to 1.2 (now 1.2.3) +- [COOK-1316] - default site should not always be enabled +- [COOK-1417] - resolve errors preventing build from source +- [COOK-1483] - source prefix attribute has no effect +- [COOK-1484] - source relies on /etc/sysconfig +- [COOK-1511] - add support for naxsi module +- [COOK-1525] - nginx source is downloaded every time +- [COOK-1526] - nginx_site does not remove sites +- [COOK-1527] - add `http_echo_module` recipe + +## v0.101.6 + +Erroneous cookbook upload due to timeout. + +Version #'s are cheap. + +## v0.101.4 + +- [COOK-1280] - Improve RHEL family support and fix ohai_plugins recipe bug +- [COOK-1194] - allow installation method via attribute +- [COOK-458] - fix duplicate nginx processes + +## v0.101.2 + +- [COOK-1211] - include the default attributes explicitly so version is available. + +## v0.101.0 + +**Attribute Change**: `node['nginx']['url']` -> `node['nginx']['source']['url']`; see the README.md. + +- [COOK-1115] - daemonize when using init script +- [COOK-477] - module compilation support in nginx::source + +## v0.100.4 + +- [COOK-1126] - source version bump to 1.0.14 + +## v0.100.2 + +- [COOK-1053] - Add :url attribute to nginx cookbook + +## v0.100.0 + +- [COOK-818] - add "application/json" per RFC. +- [COOK-870] - bluepill init style support +- [COOK-957] - Compress application/javascript. +- [COOK-981] - Add reload support to NGINX service + +## v0.99.2 + +- [COOK-809] - attribute to disable access logging +- [COOK-772] - update nginx download source location + + + +[#174]: https://github.com/miketheman/nginx/issues/174 +[#183]: https://github.com/miketheman/nginx/issues/183 +[#184]: https://github.com/miketheman/nginx/issues/184 +[#188]: https://github.com/miketheman/nginx/issues/188 +[#200]: https://github.com/miketheman/nginx/issues/200 +[#204]: https://github.com/miketheman/nginx/issues/204 +[#205]: https://github.com/miketheman/nginx/issues/205 +[#219]: https://github.com/miketheman/nginx/issues/219 +[#220]: https://github.com/miketheman/nginx/issues/220 +[#223]: https://github.com/miketheman/nginx/issues/223 +[#225]: https://github.com/miketheman/nginx/issues/225 +[#230]: https://github.com/miketheman/nginx/issues/230 +[#236]: https://github.com/miketheman/nginx/issues/236 +[#240]: https://github.com/miketheman/nginx/issues/240 +[#243]: https://github.com/miketheman/nginx/issues/243 +[#249]: https://github.com/miketheman/nginx/issues/249 +[#252]: https://github.com/miketheman/nginx/issues/252 +[#254]: https://github.com/miketheman/nginx/issues/254 +[#259]: https://github.com/miketheman/nginx/issues/259 +[#269]: https://github.com/miketheman/nginx/issues/269 +[#279]: https://github.com/miketheman/nginx/issues/279 +[#294]: https://github.com/miketheman/nginx/issues/294 +[#298]: https://github.com/miketheman/nginx/issues/298 +[#302]: https://github.com/miketheman/nginx/issues/302 +[#305]: https://github.com/miketheman/nginx/issues/305 +[#310]: https://github.com/miketheman/nginx/issues/310 +[#312]: https://github.com/miketheman/nginx/issues/312 +[#314]: https://github.com/miketheman/nginx/issues/314 +[#318]: https://github.com/miketheman/nginx/issues/318 +[#321]: https://github.com/miketheman/nginx/issues/321 +[#325]: https://github.com/miketheman/nginx/issues/325 +[#326]: https://github.com/miketheman/nginx/issues/326 +[#327]: https://github.com/miketheman/nginx/issues/327 +[#331]: https://github.com/miketheman/nginx/issues/331 +[#332]: https://github.com/miketheman/nginx/issues/332 +[#335]: https://github.com/miketheman/nginx/issues/335 +[#338]: https://github.com/miketheman/nginx/issues/338 +[@9minutesnooze]: https://github.com/9minutesnooze +[@adepue]: https://github.com/adepue +[@auth0]: https://github.com/auth0 +[@bchrobot]: https://github.com/bchrobot +[@bkw]: https://github.com/bkw +[@canofspam3bug324]: https://github.com/CanOfSpam3bug324 +[@dwradcliffe]: https://github.com/dwradcliffe +[@evertrue]: https://github.com/evertrue +[@ffuenf]: https://github.com/ffuenf +[@firmhouse]: https://github.com/firmhouse +[@gkra]: https://github.com/gkra +[@gregkare]: https://github.com/gregkare +[@irontoby]: https://github.com/irontoby +[@jalberto]: https://github.com/jalberto +[@jcoleman]: https://github.com/jcoleman +[@jenssegers]: https://github.com/jenssegers +[@josh-padnick]: https://github.com/josh-padnick +[@jujugrrr]: https://github.com/jujugrrr +[@karsten-bruckmann]: https://github.com/karsten-bruckmann +[@larkin]: https://github.com/larkin +[@miketheman]: https://github.com/miketheman +[@monsterstrike]: https://github.com/monsterstrike +[@morr]: https://github.com/morr +[@mytho]: https://github.com/Mytho +[@n1koo]: https://github.com/n1koo +[@nkadel-skyhook]: https://github.com/nkadel-skyhook +[@runningman84]: https://github.com/runningman84 +[@shtouff]: https://github.com/shtouff +[@stevenolen]: https://github.com/stevenolen +[@thomasmeeus]: https://github.com/thomasmeeus +[@thommay]: https://github.com/thommay +[@tvdinner]: https://github.com/tvdinner +[@usertesting]: https://github.com/usertesting +[@whatcould]: https://github.com/whatcould +[@yveslaroche]: https://github.com/yveslaroche diff --git a/cookbooks/bluepill/CONTRIBUTING.md b/cookbooks/chef_nginx/CONTRIBUTING.md similarity index 100% rename from cookbooks/bluepill/CONTRIBUTING.md rename to cookbooks/chef_nginx/CONTRIBUTING.md diff --git a/cookbooks/bluepill/MAINTAINERS.md b/cookbooks/chef_nginx/MAINTAINERS.md similarity index 56% rename from cookbooks/bluepill/MAINTAINERS.md rename to cookbooks/chef_nginx/MAINTAINERS.md index 00eed8d..645ed14 100644 --- a/cookbooks/bluepill/MAINTAINERS.md +++ b/cookbooks/chef_nginx/MAINTAINERS.md @@ -1,13 +1,10 @@ # 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) diff --git a/cookbooks/chef_nginx/README.md b/cookbooks/chef_nginx/README.md new file mode 100644 index 0000000..d049f10 --- /dev/null +++ b/cookbooks/chef_nginx/README.md @@ -0,0 +1,367 @@ +# nginx Cookbook + +[![Cookbook](http://img.shields.io/cookbook/v/chef_nginx.svg)](https://supermarket.chef.io/cookbooks/chef_nginx) [![Build Status](https://travis-ci.org/chef-cookbooks/chef_nginx.svg?branch=master)](https://travis-ci.org/chef-cookbooks/chef_nginx) + +Installs nginx from package OR source code and sets up configuration handling similar to Debian's Apache2 scripts. + +## nginx vs. chef_nginx + +This cookbook is a fork from the 2.7.x branch of the [community nginx cookbook](https://github.com/miketheman/nginx). + +This fork will be actively supported by Chef Software and we will continue to migrate the cookbook to a more resource driven model, with incremental changes following the SemVer model. + +## Requirements + +### Cookbooks + +The following cookbooks are direct dependencies because they're used for common "default" functionality. + +- `build-essential` for source installations +- `ohai` for setting up the ohai plugin +- `compat_resource` for setting up the nginx.org repository on Chef 12.1 - 12.13 +- `yum-epel` for setting up the EPEL repository on RHEL platforms +- `zypper` for setting up the nginx.org repository on Suse platforms + +### Platforms + +The following platforms are supported and tested with Test Kitchen: + +- Ubuntu 12.04+ +- CentOS 5+ +- Debian 7+ +- openSUSE 13.2+ +- FreeBSD 9+ + +Other Debian and RHEL family distributions are assumed to work. + +### Chef + +- Chef 12.1+ + +## Attributes + +Node attributes for this cookbook are logically separated into different files. Some attributes are set only via a specific recipe. + +### chef_nginx::auth_request + +These attributes are used in the `chef_nginx::auth_request` recipe. + +- `node['nginx']['auth_request']['url']` - The url to the auth_request module tar.gz file +- `node['nginx']['auth_request']['checksum']` - The checksum of the auth_request module tar.gz file + +### chef_nginx::default + +Generally used attributes. Some have platform specific values. See `attributes/default.rb`. "The Config" refers to "nginx.conf" the main config file. + +- `node['nginx']['dir']` - Location for nginx configuration. +- `node['nginx']['conf_template']` - The `source` template to use when creating the `nginx.conf`. +- `node['nginx']['conf_cookbook']` - The cookbook where `node['nginx']['conf_template']` resides. +- `node['nginx']['log_dir']` - Location for nginx logs. +- `node['nginx']['log_dir_perm']` - Permissions for nginx logs folder. +- `node['nginx']['user']` - User that nginx will run as. +- `node['nginx']['group']` - Group for nginx. +- `node['nginx']['port']` - Port for nginx to listen on. +- `node['nginx']['binary']` - Path to the nginx binary. +- `node['nginx']['init_style']` - How to run nginx as a service when using `chef_nginx::source`. Values can be "upstart", "systemd", or "init". This attribute is not used in the `package` recipe because the package manager's init script style for the platform is assumed. +- `node['nginx']['upstart']['foreground']` - Set this to true if you want upstart to run nginx in the foreground, set to false if you want upstart to detach and track the process via pid. +- `node['nginx']['upstart']['runlevels']` - String of runlevels in the format '2345' which determines which runlevels nginx will start at when entering and stop at when leaving. +- `node['nginx']['upstart']['respawn_limit']` - Respawn limit in upstart stanza format, count followed by space followed by interval in seconds. +- `node['nginx']['keepalive']` - Whether to use `keepalive_timeout`, any value besides "on" will leave that option out of the config. +- `node['nginx']['keepalive_requests']` - used for config value of `keepalive_requests`. +- `node['nginx']['keepalive_timeout']` - used for config value of `keepalive_timeout`. +- `node['nginx']['worker_processes']` - used for config value of `worker_processes`. +- `node['nginx']['worker_connections']` - used for config value of `events { worker_connections }` +- `node['nginx']['worker_rlimit_nofile']` - used for config value of `worker_rlimit_nofile`. Can replace any "ulimit -n" command. The value depend on your usage (cache or not) but must always be superior than worker_connections. +- `node['nginx']['worker_shutdown_timeout']` - used for config value of `worker_shutdown_timeout`. +- `node['nginx']['worker_connections']` - used for config value of `events { worker_connections }` +- `node['nginx']['multi_accept']` - used for config value of `events { multi_accept }`. Try to accept() as many connections as possible. Disable by default. +- `node['nginx']['event']` - used for config value of `events { use }`. Set the event-model. By default nginx looks for the most suitable method for your OS. +- `node['nginx']['accept_mutex_delay']` - used for config value of `accept_mutex_delay` +- `node['nginx']['server_tokens']` - used for config value of `server_tokens`. +- `node['nginx']['server_names_hash_bucket_size']` - used for config value of `server_names_hash_bucket_size`. +- `node['nginx']['disable_access_log']` - set to true to disable the general access log, may be useful on high traffic sites. +- `node['nginx']['access_log_options']` - Set to a string of additional options to be appended to the access log directive +- `node['nginx']['error_log_options']` - Set to a string of additional options to be appended to the error log directive +- `node['nginx']['default_site_enabled']` - enable the default site +- `node['nginx']['sendfile']` - Whether to use `sendfile`. Defaults to "on". +- `node['nginx']['tcp_nopush']` - Whether to use `tcp_nopush`. Defaults to "on". +- `node['nginx']['tcp_nodelay']` - Whether to use `tcp_nodelay`. Defaults to "on". +- `node['nginx']['install_method']` - Whether nginx is installed from packages or from source. +- `node['nginx']['types_hash_max_size']` - Used for the `types_hash_max_size` configuration directive. +- `node['nginx']['types_hash_bucket_size']` - Used for the `types_hash_bucket_size` configuration directive. +- `node['nginx']['proxy_read_timeout']` - defines a timeout (between two successive read operations) for reading a response from the proxied server. +- `node['nginx']['client_body_buffer_size']` - used for config value of `client_body_buffer_size`. +- `node['nginx']['client_max_body_size']` - specifies the maximum accepted body size of a client request, as indicated by the request header Content-Length. +- `node['nginx']['repo_source']` - when installed from a package this attribute affects which yum repositories, if any, will be added before installing the nginx package. The default value of 'epel' will use the `yum-epel` cookbook, 'nginx' will use the `chef_nginx::repo` recipe, 'passenger' will use the 'chef_nginx::repo_passenger' recipe, and setting no value will not add any additional repositories. +- `node['nginx']['sts_max_age']` - Enable Strict Transport Security for all apps (See: ). This attribute adds the following header: Strict-Transport-Security max-age=SECONDS to all incoming requests and takes an integer (in seconds) as its argument. +- `node['nginx']['default']['modules']` - Array specifying which modules to enable via the conf-enabled config include function. Currently the only valid value is "socketproxy". +- `node['nginx']['load_modules']` - Array of paths to modules to dynamically load on nginx startup using the `load_module` directive. Default is `[]`. + +#### authorized_ips module + +- `node['nginx']['remote_ip_var']` - The remote ip variable name to use. +- `node['nginx']['authorized_ips']` - IPs authorized by the module + +#### gzip module + +- `node['nginx']['gzip']` - Whether to use gzip, can be "on" or "off" +- `node['nginx']['gzip_http_version']` - used for config value of `gzip_http_version`. +- `node['nginx']['gzip_comp_level']` - used for config value of `gzip_comp_level`. +- `node['nginx']['gzip_proxied']` - used for config value of `gzip_proxied`. +- `node['nginx']['gzip_vary']` - used for config value of `gzip_vary`. +- `node['nginx']['gzip_buffers']` - used for config value of `gzip_buffers`. +- `node['nginx']['gzip_types']` - used for config value of `gzip_types` - must be an Array. +- `node['nginx']['gzip_min_length']` - used for config value of `gzip_min_length`. +- `node['nginx']['gzip_disable']` - used for config value of `gzip_disable`. +- `node['nginx']['gzip_static']` - used for config value of `gzip_static` (`http_gzip_static_module` must be enabled) + +#### Other configurations + +- `node['nginx']['extra_configs']` - a Hash of key/values to nginx configuration. + +### chef_nginx::echo + +These attributes are used in the `chef_nginx::http_echo_module` recipe. + +- `node['nginx']['echo']['version']` - The version of `http_echo` you want (default: 0.59) +- `node['nginx']['echo']['url']` - URL for the tarball. +- `node['nginx']['echo']['checksum']` - Checksum of the tarball. + +### chef_nginx::devel + +These attributes are used in the `chef_nginx::ngx_devel_module` recipe. + +- `node['nginx']['devel']['version']` - The version of the nginx devel module +- `node['nginx']['devel']['url']` - The URL of the nginx devel module tar.gz file +- `node['nginx']['devel']['checksum']` - The checksum of the nginx devel module tar.gz file + +### chef_nginx::geoip + +These attributes are used in the `chef_nginx::http_geoip_module` recipe. Please note that the `country_dat_checksum` and `city_dat_checksum` are based on downloads from a datacenter in Fremont, CA, USA. You really should override these with checksums for the geo tarballs from your node location. + +**Note** The upstream, maxmind.com, may block access for repeated downloads of the data files. It is recommended that you download and host the data files, and change the URLs in the attributes. + +- `node['nginx']['geoip']['path']` - Location where to install the geoip libraries. +- `node['nginx']['geoip']['enable_city']` - Whether to enable City data +- `node['nginx']['geoip']['country_dat_url']` - Country data tarball URL +- `node['nginx']['geoip']['country_dat_checksum']` - Country data tarball checksum +- `node['nginx']['geoip']['city_dat_url']` - City data tarball URL +- `node['nginx']['geoip']['city_dat_checksum']` - City data tarball checksum +- `node['nginx']['geoip']['lib_version']` - Version of the GeoIP library to install +- `node['nginx']['geoip']['lib_url']` - (Versioned) Tarball URL of the GeoIP library +- `node['nginx']['geoip']['lib_checksum']` - Checksum of the GeoIP library tarball + +### chef_nginx::http_realip_module + +From: + +- `node['nginx']['realip']['header']` - Header to use for the RealIp Module; only accepts "X-Forwarded-For" or "X-Real-IP" +- `node['nginx']['realip']['addresses']` - Addresses to use for the `http_realip` configuration. +- `node['nginx']['realip']['real_ip_recursive']` - If recursive search is enabled, the original client address that matches one of the trusted addresses is replaced by the last non-trusted address sent in the request header field. Can be on "on" or "off" (default). + +### chef_nginx::passenger + +These attributes are used in the `chef_nginx::passenger` recipe. + +- `node['nginx']['passenger']['version']` - passenger gem version +- `node['nginx']['passenger']['root']` - passenger gem root path +- `node['nginx']['passenger']['install_rake']` - set to false if rake already present on system +- `node['nginx']['passenger']['max_pool_size']` - maximum passenger pool size (default=10) +- `node['nginx']['passenger']['ruby']` - Ruby path for Passenger to use (default=`$(which ruby)`) +- `node['nginx']['passenger']['spawn_method']` - passenger spawn method to use (default=`smart-lv2`) +- `node['nginx']['passenger']['buffer_response']` - turns on or off response buffering (default=`on`) +- `node['nginx']['passenger']['max_pool_size']` - passenger maximum pool size (default=`6`) +- `node['nginx']['passenger']['min_instances']` - minimum instances (default=`1`) +- `node['nginx']['passenger']['max_instances_per_app']` - maximum instances per app (default=`0`) +- `node['nginx']['passenger']['pool_idle_time']` - passenger pool idle time (default=`300`) +- `node['nginx']['passenger']['max_requests']` - maximum requests (default=`0`) +- `node['nginx']['passenger']['nodejs']` - Nodejs path for Passenger to use (default=nil) +- `node['nginx']['passenger']['show_version_in_header']` - Show passenger version in HTTP headers (default=`on`) + +Basic configuration to use the official Phusion Passenger repositories: + +- `node['nginx']['repo_source']` - 'passenger' +- `node['nginx']['package_name']` - 'nginx-extras' +- `node['nginx']['passenger']['install_method']` - 'package' + +### chef_nginx::openssl_source + +These attributes are used in the `chef_nginx::openssl_source` recipe. + +- `node['nginx']['openssl_source']['version']` - The version of OpenSSL you want to download and use (default: 1.0.1t) +- `node['nginx']['openssl_source']['url']` - The url for the OpenSSL source + +### chef_nginx::rate_limiting + +- `node['nginx']['enable_rate_limiting']` - set to true to enable rate limiting (`limit_req_zone` in nginx.conf) +- `node['nginx']['rate_limiting_zone_name']` - sets the zone in `limit_req_zone`. +- `node['nginx']['rate_limiting_backoff']` - sets the backoff time for `limit_req_zone`. +- `node['nginx']['rate_limit']` - set the rate limit amount for `limit_req_zone`. + +### chef_nginx::socketproxy + +These attributes are used in the `chef_nginx::socketproxy` recipe. + +- `node['nginx']['socketproxy']['root']` - The directory (on your server) where socketproxy apps are deployed. +- `node['nginx']['socketproxy']['default_app']` - Static assets directory for requests to "/" that don't meet any proxy_pass filter requirements. +- `node['nginx']['socketproxy']['apps']['app_name']['prepend_slash']` - Prepend a slash to requests to app "app_name" before sending them to the socketproxy socket. +- `node['nginx']['socketproxy']['apps']['app_name']['context_name']` - URI (e.g. "app_name" in order to achieve "") at which to host the application "app_name" +- `node['nginx']['socketproxy']['apps']['app_name']['subdir']` - Directory (under `node['nginx']['socketproxy']['root']`) in which to find the application. + +### chef_nginx::source + +These attributes are used in the `chef_nginx::source` recipe. Some of them are dynamically modified during the run. See `attributes/source.rb` for default values. + +- `node['nginx']['source']['url']` - (versioned) URL for the nginx source code. By default this will use the version specified as `node['nginx']['version']`. +- `node['nginx']['source']['prefix']` - (versioned) prefix for installing nginx from source +- `node['nginx']['source']['conf_path']` - location of the main config file, in `node['nginx']['dir']` by default. +- `node['nginx']['source']['modules']` - Array of modules that should be compiled into nginx by including their recipes in `chef_nginx::source`. +- `node['nginx']['source']['default_configure_flags']` - The default flags passed to the configure script when building nginx. +- `node['nginx']['configure_flags']` - Preserved for compatibility and dynamically generated from the `node['nginx']['source']['default_configure_flags']` in the `chef_nginx::source` recipe. +- `node['nginx']['source']['use_existing_user']` - set to `true` if you do not want `chef_nginx::source` recipe to create system user with name `node['nginx']['user']`. + +### chef_nginx::status + +These attributes are used in the `chef_nginx::http_stub_status_module` recipe. + +- `node['nginx']['status']['port']` - The port on which nginx will serve the status info (default: 8090) + +### chef_nginx::syslog + +These attributes are used in the `chef_nginx::syslog_module` recipe. + +- `node['nginx']['syslog']['git_repo']` - The git repository url to use for the syslog patches. +- `node['nginx']['syslog']['git_revision']` - The revision on the git repository to checkout. + +### chef_nginx::upload_progress + +These attributes are used in the `chef_nginx::upload_progress_module` recipe. + +- `node['nginx']['upload_progress']['url']` - URL for the tarball. +- `node['nginx']['upload_progress']['checksum']` - Checksum of the tarball. +- `node['nginx']['upload_progress']['javascript_output']` - Output in javascript. Default is `true` for backwards compatibility. +- `node['nginx']['upload_progress']['zone_name']` - Zone name which will be used to store the per-connection tracking information. Default is `proxied`. +- `node['nginx']['upload_progress']['zone_size']` - Zone size in bytes. Default is `1m` (1 megabyte). + +## Resources + +### nginx_site + +Enable or disable a Server Block in `#{node['nginx']['dir']}/sites-available` by calling nxensite or nxdissite (introduced by this cookbook) to manage the symbolic link in `#{node['nginx']['dir']}/sites-enabled`. + +### Actions + +- `enable` - Enable the nginx site (default) +- `disable` - Disable the nginx site + +### Properties: + +- `name` - (optional) Name of the site to enable. By default it's assumed that the name of the nginx_site resource is the site name, but this allows overriding that. +- `template` - (optional) Path to the source for the `template` resource. +- `variables` - (optional) Variables to be used with the `template` resource + +## Ohai Plugin + +The `ohai_plugin` recipe includes an Ohai plugin. It will be automatically installed and activated, providing the following attributes via ohai, no matter how nginx is installed (source or package): + +- `node['nginx']['version']` - version of nginx +- `node['nginx']['configure_arguments']` - options passed to `./configure` when nginx was built +- `node['nginx']['prefix']` - installation prefix +- `node['nginx']['conf_path']` - configuration file path + +In the source recipe, it is used to determine whether control attributes for building nginx have changed. + +## Usage + +This cookbook provides three distinct installation methods, all of which are controlled via attributes and executed using the chef_nginx::default recipe. + +### Package installation using the nginx.org repositories + +Nginx provides repositories for RHEL, Debian/Ubuntu, and Suse platforms with up to date packages available on older distributions. Due to the age of many nginx packages shipping with distros we believe this is the ideal installation method. With no attributes set the nginx.org repositories will be added to your system and nginx will be installed via package. This provides a solid out of the box install for most users. + +### Package installation using distro repositories + +If you prefer to use the packages included in your distro or to roll your own packages you'll want to set `node['nginx']['repo_source']` to `nil` or `distro` to skip the repository setup. The default recipe will still install nginx from packages, but you'll retain control over the package location. + +### Source installation to compile non-dynamic modules + +If you need control over how nginx is built, or you need non-dynamic modules to be included you'll need to compile nginx from source. We highly recommend against using this method as it requires the installation of a full compilation toolchain and development dependencies on your nodes. Creating your own packages with nginx compiled as necessary is a preferred option. If that's not possible you can set `node['nginx']['install_method']` to `source` and provide a version in `node['nginx']['version']`. + +#### Specifying Modules to compile + +The following recipes are used to build module support into nginx. To compile a module, add its recipe name to the array attribute `node['nginx']['source']['modules']`. + +- `ipv6.rb` - enables IPv6 support +- `headers_more_module` - +- `http_auth_request_module`` +- `http_echo_module.rb` - downloads the `http_echo_module` module and enables it as a module when compiling nginx. +- `http_geoip_module.rb` - installs the GeoIP libraries and data files and enables the module for compilation. +- `http_gzip_static_module.rb` - enables the module for compilation. Be sure to set `node['nginx']['gzip_static'] = 'yes'`. +- `http_mp4_module` - +- `http_perl_module.rb` - enables embedded Perl for compilation. +- `http_realip_module.rb` - enables the module for compilation and creates the configuration. +- `http_spdy_module` - +- `http_ssl_module.rb` - enables SSL for compilation. +- `http_stub_status_module.rb` - provides `nginx_status` configuration and enables the module for compilation. +- `http_v2_module` +- `ipv6` - +- `naxsi_module` - enables the naxsi module for the web application firewall for nginx. +- `ngx_devel_module` - +- `ngx_lua_module` - +- `openssl_source.rb` - downloads and uses custom OpenSSL source when compiling nginx +- `pagespeed_module`- +- `passenger` - builds the passenger gem and configuration for "`mod_passenger`". +- `set_misc` - +- `syslog_module` - enables syslog support for nginx. This only works with source builds. See - +- `upload_progress_module.rb` - builds the `upload_progress` module and enables it as a module when compiling nginx. + +## Resources + +### nginx_site + +Enable or disable a Server Block in `#{node['nginx']['dir']}/sites-available` by calling nxensite or nxdissite (introduced by this cookbook) to manage the symbolic link in `#{node['nginx']['dir']}/sites-enabled`. + +### Actions + +- `enable` - Enable the nginx site (default) +- `disable` - Disable the nginx site + +### Properties: + +- `name` - (optional) Name of the site to enable. By default it's assumed that the name of the nginx_site resource is the site name, but this allows overriding that. +- `template` - (optional) Path to the source for the `template` resource. +- `cookbook` - (optional) The cookbook that contains the template source. +- `variables` - (optional) Variables to be used with the `template` resource + +## Adding New Modules + +Previously we'd add each possible module to this cookbook itself. That's not necessary using wrapper cookbooks and we'd prefer to not add any addition module recipes at this time. Instead in your nginx wrapper cookbook setup any necessary packages and then include the follow code to add the module to the list of modules to compile: + +```ruby +node.run_state['nginx_configure_flags'] = + node.run_state['nginx_configure_flags'] | ['--with-SOMETHING', "--with-SOME_OPT='things'"] +``` + +## License & Authors + +- Author:: Joshua Timberman ([joshua@chef.io](mailto:joshua@chef.io)) +- Author:: Adam Jacob ([adam@chef.io](mailto:adam@chef.io)) +- Author:: AJ Christensen ([aj@chef.io](mailto:aj@chef.io)) +- Author:: Jamie Winsor ([jamie@vialstudios.com](mailto:jamie@vialstudios.com)) +- Author:: Mike Fiedler ([miketheman@gmail.com](mailto:miketheman@gmail.com)) + +```text +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. +``` diff --git a/cookbooks/nginx/attributes/auth_request.rb b/cookbooks/chef_nginx/attributes/auth_request.rb similarity index 74% rename from cookbooks/nginx/attributes/auth_request.rb rename to cookbooks/chef_nginx/attributes/auth_request.rb index c4dbcf0..21eb14f 100644 --- a/cookbooks/nginx/attributes/auth_request.rb +++ b/cookbooks/chef_nginx/attributes/auth_request.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: chef_nginx # Attributes:: auth_request # # Author:: David Radcliffe () # -# Copyright 2013, David Radcliffe +# Copyright:: 2013-2017, David Radcliffe # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,5 +19,5 @@ # limitations under the License. # -default['nginx']['auth_request']['url'] = 'http://mdounin.ru/hg/ngx_http_auth_request_module/archive/ee8ff54f9b66.tar.gz' -default['nginx']['auth_request']['checksum'] = '7ab85e1c350c5a9c60ed1319c45fed144cc3c3e1' +default['nginx']['auth_request']['url'] = 'http://mdounin.ru/hg/ngx_http_auth_request_module/archive/662785733552.tar.gz' +default['nginx']['auth_request']['checksum'] = '2057bdefd2137a5000d9dbdbfca049d1ba7832ad2b9f8855a88ea5dfa70bd8c1' diff --git a/cookbooks/nginx/attributes/default.rb b/cookbooks/chef_nginx/attributes/default.rb similarity index 83% rename from cookbooks/nginx/attributes/default.rb rename to cookbooks/chef_nginx/attributes/default.rb index c3e96fe..e2000eb 100644 --- a/cookbooks/nginx/attributes/default.rb +++ b/cookbooks/chef_nginx/attributes/default.rb @@ -1,11 +1,11 @@ # -# Cookbook Name:: nginx +# Cookbook:: chef_nginx # Attributes:: default # # Author:: Adam Jacob () # Author:: Joshua Timberman () # -# Copyright 2009-2013, Chef Software, Inc. +# Copyright:: 2009-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. @@ -21,9 +21,8 @@ # # In order to update the version, the checksum attribute must be changed too. -# This attribute is in the source.rb file, though we recommend overriding -# attributes by modifying a role, or the node itself. -default['nginx']['version'] = '1.6.2' +# This attribute is defined in the source.rb attribute file +default['nginx']['version'] = '1.10.3' default['nginx']['package_name'] = 'nginx' default['nginx']['port'] = '80' default['nginx']['dir'] = '/etc/nginx' @@ -34,22 +33,20 @@ default['nginx']['binary'] = '/usr/sbin/nginx' default['nginx']['default_root'] = '/var/www/nginx-default' default['nginx']['ulimit'] = '1024' -default['nginx']['pid'] = '/var/run/nginx.pid' +# use the upstream nginx repo vs. distro packages +# this enables the use of modern nginx releases +# set this to nil to use the distro packages +# this is ignored if install_method is set to source +default['nginx']['repo_source'] = 'nginx' +default['nginx']['install_method'] = 'package' case node['platform_family'] when 'debian' - default['nginx']['user'] = 'www-data' - default['nginx']['init_style'] = 'runit' - if platform == 'ubuntu' && platform_version == '14.04' - default['nginx']['pid'] = '/run/nginx.pid' - end -when 'rhel', 'fedora' + default['nginx']['user'] = 'www-data' +when 'rhel' + default['nginx']['user'] = 'nginx' +when 'fedora' default['nginx']['user'] = 'nginx' - default['nginx']['init_style'] = 'init' - default['nginx']['repo_source'] = 'epel' -when 'gentoo' - default['nginx']['user'] = 'nginx' - default['nginx']['init_style'] = 'init' when 'freebsd' default['nginx']['package_name'] = 'www/nginx' default['nginx']['user'] = 'www' @@ -59,11 +56,9 @@ when 'freebsd' default['nginx']['default_root'] = '/usr/local/www/nginx-dist' when 'suse' default['nginx']['user'] = 'wwwrun' - default['nginx']['init_style'] = 'init' default['nginx']['group'] = 'www' else default['nginx']['user'] = 'www-data' - default['nginx']['init_style'] = 'init' end default['nginx']['upstart']['runlevels'] = '2345' @@ -87,6 +82,7 @@ default['nginx']['gzip_types'] = %w( application/xml application/rss+xml application/atom+xml + image/svg+xml text/javascript application/javascript application/json @@ -117,7 +113,6 @@ default['nginx']['access_log_options'] = nil default['nginx']['error_log_options'] = nil default['nginx']['disable_access_log'] = false default['nginx']['log_formats'] = {} -default['nginx']['install_method'] = 'package' default['nginx']['default_site_enabled'] = true default['nginx']['types_hash_max_size'] = 2_048 default['nginx']['types_hash_bucket_size'] = 64 @@ -129,3 +124,5 @@ default['nginx']['large_client_header_buffers'] = nil default['nginx']['default']['modules'] = [] default['nginx']['extra_configs'] = {} + +default['nginx']['load_modules'] = [] diff --git a/cookbooks/nginx/attributes/devel.rb b/cookbooks/chef_nginx/attributes/devel.rb similarity index 78% rename from cookbooks/nginx/attributes/devel.rb rename to cookbooks/chef_nginx/attributes/devel.rb index cb193a5..0d3cb72 100644 --- a/cookbooks/nginx/attributes/devel.rb +++ b/cookbooks/chef_nginx/attributes/devel.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: chef_nginx # Attributes:: devel # # Author:: Arthur Freyman () # -# Copyright 2013, Riot Games +# Copyright:: 2013-2017, Riot Games # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,6 +19,6 @@ # limitations under the License. # -default['nginx']['devel']['version'] = '0.2.18' +default['nginx']['devel']['version'] = '0.3.0' default['nginx']['devel']['url'] = "https://github.com/simpl/ngx_devel_kit/archive/v#{node['nginx']['devel']['version']}.tar.gz" -default['nginx']['devel']['checksum'] = 'c9c9f0a1b068d38c6c45b15d9605f1b2344dbcd45abf0764cd8e2ba92d6a3d2c' +default['nginx']['devel']['checksum'] = '88e05a99a8a7419066f5ae75966fb1efc409bad4522d14986da074554ae61619' diff --git a/cookbooks/nginx/attributes/echo.rb b/cookbooks/chef_nginx/attributes/echo.rb similarity index 77% rename from cookbooks/nginx/attributes/echo.rb rename to cookbooks/chef_nginx/attributes/echo.rb index bd9f3f1..78db4d6 100644 --- a/cookbooks/nginx/attributes/echo.rb +++ b/cookbooks/chef_nginx/attributes/echo.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: chef_nginx # Attributes:: echo # # Author:: Danial Pearce () # -# Copyright 2013, Danial Pearce +# Copyright:: 2013-2017, Danial Pearce # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,6 +19,6 @@ # limitations under the License. # -default['nginx']['echo']['version'] = '0.57' +default['nginx']['echo']['version'] = '0.59' default['nginx']['echo']['url'] = "https://github.com/openresty/echo-nginx-module/archive/v#{node['nginx']['echo']['version']}.tar.gz" -default['nginx']['echo']['checksum'] = '8467237ca0fae74ca7a32fbd34fc6044df307098415d48068214c9c235695a07' +default['nginx']['echo']['checksum'] = '9b319ad7836202883128d2b9c24ed818082541df57ef7f2065b7557085c603cd' diff --git a/cookbooks/nginx/attributes/geoip.rb b/cookbooks/chef_nginx/attributes/geoip.rb similarity index 69% rename from cookbooks/nginx/attributes/geoip.rb rename to cookbooks/chef_nginx/attributes/geoip.rb index c72141b..aee552e 100644 --- a/cookbooks/nginx/attributes/geoip.rb +++ b/cookbooks/chef_nginx/attributes/geoip.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: chef_nginx # Attributes:: geoip # # Author:: Jamie Winsor () # -# Copyright 2012-2013, Riot Games +# Copyright:: 2012-2017, Riot Games # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,13 +19,17 @@ # limitations under the License. # +# NOTE: The GeoIP database checksums are nil by default as these files change +# continuously and are not versioned. +# If you self host these files you should create a checksum and set these attributes + default['nginx']['geoip']['path'] = '/srv/geoip' default['nginx']['geoip']['enable_city'] = true default['nginx']['geoip']['country_dat_url'] = 'http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz' -default['nginx']['geoip']['country_dat_checksum'] = '79ff1099e96c2dc1c2539c9a18aaa13a9afd085cae477df60d95f1644d42bc07' +default['nginx']['geoip']['country_dat_checksum'] = nil default['nginx']['geoip']['city_dat_url'] = 'http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz' -default['nginx']['geoip']['city_dat_checksum'] = '8a6467033a528f68b1a97de24d9d0ce86c8e8e83683820e16e433ddbd3f712f7' -default['nginx']['geoip']['lib_version'] = '1.6.3' +default['nginx']['geoip']['city_dat_checksum'] = nil +default['nginx']['geoip']['lib_version'] = '1.6.9' lib_version = node['nginx']['geoip']['lib_version'] # convenience variable for line length default['nginx']['geoip']['lib_url'] = "https://github.com/maxmind/geoip-api-c/releases/download/v#{lib_version}/GeoIP-#{lib_version}.tar.gz" -default['nginx']['geoip']['lib_checksum'] = 'e483839a81a91c3c85df89ef409fc7b526c489e0355d537861cfd1ea9534a8f2' +default['nginx']['geoip']['lib_checksum'] = '4b446491843de67c1af9b887da17a3e5939e0aeed4826923a5f4bf09d845096f' diff --git a/cookbooks/nginx/attributes/headers_more.rb b/cookbooks/chef_nginx/attributes/headers_more.rb similarity index 76% rename from cookbooks/nginx/attributes/headers_more.rb rename to cookbooks/chef_nginx/attributes/headers_more.rb index 18ec681..66f2525 100644 --- a/cookbooks/nginx/attributes/headers_more.rb +++ b/cookbooks/chef_nginx/attributes/headers_more.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: chef_nginx # Attributes:: headers_more # # Author:: Lucas Jandrew () # -# Copyright 2012-2013, Riot Games +# Copyright:: 2012-2017, Riot Games # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,6 +19,6 @@ # limitations under the License. # -default['nginx']['headers_more']['version'] = '0.25' +default['nginx']['headers_more']['version'] = '0.30' default['nginx']['headers_more']['source_url'] = "https://github.com/openresty/headers-more-nginx-module/archive/v#{node['nginx']['headers_more']['version']}.tar.gz" -default['nginx']['headers_more']['source_checksum'] = '1473f96f59dcec9d83ce65d691559993c1f80da8c0a4c0c0a30dae9f969eeabf' +default['nginx']['headers_more']['source_checksum'] = '2aad309a9313c21c7c06ee4e71a39c99d4d829e31c8b3e7d76f8c964ea8047f5' diff --git a/cookbooks/nginx/attributes/lua.rb b/cookbooks/chef_nginx/attributes/lua.rb similarity index 70% rename from cookbooks/nginx/attributes/lua.rb rename to cookbooks/chef_nginx/attributes/lua.rb index effdef9..27327dc 100644 --- a/cookbooks/nginx/attributes/lua.rb +++ b/cookbooks/chef_nginx/attributes/lua.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: chef_nginx # Attributes:: lua # # Author:: Arthur Freyman () # -# Copyright 2013, Riot Games +# Copyright:: 2013-2017, Riot Games # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,10 +19,10 @@ # limitations under the License. # -default['nginx']['lua']['version'] = '0.8.7' +default['nginx']['lua']['version'] = '0.10.7' default['nginx']['lua']['url'] = "https://github.com/chaoslawful/lua-nginx-module/archive/v#{node['nginx']['lua']['version']}.tar.gz" -default['nginx']['lua']['checksum'] = '4b9be3c159b9c884a38e044e07aaf4d06bd2893977d0b0dae02c124d8e907f93' +default['nginx']['lua']['checksum'] = 'c21c8937dcdd6fc2b6a955f929e3f4d1388610f47180e60126e6dcab06786f77' -default['nginx']['luajit']['version'] = '2.0.2' +default['nginx']['luajit']['version'] = '2.0.4' default['nginx']['luajit']['url'] = "http://luajit.org/download/LuaJIT-#{node['nginx']['luajit']['version']}.tar.gz" -default['nginx']['luajit']['checksum'] = 'c05202974a5890e777b181908ac237625b499aece026654d7cc33607e3f46c38' +default['nginx']['luajit']['checksum'] = '620fa4eb12375021bef6e4f237cbd2dd5d49e56beb414bee052c746beef1807d' diff --git a/cookbooks/nginx/attributes/naxsi.rb b/cookbooks/chef_nginx/attributes/naxsi.rb similarity index 77% rename from cookbooks/nginx/attributes/naxsi.rb rename to cookbooks/chef_nginx/attributes/naxsi.rb index 3c03e38..8d0d682 100644 --- a/cookbooks/nginx/attributes/naxsi.rb +++ b/cookbooks/chef_nginx/attributes/naxsi.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: chef_nginx # Attributes:: naxsi # # Author:: Artiom Lunev () # -# Copyright 2012-2013, Artiom Lunev +# Copyright:: 2012-2017, Artiom Lunev # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,6 +19,6 @@ # limitations under the License. # -default['nginx']['naxsi']['version'] = '0.53-2' +default['nginx']['naxsi']['version'] = '0.54' default['nginx']['naxsi']['url'] = "https://github.com/nbs-system/naxsi/archive/#{node['nginx']['naxsi']['version']}.tar.gz" -default['nginx']['naxsi']['checksum'] = '3eadff1d91995beae41b92733ade28091c2075a24ae37058f4d6aa90b0f4b660' +default['nginx']['naxsi']['checksum'] = '9cc2c09405bc71f78ef26a8b6d70afcea3fccbe8125df70cb0cfc480133daba5' diff --git a/cookbooks/nginx/attributes/openssl_source.rb b/cookbooks/chef_nginx/attributes/openssl_source.rb similarity index 86% rename from cookbooks/nginx/attributes/openssl_source.rb rename to cookbooks/chef_nginx/attributes/openssl_source.rb index abe29a4..2368ce3 100644 --- a/cookbooks/nginx/attributes/openssl_source.rb +++ b/cookbooks/chef_nginx/attributes/openssl_source.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: chef_nginx # Attributes:: openssl_source # # Author:: David Radcliffe () # -# Copyright 2013, David Radcliffe +# Copyright:: 2013-2017, David Radcliffe # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,5 +19,5 @@ # limitations under the License. # -default['nginx']['openssl_source']['version'] = '1.0.1h' +default['nginx']['openssl_source']['version'] = '1.0.2k' default['nginx']['openssl_source']['url'] = "http://www.openssl.org/source/openssl-#{node['nginx']['openssl_source']['version']}.tar.gz" diff --git a/cookbooks/nginx/attributes/pagespeed.rb b/cookbooks/chef_nginx/attributes/pagespeed.rb similarity index 53% rename from cookbooks/nginx/attributes/pagespeed.rb rename to cookbooks/chef_nginx/attributes/pagespeed.rb index 48ca814..b32c693 100644 --- a/cookbooks/nginx/attributes/pagespeed.rb +++ b/cookbooks/chef_nginx/attributes/pagespeed.rb @@ -1,9 +1,9 @@ # -# Cookbook Name:: nginx +# Cookbook:: chef_nginx # Recipe:: pagespeed_module # -default['nginx']['pagespeed']['version'] = '1.8.31.4' +default['nginx']['pagespeed']['version'] = '1.11.33.2' default['nginx']['pagespeed']['url'] = "https://github.com/pagespeed/ngx_pagespeed/archive/release-#{node['nginx']['pagespeed']['version']}-beta.tar.gz" default['nginx']['psol']['url'] = "https://dl.google.com/dl/page-speed/psol/#{node['nginx']['pagespeed']['version']}.tar.gz" -default['nginx']['pagespeed']['packages']['rhel'] = %w(gcc-c++ pcre-dev pcre-devel zlib-devel make) -default['nginx']['pagespeed']['packages']['debian'] = %w(build-essential zlib1g-dev libpcre3 libpcre3-dev) +default['nginx']['pagespeed']['packages']['rhel'] = %w(pcre-devel zlib-devel) +default['nginx']['pagespeed']['packages']['debian'] = %w(zlib1g-dev libpcre3 libpcre3-dev) diff --git a/cookbooks/nginx/attributes/passenger.rb b/cookbooks/chef_nginx/attributes/passenger.rb similarity index 77% rename from cookbooks/nginx/attributes/passenger.rb rename to cookbooks/chef_nginx/attributes/passenger.rb index 5478284..8c503e4 100644 --- a/cookbooks/nginx/attributes/passenger.rb +++ b/cookbooks/chef_nginx/attributes/passenger.rb @@ -1,11 +1,11 @@ # -# Cookbook Name:: nginx +# Cookbook:: chef_nginx # Attribute:: passenger # # Author:: Alex Dergachev () # -# Copyright 2013, Chef Software, Inc. -# Copyright 2012, Susan Potter +# Copyright:: 2013-2017, Chef Software, Inc. +# Copyright:: 2012-2017, Susan Potter # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -36,11 +36,11 @@ else node.default['nginx']['passenger']['ruby'] = '/usr/bin/ruby' end -if platform_family?('rhel') && node['platform_version'].to_i >= 6 - node.default['nginx']['passenger']['packages']['rhel'] = %w(ruby-devel libcurl-devel) -else - node.default['nginx']['passenger']['packages']['rhel'] = %w(ruby-devel curl-devel) -end +node.default['nginx']['passenger']['packages']['rhel'] = if platform_family?('rhel') && node['platform_version'].to_i >= 6 + %w(ruby-devel libcurl-devel) + else + %w(ruby-devel curl-devel) + end node.default['nginx']['passenger']['packages']['fedora'] = %w(ruby-devel libcurl-devel) node.default['nginx']['passenger']['packages']['debian'] = %w(ruby-dev libcurl4-gnutls-dev) @@ -53,6 +53,9 @@ node.default['nginx']['passenger']['max_instances_per_app'] = 0 node.default['nginx']['passenger']['pool_idle_time'] = 300 node.default['nginx']['passenger']['max_requests'] = 0 node.default['nginx']['passenger']['gem_binary'] = nil +node.default['nginx']['passenger']['show_version_in_header'] = 'on' +# By default, the Passenger log file is the global Nginx error log file. Set this attribute to write passenger log to another location. +node.default['nginx']['passenger']['passenger_log_file'] = nil # NodeJs disable by default node.default['nginx']['passenger']['nodejs'] = nil diff --git a/cookbooks/nginx/attributes/rate_limiting.rb b/cookbooks/chef_nginx/attributes/rate_limiting.rb similarity index 92% rename from cookbooks/nginx/attributes/rate_limiting.rb rename to cookbooks/chef_nginx/attributes/rate_limiting.rb index afa0240..a4db398 100644 --- a/cookbooks/nginx/attributes/rate_limiting.rb +++ b/cookbooks/chef_nginx/attributes/rate_limiting.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: nginx +# Cookbook:: chef_nginx # Attribute:: rate_limiting # -# Copyright 2013, 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/nginx/attributes/repo.rb b/cookbooks/chef_nginx/attributes/repo.rb similarity index 59% rename from cookbooks/nginx/attributes/repo.rb rename to cookbooks/chef_nginx/attributes/repo.rb index 2a69ffd..b170bd8 100644 --- a/cookbooks/nginx/attributes/repo.rb +++ b/cookbooks/chef_nginx/attributes/repo.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: chef_nginx # Recipe:: repo # # Author:: Nick Rycar # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-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. @@ -21,15 +21,15 @@ case node['platform_family'] when 'rhel', 'fedora' - case node['platform'] - when 'centos' - # See http://wiki.nginx.org/Install - default['nginx']['upstream_repository'] = "http://nginx.org/packages/centos/#{node['platform_version'].to_i}/$basearch/" - when 'amazon' - default['nginx']['upstream_repository'] = 'http://nginx.org/packages/rhel/6/$basearch/' - else - default['nginx']['upstream_repository'] = "http://nginx.org/packages/rhel/#{node['platform_version'].to_i}/$basearch/" - end + default['nginx']['upstream_repository'] = case node['platform'] + when 'centos' + # See http://wiki.nginx.org/Install + "http://nginx.org/packages/centos/#{node['platform_version'].to_i}/$basearch/" + when 'amazon' + 'http://nginx.org/packages/rhel/6/$basearch/' + else + "http://nginx.org/packages/rhel/#{node['platform_version'].to_i}/$basearch/" + end when 'debian' default['nginx']['upstream_repository'] = "http://nginx.org/packages/#{node['platform']}" end diff --git a/cookbooks/chef_nginx/attributes/set_misc.rb b/cookbooks/chef_nginx/attributes/set_misc.rb new file mode 100644 index 0000000..6d8a126 --- /dev/null +++ b/cookbooks/chef_nginx/attributes/set_misc.rb @@ -0,0 +1,8 @@ +# +# Cookbook:: chef_nginx +# Attributes:: set_misc +# + +default['nginx']['set_misc']['version'] = '0.30' +default['nginx']['set_misc']['url'] = "https://github.com/agentzh/set-misc-nginx-module/archive/v#{node['nginx']['set_misc']['version']}.tar.gz" +default['nginx']['set_misc']['checksum'] = '59920dd3f92c2be32627121605751b52eae32b5884be09f2e4c53fb2fae8aabc' diff --git a/cookbooks/nginx/attributes/socketproxy.rb b/cookbooks/chef_nginx/attributes/socketproxy.rb similarity index 89% rename from cookbooks/nginx/attributes/socketproxy.rb rename to cookbooks/chef_nginx/attributes/socketproxy.rb index 17dca60..e680118 100644 --- a/cookbooks/nginx/attributes/socketproxy.rb +++ b/cookbooks/chef_nginx/attributes/socketproxy.rb @@ -1,3 +1,8 @@ +# +# Cookbook:: chef_nginx +# Attributes:: socketproxy.rb +# + default['nginx']['socketproxy']['root'] = '/usr/share/nginx/apps' default['nginx']['socketproxy']['app_owner'] = 'root' default['nginx']['socketproxy']['logname'] = 'socketproxy' diff --git a/cookbooks/nginx/attributes/source.rb b/cookbooks/chef_nginx/attributes/source.rb similarity index 69% rename from cookbooks/nginx/attributes/source.rb rename to cookbooks/chef_nginx/attributes/source.rb index 580eccf..24dce3c 100644 --- a/cookbooks/nginx/attributes/source.rb +++ b/cookbooks/chef_nginx/attributes/source.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: chef_nginx # Attributes:: source # # Author:: Jamie Winsor () # -# Copyright 2012-2013, Riot Games +# Copyright:: 2012-2017, Riot Games # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,7 +19,14 @@ # limitations under the License. # -include_attribute 'nginx::default' +include_attribute 'chef_nginx::default' + +default['nginx']['init_style'] = if node['platform'] == 'ubuntu' && node['platform_version'].to_f <= 14.04 + # init_package identifies 12.04/14.04 as init, but we should be using upstart here + 'upstart' + else + node['init_package'] + end default['nginx']['source']['version'] = node['nginx']['version'] default['nginx']['source']['prefix'] = "/opt/nginx-#{node['nginx']['source']['version']}" @@ -34,9 +41,9 @@ default['nginx']['source']['default_configure_flags'] = %W( default['nginx']['configure_flags'] = [] default['nginx']['source']['version'] = node['nginx']['version'] default['nginx']['source']['url'] = "http://nginx.org/download/nginx-#{node['nginx']['source']['version']}.tar.gz" -default['nginx']['source']['checksum'] = 'b5608c2959d3e7ad09b20fc8f9e5bd4bc87b3bc8ba5936a513c04ed8f1391a18' +default['nginx']['source']['checksum'] = '75020f1364cac459cb733c4e1caed2d00376e40ea05588fb8793076a4c69dd90' default['nginx']['source']['modules'] = %w( - nginx::http_ssl_module - nginx::http_gzip_static_module + chef_nginx::http_ssl_module + chef_nginx::http_gzip_static_module ) default['nginx']['source']['use_existing_user'] = false diff --git a/cookbooks/nginx/attributes/status.rb b/cookbooks/chef_nginx/attributes/status.rb similarity index 91% rename from cookbooks/nginx/attributes/status.rb rename to cookbooks/chef_nginx/attributes/status.rb index b4ad16b..00bbef2 100644 --- a/cookbooks/nginx/attributes/status.rb +++ b/cookbooks/chef_nginx/attributes/status.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: chef_nginx # Attributes:: status # # Author:: David Radcliffe () # -# Copyright 2013, David Radcliffe +# Copyright:: 2013-2017, David Radcliffe # # 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/nginx/attributes/syslog.rb b/cookbooks/chef_nginx/attributes/syslog.rb similarity index 92% rename from cookbooks/nginx/attributes/syslog.rb rename to cookbooks/chef_nginx/attributes/syslog.rb index e95ce51..707e050 100644 --- a/cookbooks/nginx/attributes/syslog.rb +++ b/cookbooks/chef_nginx/attributes/syslog.rb @@ -1,11 +1,10 @@ - # -# Cookbook Name:: nginx +# Cookbook:: chef_nginx # Attributes:: syslog # # Author:: Bob Ziuchkovski () # -# Copyright 2014, UserTesting +# Copyright:: 2014-2017, UserTesting # # 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/nginx/attributes/upload_progress.rb b/cookbooks/chef_nginx/attributes/upload_progress.rb similarity index 94% rename from cookbooks/nginx/attributes/upload_progress.rb rename to cookbooks/chef_nginx/attributes/upload_progress.rb index a4e316f..af38586 100644 --- a/cookbooks/nginx/attributes/upload_progress.rb +++ b/cookbooks/chef_nginx/attributes/upload_progress.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: chef_nginx # Attributes:: upload_progress # # Author:: Jamie Winsor () # -# Copyright 2012, Riot Games +# Copyright:: 2012-2017, Riot Games # # 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/chef_nginx/files/default/mime.types b/cookbooks/chef_nginx/files/default/mime.types new file mode 100644 index 0000000..6b03a32 --- /dev/null +++ b/cookbooks/chef_nginx/files/default/mime.types @@ -0,0 +1,134 @@ +types { + + # Data interchange + + application/atom+xml atom; + application/json json map topojson; + application/ld+json jsonld; + application/rss+xml rss; + application/vnd.geo+json geojson; + application/xml rdf xml; + + + # JavaScript + + # Normalize to standard type. + # https://tools.ietf.org/html/rfc4329#section-7.2 + application/javascript js; + + + # Manifest files + + application/manifest+json webmanifest; + application/x-web-app-manifest+json webapp; + text/cache-manifest appcache; + text/cache.manifest manifest; + + + # Media files + + audio/midi mid midi kar; + audio/mp4 aac f4a f4b m4a; + audio/mpeg mp3; + audio/ogg oga ogg opus; + audio/x-realaudio ra; + audio/x-wav wav; + image/bmp bmp; + image/gif gif; + image/jpeg jpeg jpg; + image/png png; + image/svg+xml svg svgz; + image/tiff tif tiff; + image/vnd.wap.wbmp wbmp; + image/webp webp; + image/x-jng jng; + video/3gpp 3gp 3gpp; + video/mp4 f4p f4v m4v mp4; + video/mpeg mpeg mpg; + video/ogg ogv; + video/quicktime mov; + video/webm webm; + video/x-flv flv; + video/x-mng mng; + video/x-ms-asf asf asx; + video/x-ms-wmv wmv; + video/x-msvideo avi; + + # Serving `.ico` image files with a different media type + # prevents Internet Explorer from displaying then as images: + # https://github.com/h5bp/html5-boilerplate/commit/37b5fec090d00f38de64b591bcddcb205aadf8ee + + image/x-icon cur ico; + + + # Microsoft Office + + application/msword doc; + application/vnd.ms-excel xls; + application/vnd.ms-powerpoint ppt; + application/vnd.openxmlformats-officedocument.wordprocessingml.document docx; + application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx; + application/vnd.openxmlformats-officedocument.presentationml.presentation pptx; + + + # Web fonts + + application/font-woff woff; + application/font-woff2 woff2; + application/vnd.ms-fontobject eot; + + # Browsers usually ignore the font media types and simply sniff + # the bytes to figure out the font type. + # https://mimesniff.spec.whatwg.org/#matching-a-font-type-pattern + # + # However, Blink and WebKit based browsers will show a warning + # in the console if the following font types are served with any + # other media types. + + application/x-font-ttf ttc ttf; + font/opentype otf; + + # Other + + application/java-archive ear jar war; + application/mac-binhex40 hqx; + application/octet-stream bin deb dll dmg exe img iso msi msm msp safariextz; + application/pdf pdf; + application/postscript ai eps ps; + application/rtf rtf; + application/vnd.google-earth.kml+xml kml; + application/vnd.google-earth.kmz kmz; + application/vnd.wap.wmlc wmlc; + application/x-7z-compressed 7z; + application/x-bb-appworld bbaw; + application/x-bittorrent torrent; + application/x-chrome-extension crx; + application/x-cocoa cco; + application/x-java-archive-diff jardiff; + application/x-java-jnlp-file jnlp; + application/x-makeself run; + application/x-opera-extension oex; + application/x-perl pl pm; + application/x-pilot pdb prc; + application/x-rar-compressed rar; + application/x-redhat-package-manager rpm; + application/x-sea sea; + application/x-shockwave-flash swf; + application/x-stuffit sit; + application/x-tcl tcl tk; + application/x-x509-ca-cert crt der pem; + application/x-xpinstall xpi; + application/xhtml+xml xhtml; + application/xslt+xml xsl; + application/zip zip; + text/css css; + text/html htm html shtml; + text/mathml mml; + text/plain txt; + text/vcard vcard vcf; + text/vnd.rim.location.xloc xloc; + text/vnd.sun.j2me.app-descriptor jad; + text/vnd.wap.wml wml; + text/vtt vtt; + text/x-component htc; +} diff --git a/cookbooks/nginx/files/default/naxsi_core.rules b/cookbooks/chef_nginx/files/default/naxsi_core.rules similarity index 100% rename from cookbooks/nginx/files/default/naxsi_core.rules rename to cookbooks/chef_nginx/files/default/naxsi_core.rules diff --git a/cookbooks/chef_nginx/libraries/helpers.rb b/cookbooks/chef_nginx/libraries/helpers.rb new file mode 100644 index 0000000..a81413b --- /dev/null +++ b/cookbooks/chef_nginx/libraries/helpers.rb @@ -0,0 +1,38 @@ +# +# Cookbook:: chef_nginx +# Library:: helpers +# +# Author:: Tim Smith () +# +# Copyright:: 2016-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. +# 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. +# + +# simple helper module for the nginx cookbook +module NginxRecipeHelpers + # pidfile is hard to determine on Debian systems. + # Upstream packages and older distro releases use '/var/run/nginx.pid' + # systemd based distros and Ubuntu 14.04 use '/run/nginx.pid' for their + # packages + def pidfile_location + if (node['nginx']['repo_source'].nil? || node['nginx']['repo_source'] == 'distro') && + (node['init_package'] == 'systemd' || node['platform_version'].to_f == 14.04) + '/run/nginx.pid' + else + '/var/run/nginx.pid' + end + end +end + +Chef::Resource.send(:include, NginxRecipeHelpers) diff --git a/cookbooks/build-essential/recipes/_rhel.rb b/cookbooks/chef_nginx/libraries/matchers.rb similarity index 53% rename from cookbooks/build-essential/recipes/_rhel.rb rename to cookbooks/chef_nginx/libraries/matchers.rb index 9719a33..1a6acc4 100644 --- a/cookbooks/build-essential/recipes/_rhel.rb +++ b/cookbooks/chef_nginx/libraries/matchers.rb @@ -1,8 +1,10 @@ # -# Cookbook Name:: build-essential -# Recipe:: rhel +# Cookbook:: chef_nginx +# Library:: matchers # -# Copyright 2008-2016, Chef Software, Inc. +# Author:: Tim Smith () +# +# Copyright:: 2016-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. @@ -17,21 +19,17 @@ # limitations under the License. # -potentially_at_compile_time do - package 'autoconf' - package 'bison' - package 'flex' - package 'gcc' - package 'gcc-c++' - package 'kernel-devel' - package 'make' - package 'm4' - package 'patch' - package 'gettext-devel' +if defined?(ChefSpec) + ############# + # nginx_site + ############# + ChefSpec.define_matcher :nginx_site - # Ensure GCC 4 is available on older pre-6 EL - if node['platform_version'].to_i < 6 - package 'gcc44' - package 'gcc44-c++' + def enable_nginx_site(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:nginx_site, :enable, resource_name) + end + + def disable_nginx_site(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:nginx_site, :disable, resource_name) end end diff --git a/cookbooks/chef_nginx/metadata.json b/cookbooks/chef_nginx/metadata.json new file mode 100644 index 0000000..2adb415 --- /dev/null +++ b/cookbooks/chef_nginx/metadata.json @@ -0,0 +1 @@ +{"name":"chef_nginx","version":"6.0.2","description":"Installs and configures nginx","long_description":"# nginx Cookbook\n\n[![Cookbook](http://img.shields.io/cookbook/v/chef_nginx.svg)](https://supermarket.chef.io/cookbooks/chef_nginx) [![Build Status](https://travis-ci.org/chef-cookbooks/chef_nginx.svg?branch=master)](https://travis-ci.org/chef-cookbooks/chef_nginx)\n\nInstalls nginx from package OR source code and sets up configuration handling similar to Debian's Apache2 scripts.\n\n## nginx vs. chef_nginx\n\nThis cookbook is a fork from the 2.7.x branch of the [community nginx cookbook](https://github.com/miketheman/nginx).\n\nThis fork will be actively supported by Chef Software and we will continue to migrate the cookbook to a more resource driven model, with incremental changes following the SemVer model.\n\n## Requirements\n\n### Cookbooks\n\nThe following cookbooks are direct dependencies because they're used for common \"default\" functionality.\n\n- `build-essential` for source installations\n- `ohai` for setting up the ohai plugin\n- `compat_resource` for setting up the nginx.org repository on Chef 12.1 - 12.13\n- `yum-epel` for setting up the EPEL repository on RHEL platforms\n- `zypper` for setting up the nginx.org repository on Suse platforms\n\n### Platforms\n\nThe following platforms are supported and tested with Test Kitchen:\n\n- Ubuntu 12.04+\n- CentOS 5+\n- Debian 7+\n- openSUSE 13.2+\n- FreeBSD 9+\n\nOther Debian and RHEL family distributions are assumed to work.\n\n### Chef\n\n- Chef 12.1+\n\n## Attributes\n\nNode attributes for this cookbook are logically separated into different files. Some attributes are set only via a specific recipe.\n\n### chef_nginx::auth_request\n\nThese attributes are used in the `chef_nginx::auth_request` recipe.\n\n- `node['nginx']['auth_request']['url']` - The url to the auth_request module tar.gz file\n- `node['nginx']['auth_request']['checksum']` - The checksum of the auth_request module tar.gz file\n\n### chef_nginx::default\n\nGenerally used attributes. Some have platform specific values. See `attributes/default.rb`. \"The Config\" refers to \"nginx.conf\" the main config file.\n\n- `node['nginx']['dir']` - Location for nginx configuration.\n- `node['nginx']['conf_template']` - The `source` template to use when creating the `nginx.conf`.\n- `node['nginx']['conf_cookbook']` - The cookbook where `node['nginx']['conf_template']` resides.\n- `node['nginx']['log_dir']` - Location for nginx logs.\n- `node['nginx']['log_dir_perm']` - Permissions for nginx logs folder.\n- `node['nginx']['user']` - User that nginx will run as.\n- `node['nginx']['group']` - Group for nginx.\n- `node['nginx']['port']` - Port for nginx to listen on.\n- `node['nginx']['binary']` - Path to the nginx binary.\n- `node['nginx']['init_style']` - How to run nginx as a service when using `chef_nginx::source`. Values can be \"upstart\", \"systemd\", or \"init\". This attribute is not used in the `package` recipe because the package manager's init script style for the platform is assumed.\n- `node['nginx']['upstart']['foreground']` - Set this to true if you want upstart to run nginx in the foreground, set to false if you want upstart to detach and track the process via pid.\n- `node['nginx']['upstart']['runlevels']` - String of runlevels in the format '2345' which determines which runlevels nginx will start at when entering and stop at when leaving.\n- `node['nginx']['upstart']['respawn_limit']` - Respawn limit in upstart stanza format, count followed by space followed by interval in seconds.\n- `node['nginx']['keepalive']` - Whether to use `keepalive_timeout`, any value besides \"on\" will leave that option out of the config.\n- `node['nginx']['keepalive_requests']` - used for config value of `keepalive_requests`.\n- `node['nginx']['keepalive_timeout']` - used for config value of `keepalive_timeout`.\n- `node['nginx']['worker_processes']` - used for config value of `worker_processes`.\n- `node['nginx']['worker_connections']` - used for config value of `events { worker_connections }`\n- `node['nginx']['worker_rlimit_nofile']` - used for config value of `worker_rlimit_nofile`. Can replace any \"ulimit -n\" command. The value depend on your usage (cache or not) but must always be superior than worker_connections.\n- `node['nginx']['worker_shutdown_timeout']` - used for config value of `worker_shutdown_timeout`.\n- `node['nginx']['worker_connections']` - used for config value of `events { worker_connections }`\n- `node['nginx']['multi_accept']` - used for config value of `events { multi_accept }`. Try to accept() as many connections as possible. Disable by default.\n- `node['nginx']['event']` - used for config value of `events { use }`. Set the event-model. By default nginx looks for the most suitable method for your OS.\n- `node['nginx']['accept_mutex_delay']` - used for config value of `accept_mutex_delay`\n- `node['nginx']['server_tokens']` - used for config value of `server_tokens`.\n- `node['nginx']['server_names_hash_bucket_size']` - used for config value of `server_names_hash_bucket_size`.\n- `node['nginx']['disable_access_log']` - set to true to disable the general access log, may be useful on high traffic sites.\n- `node['nginx']['access_log_options']` - Set to a string of additional options to be appended to the access log directive\n- `node['nginx']['error_log_options']` - Set to a string of additional options to be appended to the error log directive\n- `node['nginx']['default_site_enabled']` - enable the default site\n- `node['nginx']['sendfile']` - Whether to use `sendfile`. Defaults to \"on\".\n- `node['nginx']['tcp_nopush']` - Whether to use `tcp_nopush`. Defaults to \"on\".\n- `node['nginx']['tcp_nodelay']` - Whether to use `tcp_nodelay`. Defaults to \"on\".\n- `node['nginx']['install_method']` - Whether nginx is installed from packages or from source.\n- `node['nginx']['types_hash_max_size']` - Used for the `types_hash_max_size` configuration directive.\n- `node['nginx']['types_hash_bucket_size']` - Used for the `types_hash_bucket_size` configuration directive.\n- `node['nginx']['proxy_read_timeout']` - defines a timeout (between two successive read operations) for reading a response from the proxied server.\n- `node['nginx']['client_body_buffer_size']` - used for config value of `client_body_buffer_size`.\n- `node['nginx']['client_max_body_size']` - specifies the maximum accepted body size of a client request, as indicated by the request header Content-Length.\n- `node['nginx']['repo_source']` - when installed from a package this attribute affects which yum repositories, if any, will be added before installing the nginx package. The default value of 'epel' will use the `yum-epel` cookbook, 'nginx' will use the `chef_nginx::repo` recipe, 'passenger' will use the 'chef_nginx::repo_passenger' recipe, and setting no value will not add any additional repositories.\n- `node['nginx']['sts_max_age']` - Enable Strict Transport Security for all apps (See: ). This attribute adds the following header: Strict-Transport-Security max-age=SECONDS to all incoming requests and takes an integer (in seconds) as its argument.\n- `node['nginx']['default']['modules']` - Array specifying which modules to enable via the conf-enabled config include function. Currently the only valid value is \"socketproxy\".\n- `node['nginx']['load_modules']` - Array of paths to modules to dynamically load on nginx startup using the `load_module` directive. Default is `[]`.\n\n#### authorized_ips module\n\n- `node['nginx']['remote_ip_var']` - The remote ip variable name to use.\n- `node['nginx']['authorized_ips']` - IPs authorized by the module\n\n#### gzip module\n\n- `node['nginx']['gzip']` - Whether to use gzip, can be \"on\" or \"off\"\n- `node['nginx']['gzip_http_version']` - used for config value of `gzip_http_version`.\n- `node['nginx']['gzip_comp_level']` - used for config value of `gzip_comp_level`.\n- `node['nginx']['gzip_proxied']` - used for config value of `gzip_proxied`.\n- `node['nginx']['gzip_vary']` - used for config value of `gzip_vary`.\n- `node['nginx']['gzip_buffers']` - used for config value of `gzip_buffers`.\n- `node['nginx']['gzip_types']` - used for config value of `gzip_types` - must be an Array.\n- `node['nginx']['gzip_min_length']` - used for config value of `gzip_min_length`.\n- `node['nginx']['gzip_disable']` - used for config value of `gzip_disable`.\n- `node['nginx']['gzip_static']` - used for config value of `gzip_static` (`http_gzip_static_module` must be enabled)\n\n#### Other configurations\n\n- `node['nginx']['extra_configs']` - a Hash of key/values to nginx configuration.\n\n### chef_nginx::echo\n\nThese attributes are used in the `chef_nginx::http_echo_module` recipe.\n\n- `node['nginx']['echo']['version']` - The version of `http_echo` you want (default: 0.59)\n- `node['nginx']['echo']['url']` - URL for the tarball.\n- `node['nginx']['echo']['checksum']` - Checksum of the tarball.\n\n### chef_nginx::devel\n\nThese attributes are used in the `chef_nginx::ngx_devel_module` recipe.\n\n- `node['nginx']['devel']['version']` - The version of the nginx devel module\n- `node['nginx']['devel']['url']` - The URL of the nginx devel module tar.gz file\n- `node['nginx']['devel']['checksum']` - The checksum of the nginx devel module tar.gz file\n\n### chef_nginx::geoip\n\nThese attributes are used in the `chef_nginx::http_geoip_module` recipe. Please note that the `country_dat_checksum` and `city_dat_checksum` are based on downloads from a datacenter in Fremont, CA, USA. You really should override these with checksums for the geo tarballs from your node location.\n\n**Note** The upstream, maxmind.com, may block access for repeated downloads of the data files. It is recommended that you download and host the data files, and change the URLs in the attributes.\n\n- `node['nginx']['geoip']['path']` - Location where to install the geoip libraries.\n- `node['nginx']['geoip']['enable_city']` - Whether to enable City data\n- `node['nginx']['geoip']['country_dat_url']` - Country data tarball URL\n- `node['nginx']['geoip']['country_dat_checksum']` - Country data tarball checksum\n- `node['nginx']['geoip']['city_dat_url']` - City data tarball URL\n- `node['nginx']['geoip']['city_dat_checksum']` - City data tarball checksum\n- `node['nginx']['geoip']['lib_version']` - Version of the GeoIP library to install\n- `node['nginx']['geoip']['lib_url']` - (Versioned) Tarball URL of the GeoIP library\n- `node['nginx']['geoip']['lib_checksum']` - Checksum of the GeoIP library tarball\n\n### chef_nginx::http_realip_module\n\nFrom: \n\n- `node['nginx']['realip']['header']` - Header to use for the RealIp Module; only accepts \"X-Forwarded-For\" or \"X-Real-IP\"\n- `node['nginx']['realip']['addresses']` - Addresses to use for the `http_realip` configuration.\n- `node['nginx']['realip']['real_ip_recursive']` - If recursive search is enabled, the original client address that matches one of the trusted addresses is replaced by the last non-trusted address sent in the request header field. Can be on \"on\" or \"off\" (default).\n\n### chef_nginx::passenger\n\nThese attributes are used in the `chef_nginx::passenger` recipe.\n\n- `node['nginx']['passenger']['version']` - passenger gem version\n- `node['nginx']['passenger']['root']` - passenger gem root path\n- `node['nginx']['passenger']['install_rake']` - set to false if rake already present on system\n- `node['nginx']['passenger']['max_pool_size']` - maximum passenger pool size (default=10)\n- `node['nginx']['passenger']['ruby']` - Ruby path for Passenger to use (default=`$(which ruby)`)\n- `node['nginx']['passenger']['spawn_method']` - passenger spawn method to use (default=`smart-lv2`)\n- `node['nginx']['passenger']['buffer_response']` - turns on or off response buffering (default=`on`)\n- `node['nginx']['passenger']['max_pool_size']` - passenger maximum pool size (default=`6`)\n- `node['nginx']['passenger']['min_instances']` - minimum instances (default=`1`)\n- `node['nginx']['passenger']['max_instances_per_app']` - maximum instances per app (default=`0`)\n- `node['nginx']['passenger']['pool_idle_time']` - passenger pool idle time (default=`300`)\n- `node['nginx']['passenger']['max_requests']` - maximum requests (default=`0`)\n- `node['nginx']['passenger']['nodejs']` - Nodejs path for Passenger to use (default=nil)\n- `node['nginx']['passenger']['show_version_in_header']` - Show passenger version in HTTP headers (default=`on`)\n\nBasic configuration to use the official Phusion Passenger repositories:\n\n- `node['nginx']['repo_source']` - 'passenger'\n- `node['nginx']['package_name']` - 'nginx-extras'\n- `node['nginx']['passenger']['install_method']` - 'package'\n\n### chef_nginx::openssl_source\n\nThese attributes are used in the `chef_nginx::openssl_source` recipe.\n\n- `node['nginx']['openssl_source']['version']` - The version of OpenSSL you want to download and use (default: 1.0.1t)\n- `node['nginx']['openssl_source']['url']` - The url for the OpenSSL source\n\n### chef_nginx::rate_limiting\n\n- `node['nginx']['enable_rate_limiting']` - set to true to enable rate limiting (`limit_req_zone` in nginx.conf)\n- `node['nginx']['rate_limiting_zone_name']` - sets the zone in `limit_req_zone`.\n- `node['nginx']['rate_limiting_backoff']` - sets the backoff time for `limit_req_zone`.\n- `node['nginx']['rate_limit']` - set the rate limit amount for `limit_req_zone`.\n\n### chef_nginx::socketproxy\n\nThese attributes are used in the `chef_nginx::socketproxy` recipe.\n\n- `node['nginx']['socketproxy']['root']` - The directory (on your server) where socketproxy apps are deployed.\n- `node['nginx']['socketproxy']['default_app']` - Static assets directory for requests to \"/\" that don't meet any proxy_pass filter requirements.\n- `node['nginx']['socketproxy']['apps']['app_name']['prepend_slash']` - Prepend a slash to requests to app \"app_name\" before sending them to the socketproxy socket.\n- `node['nginx']['socketproxy']['apps']['app_name']['context_name']` - URI (e.g. \"app_name\" in order to achieve \"\") at which to host the application \"app_name\"\n- `node['nginx']['socketproxy']['apps']['app_name']['subdir']` - Directory (under `node['nginx']['socketproxy']['root']`) in which to find the application.\n\n### chef_nginx::source\n\nThese attributes are used in the `chef_nginx::source` recipe. Some of them are dynamically modified during the run. See `attributes/source.rb` for default values.\n\n- `node['nginx']['source']['url']` - (versioned) URL for the nginx source code. By default this will use the version specified as `node['nginx']['version']`.\n- `node['nginx']['source']['prefix']` - (versioned) prefix for installing nginx from source\n- `node['nginx']['source']['conf_path']` - location of the main config file, in `node['nginx']['dir']` by default.\n- `node['nginx']['source']['modules']` - Array of modules that should be compiled into nginx by including their recipes in `chef_nginx::source`.\n- `node['nginx']['source']['default_configure_flags']` - The default flags passed to the configure script when building nginx.\n- `node['nginx']['configure_flags']` - Preserved for compatibility and dynamically generated from the `node['nginx']['source']['default_configure_flags']` in the `chef_nginx::source` recipe.\n- `node['nginx']['source']['use_existing_user']` - set to `true` if you do not want `chef_nginx::source` recipe to create system user with name `node['nginx']['user']`.\n\n### chef_nginx::status\n\nThese attributes are used in the `chef_nginx::http_stub_status_module` recipe.\n\n- `node['nginx']['status']['port']` - The port on which nginx will serve the status info (default: 8090)\n\n### chef_nginx::syslog\n\nThese attributes are used in the `chef_nginx::syslog_module` recipe.\n\n- `node['nginx']['syslog']['git_repo']` - The git repository url to use for the syslog patches.\n- `node['nginx']['syslog']['git_revision']` - The revision on the git repository to checkout.\n\n### chef_nginx::upload_progress\n\nThese attributes are used in the `chef_nginx::upload_progress_module` recipe.\n\n- `node['nginx']['upload_progress']['url']` - URL for the tarball.\n- `node['nginx']['upload_progress']['checksum']` - Checksum of the tarball.\n- `node['nginx']['upload_progress']['javascript_output']` - Output in javascript. Default is `true` for backwards compatibility.\n- `node['nginx']['upload_progress']['zone_name']` - Zone name which will be used to store the per-connection tracking information. Default is `proxied`.\n- `node['nginx']['upload_progress']['zone_size']` - Zone size in bytes. Default is `1m` (1 megabyte).\n\n## Resources\n\n### nginx_site\n\nEnable or disable a Server Block in `#{node['nginx']['dir']}/sites-available` by calling nxensite or nxdissite (introduced by this cookbook) to manage the symbolic link in `#{node['nginx']['dir']}/sites-enabled`.\n\n### Actions\n\n- `enable` - Enable the nginx site (default)\n- `disable` - Disable the nginx site\n\n### Properties:\n\n- `name` - (optional) Name of the site to enable. By default it's assumed that the name of the nginx_site resource is the site name, but this allows overriding that.\n- `template` - (optional) Path to the source for the `template` resource.\n- `variables` - (optional) Variables to be used with the `template` resource\n\n## Ohai Plugin\n\nThe `ohai_plugin` recipe includes an Ohai plugin. It will be automatically installed and activated, providing the following attributes via ohai, no matter how nginx is installed (source or package):\n\n- `node['nginx']['version']` - version of nginx\n- `node['nginx']['configure_arguments']` - options passed to `./configure` when nginx was built\n- `node['nginx']['prefix']` - installation prefix\n- `node['nginx']['conf_path']` - configuration file path\n\nIn the source recipe, it is used to determine whether control attributes for building nginx have changed.\n\n## Usage\n\nThis cookbook provides three distinct installation methods, all of which are controlled via attributes and executed using the chef_nginx::default recipe.\n\n### Package installation using the nginx.org repositories\n\nNginx provides repositories for RHEL, Debian/Ubuntu, and Suse platforms with up to date packages available on older distributions. Due to the age of many nginx packages shipping with distros we believe this is the ideal installation method. With no attributes set the nginx.org repositories will be added to your system and nginx will be installed via package. This provides a solid out of the box install for most users.\n\n### Package installation using distro repositories\n\nIf you prefer to use the packages included in your distro or to roll your own packages you'll want to set `node['nginx']['repo_source']` to `nil` or `distro` to skip the repository setup. The default recipe will still install nginx from packages, but you'll retain control over the package location.\n\n### Source installation to compile non-dynamic modules\n\nIf you need control over how nginx is built, or you need non-dynamic modules to be included you'll need to compile nginx from source. We highly recommend against using this method as it requires the installation of a full compilation toolchain and development dependencies on your nodes. Creating your own packages with nginx compiled as necessary is a preferred option. If that's not possible you can set `node['nginx']['install_method']` to `source` and provide a version in `node['nginx']['version']`.\n\n#### Specifying Modules to compile\n\nThe following recipes are used to build module support into nginx. To compile a module, add its recipe name to the array attribute `node['nginx']['source']['modules']`.\n\n- `ipv6.rb` - enables IPv6 support\n- `headers_more_module` -\n- `http_auth_request_module``\n- `http_echo_module.rb` - downloads the `http_echo_module` module and enables it as a module when compiling nginx.\n- `http_geoip_module.rb` - installs the GeoIP libraries and data files and enables the module for compilation.\n- `http_gzip_static_module.rb` - enables the module for compilation. Be sure to set `node['nginx']['gzip_static'] = 'yes'`.\n- `http_mp4_module` -\n- `http_perl_module.rb` - enables embedded Perl for compilation.\n- `http_realip_module.rb` - enables the module for compilation and creates the configuration.\n- `http_spdy_module` -\n- `http_ssl_module.rb` - enables SSL for compilation.\n- `http_stub_status_module.rb` - provides `nginx_status` configuration and enables the module for compilation.\n- `http_v2_module`\n- `ipv6` -\n- `naxsi_module` - enables the naxsi module for the web application firewall for nginx.\n- `ngx_devel_module` -\n- `ngx_lua_module` -\n- `openssl_source.rb` - downloads and uses custom OpenSSL source when compiling nginx\n- `pagespeed_module`-\n- `passenger` - builds the passenger gem and configuration for \"`mod_passenger`\".\n- `set_misc` -\n- `syslog_module` - enables syslog support for nginx. This only works with source builds. See -\n- `upload_progress_module.rb` - builds the `upload_progress` module and enables it as a module when compiling nginx.\n\n## Resources\n\n### nginx_site\n\nEnable or disable a Server Block in `#{node['nginx']['dir']}/sites-available` by calling nxensite or nxdissite (introduced by this cookbook) to manage the symbolic link in `#{node['nginx']['dir']}/sites-enabled`.\n\n### Actions\n\n- `enable` - Enable the nginx site (default)\n- `disable` - Disable the nginx site\n\n### Properties:\n\n- `name` - (optional) Name of the site to enable. By default it's assumed that the name of the nginx_site resource is the site name, but this allows overriding that.\n- `template` - (optional) Path to the source for the `template` resource.\n- `cookbook` - (optional) The cookbook that contains the template source.\n- `variables` - (optional) Variables to be used with the `template` resource\n\n## Adding New Modules\n\nPreviously we'd add each possible module to this cookbook itself. That's not necessary using wrapper cookbooks and we'd prefer to not add any addition module recipes at this time. Instead in your nginx wrapper cookbook setup any necessary packages and then include the follow code to add the module to the list of modules to compile:\n\n```ruby\nnode.run_state['nginx_configure_flags'] =\n node.run_state['nginx_configure_flags'] | ['--with-SOMETHING', \"--with-SOME_OPT='things'\"]\n```\n\n## License & Authors\n\n- Author:: Joshua Timberman ([joshua@chef.io](mailto:joshua@chef.io))\n- Author:: Adam Jacob ([adam@chef.io](mailto:adam@chef.io))\n- Author:: AJ Christensen ([aj@chef.io](mailto:aj@chef.io))\n- Author:: Jamie Winsor ([jamie@vialstudios.com](mailto:jamie@vialstudios.com))\n- Author:: Mike Fiedler ([miketheman@gmail.com](mailto:miketheman@gmail.com))\n\n```text\nCopyright 2008-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","fedora":">= 0.0.0","oracle":">= 0.0.0","redhat":">= 0.0.0","scientific":">= 0.0.0","ubuntu":">= 0.0.0","suse":">= 0.0.0","opensuse":">= 0.0.0","opensuseleap":">= 0.0.0"},"dependencies":{"build-essential":">= 0.0.0","ohai":">= 4.1.0","yum-epel":">= 0.0.0","compat_resource":">= 12.16.3","zypper":">= 0.0.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{"chef_nginx":"Installs nginx package and sets up configuration with Debian apache style with sites-enabled/sites-available","chef_nginx::source":"Installs nginx from source and sets up configuration with Debian apache style with sites-enabled/sites-available"},"source_url":"https://github.com/chef-cookbooks/chef_nginx","issues_url":"https://github.com/chef-cookbooks/chef_nginx/issues","chef_version":[[">= 12.1"]],"ohai_version":[]} \ No newline at end of file diff --git a/cookbooks/nginx/recipes/authorized_ips.rb b/cookbooks/chef_nginx/recipes/authorized_ips.rb similarity index 88% rename from cookbooks/nginx/recipes/authorized_ips.rb rename to cookbooks/chef_nginx/recipes/authorized_ips.rb index d6949ae..c11d6dd 100644 --- a/cookbooks/nginx/recipes/authorized_ips.rb +++ b/cookbooks/chef_nginx/recipes/authorized_ips.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: nginx # Recipe:: authorized_ips # # Author:: Jamie Winsor () # -# Copyright 2012-2013, Riot Games +# Copyright:: 2012-2017, Riot Games # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -25,8 +25,5 @@ node.default['nginx']['authorized_ips'] = ['127.0.0.1/32'] template 'authorized_ip' do path "#{node['nginx']['dir']}/authorized_ip" source 'modules/authorized_ip.erb' - owner 'root' - group node['root_group'] - mode '0644' notifies :reload, 'service[nginx]', :delayed end diff --git a/cookbooks/nginx/recipes/commons.rb b/cookbooks/chef_nginx/recipes/commons.rb similarity index 76% rename from cookbooks/nginx/recipes/commons.rb rename to cookbooks/chef_nginx/recipes/commons.rb index 0492bb0..46bdea7 100644 --- a/cookbooks/nginx/recipes/commons.rb +++ b/cookbooks/chef_nginx/recipes/commons.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: nginx # Recipe:: commons # # Author:: AJ Christensen # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-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. @@ -19,6 +19,6 @@ # limitations under the License. # -include_recipe 'nginx::commons_dir' -include_recipe 'nginx::commons_script' -include_recipe 'nginx::commons_conf' +include_recipe 'chef_nginx::commons_dir' +include_recipe 'chef_nginx::commons_script' +include_recipe 'chef_nginx::commons_conf' diff --git a/cookbooks/nginx/recipes/commons_conf.rb b/cookbooks/chef_nginx/recipes/commons_conf.rb similarity index 81% rename from cookbooks/nginx/recipes/commons_conf.rb rename to cookbooks/chef_nginx/recipes/commons_conf.rb index fccd470..948e543 100644 --- a/cookbooks/nginx/recipes/commons_conf.rb +++ b/cookbooks/chef_nginx/recipes/commons_conf.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: nginx # Recipe:: common/conf # # Author:: AJ Christensen # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-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. @@ -23,20 +23,15 @@ template 'nginx.conf' do path "#{node['nginx']['dir']}/nginx.conf" source node['nginx']['conf_template'] cookbook node['nginx']['conf_cookbook'] - owner 'root' - group node['root_group'] - mode '0644' notifies :reload, 'service[nginx]', :delayed + variables(lazy { { pid_file: pidfile_location } }) end template "#{node['nginx']['dir']}/sites-available/default" do source 'default-site.erb' - owner 'root' - group node['root_group'] - mode '0644' notifies :reload, 'service[nginx]', :delayed end nginx_site 'default' do - enable node['nginx']['default_site_enabled'] + action node['nginx']['default_site_enabled'] ? :enable : :disable end diff --git a/cookbooks/nginx/recipes/commons_dir.rb b/cookbooks/chef_nginx/recipes/commons_dir.rb similarity index 75% rename from cookbooks/nginx/recipes/commons_dir.rb rename to cookbooks/chef_nginx/recipes/commons_dir.rb index bfad3f7..311020c 100644 --- a/cookbooks/nginx/recipes/commons_dir.rb +++ b/cookbooks/chef_nginx/recipes/commons_dir.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: nginx # Recipe:: common/dir # # Author:: AJ Christensen # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-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. @@ -20,8 +20,6 @@ # directory node['nginx']['dir'] do - owner 'root' - group node['root_group'] mode '0755' recursive true end @@ -33,22 +31,19 @@ directory node['nginx']['log_dir'] do recursive true end -directory File.dirname(node['nginx']['pid']) do - owner 'root' - group node['root_group'] +directory 'pid file directory' do + path lazy { File.dirname(pidfile_location) } mode '0755' recursive true end %w(sites-available sites-enabled conf.d).each do |leaf| directory File.join(node['nginx']['dir'], leaf) do - owner 'root' - group node['root_group'] mode '0755' end end -if !node['nginx']['default_site_enabled'] && (node['platform_family'] == 'rhel' || node['platform_family'] == 'fedora') +if !node['nginx']['default_site_enabled'] && platform_family?('rhel', 'fedora') %w(default.conf example_ssl.conf).each do |config| file "/etc/nginx/conf.d/#{config}" do action :delete diff --git a/cookbooks/nginx/recipes/commons_script.rb b/cookbooks/chef_nginx/recipes/commons_script.rb similarity index 87% rename from cookbooks/nginx/recipes/commons_script.rb rename to cookbooks/chef_nginx/recipes/commons_script.rb index 324d374..6b051c0 100644 --- a/cookbooks/nginx/recipes/commons_script.rb +++ b/cookbooks/chef_nginx/recipes/commons_script.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: nginx # Recipe:: common/script # # Author:: AJ Christensen # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-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. @@ -23,7 +23,5 @@ template "#{node['nginx']['script_dir']}/#{nxscript}" do source "#{nxscript}.erb" mode '0755' - owner 'root' - group node['root_group'] end end diff --git a/cookbooks/nginx/recipes/default.rb b/cookbooks/chef_nginx/recipes/default.rb similarity index 71% rename from cookbooks/nginx/recipes/default.rb rename to cookbooks/chef_nginx/recipes/default.rb index 3f75eec..c0e0d37 100644 --- a/cookbooks/nginx/recipes/default.rb +++ b/cookbooks/chef_nginx/recipes/default.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: nginx # Recipe:: default # # Author:: AJ Christensen # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-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. @@ -19,13 +19,8 @@ # limitations under the License. # -include_recipe "nginx::#{node['nginx']['install_method']}" - -service 'nginx' do - supports :status => true, :restart => true, :reload => true - action :start -end +include_recipe "chef_nginx::#{node['nginx']['install_method']}" node['nginx']['default']['modules'].each do |ngx_module| - include_recipe "nginx::#{ngx_module}" + include_recipe "chef_nginx::#{ngx_module}" end diff --git a/cookbooks/nginx/recipes/headers_more_module.rb b/cookbooks/chef_nginx/recipes/headers_more_module.rb similarity index 80% rename from cookbooks/nginx/recipes/headers_more_module.rb rename to cookbooks/chef_nginx/recipes/headers_more_module.rb index 08c586c..cde990f 100644 --- a/cookbooks/nginx/recipes/headers_more_module.rb +++ b/cookbooks/chef_nginx/recipes/headers_more_module.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: nginx # Recipe:: headers_more_module # # Author:: Lucas Jandrew () # -# Copyright 2012-2013, Riot Games +# Copyright:: 2012-2017, Riot Games # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -24,14 +24,9 @@ module_location = "#{Chef::Config['file_cache_path']}/headers_more/#{node['nginx remote_file tar_location do source node['nginx']['headers_more']['source_url'] checksum node['nginx']['headers_more']['source_checksum'] - owner 'root' - group node['root_group'] - mode '0644' end directory module_location do - owner 'root' - group node['root_group'] mode '0755' recursive true action :create @@ -47,4 +42,4 @@ bash 'extract_headers_more' do end node.run_state['nginx_configure_flags'] = - node.run_state['nginx_configure_flags'] | ["--add-module=#{module_location}/headers-more-nginx-module-#{node['nginx']['headers_more']['version']}/"] + node.run_state['nginx_configure_flags'] | ["--add-module=#{module_location}/headers-more-nginx-module-#{node['nginx']['headers_more']['version']}/"] diff --git a/cookbooks/nginx/recipes/http_auth_request_module.rb b/cookbooks/chef_nginx/recipes/http_auth_request_module.rb similarity index 93% rename from cookbooks/nginx/recipes/http_auth_request_module.rb rename to cookbooks/chef_nginx/recipes/http_auth_request_module.rb index 5283ac5..3a6f6de 100644 --- a/cookbooks/nginx/recipes/http_auth_request_module.rb +++ b/cookbooks/chef_nginx/recipes/http_auth_request_module.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: nginx # Recipe:: http_auth_request_module # # Author:: David Radcliffe () # -# Copyright 2013, David Radcliffe +# Copyright:: 2013-2017, David Radcliffe # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -32,9 +32,6 @@ else remote_file arm_src_filepath do source node['nginx']['auth_request']['url'] checksum node['nginx']['auth_request']['checksum'] - owner 'root' - group node['root_group'] - mode '0644' end bash 'extract_auth_request_module' do diff --git a/cookbooks/nginx/recipes/http_echo_module.rb b/cookbooks/chef_nginx/recipes/http_echo_module.rb similarity index 92% rename from cookbooks/nginx/recipes/http_echo_module.rb rename to cookbooks/chef_nginx/recipes/http_echo_module.rb index 85c2861..a660e5d 100644 --- a/cookbooks/nginx/recipes/http_echo_module.rb +++ b/cookbooks/chef_nginx/recipes/http_echo_module.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: nginx # Recipe:: http_echo_module # # Author:: Danial Pearce () # -# Copyright 2012-2013, CushyCMS +# Copyright:: 2012-2017, CushyCMS # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -26,9 +26,6 @@ echo_extract_path = "#{Chef::Config['file_cache_path']}/nginx_echo_module/#{node remote_file echo_src_filepath do source node['nginx']['echo']['url'] checksum node['nginx']['echo']['checksum'] - owner 'root' - group node['root_group'] - mode '0644' end bash 'extract_http_echo_module' do diff --git a/cookbooks/nginx/recipes/http_geoip_module.rb b/cookbooks/chef_nginx/recipes/http_geoip_module.rb similarity index 86% rename from cookbooks/nginx/recipes/http_geoip_module.rb rename to cookbooks/chef_nginx/recipes/http_geoip_module.rb index f61b711..cba28ab 100644 --- a/cookbooks/nginx/recipes/http_geoip_module.rb +++ b/cookbooks/chef_nginx/recipes/http_geoip_module.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: nginx # Recipe:: http_geoip_module # # Author:: Jamie Winsor () # -# Copyright 2012-2013, Riot Games +# Copyright:: 2012-2017, Riot Games # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -31,9 +31,6 @@ geolib_filepath = "#{Chef::Config['file_cache_path']}/#{geolib_filename}" remote_file geolib_filepath do source node['nginx']['geoip']['lib_url'] checksum node['nginx']['geoip']['lib_checksum'] - owner 'root' - group node['root_group'] - mode '0644' end bash 'extract_geolib' do @@ -50,8 +47,6 @@ bash 'extract_geolib' do end directory node['nginx']['geoip']['path'] do - owner 'root' - group node['root_group'] mode '0755' recursive true end @@ -63,9 +58,6 @@ remote_file country_src_filepath do end source node['nginx']['geoip']['country_dat_url'] checksum node['nginx']['geoip']['country_dat_checksum'] - owner 'root' - group node['root_group'] - mode '0644' end bash 'gunzip_geo_lite_country_dat' do @@ -76,7 +68,7 @@ bash 'gunzip_geo_lite_country_dat' do end if node['nginx']['geoip']['enable_city'] - city_dat = "#{node['nginx']['geoip']['path']}/GeoLiteCity.dat" + city_dat = "#{node['nginx']['geoip']['path']}/GeoLiteCity.dat" remote_file city_src_filepath do not_if do @@ -85,9 +77,6 @@ if node['nginx']['geoip']['enable_city'] end source node['nginx']['geoip']['city_dat_url'] checksum node['nginx']['geoip']['city_dat_checksum'] - owner 'root' - group node['root_group'] - mode '0644' end bash 'gunzip_geo_lite_city_dat' do @@ -100,12 +89,9 @@ end template "#{node['nginx']['dir']}/conf.d/http_geoip.conf" do source 'modules/http_geoip.conf.erb' - owner 'root' - group node['root_group'] - mode '0644' variables( - :country_dat => country_dat, - :city_dat => city_dat + country_dat: country_dat, + city_dat: city_dat ) end diff --git a/cookbooks/nginx/recipes/http_gzip_static_module.rb b/cookbooks/chef_nginx/recipes/http_gzip_static_module.rb similarity index 88% rename from cookbooks/nginx/recipes/http_gzip_static_module.rb rename to cookbooks/chef_nginx/recipes/http_gzip_static_module.rb index 4607c35..d52fadd 100644 --- a/cookbooks/nginx/recipes/http_gzip_static_module.rb +++ b/cookbooks/chef_nginx/recipes/http_gzip_static_module.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: nginx # Recipe:: http_gzip_static_module # # Author:: Jamie Winsor () # -# Copyright 2012-2013, Riot Games +# Copyright:: 2012-2017, Riot Games # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -21,9 +21,6 @@ template "#{node['nginx']['dir']}/conf.d/http_gzip_static.conf" do source 'modules/http_gzip_static.conf.erb' - owner 'root' - group node['root_group'] - mode '0644' end node.run_state['nginx_configure_flags'] = diff --git a/cookbooks/nginx/recipes/http_mp4_module.rb b/cookbooks/chef_nginx/recipes/http_mp4_module.rb similarity index 100% rename from cookbooks/nginx/recipes/http_mp4_module.rb rename to cookbooks/chef_nginx/recipes/http_mp4_module.rb diff --git a/cookbooks/nginx/recipes/http_perl_module.rb b/cookbooks/chef_nginx/recipes/http_perl_module.rb similarity index 93% rename from cookbooks/nginx/recipes/http_perl_module.rb rename to cookbooks/chef_nginx/recipes/http_perl_module.rb index e4f55d9..8efe202 100644 --- a/cookbooks/nginx/recipes/http_perl_module.rb +++ b/cookbooks/chef_nginx/recipes/http_perl_module.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: nginx # Recipe:: http_perl_module # # Author:: Akzhan Abdulin () # -# Copyright 2012-2013, REG.RU +# Copyright:: 2012-2017, REG.RU # # 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/nginx/recipes/http_realip_module.rb b/cookbooks/chef_nginx/recipes/http_realip_module.rb similarity index 91% rename from cookbooks/nginx/recipes/http_realip_module.rb rename to cookbooks/chef_nginx/recipes/http_realip_module.rb index 6451bf9..d07ff4e 100644 --- a/cookbooks/nginx/recipes/http_realip_module.rb +++ b/cookbooks/chef_nginx/recipes/http_realip_module.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: nginx # Recipe:: http_realip_module # # Author:: Jamie Winsor () # -# Copyright 2012-2013, Riot Games +# Copyright:: 2012-2017, Riot Games # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -28,9 +28,6 @@ node.default['nginx']['realip']['real_ip_recursive'] = 'off' template "#{node['nginx']['dir']}/conf.d/http_realip.conf" do source 'modules/http_realip.conf.erb' - owner 'root' - group node['root_group'] - mode '0644' notifies :reload, 'service[nginx]', :delayed end diff --git a/cookbooks/nginx/recipes/http_spdy_module.rb b/cookbooks/chef_nginx/recipes/http_spdy_module.rb similarity index 92% rename from cookbooks/nginx/recipes/http_spdy_module.rb rename to cookbooks/chef_nginx/recipes/http_spdy_module.rb index 1eafa9b..e15518e 100644 --- a/cookbooks/nginx/recipes/http_spdy_module.rb +++ b/cookbooks/chef_nginx/recipes/http_spdy_module.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: nginx # Recipe:: http_spdy_module # # Author:: Christoph Buente () # -# Copyright 2013, MeinekleineFarm.org +# Copyright:: 2013-2017, MeinekleineFarm.org # # 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/nginx/recipes/http_ssl_module.rb b/cookbooks/chef_nginx/recipes/http_ssl_module.rb similarity index 92% rename from cookbooks/nginx/recipes/http_ssl_module.rb rename to cookbooks/chef_nginx/recipes/http_ssl_module.rb index 6ff4f7c..4163a05 100644 --- a/cookbooks/nginx/recipes/http_ssl_module.rb +++ b/cookbooks/chef_nginx/recipes/http_ssl_module.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: nginx # Recipe:: http_ssl_module # # Author:: Jamie Winsor () # -# Copyright 2012-2013, Riot Games +# Copyright:: 2012-2017, Riot Games # # 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/nginx/recipes/http_stub_status_module.rb b/cookbooks/chef_nginx/recipes/http_stub_status_module.rb similarity index 86% rename from cookbooks/nginx/recipes/http_stub_status_module.rb rename to cookbooks/chef_nginx/recipes/http_stub_status_module.rb index c07243c..fb3fdbd 100644 --- a/cookbooks/nginx/recipes/http_stub_status_module.rb +++ b/cookbooks/chef_nginx/recipes/http_stub_status_module.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: nginx # Recipe:: http_stub_status_module # # Author:: Jamie Winsor () # -# Copyright 2012-2013, Riot Games +# Copyright:: 2012-2017, Riot Games # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,14 +19,11 @@ # limitations under the License. # -include_recipe 'nginx::authorized_ips' +include_recipe 'chef_nginx::authorized_ips' template 'nginx_status' do path "#{node['nginx']['dir']}/sites-available/nginx_status" source 'modules/nginx_status.erb' - owner 'root' - group node['root_group'] - mode '0644' notifies :reload, 'service[nginx]', :delayed end diff --git a/cookbooks/build-essential/recipes/_mac_os_x.rb b/cookbooks/chef_nginx/recipes/http_v2_module.rb similarity index 76% rename from cookbooks/build-essential/recipes/_mac_os_x.rb rename to cookbooks/chef_nginx/recipes/http_v2_module.rb index 1a235a4..0a7148f 100644 --- a/cookbooks/build-essential/recipes/_mac_os_x.rb +++ b/cookbooks/chef_nginx/recipes/http_v2_module.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: build-essential -# Recipe:: mac_os_x +# Cookbook:: nginx +# Recipe:: http_v2_module +# # -# 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. @@ -17,6 +17,5 @@ # limitations under the License. # -potentially_at_compile_time do - xcode_command_line_tools 'install' -end +node.run_state['nginx_configure_flags'] = + node.run_state['nginx_configure_flags'] | ['--with-http_v2_module'] diff --git a/cookbooks/nginx/recipes/ipv6.rb b/cookbooks/chef_nginx/recipes/ipv6.rb similarity index 92% rename from cookbooks/nginx/recipes/ipv6.rb rename to cookbooks/chef_nginx/recipes/ipv6.rb index 2c67601..57dba63 100644 --- a/cookbooks/nginx/recipes/ipv6.rb +++ b/cookbooks/chef_nginx/recipes/ipv6.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: nginx # Recipe:: ipv6 # # Author:: Alan Harper (alan@sct.com.au) # -# Copyright 2013 Alan Harper +# Copyright:: 2013-2017, Alan Harper # # 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/nginx/recipes/lua.rb b/cookbooks/chef_nginx/recipes/lua.rb similarity index 79% rename from cookbooks/nginx/recipes/lua.rb rename to cookbooks/chef_nginx/recipes/lua.rb index 9526389..7f3a1a3 100644 --- a/cookbooks/nginx/recipes/lua.rb +++ b/cookbooks/chef_nginx/recipes/lua.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: nginx -# Recipe:: default +# Cookbook:: nginx +# Recipe:: lua # -# Copyright 2013, 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. @@ -24,9 +24,6 @@ luajit_extract_path = "#{Chef::Config['file_cache_path']}/luajit-#{node['nginx'] remote_file luajit_src_filepath do source node['nginx']['luajit']['url'] checksum node['nginx']['luajit']['checksum'] - owner 'root' - group node['root_group'] - mode '0644' end bash 'extract_luajit' do @@ -36,12 +33,14 @@ bash 'extract_luajit' do tar xzf #{luajit_src_filename} -C #{luajit_extract_path} cd luajit-#{node['nginx']['luajit']['version']}/LuaJIT-#{node['nginx']['luajit']['version']} make && make install - export LUAJIT_INC="/usr/local/include/luajit-2.0" - export LUAJIT_LIB="usr/local/lib" EOH not_if { ::File.exist?(luajit_extract_path) } end -package 'lua-devel' do - action :install -end +node.run_state['nginx_source_env'].merge!( + 'LUAJIT_INC' => '/usr/local/include/luajit-2.0', + 'LUAJIT_LIB' => '/usr/local/lib' +) + +node.run_state['nginx_configure_flags'] = + node.run_state['nginx_configure_flags'] | ['--with-ld-opt=-Wl,-rpath,/usr/local/lib'] diff --git a/cookbooks/nginx/recipes/naxsi_module.rb b/cookbooks/chef_nginx/recipes/naxsi_module.rb similarity index 89% rename from cookbooks/nginx/recipes/naxsi_module.rb rename to cookbooks/chef_nginx/recipes/naxsi_module.rb index 063f537..2adbaf6 100644 --- a/cookbooks/nginx/recipes/naxsi_module.rb +++ b/cookbooks/chef_nginx/recipes/naxsi_module.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: nginx # Recipe:: naxsi_module # # Author:: Artiom Lunev () # -# Copyright 2012-2013, Artiom Lunev +# Copyright:: 2012-2017, Artiom Lunev # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -21,9 +21,6 @@ cookbook_file "#{node['nginx']['dir']}/naxsi_core.rules" do source 'naxsi_core.rules' - owner 'root' - group node['root_group'] - mode '0644' notifies :reload, 'service[nginx]', :delayed end @@ -34,9 +31,6 @@ naxsi_extract_path = "#{Chef::Config['file_cache_path']}/nginx-naxsi-#{node['ngi remote_file naxsi_src_filepath do source node['nginx']['naxsi']['url'] checksum node['nginx']['naxsi']['checksum'] - owner 'root' - group node['root_group'] - mode '0644' end bash 'extract_naxsi_module' do diff --git a/cookbooks/nginx/recipes/ngx_devel_module.rb b/cookbooks/chef_nginx/recipes/ngx_devel_module.rb similarity index 92% rename from cookbooks/nginx/recipes/ngx_devel_module.rb rename to cookbooks/chef_nginx/recipes/ngx_devel_module.rb index 3c15c54..89c9d46 100644 --- a/cookbooks/nginx/recipes/ngx_devel_module.rb +++ b/cookbooks/chef_nginx/recipes/ngx_devel_module.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: nginx # Recipes:: devel # # Author:: Arthur Freyman () # -# Copyright 2013, Riot Games +# Copyright:: 2013-2017, Riot Games # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -26,9 +26,6 @@ devel_extract_path = "#{Chef::Config['file_cache_path']}/nginx-devel-#{node['ngi remote_file devel_src_filepath do source node['nginx']['devel']['url'] checksum node['nginx']['devel']['checksum'] - owner 'root' - group node['root_group'] - mode '0644' end bash 'extract_devel_module' do diff --git a/cookbooks/nginx/recipes/ngx_lua_module.rb b/cookbooks/chef_nginx/recipes/ngx_lua_module.rb similarity index 87% rename from cookbooks/nginx/recipes/ngx_lua_module.rb rename to cookbooks/chef_nginx/recipes/ngx_lua_module.rb index 2371f27..25c09c6 100644 --- a/cookbooks/nginx/recipes/ngx_lua_module.rb +++ b/cookbooks/chef_nginx/recipes/ngx_lua_module.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx -# Recipes:: lua +# Cookbook:: nginx +# Recipes:: nginx_lua_module # # Author:: Arthur Freyman () # -# Copyright 2013, Riot Games +# Copyright:: 2013-2017, Riot Games # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -26,9 +26,6 @@ lua_extract_path = "#{Chef::Config['file_cache_path']}/nginx-lua-#{node['nginx'] remote_file lua_src_filepath do source node['nginx']['lua']['url'] checksum node['nginx']['lua']['checksum'] - owner 'root' - group node['root_group'] - mode '0644' end bash 'extract_lua_module' do @@ -43,5 +40,5 @@ end node.run_state['nginx_configure_flags'] = node.run_state['nginx_configure_flags'] | ["--add-module=#{lua_extract_path}/lua-nginx-module-#{node['nginx']['lua']['version']}"] -include_recipe 'nginx::lua' -include_recipe 'nginx::ngx_devel_module' +include_recipe 'chef_nginx::lua' +include_recipe 'chef_nginx::ngx_devel_module' diff --git a/cookbooks/nginx/recipes/ohai_plugin.rb b/cookbooks/chef_nginx/recipes/ohai_plugin.rb similarity index 70% rename from cookbooks/nginx/recipes/ohai_plugin.rb rename to cookbooks/chef_nginx/recipes/ohai_plugin.rb index a474d49..a554754 100644 --- a/cookbooks/nginx/recipes/ohai_plugin.rb +++ b/cookbooks/chef_nginx/recipes/ohai_plugin.rb @@ -1,10 +1,11 @@ # -# Cookbook Name:: nginx +# Cookbook:: nginx # Recipe:: ohai_plugin # # Author:: Jamie Winsor () # -# Copyright 2012-2013, Riot Games +# Copyright:: 2012-2017, Riot Games +# Copyright:: 2016-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. @@ -19,17 +20,14 @@ # limitations under the License. # +# for notification post install / change ohai 'reload_nginx' do plugin 'nginx' action :nothing end -template "#{node['ohai']['plugin_path']}/nginx.rb" do - source 'plugins/nginx.rb.erb' - owner 'root' - group node['root_group'] - mode '0755' - notifies :reload, 'ohai[reload_nginx]', :immediately +ohai_plugin 'nginx' do + source_file 'plugins/ohai-nginx.rb.erb' + variables binary: node['nginx']['binary'] + resource :template end - -include_recipe 'ohai::default' diff --git a/cookbooks/nginx/recipes/openssl_source.rb b/cookbooks/chef_nginx/recipes/openssl_source.rb similarity index 92% rename from cookbooks/nginx/recipes/openssl_source.rb rename to cookbooks/chef_nginx/recipes/openssl_source.rb index f286f3d..01969bb 100644 --- a/cookbooks/nginx/recipes/openssl_source.rb +++ b/cookbooks/chef_nginx/recipes/openssl_source.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: nginx # Recipe:: openssl_source # # Author:: David Radcliffe () # -# Copyright 2013, David Radcliffe +# Copyright:: 2013-2017, David Radcliffe # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -25,9 +25,6 @@ extract_path = "#{Chef::Config['file_cache_path']}/openssl-#{node['nginx']['open remote_file src_filepath do source node['nginx']['openssl_source']['url'] - owner 'root' - group node['root_group'] - mode '0644' not_if { ::File.exist?(src_filepath) } end diff --git a/cookbooks/chef_nginx/recipes/package.rb b/cookbooks/chef_nginx/recipes/package.rb new file mode 100644 index 0000000..f39b375 --- /dev/null +++ b/cookbooks/chef_nginx/recipes/package.rb @@ -0,0 +1,53 @@ +# +# Cookbook:: nginx +# Recipe:: package +# Author:: AJ Christensen +# +# Copyright:: 2008-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. +# 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. +# + +include_recipe 'chef_nginx::ohai_plugin' + +case node['nginx']['repo_source'] +when 'epel' + if platform_family?('rhel') + include_recipe 'yum-epel' + else + Chef::Log.warn("node['nginx']['repo_source'] set to EPEL, but not running on a RHEL platform so skipping EPEL setup") + end +when 'nginx' + include_recipe 'chef_nginx::repo' + package_install_opts = '--disablerepo=* --enablerepo=nginx' if platform_family?('rhel') +when 'passenger' + if platform_family?('debian') + include_recipe 'chef_nginx::repo_passenger' + else + Chef::Log.warn("node['nginx']['repo_source'] set to passenger, but not running on a Debian based platform so skipping repo setup") + end +else + Chef::Log.warn('Unrecognized distro value set, or no value set. Using distro provided packages instead.') +end + +package node['nginx']['package_name'] do + options package_install_opts + notifies :reload, 'ohai[reload_nginx]', :immediately +end + +service 'nginx' do + supports status: true, restart: true, reload: true + action [:start, :enable] +end + +include_recipe 'chef_nginx::commons' diff --git a/cookbooks/nginx/recipes/pagespeed_module.rb b/cookbooks/chef_nginx/recipes/pagespeed_module.rb similarity index 78% rename from cookbooks/nginx/recipes/pagespeed_module.rb rename to cookbooks/chef_nginx/recipes/pagespeed_module.rb index b8fc608..150558b 100644 --- a/cookbooks/nginx/recipes/pagespeed_module.rb +++ b/cookbooks/chef_nginx/recipes/pagespeed_module.rb @@ -1,5 +1,5 @@ # -# Cookbook Name:: nginx +# Cookbook:: nginx # Recipe:: pagespeed_module # @@ -9,9 +9,6 @@ extract_path = "#{Chef::Config['file_cache_path']}/nginx_pagespeed-#{node['nginx remote_file src_filepath do source node['nginx']['pagespeed']['url'] - owner 'root' - group node['root_group'] - mode '0644' not_if { ::File.exist?(src_filepath) } end @@ -21,22 +18,15 @@ psol_extract_path = "#{Chef::Config['file_cache_path']}/nginx_pagespeed-#{node[' remote_file psol_src_filepath do source node['nginx']['psol']['url'] - owner 'root' - group node['root_group'] - mode '0644' not_if { ::File.exist?(psol_src_filepath) } end -packages = value_for_platform_family( - %w(rhel) => node['nginx']['pagespeed']['packages']['rhel'], - %w(debian) => node['nginx']['pagespeed']['packages']['debian'] +package_array = value_for_platform_family( + %w(rhel) => node['nginx']['pagespeed']['packages']['rhel'], + %w(debian) => node['nginx']['pagespeed']['packages']['debian'] ) -unless packages.empty? - packages.each do |name| - package name - end -end +package package_array unless package_array.empty? bash 'extract_pagespeed' do cwd ::File.dirname(src_filepath) diff --git a/cookbooks/nginx/recipes/passenger.rb b/cookbooks/chef_nginx/recipes/passenger.rb similarity index 70% rename from cookbooks/nginx/recipes/passenger.rb rename to cookbooks/chef_nginx/recipes/passenger.rb index 93a3ae6..7dc27a5 100644 --- a/cookbooks/nginx/recipes/passenger.rb +++ b/cookbooks/chef_nginx/recipes/passenger.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: nginx +# Cookbook:: nginx # Recipe:: Passenger # -# Copyright 2013, 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. @@ -18,8 +18,8 @@ # packages = value_for_platform_family( - %w(rhel) => node['nginx']['passenger']['packages']['rhel'], - %w(fedora) => node['nginx']['passenger']['packages']['fedora'], + %w(rhel) => node['nginx']['passenger']['packages']['rhel'], + %w(fedora) => node['nginx']['passenger']['packages']['fedora'], %w(debian) => node['nginx']['passenger']['packages']['debian'] ) @@ -42,15 +42,20 @@ elsif node['nginx']['passenger']['install_method'] == 'source' gem_binary node['nginx']['passenger']['gem_binary'] if node['nginx']['passenger']['gem_binary'] end + passenger_module = node['nginx']['passenger']['root'] + + passenger_module += if Chef::VersionConstraint.new('>= 5.0.19').include?(node['nginx']['passenger']['version']) + '/src/nginx_module' + else + '/ext/nginx' + end + node.run_state['nginx_configure_flags'] = - node.run_state['nginx_configure_flags'] | ["--add-module=#{node['nginx']['passenger']['root']}/ext/nginx"] + node.run_state['nginx_configure_flags'] | ["--add-module=#{passenger_module}"] end template "#{node['nginx']['dir']}/conf.d/passenger.conf" do source 'modules/passenger.conf.erb' - owner 'root' - group node['root_group'] - mode '0644' notifies :reload, 'service[nginx]', :delayed end diff --git a/cookbooks/nginx/recipes/repo.rb b/cookbooks/chef_nginx/recipes/repo.rb similarity index 61% rename from cookbooks/nginx/recipes/repo.rb rename to cookbooks/chef_nginx/recipes/repo.rb index de24b7a..ee44e01 100644 --- a/cookbooks/nginx/recipes/repo.rb +++ b/cookbooks/chef_nginx/recipes/repo.rb @@ -1,9 +1,9 @@ # -# Cookbook Name:: nginx +# Cookbook:: nginx # Recipe:: repo # Author:: Nick Rycar # -# Copyright 2008-2013, Chef Software, Inc. +# Copyright:: 2008-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. @@ -19,17 +19,24 @@ # case node['platform_family'] -when 'rhel', 'fedora' +when 'rhel' yum_repository 'nginx' do - description 'Nginx.org Repository' - baseurl node['nginx']['upstream_repository'] - gpgkey 'http://nginx.org/keys/nginx_signing.key' - action :create + description 'Nginx.org Repository' + baseurl node['nginx']['upstream_repository'] + gpgkey 'http://nginx.org/keys/nginx_signing.key' + action :create + end + +when 'suse' + + zypper_repo 'nginx' do + repo_name 'Nginx.org Repository' + uri 'http://nginx.org/packages/sles/12' + key 'http://nginx.org/keys/nginx_signing.key' end when 'debian' - include_recipe 'apt::default' apt_repository 'nginx' do uri node['nginx']['upstream_repository'] @@ -38,4 +45,9 @@ when 'debian' deb_src true key 'http://nginx.org/keys/nginx_signing.key' end + +else + log "nginx.org does not maintain packages for platform #{node['platform']}. Cannot setup the upstream repo!" do + level :warn + end end diff --git a/cookbooks/nginx/recipes/repo_passenger.rb b/cookbooks/chef_nginx/recipes/repo_passenger.rb similarity index 75% rename from cookbooks/nginx/recipes/repo_passenger.rb rename to cookbooks/chef_nginx/recipes/repo_passenger.rb index 4b3dad4..e1a54cd 100644 --- a/cookbooks/nginx/recipes/repo_passenger.rb +++ b/cookbooks/chef_nginx/recipes/repo_passenger.rb @@ -1,4 +1,4 @@ -# Cookbook Name:: nginx +# Cookbook:: nginx # Recipe:: repo_passenger # Author:: Jose Alberto Suarez Lopez # @@ -15,16 +15,8 @@ # limitations under the License. # -case node['platform_family'] -when 'rhel', 'fedora' - - log 'There is not official phusion passenger repo for redhat based systems.' do - level :info - end - -when 'debian' - include_recipe 'apt::default' - package 'apt-transport-https' +if platform_family?('debian') + package 'ca-certificates' apt_repository 'phusionpassenger' do uri 'https://oss-binaries.phusionpassenger.com/apt/passenger' @@ -35,5 +27,9 @@ when 'debian' key '561F9B9CAC40B2F7' end - include_recipe 'nginx::passenger' + include_recipe 'chef_nginx::passenger' +else + log "There is not official phusion passenger repo platform #{node['platform']}. Skipping repo setup!" do + level :warn + end end diff --git a/cookbooks/nginx/recipes/set_misc.rb b/cookbooks/chef_nginx/recipes/set_misc.rb similarity index 88% rename from cookbooks/nginx/recipes/set_misc.rb rename to cookbooks/chef_nginx/recipes/set_misc.rb index 53b1060..e38e5f7 100644 --- a/cookbooks/nginx/recipes/set_misc.rb +++ b/cookbooks/chef_nginx/recipes/set_misc.rb @@ -1,5 +1,5 @@ # -# Cookbook Name:: nginx +# Cookbook:: nginx # Recipes:: set_misc # @@ -10,9 +10,6 @@ set_misc_extract_path = "#{Chef::Config['file_cache_path']}/nginx-set_misc-#{nod remote_file set_misc_src_filepath do source node['nginx']['set_misc']['url'] checksum node['nginx']['set_misc']['checksum'] - owner 'root' - group 'root' - mode '0644' end bash 'extract_set_misc_module' do @@ -27,4 +24,4 @@ end node.run_state['nginx_configure_flags'] = node.run_state['nginx_configure_flags'] | ["--add-module=#{set_misc_extract_path}/set-misc-nginx-module-#{node['nginx']['set_misc']['version']}"] -include_recipe 'nginx::ngx_devel_module' +include_recipe 'chef_nginx::ngx_devel_module' diff --git a/cookbooks/nginx/recipes/socketproxy.rb b/cookbooks/chef_nginx/recipes/socketproxy.rb similarity index 73% rename from cookbooks/nginx/recipes/socketproxy.rb rename to cookbooks/chef_nginx/recipes/socketproxy.rb index 4498922..292142f 100644 --- a/cookbooks/nginx/recipes/socketproxy.rb +++ b/cookbooks/chef_nginx/recipes/socketproxy.rb @@ -1,9 +1,9 @@ -include_recipe 'nginx::commons_dir' +include_recipe 'chef_nginx::commons_dir' directory node['nginx']['socketproxy']['root'] do owner node['nginx']['socketproxy']['app_owner'] group node['nginx']['socketproxy']['app_owner'] - mode 00755 + mode '0755' action :create end @@ -11,13 +11,10 @@ context_names = node['nginx']['socketproxy']['apps'].map do |_app, app_conf| app_conf['context_name'] end -fail 'More than one app has the same context_name configured.' if context_names.uniq.length != context_names.length +raise 'More than one app has the same context_name configured.' if context_names.uniq.length != context_names.length template node['nginx']['dir'] + '/sites-available/socketproxy.conf' do source 'modules/socketproxy.conf.erb' - owner 'root' - group 'root' - mode 00644 notifies :reload, 'service[nginx]', :delayed end diff --git a/cookbooks/nginx/recipes/source.rb b/cookbooks/chef_nginx/recipes/source.rb similarity index 54% rename from cookbooks/nginx/recipes/source.rb rename to cookbooks/chef_nginx/recipes/source.rb index 5f565b6..415fa1e 100644 --- a/cookbooks/nginx/recipes/source.rb +++ b/cookbooks/chef_nginx/recipes/source.rb @@ -1,12 +1,12 @@ # -# Cookbook Name:: nginx +# Cookbook:: nginx # Recipe:: source # # Author:: Adam Jacob () # Author:: Joshua Timberman () # Author:: Jamie Winsor () # -# Copyright 2009-2013, Chef Software, Inc. +# Copyright:: 2009-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. @@ -21,71 +21,59 @@ # limitations under the License. # -# This is for Chef 10 and earlier where attributes aren't loaded -# deterministically (resolved in Chef 11). -node.load_attribute_by_short_filename('source', 'nginx') if node.respond_to?(:load_attribute_by_short_filename) +raise "#{node['platform']} is not a supported platform in the nginx::source recipe" unless platform_family?('rhel', 'fedora', 'debian', 'suse') -nginx_url = node['nginx']['source']['url'] || - "http://nginx.org/download/nginx-#{node['nginx']['source']['version']}.tar.gz" +node.normal['nginx']['binary'] = node['nginx']['source']['sbin_path'] +node.normal['nginx']['daemon_disable'] = true -node.set['nginx']['binary'] = node['nginx']['source']['sbin_path'] -node.set['nginx']['daemon_disable'] = true - -unless node['nginx']['source']['use_existing_user'] - user node['nginx']['user'] do - system true - shell '/bin/false' - home '/var/www' - end +user node['nginx']['user'] do + system true + shell '/bin/false' + home '/var/www' + not_if { node['nginx']['source']['use_existing_user'] } end -include_recipe 'nginx::ohai_plugin' -include_recipe 'nginx::commons_dir' -include_recipe 'nginx::commons_script' +include_recipe 'chef_nginx::ohai_plugin' +include_recipe 'chef_nginx::commons_dir' +include_recipe 'chef_nginx::commons_script' include_recipe 'build-essential::default' -src_filepath = "#{Chef::Config['file_cache_path'] || '/tmp'}/nginx-#{node['nginx']['source']['version']}.tar.gz" -packages = value_for_platform_family( - %w(rhel fedora suse) => %w(pcre-devel openssl-devel), - %w(gentoo) => [], - %w(default) => %w(libpcre3 libpcre3-dev libssl-dev) +src_filepath = "#{Chef::Config['file_cache_path']}/nginx-#{node['nginx']['source']['version']}.tar.gz" + +# install prereqs +package value_for_platform_family( + %w(rhel fedora) => %w(pcre-devel openssl-devel tar), + %w(suse) => %w(pcre-devel libopenssl-devel tar), + %w(debian) => %w(libpcre3 libpcre3-dev libssl-dev tar) ) -packages.each do |name| - package name -end - -remote_file nginx_url do - source nginx_url +remote_file 'nginx source' do + source node['nginx']['source']['url'] checksum node['nginx']['source']['checksum'] path src_filepath backup false + retries 4 end node.run_state['nginx_force_recompile'] = false node.run_state['nginx_configure_flags'] = node['nginx']['source']['default_configure_flags'] | node['nginx']['configure_flags'] +node.run_state['nginx_source_env'] = {} -include_recipe 'nginx::commons_conf' +include_recipe 'chef_nginx::commons_conf' cookbook_file "#{node['nginx']['dir']}/mime.types" do source 'mime.types' - owner 'root' - group node['root_group'] - mode '0644' notifies :reload, 'service[nginx]', :delayed end -# source install depends on the existence of the `tar` package -package 'tar' - # Unpack downloaded source so we could apply nginx patches # in custom modules - example http://yaoweibin.github.io/nginx_tcp_proxy_module/ # patch -p1 < /path/to/nginx_tcp_proxy_module/tcp.patch bash 'unarchive_source' do cwd ::File.dirname(src_filepath) code <<-EOH - tar zxf #{::File.basename(src_filepath)} -C #{::File.dirname(src_filepath)} + tar zxf #{::File.basename(src_filepath)} -C #{::File.dirname(src_filepath)} --no-same-owner EOH not_if { ::File.directory?("#{Chef::Config['file_cache_path'] || '/tmp'}/nginx-#{node['nginx']['source']['version']}") } end @@ -99,6 +87,7 @@ nginx_force_recompile = node.run_state['nginx_force_recompile'] bash 'compile_nginx_source' do cwd ::File.dirname(src_filepath) + environment node.run_state['nginx_source_env'] code <<-EOH cd nginx-#{node['nginx']['source']['version']} && ./configure #{node.run_state['nginx_configure_flags'].join(' ')} && @@ -117,87 +106,65 @@ bash 'compile_nginx_source' do end case node['nginx']['init_style'] -when 'runit' - node.set['nginx']['src_binary'] = node['nginx']['binary'] - include_recipe 'runit::default' - - runit_service 'nginx' - - service 'nginx' do - supports :status => true, :restart => true, :reload => true - reload_command "#{node['runit']['sv_bin']} hup #{node['runit']['service_dir']}/nginx" - end -when 'bluepill' - include_recipe 'bluepill::default' - - template "#{node['bluepill']['conf_dir']}/nginx.pill" do - source 'nginx.pill.erb' - mode '0644' - end - - bluepill_service 'nginx' do - action [:enable, :load] - end - - service 'nginx' do - supports :status => true, :restart => true, :reload => true - reload_command "[[ -f #{node['nginx']['pid']} ]] && kill -HUP `cat #{node['nginx']['pid']}` || true" - action :nothing - end when 'upstart' # we rely on this to set up nginx.conf with daemon disable instead of doing # it in the upstart init script. - node.set['nginx']['daemon_disable'] = node['nginx']['upstart']['foreground'] + node.normal['nginx']['daemon_disable'] = node['nginx']['upstart']['foreground'] template '/etc/init/nginx.conf' do source 'nginx-upstart.conf.erb' - owner 'root' - group node['root_group'] - mode '0644' + variables(lazy { { pid_file: pidfile_location } }) end service 'nginx' do provider Chef::Provider::Service::Upstart - supports :status => true, :restart => true, :reload => true - action :nothing + supports status: true, restart: true, reload: true + action [:start, :enable] + end +when 'systemd' + + systemd_prefix = platform_family?('suse') ? '/usr/lib' : '/lib' + + template "#{systemd_prefix}/systemd/system/nginx.service" do + source 'nginx.service.erb' + end + + service 'nginx' do + provider Chef::Provider::Service::Systemd + supports status: true, restart: true, reload: true + action [:start, :enable] end else - node.set['nginx']['daemon_disable'] = false + node.normal['nginx']['daemon_disable'] = false generate_init = true case node['platform'] - when 'gentoo' - generate_template = false when 'debian', 'ubuntu' generate_template = true - defaults_path = '/etc/default/nginx' + defaults_path = '/etc/default/nginx' when 'freebsd' - generate_init = false + generate_init = false else generate_template = true - defaults_path = '/etc/sysconfig/nginx' + defaults_path = '/etc/sysconfig/nginx' end template '/etc/init.d/nginx' do source 'nginx.init.erb' - owner 'root' - group node['root_group'] mode '0755' + variables(lazy { { pid_file: pidfile_location } }) end if generate_init - if generate_template + if generate_template # ~FC023 template defaults_path do source 'nginx.sysconfig.erb' - owner 'root' - group node['root_group'] - mode '0644' end end service 'nginx' do - supports :status => true, :restart => true, :reload => true - action :enable + supports status: true, restart: true, reload: true + action [:start, :enable] end end diff --git a/cookbooks/nginx/recipes/syslog_module.rb b/cookbooks/chef_nginx/recipes/syslog_module.rb similarity index 71% rename from cookbooks/nginx/recipes/syslog_module.rb rename to cookbooks/chef_nginx/recipes/syslog_module.rb index aea546b..e731910 100644 --- a/cookbooks/nginx/recipes/syslog_module.rb +++ b/cookbooks/chef_nginx/recipes/syslog_module.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: nginx # Recipe:: syslog_module # # Author:: Bob Ziuchkovski () # -# Copyright 2014, UserTesting +# Copyright:: 2014-2017, UserTesting # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -23,24 +23,24 @@ nginx_src = "#{Chef::Config['file_cache_path']}/nginx-#{node['nginx']['source'][ nginx_syslog_src = "#{Chef::Config['file_cache_path']}/nginx_syslog_module" major, minor, patch = node['nginx']['source']['version'].split('.').map { |s| Integer(s) } -fail 'Unsupported nginx version' if major != 1 +raise 'Unsupported nginx version' if major != 1 case minor when 2 - case patch - when 0..6 - syslog_patch = 'syslog_1.2.0.patch' - else - syslog_patch = 'syslog_1.2.7.patch' - end + syslog_patch = case patch + when 0..6 + 'syslog_1.2.0.patch' + else + 'syslog_1.2.7.patch' + end when 3 - case patch - when 0..9 - syslog_patch = 'syslog_1.2.0.patch' - when 10..13 - syslog_patch = 'syslog_1.3.11.patch' - else - syslog_patch = 'syslog_1.3.14.patch' - end + syslog_patch = case patch + when 0..9 + 'syslog_1.2.0.patch' + when 10..13 + 'syslog_1.3.11.patch' + else + 'syslog_1.3.14.patch' + end when 4 syslog_patch = 'syslog_1.4.0.patch' when 5..6 @@ -48,21 +48,19 @@ when 5..6 when 7 syslog_patch = 'syslog_1.7.0.patch' else - fail 'Unsupported nginx version' + raise 'Unsupported nginx version' end git nginx_syslog_src do repository node['nginx']['syslog']['git_repo'] revision node['nginx']['syslog']['git_revision'] action :sync - user 'root' - group 'root' end execute 'apply_nginx_syslog_patch' do cwd nginx_src command "patch -p1 < #{nginx_syslog_src}/#{syslog_patch}" - not_if "patch -p1 --dry-run --reverse --silent < #{nginx_syslog_src}/#{syslog_patch}", :cwd => nginx_src + not_if "patch -p1 --dry-run --reverse --silent < #{nginx_syslog_src}/#{syslog_patch}", cwd: nginx_src end node.run_state['nginx_configure_flags'] = diff --git a/cookbooks/nginx/recipes/upload_progress_module.rb b/cookbooks/chef_nginx/recipes/upload_progress_module.rb similarity index 89% rename from cookbooks/nginx/recipes/upload_progress_module.rb rename to cookbooks/chef_nginx/recipes/upload_progress_module.rb index ccb1cfb..8a64f07 100644 --- a/cookbooks/nginx/recipes/upload_progress_module.rb +++ b/cookbooks/chef_nginx/recipes/upload_progress_module.rb @@ -1,10 +1,10 @@ # -# Cookbook Name:: nginx +# Cookbook:: nginx # Recipe:: upload_progress_module # # Author:: Jamie Winsor () # -# Copyright 2012-2013, Riot Games +# Copyright:: 2012-2017, Riot Games # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -26,16 +26,10 @@ upm_extract_path = "#{Chef::Config['file_cache_path']}/nginx_upload_progress/#{n remote_file upm_src_filepath do source node['nginx']['upload_progress']['url'] checksum node['nginx']['upload_progress']['checksum'] - owner 'root' - group node['root_group'] - mode '0644' end template "#{node['nginx']['dir']}/conf.d/upload_progress.conf" do source 'modules/upload_progress.erb' - owner 'root' - group node['root_group'] - mode '0644' notifies :reload, 'service[nginx]', :delayed end diff --git a/cookbooks/chef_nginx/resources/site.rb b/cookbooks/chef_nginx/resources/site.rb new file mode 100644 index 0000000..b597036 --- /dev/null +++ b/cookbooks/chef_nginx/resources/site.rb @@ -0,0 +1,81 @@ +# +# Cookbook:: nginx +# Resource:: site +# +# Author:: AJ Christensen +# Author:: Tim Smith +# +# Copyright:: 2008-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. +# 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 :nginx_site + +property :name, String, name_property: true +property :variables, Hash, default: {} +property :cookbook, String +property :template, [String, Array] +property :enable, [String, true, false] + +action :enable do + # this is pretty evil, but gives us backwards compat with the old + # definition where there was an enable property vs a true action + if new_resource.enable + Chef::Log.warn('The "enable" property in nginx_site is deprecated. Use "action :enable" instead.') + elsif new_resource.enable == false || new_resource.enable == 'false' + Chef::Log.warn('The "enable" property in nginx_site is deprecated. Use "action :disable" instead.') + action_disable + return # don't perform the actual enable action afterwards + end + + if new_resource.template + # use declare_resource so we can have a property also named template + declare_resource(:template, "#{node['nginx']['dir']}/sites-available/#{new_resource.name}") do + source new_resource.template + cookbook new_resource.cookbook + variables(new_resource.variables) + notifies :reload, 'service[nginx]' + end + end + + execute "nxensite #{new_resource.name}" do + command "#{node['nginx']['script_dir']}/nxensite #{new_resource.name}" + notifies :reload, 'service[nginx]' + not_if do + ::File.symlink?("#{node['nginx']['dir']}/sites-enabled/#{new_resource.name}") || + ::File.symlink?("#{node['nginx']['dir']}/sites-enabled/000-#{new_resource.name}") + end + end +end + +action :disable do + execute "nxdissite #{new_resource.name}" do + command "#{node['nginx']['script_dir']}/nxdissite #{new_resource.name}" + notifies :reload, 'service[nginx]' + only_if do + ::File.symlink?("#{node['nginx']['dir']}/sites-enabled/#{new_resource.name}") || + ::File.symlink?("#{node['nginx']['dir']}/sites-enabled/000-#{new_resource.name}") + end + end + + # The nginx.org packages store the default site at /etc/nginx/conf.d/default.conf and our + # normal script doesn't disable these. + if new_resource.name == 'default' && ::File.exist?('/etc/nginx/conf.d/default.conf') # ~FC023 + execute 'Move nginx.org package default site config to sites-available' do + command "mv /etc/nginx/conf.d/default.conf #{node['nginx']['dir']}/sites-available/default" + user 'root' + notifies :reload, 'service[nginx]' + end + end +end diff --git a/cookbooks/nginx/templates/debian/nginx.init.erb b/cookbooks/chef_nginx/templates/debian/nginx.init.erb similarity index 98% rename from cookbooks/nginx/templates/debian/nginx.init.erb rename to cookbooks/chef_nginx/templates/debian/nginx.init.erb index 5a3711e..f058d78 100644 --- a/cookbooks/nginx/templates/debian/nginx.init.erb +++ b/cookbooks/chef_nginx/templates/debian/nginx.init.erb @@ -14,7 +14,7 @@ PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin DAEMON=<%= node['nginx']['binary'] %> NAME=nginx DESC=nginx -PID=<%= node['nginx']['pid'] %> +PID=<%= @pid_file %> # Include nginx defaults if available if [ -f /etc/default/nginx ]; then diff --git a/cookbooks/nginx/templates/default/default-site.erb b/cookbooks/chef_nginx/templates/default/default-site.erb similarity index 100% rename from cookbooks/nginx/templates/default/default-site.erb rename to cookbooks/chef_nginx/templates/default/default-site.erb diff --git a/cookbooks/nginx/templates/default/modules/authorized_ip.erb b/cookbooks/chef_nginx/templates/default/modules/authorized_ip.erb similarity index 100% rename from cookbooks/nginx/templates/default/modules/authorized_ip.erb rename to cookbooks/chef_nginx/templates/default/modules/authorized_ip.erb diff --git a/cookbooks/nginx/templates/default/modules/http_geoip.conf.erb b/cookbooks/chef_nginx/templates/default/modules/http_geoip.conf.erb similarity index 100% rename from cookbooks/nginx/templates/default/modules/http_geoip.conf.erb rename to cookbooks/chef_nginx/templates/default/modules/http_geoip.conf.erb diff --git a/cookbooks/nginx/templates/default/modules/http_gzip_static.conf.erb b/cookbooks/chef_nginx/templates/default/modules/http_gzip_static.conf.erb similarity index 100% rename from cookbooks/nginx/templates/default/modules/http_gzip_static.conf.erb rename to cookbooks/chef_nginx/templates/default/modules/http_gzip_static.conf.erb diff --git a/cookbooks/nginx/templates/default/modules/http_realip.conf.erb b/cookbooks/chef_nginx/templates/default/modules/http_realip.conf.erb similarity index 58% rename from cookbooks/nginx/templates/default/modules/http_realip.conf.erb rename to cookbooks/chef_nginx/templates/default/modules/http_realip.conf.erb index 5f9ffd1..3a5180c 100644 --- a/cookbooks/nginx/templates/default/modules/http_realip.conf.erb +++ b/cookbooks/chef_nginx/templates/default/modules/http_realip.conf.erb @@ -1,7 +1,7 @@ -<% node['nginx']['realip']['addresses'].each do |address| %> +<% node['nginx']['realip']['addresses'].each do |address| -%> set_real_ip_from <%= address %>; -<% end %> +<% end -%> real_ip_header <%= node['nginx']['realip']['header'] %>; -<% if node['nginx']['version'] >= '1.2.1' -%> +<% if node['nginx']['version'].to_f >= 1.2 -%> real_ip_recursive <%= node['nginx']['realip']['real_ip_recursive'] %>; <% end -%> diff --git a/cookbooks/nginx/templates/default/modules/nginx_status.erb b/cookbooks/chef_nginx/templates/default/modules/nginx_status.erb similarity index 86% rename from cookbooks/nginx/templates/default/modules/nginx_status.erb rename to cookbooks/chef_nginx/templates/default/modules/nginx_status.erb index 77e295d..eeb6ab5 100644 --- a/cookbooks/nginx/templates/default/modules/nginx_status.erb +++ b/cookbooks/chef_nginx/templates/default/modules/nginx_status.erb @@ -11,4 +11,8 @@ server { stub_status on; access_log off; } + + location / { + return 404; + } } diff --git a/cookbooks/nginx/templates/default/modules/passenger.conf.erb b/cookbooks/chef_nginx/templates/default/modules/passenger.conf.erb similarity index 76% rename from cookbooks/nginx/templates/default/modules/passenger.conf.erb rename to cookbooks/chef_nginx/templates/default/modules/passenger.conf.erb index 992b14f..1de3720 100644 --- a/cookbooks/nginx/templates/default/modules/passenger.conf.erb +++ b/cookbooks/chef_nginx/templates/default/modules/passenger.conf.erb @@ -7,6 +7,10 @@ passenger_min_instances <%= node['nginx']['passenger']['min_instances'] %>; passenger_max_instances_per_app <%= node['nginx']['passenger']['max_instances_per_app'] %>; passenger_pool_idle_time <%= node['nginx']['passenger']['pool_idle_time'] %>; passenger_max_requests <%= node['nginx']['passenger']['max_requests'] %>; +passenger_show_version_in_header <%= node['nginx']['passenger']['show_version_in_header'] %>; +<%- if node['nginx']['passenger']['passenger_log_file'] %> + passenger_log_file <%= node['nginx']['passenger']['passenger_log_file'] %>; +<% end %> <%- if node['nginx']['passenger']['nodejs'] %> passenger_nodejs <%= node['nginx']['passenger']['nodejs'] %>; diff --git a/cookbooks/nginx/templates/default/modules/socketproxy.conf.erb b/cookbooks/chef_nginx/templates/default/modules/socketproxy.conf.erb similarity index 100% rename from cookbooks/nginx/templates/default/modules/socketproxy.conf.erb rename to cookbooks/chef_nginx/templates/default/modules/socketproxy.conf.erb diff --git a/cookbooks/nginx/templates/default/modules/upload_progress.erb b/cookbooks/chef_nginx/templates/default/modules/upload_progress.erb similarity index 100% rename from cookbooks/nginx/templates/default/modules/upload_progress.erb rename to cookbooks/chef_nginx/templates/default/modules/upload_progress.erb diff --git a/cookbooks/nginx/templates/default/nginx-upstart.conf.erb b/cookbooks/chef_nginx/templates/default/nginx-upstart.conf.erb similarity index 74% rename from cookbooks/nginx/templates/default/nginx-upstart.conf.erb rename to cookbooks/chef_nginx/templates/default/nginx-upstart.conf.erb index 35cf867..fa88f24 100644 --- a/cookbooks/nginx/templates/default/nginx-upstart.conf.erb +++ b/cookbooks/chef_nginx/templates/default/nginx-upstart.conf.erb @@ -6,13 +6,13 @@ start on (local-filesystems and net-device-up IFACE=lo and runlevel [<%= node['n stop on runlevel [!<%= node['nginx']['upstart']['runlevels'] %>] env DAEMON=<%= node['nginx']['binary'] %> -env PID=<%= node['nginx']['pid'] %> +env PID=<%= @pid_file %> env CONFIG=<%= node['nginx']['source']['conf_path'] %> respawn -<% if node['nginx']['upstart']['respawn_limit'] %> +<% if node['nginx']['upstart']['respawn_limit'] -%> respawn limit <%= node['nginx']['upstart']['respawn_limit'] %> -<% end %> +<% end -%> pre-start script ${DAEMON} -t @@ -21,19 +21,19 @@ pre-start script fi end script -<% unless node['nginx']['upstart']['foreground'] %> +<% unless node['nginx']['upstart']['foreground'] -%> expect fork -<% else %> +<% else -%> console output -<% end %> +<% end -%> exec ${DAEMON} -c "${CONFIG}" -<% if node.recipe?('nginx::passenger') and not node['nginx']['upstart']['foreground'] %> +<% if node.recipe?('chef_nginx::passenger') && !node['nginx']['upstart']['foreground'] -%> # classic example of why pidfiles should have gone away # with the advent of fork(). we missed that bus a long # time ago so hack around it. post-stop script start-stop-daemon --stop --pidfile ${PID} --name nginx --exec ${DAEMON} --signal QUIT end script -<% end %> +<% end -%> diff --git a/cookbooks/nginx/templates/default/nginx.conf.erb b/cookbooks/chef_nginx/templates/default/nginx.conf.erb similarity index 88% rename from cookbooks/nginx/templates/default/nginx.conf.erb rename to cookbooks/chef_nginx/templates/default/nginx.conf.erb index 169eb24..98cb4a8 100644 --- a/cookbooks/nginx/templates/default/nginx.conf.erb +++ b/cookbooks/chef_nginx/templates/default/nginx.conf.erb @@ -1,15 +1,20 @@ user <%= node['nginx']['user'] %><% if node['nginx']['user'] != node['nginx']['group'] %> <%= node['nginx']['group'] %><% end %>; -worker_processes <%= node['nginx']['worker_processes'] %>; +worker_processes <%= node['nginx']['worker_processes'] %>; <% if node['nginx']['daemon_disable'] -%> daemon off; <% end -%> <% if node['nginx']['worker_rlimit_nofile'] -%> worker_rlimit_nofile <%= node['nginx']['worker_rlimit_nofile'] %>; <% end -%> +<% if node['nginx']['worker_shutdown_timeout'] -%> +worker_shutdown_timeout <%= node['nginx']['worker_shutdown_timeout'] %>; +<% end -%> +<% node['nginx']['load_modules'].each do |module_to_load| %> +load_module <%= module_to_load %>; +<% end -%> error_log <%= node['nginx']['log_dir'] %>/error.log<% if node['nginx']['error_log_options'] %> <%= node['nginx']['error_log_options'] %><% end %>; -pid <%= node['nginx']['pid'] %>; - +pid <%= @pid_file %>; events { worker_connections <%= node['nginx']['worker_connections'] %>; <% if node['nginx']['multi_accept'] -%> @@ -24,12 +29,13 @@ events { } http { - <% if node.recipe?('nginx::naxsi_module') %> + <% if node.recipe?('chef_nginx::naxsi_module') %> include <%= node['nginx']['dir'] %>/naxsi_core.rules; <% end %> include <%= node['nginx']['dir'] %>/mime.types; default_type application/octet-stream; + charset_types text/css text/plain text/vnd.wap.wml application/javascript application/json application/rss+xml application/xml; <% node['nginx']['log_formats'].each do |name, format| %> log_format <%= name %> <%= format %>; diff --git a/cookbooks/nginx/templates/default/nginx.init.erb b/cookbooks/chef_nginx/templates/default/nginx.init.erb similarity index 100% rename from cookbooks/nginx/templates/default/nginx.init.erb rename to cookbooks/chef_nginx/templates/default/nginx.init.erb diff --git a/cookbooks/chef_nginx/templates/default/nginx.service.erb b/cookbooks/chef_nginx/templates/default/nginx.service.erb new file mode 100644 index 0000000..c187ad6 --- /dev/null +++ b/cookbooks/chef_nginx/templates/default/nginx.service.erb @@ -0,0 +1,13 @@ +[Unit] +Description=The nginx HTTP and reverse proxy server +After=network.target remote-fs.target nss-lookup.target + +[Service] +ExecStartPre=<%= node['nginx']['binary'] %> -t +ExecStart=<%= node['nginx']['binary'] %> +ExecReload=/bin/kill -s HUP $MAINPID +ExecStop=/bin/kill -s QUIT $MAINPID +PrivateTmp=true + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/cookbooks/nginx/templates/default/nginx.sysconfig.erb b/cookbooks/chef_nginx/templates/default/nginx.sysconfig.erb similarity index 100% rename from cookbooks/nginx/templates/default/nginx.sysconfig.erb rename to cookbooks/chef_nginx/templates/default/nginx.sysconfig.erb diff --git a/cookbooks/nginx/templates/default/nxdissite.erb b/cookbooks/chef_nginx/templates/default/nxdissite.erb similarity index 100% rename from cookbooks/nginx/templates/default/nxdissite.erb rename to cookbooks/chef_nginx/templates/default/nxdissite.erb diff --git a/cookbooks/nginx/templates/default/nxensite.erb b/cookbooks/chef_nginx/templates/default/nxensite.erb similarity index 100% rename from cookbooks/nginx/templates/default/nxensite.erb rename to cookbooks/chef_nginx/templates/default/nxensite.erb diff --git a/cookbooks/chef_nginx/templates/default/plugins/ohai-nginx.rb.erb b/cookbooks/chef_nginx/templates/default/plugins/ohai-nginx.rb.erb new file mode 100644 index 0000000..a66d65e --- /dev/null +++ b/cookbooks/chef_nginx/templates/default/plugins/ohai-nginx.rb.erb @@ -0,0 +1,82 @@ +# +# Author:: Jamie Winsor () +# +# Copyright 2012, Riot Games +# +# 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. +# + +Ohai.plugin(:Nginx) do + provides "nginx" + provides "nginx/version" + provides "nginx/configure_arguments" + provides "nginx/prefix" + provides "nginx/conf_path" + + def parse_flags(flags) + prefix = nil + conf_path = nil + + flags.each do |flag| + case flag + when /^--prefix=(.+)$/ + prefix = Regexp.last_match(1) + when /^--conf-path=(.+)$/ + conf_path = Regexp.last_match(1) + end + end + + [prefix, conf_path] + end + + collect_data do + nginx Mash.new unless nginx + # if we fail we should still have these values to avoid nil class errors + # if people try to use them + nginx[:version] = nil unless nginx[:version] + nginx[:configure_arguments] = [] unless nginx[:configure_arguments] + nginx[:prefix] = nil unless nginx[:prefix] + nginx[:conf_path] = nil unless nginx[:conf_path] + + begin + so = shell_out("<%= @binary %> -V") + # Sample output: + # nginx version: nginx/1.10.1 + # built by clang 7.3.0 (clang-703.0.31) + # built with OpenSSL 1.0.2h 3 May 2016 + # TLS SNI support enabled + # configure arguments: --prefix=/usr/local/Cellar/nginx/1.10.1 --with-http_ssl_module --with-pcre --with-ipv6 --sbin-path=/usr/local/Cellar/nginx/1.10.1/bin/nginx --with-cc-opt='-I/usr/local/Cellar/pcre/8.38/include -I/usr/local/Cellar/openssl/1.0.2h_1/include' --with-ld-opt='-L/usr/local/Cellar/pcre/8.38/lib -L/usr/local/Cellar/openssl/1.0.2h_1/lib' --conf-path=/usr/local/etc/nginx/nginx.conf --pid-path=/usr/local/var/run/nginx.pid --lock-path=/usr/local/var/run/nginx.lock --http-client-body-temp-path=/usr/local/var/run/nginx/client_body_temp --http-proxy-temp-path=/usr/local/var/run/nginx/proxy_temp --http-fastcgi-temp-path=/usr/local/var/run/nginx/fastcgi_temp --http-uwsgi-temp-path=/usr/local/var/run/nginx/uwsgi_temp --http-scgi-temp-path=/usr/local/var/run/nginx/scgi_temp --http-log-path=/usr/local/var/log/nginx/access.log --error-log-path=/usr/local/var/log/nginx/error.log --with-http_gzip_static_module + + if so.exitstatus == 0 + so.stderr.split("\n").each do |line| + case line + when /^configure arguments:(.+)/ + # This could be better: I'm splitting on configure arguments which removes them and also + # adds a blank string at index 0 of the array. This is why we drop index 0 and map to + # add the '--' prefix back to the configure argument. + nginx[:configure_arguments] = Regexp.last_match(1).split(/\s--(?!param)/).drop(1).map { |ca| "--#{ca}" } + + prefix, conf_path = parse_flags(nginx[:configure_arguments]) + + nginx[:prefix] = prefix + nginx[:conf_path] = conf_path + when /^nginx version: nginx\/(\d+\.\d+\.\d+)/ + nginx[:version] = Regexp.last_match(1) + end + end + end + rescue + Ohai::Log.debug('Nginx plugin: Could not shell_out "<%= @binary %> -V"') + end + end +end diff --git a/cookbooks/nginx/templates/default/sv-nginx-log-run.erb b/cookbooks/chef_nginx/templates/default/sv-nginx-log-run.erb similarity index 100% rename from cookbooks/nginx/templates/default/sv-nginx-log-run.erb rename to cookbooks/chef_nginx/templates/default/sv-nginx-log-run.erb diff --git a/cookbooks/nginx/templates/default/sv-nginx-run.erb b/cookbooks/chef_nginx/templates/default/sv-nginx-run.erb similarity index 100% rename from cookbooks/nginx/templates/default/sv-nginx-run.erb rename to cookbooks/chef_nginx/templates/default/sv-nginx-run.erb diff --git a/cookbooks/nginx/templates/ubuntu/nginx.init.erb b/cookbooks/chef_nginx/templates/ubuntu/nginx.init.erb similarity index 98% rename from cookbooks/nginx/templates/ubuntu/nginx.init.erb rename to cookbooks/chef_nginx/templates/ubuntu/nginx.init.erb index 5a3711e..f058d78 100644 --- a/cookbooks/nginx/templates/ubuntu/nginx.init.erb +++ b/cookbooks/chef_nginx/templates/ubuntu/nginx.init.erb @@ -14,7 +14,7 @@ PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin DAEMON=<%= node['nginx']['binary'] %> NAME=nginx DESC=nginx -PID=<%= node['nginx']['pid'] %> +PID=<%= @pid_file %> # Include nginx defaults if available if [ -f /etc/default/nginx ]; then diff --git a/cookbooks/dmg/.foodcritic b/cookbooks/dmg/.foodcritic deleted file mode 100644 index 3318b2a..0000000 --- a/cookbooks/dmg/.foodcritic +++ /dev/null @@ -1,4 +0,0 @@ -~FC007 -~FC023 -~FC024 -~FC048 diff --git a/cookbooks/dmg/CHANGELOG.md b/cookbooks/dmg/CHANGELOG.md index 9eed8f2..0890748 100644 --- a/cookbooks/dmg/CHANGELOG.md +++ b/cookbooks/dmg/CHANGELOG.md @@ -2,6 +2,23 @@ This file is used to list changes made in each version of the dmg cookbook. +## 4.0.0 (2017-04-27) + +- Converted the existing LWRP to a custom resource which increases the required chef-client release to 12.5+ +- Added Test Kitchen config with private atlas boxes for 10.10 and 10.11 +- Added a test recipe to installed Tunnelblick +- Added an Inspec test to confirm that Tunnelblick actually installs +- Remove unused attributes and the entire attributes file +- Add a warning if you include the default recipe on your runlist +- Update specs to run on 10.12 and against the test recipe since dmg::default is empty and the existing spec tested nothing + +## 3.1.1 (2017-04-11) + +- Cookstyle updates +- Test with Local Delivery and not Rake +- Update apache2 license string +- Remove foodcritic exclusions + ## 3.1.0 (2017-01-18) - Fixed pkg,mpkg installation when it was using mounted app name while it was actually mounted under different name for some applications diff --git a/cookbooks/dmg/README.md b/cookbooks/dmg/README.md index 7cbbb13..cfe0f85 100644 --- a/cookbooks/dmg/README.md +++ b/cookbooks/dmg/README.md @@ -8,11 +8,11 @@ Resource to install OS X applications (.app) from dmg files. ### Platforms -- Mac OS X +- macOS ### Chef -- Chef 12.1+ +- Chef 12.5+ ### Cookbooks @@ -56,8 +56,8 @@ Install `/Applications/Tunnelblick.app` from the primary download site. ```ruby dmg_package 'Tunnelblick' do - source 'http://tunnelblick.googlecode.com/files/Tunnelblick_3.1.2.dmg' - checksum 'a3fae60b6833175f32df20c90cd3a3603a' + source 'https://tunnelblick.net/release/Tunnelblick_3.7.0_build_4790.dmg' + checksum '5053038aa8caf7dea66dcab11d6d240672216e6546eff4c2622e216c61af85e5' action :install end ``` @@ -129,7 +129,7 @@ end **Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io)) -**Copyright:** 2011-2015, Chef Software, Inc. +**Copyright:** 2011-2017, Chef Software, Inc. ``` Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/cookbooks/dmg/attributes/default.rb b/cookbooks/dmg/attributes/default.rb deleted file mode 100644 index e8cbfae..0000000 --- a/cookbooks/dmg/attributes/default.rb +++ /dev/null @@ -1,20 +0,0 @@ -# -# Cookbook:: dmg -# Attributes:: default -# -# 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. -# 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. -# -default['dmg']['base_dir'] = '/Applications' -default['dmg']['cache_dir'] = Chef::Config[:file_cache_path] diff --git a/cookbooks/dmg/libraries/matchers.rb b/cookbooks/dmg/libraries/matchers.rb index 5b688c2..c66a086 100644 --- a/cookbooks/dmg/libraries/matchers.rb +++ b/cookbooks/dmg/libraries/matchers.rb @@ -2,7 +2,7 @@ # Cookbook:: dmg # Library:: matchers # -# Copyright:: 2014-2016, Fletcher Nichol +# Copyright:: 2014-2017, Fletcher Nichol # # 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/dmg/metadata.json b/cookbooks/dmg/metadata.json index 6e9e1e1..05ee917 100644 --- a/cookbooks/dmg/metadata.json +++ b/cookbooks/dmg/metadata.json @@ -1 +1 @@ -{"name":"dmg","version":"3.1.0","description":"LWRP to install OS X applications from dmgs","long_description":"# dmg Cookbook\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/dmg.svg?branch=master)](https://travis-ci.org/chef-cookbooks/dmg) [![Cookbook Version](https://img.shields.io/cookbook/v/dmg.svg)](https://supermarket.chef.io/cookbooks/dmg)\n\nResource to install OS X applications (.app) from dmg files.\n\n## Requirements\n\n### Platforms\n\n- Mac OS X\n\n### Chef\n\n- Chef 12.1+\n\n### Cookbooks\n\n- none\n\n## Resources/Providers\n\n### dmg_package\n\nThis resource will install a DMG \"Package\". It will retrieve the DMG from a remote URL, mount it using OS X's `hdid`, copy the application (.app directory) to the specified destination (/Applications), and detach the image using `hdiutil`. The dmg file will be stored in the `Chef::Config[:file_cache_path]`. If you want to install an application that has already been downloaded (not using the `source` parameter), copy it to the appropriate location. You can find out what directory this is with the following command on the node to run chef:\n\n```bash\nknife exec -E 'p Chef::Config[:file_cache_path]' -c /etc/chef/client.rb\n```\n\nOptionally, the LWRP can install an \"mpkg\" or \"pkg\" package using installer(8).\n\n#### Actions\n\n- :install - Installs the application.\n\n#### Parameter attributes:\n\n- `app` - This is the name of the application used by default for the /Volumes directory and the .app directory copied to /Applications.\n- `source` - remote URL for the dmg to download if specified. Default is nil.\n- `file` - local dmg full file path. Default is nil.\n- `owner` - owner that should own the package installation.\n- `destination` - directory to copy the .app into. Default is /Applications.\n- `checksum` - sha256 checksum of the dmg to download. Default is nil.\n- `type` - type of package, \"app\", \"pkg\" or \"mpkg\". Default is \"app\". When using \"pkg\" or \"mpkg\", the destination must be /Applications.\n- `volumes_dir` - Directory under /Volumes where the dmg is mounted. Not all dmgs are mounted into a /Volumes location matching the name of the dmg. If not specified, this will use the name attribute.\n- `package_id` - Package id registered with pkgutil when a pkg or mpkg is installed\n- `dmg_name` - Specify the name of the dmg if it is not the same as `app`, or if the name has spaces.\n- `dmg_passphrase` - Specify a passphrase to use to unencrypt the dmg while mounting.\n- `accept_eula` - Specify whether to accept the EULA. Certain dmgs require acceptance of EULA before mounting. Can be true or false, defaults to false.\n- `headers` - Allows custom HTTP headers (like cookies) to be set on the remote_file resource.\n\n#### Examples\n\nInstall `/Applications/Tunnelblick.app` from the primary download site.\n\n```ruby\ndmg_package 'Tunnelblick' do\n source 'http://tunnelblick.googlecode.com/files/Tunnelblick_3.1.2.dmg'\n checksum 'a3fae60b6833175f32df20c90cd3a3603a'\n action :install\nend\n```\n\nInstall Google Chrome. Uses the `dmg_name` because the application name has spaces. Installs in `/Applications/Google Chrome.app`.\n\n```ruby\ndmg_package 'Google Chrome' do\n dmg_name 'googlechrome'\n source 'https://dl-ssl.google.com/chrome/mac/stable/GGRM/googlechrome.dmg'\n checksum '7daa2dc5c46d9bfb14f1d7ff4b33884325e5e63e694810adc58f14795165c91a'\n action :install\nend\n```\n\nInstall Dropbox. Uses `volumes_dir` because the mounted directory is different than the name of the application directory. Installs in `/Applications/Dropbox.app`.\n\n```ruby\ndmg_package 'Dropbox' do\n volumes_dir 'Dropbox Installer'\n source 'http://www.dropbox.com/download?plat=mac'\n checksum 'b4ea620ca22b0517b75753283ceb82326aca8bc3c86212fbf725de6446a96a13'\n action :install\nend\n```\n\nInstall MacIrssi to `~/Applications` from the local file downloaded to the cache path into an Applications directory in the current user's home directory. Chef should run as a non-root user for this.\n\n```ruby\ndirectory \"#{ENV['HOME']}/Applications\"\n\ndmg_package 'MacIrssi' do\n destination \"#{ENV['HOME']}/Applications\"\n action :install\nend\n```\n\nInstall Virtualbox to `/Applications` from the .mpkg:\n\n```ruby\ndmg_package 'Virtualbox' do\n source 'http://dlc.sun.com.edgesuite.net/virtualbox/4.0.8/VirtualBox-4.0.8-71778-OSX.dmg'\n type 'mpkg'\nend\n```\n\nInstall pgAdmin to `/Applications` and automatically accept the EULA:\n\n```ruby\ndmg_package 'pgAdmin3' do\n source 'http://wwwmaster.postgresql.org/redir/198/h/pgadmin3/release/v1.12.3/osx/pgadmin3-1.12.3.dmg'\n checksum '9435f79d5b52d0febeddfad392adf82db9df159196f496c1ab139a6957242ce9'\n accept_eula true\nend\n```\n\nInstall Silverlight, with idempotence check based on pkgutil:\n\n```ruby\ndmg_package 'Silerlight' do\n source 'http://silverlight.dlservice.microsoft.com/download/D/C/2/DC2D5838-9138-4D25-AA92-52F61F7C51E6/runtime/Silverlight.dmg'\n type 'pkg'\n checksum '6d4a0ad4552d9815531463eb3f467fb8cf4bffcc'\n package_id 'com.microsoft.installSilverlightPlugin'\nend\n```\n\n## License & Authors\n\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":{"mac_os_x":">= 0.0.0"},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{}} \ No newline at end of file +{"name":"dmg","version":"4.0.0","description":"Resource for installing macOS applications from DMGs","long_description":"# dmg Cookbook\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/dmg.svg?branch=master)](https://travis-ci.org/chef-cookbooks/dmg) [![Cookbook Version](https://img.shields.io/cookbook/v/dmg.svg)](https://supermarket.chef.io/cookbooks/dmg)\n\nResource to install OS X applications (.app) from dmg files.\n\n## Requirements\n\n### Platforms\n\n- macOS\n\n### Chef\n\n- Chef 12.5+\n\n### Cookbooks\n\n- none\n\n## Resources/Providers\n\n### dmg_package\n\nThis resource will install a DMG \"Package\". It will retrieve the DMG from a remote URL, mount it using OS X's `hdid`, copy the application (.app directory) to the specified destination (/Applications), and detach the image using `hdiutil`. The dmg file will be stored in the `Chef::Config[:file_cache_path]`. If you want to install an application that has already been downloaded (not using the `source` parameter), copy it to the appropriate location. You can find out what directory this is with the following command on the node to run chef:\n\n```bash\nknife exec -E 'p Chef::Config[:file_cache_path]' -c /etc/chef/client.rb\n```\n\nOptionally, the LWRP can install an \"mpkg\" or \"pkg\" package using installer(8).\n\n#### Actions\n\n- :install - Installs the application.\n\n#### Parameter attributes:\n\n- `app` - This is the name of the application used by default for the /Volumes directory and the .app directory copied to /Applications.\n- `source` - remote URL for the dmg to download if specified. Default is nil.\n- `file` - local dmg full file path. Default is nil.\n- `owner` - owner that should own the package installation.\n- `destination` - directory to copy the .app into. Default is /Applications.\n- `checksum` - sha256 checksum of the dmg to download. Default is nil.\n- `type` - type of package, \"app\", \"pkg\" or \"mpkg\". Default is \"app\". When using \"pkg\" or \"mpkg\", the destination must be /Applications.\n- `volumes_dir` - Directory under /Volumes where the dmg is mounted. Not all dmgs are mounted into a /Volumes location matching the name of the dmg. If not specified, this will use the name attribute.\n- `package_id` - Package id registered with pkgutil when a pkg or mpkg is installed\n- `dmg_name` - Specify the name of the dmg if it is not the same as `app`, or if the name has spaces.\n- `dmg_passphrase` - Specify a passphrase to use to unencrypt the dmg while mounting.\n- `accept_eula` - Specify whether to accept the EULA. Certain dmgs require acceptance of EULA before mounting. Can be true or false, defaults to false.\n- `headers` - Allows custom HTTP headers (like cookies) to be set on the remote_file resource.\n\n#### Examples\n\nInstall `/Applications/Tunnelblick.app` from the primary download site.\n\n```ruby\ndmg_package 'Tunnelblick' do\n source 'https://tunnelblick.net/release/Tunnelblick_3.7.0_build_4790.dmg'\n checksum '5053038aa8caf7dea66dcab11d6d240672216e6546eff4c2622e216c61af85e5'\n action :install\nend\n```\n\nInstall Google Chrome. Uses the `dmg_name` because the application name has spaces. Installs in `/Applications/Google Chrome.app`.\n\n```ruby\ndmg_package 'Google Chrome' do\n dmg_name 'googlechrome'\n source 'https://dl-ssl.google.com/chrome/mac/stable/GGRM/googlechrome.dmg'\n checksum '7daa2dc5c46d9bfb14f1d7ff4b33884325e5e63e694810adc58f14795165c91a'\n action :install\nend\n```\n\nInstall Dropbox. Uses `volumes_dir` because the mounted directory is different than the name of the application directory. Installs in `/Applications/Dropbox.app`.\n\n```ruby\ndmg_package 'Dropbox' do\n volumes_dir 'Dropbox Installer'\n source 'http://www.dropbox.com/download?plat=mac'\n checksum 'b4ea620ca22b0517b75753283ceb82326aca8bc3c86212fbf725de6446a96a13'\n action :install\nend\n```\n\nInstall MacIrssi to `~/Applications` from the local file downloaded to the cache path into an Applications directory in the current user's home directory. Chef should run as a non-root user for this.\n\n```ruby\ndirectory \"#{ENV['HOME']}/Applications\"\n\ndmg_package 'MacIrssi' do\n destination \"#{ENV['HOME']}/Applications\"\n action :install\nend\n```\n\nInstall Virtualbox to `/Applications` from the .mpkg:\n\n```ruby\ndmg_package 'Virtualbox' do\n source 'http://dlc.sun.com.edgesuite.net/virtualbox/4.0.8/VirtualBox-4.0.8-71778-OSX.dmg'\n type 'mpkg'\nend\n```\n\nInstall pgAdmin to `/Applications` and automatically accept the EULA:\n\n```ruby\ndmg_package 'pgAdmin3' do\n source 'http://wwwmaster.postgresql.org/redir/198/h/pgadmin3/release/v1.12.3/osx/pgadmin3-1.12.3.dmg'\n checksum '9435f79d5b52d0febeddfad392adf82db9df159196f496c1ab139a6957242ce9'\n accept_eula true\nend\n```\n\nInstall Silverlight, with idempotence check based on pkgutil:\n\n```ruby\ndmg_package 'Silerlight' do\n source 'http://silverlight.dlservice.microsoft.com/download/D/C/2/DC2D5838-9138-4D25-AA92-52F61F7C51E6/runtime/Silverlight.dmg'\n type 'pkg'\n checksum '6d4a0ad4552d9815531463eb3f467fb8cf4bffcc'\n package_id 'com.microsoft.installSilverlightPlugin'\nend\n```\n\n## License & Authors\n\n**Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io))\n\n**Copyright:** 2011-2017, 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":{"mac_os_x":">= 0.0.0"},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{},"source_url":"https://github.com/chef-cookbooks/dmg","issues_url":"https://github.com/chef-cookbooks/dmg/issues","chef_version":[[">= 12.5"]],"ohai_version":[]} \ No newline at end of file diff --git a/cookbooks/dmg/providers/package.rb b/cookbooks/dmg/providers/package.rb deleted file mode 100644 index ac0bb9a..0000000 --- a/cookbooks/dmg/providers/package.rb +++ /dev/null @@ -1,95 +0,0 @@ -# -# Cookbook:: dmg -# Provider:: package -# -# 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. -# 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. -# - -include Chef::Mixin::ShellOut - -use_inline_resources if defined?(use_inline_resources) - -def load_current_resource - @dmgpkg = Chef::Resource::DmgPackage.new(new_resource.name) - @dmgpkg.app(new_resource.app) - Chef::Log.debug("Checking for application #{new_resource.app}") - @dmgpkg.installed(installed?) -end - -action :install do - unless @dmgpkg.installed - - volumes_dir = new_resource.volumes_dir ? new_resource.volumes_dir : new_resource.app - dmg_name = new_resource.dmg_name ? new_resource.dmg_name : new_resource.app - - dmg_file = if new_resource.file.nil? - "#{Chef::Config[:file_cache_path]}/#{dmg_name}.dmg" - else - new_resource.file - end - - remote_file "#{dmg_file} - #{@dmgpkg.name}" do - path dmg_file - source new_resource.source - headers new_resource.headers if new_resource.headers - checksum new_resource.checksum if new_resource.checksum - end if new_resource.source - - passphrase_cmd = new_resource.dmg_passphrase ? "-passphrase #{new_resource.dmg_passphrase}" : '' - ruby_block "attach #{dmg_file}" do - block do - cmd = shell_out("hdiutil imageinfo #{passphrase_cmd} '#{dmg_file}' | grep -q 'Software License Agreement: true'") - software_license_agreement = cmd.exitstatus.zero? - raise "Requires EULA Acceptance; add 'accept_eula true' to package resource" if software_license_agreement && !new_resource.accept_eula - accept_eula_cmd = new_resource.accept_eula ? 'echo Y | PAGER=true' : '' - shell_out!("#{accept_eula_cmd} hdiutil attach #{passphrase_cmd} '#{dmg_file}' -mountpoint '/Volumes/#{volumes_dir}' -quiet") - end - not_if "hdiutil info #{passphrase_cmd} | grep -q 'image-path.*#{dmg_file}'" - end - - case new_resource.type - when 'app' - execute "rsync --force --recursive --links --perms --executability --owner --group --times '/Volumes/#{volumes_dir}/#{new_resource.app}.app' '#{new_resource.destination}'" do - user new_resource.owner if new_resource.owner - end - - file "#{new_resource.destination}/#{new_resource.app}.app/Contents/MacOS/#{new_resource.app}" do - mode '755' - ignore_failure true - end - when 'mpkg', 'pkg' - execute "installation_file=$(ls '/Volumes/#{volumes_dir}' | grep '.#{new_resource.type}$') && sudo installer -pkg \"/Volumes/#{volumes_dir}/$installation_file\" -target /" do - # Prevent cfprefsd from holding up hdiutil detach for certain disk images - environment('__CFPREFERENCES_AVOID_DAEMON' => '1') if Gem::Version.new(node['platform_version']) >= Gem::Version.new('10.8') - end - end - - execute "hdiutil detach '/Volumes/#{volumes_dir}' || hdiutil detach '/Volumes/#{volumes_dir}' -force" - end -end - -private - -def installed? - if ::File.directory?("#{new_resource.destination}/#{new_resource.app}.app") - Chef::Log.info "Already installed; to upgrade, remove \"#{new_resource.destination}/#{new_resource.app}.app\"" - true - elsif shell_out("pkgutil --pkgs='#{new_resource.package_id}'").exitstatus.zero? - Chef::Log.info "Already installed; to upgrade, try \"sudo pkgutil --forget '#{new_resource.package_id}'\"" - true - else - false - end -end diff --git a/cookbooks/dmg/recipes/default.rb b/cookbooks/dmg/recipes/default.rb index 017b9d8..2690d0c 100644 --- a/cookbooks/dmg/recipes/default.rb +++ b/cookbooks/dmg/recipes/default.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: dmg +# Cookbook:: dmg # Recipe:: default # -# Copyright 2011-2016, 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. @@ -16,3 +16,5 @@ # See the License for the specific language governing permissions and # limitations under the License. # + +Chef::Log.warn('The dmg::default recipe does not contain any resources and should not be applied to a node') diff --git a/cookbooks/dmg/resources/package.rb b/cookbooks/dmg/resources/package.rb index 4d1a2d8..8a3a089 100644 --- a/cookbooks/dmg/resources/package.rb +++ b/cookbooks/dmg/resources/package.rb @@ -1,8 +1,9 @@ -# Encoding: utf-8 +# +# Author:: Joshua Timberman () # Cookbook:: dmg # Resource:: package # -# Copyright:: 2011-2016, Joshua Timberman +# 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. @@ -16,24 +17,82 @@ # See the License for the specific language governing permissions and # limitations under the License. # -actions :install -attribute :app, kind_of: String, name_attribute: true -attribute :source, kind_of: String, default: nil -attribute :file, kind_of: String, default: nil -attribute :owner, kind_of: String, default: nil -attribute :destination, kind_of: String, default: '/Applications' -attribute :checksum, kind_of: String, default: nil -attribute :volumes_dir, kind_of: String, default: nil -attribute :dmg_name, kind_of: String, default: nil -attribute :type, kind_of: String, default: 'app' -attribute :installed, kind_of: [TrueClass, FalseClass], default: false -attribute :package_id, kind_of: String, default: nil -attribute :dmg_passphrase, kind_of: String, default: nil -attribute :accept_eula, kind_of: [TrueClass, FalseClass], default: false -attribute :headers, kind_of: Hash, default: nil +property :app, String, name_property: true +property :source, String +property :file, String +property :owner, String +property :destination, String, default: '/Applications' +property :checksum, String +property :volumes_dir, String +property :dmg_name, String +property :type, String, default: 'app' +property :installed, [true, false], default: false, desired_state: false +property :package_id, String +property :dmg_passphrase, String +property :accept_eula, [true, false], default: false +property :headers, [Hash, nil], default: nil -def initialize(name, run_context = nil) - super - @action = :install +load_current_value do |new_resource| + if ::File.directory?("#{new_resource.destination}/#{new_resource.app}.app") + Chef::Log.info "Already installed; to upgrade, remove \"#{new_resource.destination}/#{new_resource.app}.app\"" + installed true + elsif shell_out("pkgutil --pkgs='#{new_resource.package_id}'").exitstatus == 0 + Chef::Log.info "Already installed; to upgrade, try \"sudo pkgutil --forget '#{new_resource.package_id}'\"" + installed true + else + installed false + end +end + +action :install do + unless current_resource.installed + + volumes_dir = new_resource.volumes_dir ? new_resource.volumes_dir : new_resource.app + dmg_name = new_resource.dmg_name ? new_resource.dmg_name : new_resource.app + + dmg_file = if new_resource.file.nil? + "#{Chef::Config[:file_cache_path]}/#{dmg_name}.dmg" + else + new_resource.file + end + + remote_file "#{dmg_file} - #{new_resource.name}" do + path dmg_file + source new_resource.source + headers new_resource.headers if new_resource.headers + checksum new_resource.checksum if new_resource.checksum + end if new_resource.source + + passphrase_cmd = new_resource.dmg_passphrase ? "-passphrase #{new_resource.dmg_passphrase}" : '' + ruby_block "attach #{dmg_file}" do + block do + cmd = shell_out("hdiutil imageinfo #{passphrase_cmd} '#{dmg_file}' | grep -q 'Software License Agreement: true'") + software_license_agreement = cmd.exitstatus == 0 + raise "Requires EULA Acceptance; add 'accept_eula true' to package resource" if software_license_agreement && !new_resource.accept_eula + accept_eula_cmd = new_resource.accept_eula ? 'echo Y | PAGER=true' : '' + shell_out!("#{accept_eula_cmd} hdiutil attach #{passphrase_cmd} '#{dmg_file}' -mountpoint '/Volumes/#{volumes_dir}' -quiet") + end + not_if "hdiutil info #{passphrase_cmd} | grep -q 'image-path.*#{dmg_file}'" + end + + case new_resource.type + when 'app' + execute "rsync --force --recursive --links --perms --executability --owner --group --times '/Volumes/#{volumes_dir}/#{new_resource.app}.app' '#{new_resource.destination}'" do + user new_resource.owner if new_resource.owner + end + + declare_resource(:file, "#{new_resource.destination}/#{new_resource.app}.app/Contents/MacOS/#{new_resource.app}") do + mode '755' + ignore_failure true + end + when 'mpkg', 'pkg' + execute "installation_file=$(ls '/Volumes/#{volumes_dir}' | grep '.#{new_resource.type}$') && sudo installer -pkg \"/Volumes/#{volumes_dir}/$installation_file\" -target /" do + # Prevent cfprefsd from holding up hdiutil detach for certain disk images + environment('__CFPREFERENCES_AVOID_DAEMON' => '1') + end + end + + execute "hdiutil detach '/Volumes/#{volumes_dir}' || hdiutil detach '/Volumes/#{volumes_dir}' -force" + end end diff --git a/cookbooks/mediawiki/metadata.rb b/cookbooks/mediawiki/metadata.rb index 169fb66..cafb353 100644 --- a/cookbooks/mediawiki/metadata.rb +++ b/cookbooks/mediawiki/metadata.rb @@ -3,13 +3,13 @@ maintainer 'pulsation' license 'BSD' description 'Installs/Configures mediawiki' long_description 'Installs/Configures mediawiki' -version '0.2.0' +version '0.3.0' depends 'apache2' depends 'php' depends 'mysql' depends 'database' -depends 'nginx' +depends 'chef_nginx' depends 'mysql2_chef_gem' depends 'php-fpm' diff --git a/cookbooks/mediawiki/recipes/nginx.rb b/cookbooks/mediawiki/recipes/nginx.rb index 22ff455..47bf189 100644 --- a/cookbooks/mediawiki/recipes/nginx.rb +++ b/cookbooks/mediawiki/recipes/nginx.rb @@ -25,7 +25,7 @@ php_fpm_pool "mediawiki" do end include_recipe "php::module_mysql" -include_recipe "nginx" +include_recipe "chef_nginx" directory node["mediawiki"]["docroot_dir"] do user node['nginx']['user'] diff --git a/cookbooks/nginx/CHANGELOG.md b/cookbooks/nginx/CHANGELOG.md deleted file mode 100644 index 8d5122b..0000000 --- a/cookbooks/nginx/CHANGELOG.md +++ /dev/null @@ -1,435 +0,0 @@ -nginx Cookbook CHANGELOG -======================== -This file is used to list changes made in each version of the nginx cookbook. - -v2.7.6 / 2015-03-17 -================== - - * Bugfix sites do not need a .conf suffix anymore, [#338][] [@runningman84][] - -v2.7.5 (2015-03-17) -------------------- -**NOTE** As of this release, this cookbook in its current format is deprecated, -and only critical bugs and fixes will be added. -A complete rewrite is in progress, so we appreciate your patience while we sort things out. -The amount of change included here - -* Fix nginx 1.4.4 archive checksum to prevent redownload, [#305][] [@irontoby][] -* Allow setting an empty string to prevent additional repos, [#243][] [@miketheman][] -* Use correct `mime.types` for javascript, [#259][] [@dwradcliffe][] -* Fix `headers_more` module for source installs, [#279][], [@josh-padnick][] & [@miketheman][] -* Remove `libtool` from `geoip` and update download paths & checksums, [@miketheman][] -* Fix unquoted URL with params failing geoip module build (and tests!), [#294][] [@karsten-bruckmann][] & [@miketheman][] -* Fix typo in `source.rb`, [#205][] [@gregkare][] -* Test updates: ChefSpec, test-kitchen. Lots of help by [@jujugrrr][] -* Toolchain updates for testing -* Adds support for `tcp_nopush`, `tcp_nodelay` [@shtouff][] - -After merging a ton of pull requests, here's a brief changelog. Click each to read more. - -* Merge pull request [#335][] from [@stevenolen][] -* Merge pull request [#332][] from [@monsterstrike][] -* Merge pull request [#331][] from [@jalberto][] -* Merge pull request [#327][] from [@nkadel-skyhook][] -* Merge pull request [#326][] from [@bchrobot][] -* Merge pull request [#325][] from [@CanOfSpam3bug324][] -* Merge pull request [#321][] from [@jalberto][] -* Merge pull request [#318][] from [@evertrue][] -* Merge pull request [#314][] from [@bkw][] -* Merge pull request [#312][] from [@thomasmeeus][] -* Merge pull request [#310][] from [@morr][] -* Merge pull request [#305][] from [@irontoby][] -* Merge pull request [#302][] from [@auth0][] -* Merge pull request [#298][] from [@Mytho][] -* Merge pull request [#269][] from [@yveslaroche][] -* Merge pull request [#259][] from [@dwradcliffe][] -* Merge pull request [#254][] from [@evertrue][] -* Merge pull request [#252][] from [@gkra][] -* Merge pull request [#249][] from [@whatcould][] -* Merge pull request [#240][] from [@jcoleman][] -* Merge pull request [#236][] from [@adepue][] -* Merge pull request [#230][] from [@n1koo][] -* Merge pull request [#225][] from [@thommay][] -* Merge pull request [#223][] from [@firmhouse][] -* Merge pull request [#220][] from [@evertrue][] -* Merge pull request [#219][] from [@evertrue][] -* Merge pull request [#204][] from [@usertesting][] -* Merge pull request [#200][] from [@ffuenf][] -* Merge pull request [#188][] from [@larkin][] -* Merge pull request [#184][] from [@tvdinner][] -* Merge pull request [#183][] from [@jenssegers][] -* Merge pull request [#174][] from [@9minutesnooze][] - -https://github.com/miketheman/nginx/compare/v2.7.4...v2.7.5 - -v2.7.4 (2014-06-06) -------------------- -* [COOK-4703] Default openssl version to 1.0.1h to address CVE-2014-0224 - - -v2.7.2 (2014-05-27) -------------------- - -- [COOK-4658] - Nginx::socketproxy if the context is blank or nonexistent, the location in the config file has a double slash at the beginning -- [COOK-4644] - add support to nginx::repo for Amazon Linux -- Allow .kitchen.cloud.yml to use an environment variable for the EC2 Availability Zone - - -v2.7.0 (2014-05-15) -------------------- -- [COOK-4643] - Update metadata lock on ohai -- [COOK-4588] - Give more love to FreeBSD -- [COOK-4601] - Add proxy type: Socket - - -v2.6.2 (2014-04-09) -------------------- -[COOK-4527] - set default openssl source version to 1.0.1g to address CVE-2014-0160 aka Heartbleed - - -v2.6.0 (2014-04-08) -------------------- -- Reverting COOK-4323 - - -v2.5.0 (2014-03-27) -------------------- -- [COOK-4323] - Need a resource to easily configure available sites (vhosts) - - -v2.4.4 (2014-03-13) -------------------- -- Updating for build-essential 2.0 - - -v2.4.2 (2014-02-28) -------------------- -Fixing bad commit from COOK-4330 - - -v2.4.1 (2014-02-27) -------------------- -- [COOK-4345] - nginx default recipe include install type recipe directly - - -v2.4.0 (2014-02-27) -------------------- -- [COOK-4380] - kitchen.yml platform listings for ubuntu-10.04 and ubuntu-12.04 are missing the dot -- [COOK-4330] - Bump nginx version for security issues (CVE-2013-0337, CVE-2013-4547) - - -v2.3.0 (2014-02-25) -------------------- -- **[COOK-4293](https://tickets.chef.io/browse/COOK-4293)** - Update testing Gems in nginx and fix a rubocop warnings -- **[COOK-4237] - Nginx version incorrectly parsed on Ubuntu 13 -- **[COOK-3866] - Nginx default site folder - - -v2.2.2 (2014-01-23) -------------------- -[COOK-3672] - Add gzip_static option - - -v2.2.0 ------- -No changes. Version bump for toolchain - - -v2.1.0 ------- -[COOK-3923] - Enable the list of packages installed by nginx::passenger to be configurable -[COOK-3672] - Nginx should support the gzip_static option -Updating for yum ~> 3.0 -Fixing up style for rubocop -Updating test-kitchen harness - - -v2.0.8 ------- -fixing metadata version error. locking to 3.0 - - -v2.0.6 ------- -Locking yum dependency to '< 3' - - -v2.0.4 ------- -### Bug -- **[COOK-3808](https://tickets.chef.io/browse/COOK-3808)** - nginx::passenger run fails because of broken installation of package dependencies -- **[COOK-3779](https://tickets.chef.io/browse/COOK-3779)** - Build in master fails due to rubocop error - - -v2.0.2 ------- -### Bug -- **[COOK-3808](https://tickets.chef.io/browse/COOK-3808)** - nginx::passenger run fails because of broken installation of package dependencies -- **[COOK-3779](https://tickets.chef.io/browse/COOK-3779)** - Build in master fails due to rubocop error - - -v2.0.0 ------- -### Improvement -- **[COOK-3733](https://tickets.chef.io/browse/COOK-3733)** - Add RPM key names and GPG checking -- **[COOK-3687](https://tickets.chef.io/browse/COOK-3687)** - Add support for `http_perl` -- **[COOK-3603](https://tickets.chef.io/browse/COOK-3603)** - Add a recipe for using custom openssl -- **[COOK-3602](https://tickets.chef.io/browse/COOK-3602)** - Use an attribute for the status module port -- **[COOK-3549](https://tickets.chef.io/browse/COOK-3549)** - Refactor custom modules support -- **[COOK-3521](https://tickets.chef.io/browse/COOK-3521)** - Add support for `http_auth_request` -- **[COOK-3520](https://tickets.chef.io/browse/COOK-3520)** - Add support for `spdy` -- **[COOK-3185](https://tickets.chef.io/browse/COOK-3185)** - Add `gzip_*` attributes -- **[COOK-2712](https://tickets.chef.io/browse/COOK-2712)** - Update `upload_progress` version to 0.9.0 - -### Bug -- **[COOK-3686](https://tickets.chef.io/browse/COOK-3686)** - Remove deprecated 'passenger_use_global_queue' directive -- **[COOK-3626](https://tickets.chef.io/browse/COOK-3626)** - Parameterize hardcoded path to helper scripts -- **[COOK-3571](https://tickets.chef.io/browse/COOK-3571)** - Reloda ohai plugin after installation -- **[COOK-3428](https://tickets.chef.io/browse/COOK-3428)** - Fix an issue where access logs are not disabled when the `disable_access_log` attribute is set to `true` -- **[COOK-3322](https://tickets.chef.io/browse/COOK-3322)** - Fix an issue where `nginx::ohai_plugin` fails when using source recipe -- **[COOK-3241](https://tickets.chef.io/browse/COOK-3241)** - Fix an issue where`nginx::ohai_plugin` fails unless using source recipe - -### New Feature -- **[COOK-3605](https://tickets.chef.io/browse/COOK-3605)** - Add Lua module - - -v1.8.0 ------- -### Bug -- **[COOK-3397](https://tickets.chef.io/browse/COOK-3397)** - Fix user from nginx package on Gentoo -- **[COOK-2968](https://tickets.chef.io/browse/COOK-2968)** - Fix foodcritic failure -- **[COOK-2723](https://tickets.chef.io/browse/COOK-2723)** - Remove duplicate passenger `max_pool_size` - -### Improvement -- **[COOK-3186](https://tickets.chef.io/browse/COOK-3186)** - Add `client_body_buffer_size` and `server_tokens attributes` -- **[COOK-3080](https://tickets.chef.io/browse/COOK-3080)** - Add rate-limiting support -- **[COOK-2927](https://tickets.chef.io/browse/COOK-2927)** - Add support for `real_ip_recursive` directive -- **[COOK-2925](https://tickets.chef.io/browse/COOK-2925)** - Fix ChefSpec converge -- **[COOK-2724](https://tickets.chef.io/browse/COOK-2724)** - Automatically create directory for PID file -- **[COOK-2472](https://tickets.chef.io/browse/COOK-2472)** - Bump nginx version to 1.2.9 -- **[COOK-2312](https://tickets.chef.io/browse/COOK-2312)** - Add additional `mine_types` to the `gzip_types` value - -### New Feature -- **[COOK-3183](https://tickets.chef.io/browse/COOK-3183)** - Allow inclusion in extra-cookbook modules - -v1.7.0 ------- -### Improvement -- [COOK-3030]: The repo_source attribute should allow you to not add any additional repositories to your node - -### Sub-task -- [COOK-2738]: move nginx::passenger attributes to `nginx/attributes/passenger.rb` - -v1.6.0 ------- -### Task -- [COOK-2409]: update nginx::source recipe for new `runit_service` resource -- [COOK-2877]: update nginx cookbook test-kitchen support to 1.0 (alpha) - -### Improvement -- [COOK-1976]: nginx source should be able to configure binary path -- [COOK-2622]: nginx: add upstart support -- [COOK-2725]: add "configtest" subcommand in initscript - -### Bug -- [COOK-2398]: nginx_site definition cannot be used to manage the default site -- [COOK-2493]: Resources in nginx::source recipe always use 1.2.6 version, even overriding version attribute -- [COOK-2531]: Remove usage of non-existant attribute "description" for `apt_repository` -- [COOK-2665]: nginx::source install with custom sbin_path breaks ohai data - -v1.4.0 ------- -- [COOK-2183] - Install nginx package from nginxyum repo -- [COOK-2311] - headers-more should be updated to the latest version -- [COOK-2455] - Support sendfile option (nginx.conf) - -v1.3.0 ------- -- [COOK-1979] - Passenger module requires curl-dev(el) -- [COOK-2219] - Support `proxy_read_timeout` (in nginx.conf) -- [COOK-2220] - Support `client_max_body_size` (in nginx.conf) -- [COOK-2280] - Allow custom timing of nginx_site's reload notification -- [COOK-2304] - nginx cookbook should install 1.2.6 not 1.2.3 for source installs -- [COOK-2309] - checksums for geoip files need to be updated in nginx -- [COOK-2310] - Checksum in the `nginx::upload_progress` recipe is not correct -- [COOK-2314] - nginx::passenger: Install the latest version of passenger -- [COOK-2327] - nginx: passenger recipe should find ruby via Ohai -- [COOK-2328] - nginx: Update mime.types file to the latest -- [COOK-2329] - nginx: Update naxsi rules to the current - -v1.2.0 ------- -- [COOK-1752] - Add headers more module to the nginx cookbook -- [COOK-2209] - nginx source recipe should create web user before creating directories -- [COOK-2221] - make nginx::source compatible with gentoo -- [COOK-2267] - add version for runit recommends - -v1.1.4 ------- -- [COOK-2168] - specify package name as an attribute - -v1.1.2 ------- -- [COOK-1766] - Nginx Source Recipe Rebuilding Source at Every Run -- [COOK-1910] - Add IPv6 module -- [COOK-1966] - nginx cookbook should let you set `gzip_vary` and `gzip_buffers` in nginx.conf -- [COOK-1969]- - nginx::passenger module not included due to use of symbolized `:nginx_configure_flags` -- [COOK-1971] - Template passenger.conf.erb configures key `passenger_max_pool_size` 2 times -- [COOK-1972] - nginx::source compile_nginx_source reports success in spite of failed compilation -- [COOK-1975] - nginx::passenger requires rake gem -- [COOK-1979] - Passenger module requires curl-dev(el) -- [COOK-2080] - Restart nginx on source compilation - -v1.1.0 ------- -- [COOK-1263] - Nginx log (and possibly other) directory creations should be recursive -- [COOK-1515] - move creation of `node['nginx']['dir']` out of commons.rb -- [COOK-1523] - nginx `http_geoip_module` requires libtoolize -- [COOK-1524] - nginx checksums are md5 -- [COOK-1641] - add "use", "`multi_accept`" and "`worker_rlimit_nofile`" to nginx cookbook -- [COOK-1683] - Nginx fails Windows nodes just by being required in metadata -- [COOK-1735] - Support Amazon Linux in nginx::source recipe -- [COOK-1753] - Add ability for nginx::passenger recipe to configure more Passenger global settings -- [COOK-1754] - Allow group to be set in nginx.conf file -- [COOK-1770] - nginx cookbook fails on servers that don't have a "cpu" attribute -- [COOK-1781] - Use 'sv' to reload nginx when using runit -- [COOK-1789] - stop depending on bluepill, runit and yum. they are not required by nginx cookbook -- [COOK-1791] - add name attribute to metadata -- [COOK-1837] - nginx::passenger doesn't work on debian family -- [COOK-1956] - update naxsi version due to incompatibility with newer nginx - -v1.0.2 ------- -- [COOK-1636] - relax the version constraint on ohai - -v1.0.0 ------- -- [COOK-913] - defaults for gzip cause warning on service restart -- [COOK-1020] - duplicate MIME type -- [COOK-1269] - add passenger module support through new recipe -- [COOK-1306] - increment nginx version to 1.2 (now 1.2.3) -- [COOK-1316] - default site should not always be enabled -- [COOK-1417] - resolve errors preventing build from source -- [COOK-1483] - source prefix attribute has no effect -- [COOK-1484] - source relies on /etc/sysconfig -- [COOK-1511] - add support for naxsi module -- [COOK-1525] - nginx source is downloaded every time -- [COOK-1526] - nginx_site does not remove sites -- [COOK-1527] - add `http_echo_module` recipe - -v0.101.6 --------- -Erroneous cookbook upload due to timeout. - -Version #'s are cheap. - -v0.101.4 --------- -- [COOK-1280] - Improve RHEL family support and fix ohai_plugins recipe bug -- [COOK-1194] - allow installation method via attribute -- [COOK-458] - fix duplicate nginx processes - -v0.101.2 --------- -* [COOK-1211] - include the default attributes explicitly so version is available. - -v0.101.0 --------- -**Attribute Change**: `node['nginx']['url']` -> `node['nginx']['source']['url']`; see the README.md. - -- [COOK-1115] - daemonize when using init script -- [COOK-477] - module compilation support in nginx::source - -v0.100.4 --------- -- [COOK-1126] - source version bump to 1.0.14 - -v0.100.2 --------- -- [COOK-1053] - Add :url attribute to nginx cookbook - -v0.100.0 --------- -- [COOK-818] - add "application/json" per RFC. -- [COOK-870] - bluepill init style support -- [COOK-957] - Compress application/javascript. -- [COOK-981] - Add reload support to NGINX service - -v0.99.2 -------- -- [COOK-809] - attribute to disable access logging -- [COOK-772] - update nginx download source location - - -[#174]: https://github.com/miketheman/nginx/issues/174 -[#183]: https://github.com/miketheman/nginx/issues/183 -[#184]: https://github.com/miketheman/nginx/issues/184 -[#188]: https://github.com/miketheman/nginx/issues/188 -[#200]: https://github.com/miketheman/nginx/issues/200 -[#204]: https://github.com/miketheman/nginx/issues/204 -[#205]: https://github.com/miketheman/nginx/issues/205 -[#219]: https://github.com/miketheman/nginx/issues/219 -[#220]: https://github.com/miketheman/nginx/issues/220 -[#223]: https://github.com/miketheman/nginx/issues/223 -[#225]: https://github.com/miketheman/nginx/issues/225 -[#230]: https://github.com/miketheman/nginx/issues/230 -[#236]: https://github.com/miketheman/nginx/issues/236 -[#240]: https://github.com/miketheman/nginx/issues/240 -[#243]: https://github.com/miketheman/nginx/issues/243 -[#249]: https://github.com/miketheman/nginx/issues/249 -[#252]: https://github.com/miketheman/nginx/issues/252 -[#254]: https://github.com/miketheman/nginx/issues/254 -[#259]: https://github.com/miketheman/nginx/issues/259 -[#269]: https://github.com/miketheman/nginx/issues/269 -[#279]: https://github.com/miketheman/nginx/issues/279 -[#294]: https://github.com/miketheman/nginx/issues/294 -[#298]: https://github.com/miketheman/nginx/issues/298 -[#302]: https://github.com/miketheman/nginx/issues/302 -[#305]: https://github.com/miketheman/nginx/issues/305 -[#310]: https://github.com/miketheman/nginx/issues/310 -[#312]: https://github.com/miketheman/nginx/issues/312 -[#314]: https://github.com/miketheman/nginx/issues/314 -[#318]: https://github.com/miketheman/nginx/issues/318 -[#321]: https://github.com/miketheman/nginx/issues/321 -[#325]: https://github.com/miketheman/nginx/issues/325 -[#326]: https://github.com/miketheman/nginx/issues/326 -[#327]: https://github.com/miketheman/nginx/issues/327 -[#331]: https://github.com/miketheman/nginx/issues/331 -[#332]: https://github.com/miketheman/nginx/issues/332 -[#335]: https://github.com/miketheman/nginx/issues/335 -[#338]: https://github.com/miketheman/nginx/issues/338 -[@9minutesnooze]: https://github.com/9minutesnooze -[@CanOfSpam3bug324]: https://github.com/CanOfSpam3bug324 -[@Mytho]: https://github.com/Mytho -[@adepue]: https://github.com/adepue -[@auth0]: https://github.com/auth0 -[@bchrobot]: https://github.com/bchrobot -[@bkw]: https://github.com/bkw -[@dwradcliffe]: https://github.com/dwradcliffe -[@evertrue]: https://github.com/evertrue -[@ffuenf]: https://github.com/ffuenf -[@firmhouse]: https://github.com/firmhouse -[@gkra]: https://github.com/gkra -[@gregkare]: https://github.com/gregkare -[@irontoby]: https://github.com/irontoby -[@jalberto]: https://github.com/jalberto -[@jcoleman]: https://github.com/jcoleman -[@jenssegers]: https://github.com/jenssegers -[@josh-padnick]: https://github.com/josh-padnick -[@jujugrrr]: https://github.com/jujugrrr -[@karsten-bruckmann]: https://github.com/karsten-bruckmann -[@larkin]: https://github.com/larkin -[@miketheman]: https://github.com/miketheman -[@monsterstrike]: https://github.com/monsterstrike -[@morr]: https://github.com/morr -[@n1koo]: https://github.com/n1koo -[@nkadel-skyhook]: https://github.com/nkadel-skyhook -[@runningman84]: https://github.com/runningman84 -[@shtouff]: https://github.com/shtouff -[@stevenolen]: https://github.com/stevenolen -[@thomasmeeus]: https://github.com/thomasmeeus -[@thommay]: https://github.com/thommay -[@tvdinner]: https://github.com/tvdinner -[@usertesting]: https://github.com/usertesting -[@whatcould]: https://github.com/whatcould -[@yveslaroche]: https://github.com/yveslaroche diff --git a/cookbooks/nginx/README.md b/cookbooks/nginx/README.md deleted file mode 100644 index 8281bad..0000000 --- a/cookbooks/nginx/README.md +++ /dev/null @@ -1,521 +0,0 @@ -nginx Cookbook -============== -[![Cookbook](http://img.shields.io/cookbook/v/nginx.svg)](https://github.com/miketheman/nginx) -[![Build Status](https://travis-ci.org/miketheman/nginx.svg?branch=master)](https://travis-ci.org/miketheman/nginx) -[![Gitter chat](https://img.shields.io/badge/Gitter-miketheman%2Fnginx-brightgreen.svg)](https://gitter.im/miketheman/nginx) - -Installs nginx from package OR source code and sets up configuration handling similar to Debian's Apache2 scripts. - -# READ THIS FIRST - -After having struggled with the cookbook format and the interfaces being brittle, the maintainers have decided to begin rewriting the core implmenetation of the nginx cookbook from the ground up, to allow for better flexibility, testability and maintianability. - -To this end, we request that you not open new issues for the existing codebase. - -Pull requests for bugs will be merged, any obvious optimizations and clarifications will be merged, and a 2.7.5 release will be shipped, and we will focus on writing the 3.0.0 version. - -Thank you for your help on this front! - --- The Maintainers - ---- - - -Requirements ------------- -### Cookbooks -The following cookbooks are direct dependencies because they're used for common "default" functionality. - -- build-essential (for nginx::source) -- ohai (for nginx::ohai_plugin) - -The following cookbook is not a strict dependency because its use can be controlled by an attribute, so it may not be a common "default." - -- runit (for nginx::source) -- On RHEL family distros, the "yum" cookbook is required for `recipe[yum::epel]`. -- On Ubuntu, when using Nginx.org's stable package, `recipe[apt::default]` is required. - - -### Platforms -The following platforms are supported and tested under test kitchen: - -- Ubuntu 10.04, Ubuntu 12.04 -- CentOS 5.8, 6.3 - -Other Debian and RHEL family distributions are assumed to work. - - -Attributes ----------- -Node attributes for this cookbook are logically separated into different files. Some attributes are set only via a specific recipe. - -### default -Generally used attributes. Some have platform specific values. See `attributes/default.rb`. "The Config" refers to "nginx.conf" the main config file. - -- `node['nginx']['dir']` - Location for Nginx configuration. -- `node['nginx']['conf_template']` - The `source` template to use when creating the `nginx.conf`. -- `node['nginx']['conf_cookbook']` - The cookbook where `node['nginx']['conf_template']` resides. -- `node['nginx']['log_dir']` - Location for Nginx logs. -- `node['nginx']['log_dir_perm']` - Permissions for Nginx logs folder. -- `node['nginx']['user']` - User that Nginx will run as. -- `node['nginx']['group]` - Group for Nginx. -- `node['nginx']['port']` - Port for nginx to listen on. -- `node['nginx']['binary']` - Path to the Nginx binary. -- `node['nginx']['init_style']` - How to run Nginx as a service when - using `nginx::source`. Values can be "runit", "upstart", "init" or - "bluepill". When using runit or bluepill, those recipes will be - included as well and are dependencies of this cookbook. Recipes - are not included for upstart, it is assumed that upstart is built - into the platform you are using (ubuntu or el6). This attribute is - not used in the `nginx` recipe because the package manager's init - script style for the platform is assumed. Upstart is never set as - a default as this represents a change in behavior, if you are running - ubuntu or el6 and want to use upstart, please set this attribute in - a role or similar. -- `node['nginx']['upstart']['foreground']` - Set this to true if you - want upstart to run nginx in the foreground, set to false if you - want upstart to detach and track the process via pid. -- `node['nginx']['upstart']['runlevels']` - String of runlevels in the - format '2345' which determines which runlevels nginx will start at - when entering and stop at when leaving. -- `node['nginx']['upstart']['respawn_limit']` - Respawn limit in upstart - stanza format, count followed by space followed by interval in seconds. -- `node['nginx']['pid']` - Location of the PID file. -- `node['nginx']['keepalive']` - Whether to use `keepalive_timeout`, - any value besides "on" will leave that option out of the config. -- `node['nginx']['keepalive_requests']` - used for config value of - `keepalive_requests`. -- `node['nginx']['keepalive_timeout']` - used for config value of - `keepalive_timeout`. -- `node['nginx']['worker_processes']` - used for config value of - `worker_processes`. -- `node['nginx']['worker_connections']` - used for config value of - `events { worker_connections }` -- `node['nginx']['worker_rlimit_nofile']` - used for config value of - `worker_rlimit_nofile`. Can replace any "ulimit -n" command. The - value depend on your usage (cache or not) but must always be - superior than worker_connections. -- `node['nginx']['multi_accept']` - used for config value of `events { - multi_accept }`. Try to accept() as many connections as possible. - Disable by default. -- `node['nginx']['event']` - used for config value of `events { use - }`. Set the event-model. By default nginx looks for the most - suitable method for your OS. -- `node['nginx']['accept_mutex_delay']` - used for config value of - `accept_mutex_delay` -- `node['nginx']['server_tokens']` - used for config value of - `server_tokens`. -- `node['nginx']['server_names_hash_bucket_size']` - used for config - value of `server_names_hash_bucket_size`. -- `node['nginx']['disable_access_log']` - set to true to disable the - general access log, may be useful on high traffic sites. -- `node['nginx']['access_log_options']` - Set to a string of additional options - to be appended to the access log directive -- `node['nginx']['error_log_options']` - Set to a string of additional options - to be appended to the error log directive -- `node['nginx']['default_site_enabled']` - enable the default site -- `node['nginx']['sendfile']` - Whether to use `sendfile`. Defaults to "on". -- `node['nginx']['tcp_nopush']` - Whether to use `tcp_nopush`. Defaults to "on". -- `node['nginx']['tcp_nodelay']` - Whether to use `tcp_nodelay`. Defaults to "on". -- `node['nginx']['install_method']` - Whether nginx is installed from - packages or from source. -- `node['nginx']['types_hash_max_size']` - Used for the - `types_hash_max_size` configuration directive. -- `node['nginx']['types_hash_bucket_size']` - Used for the - `types_hash_bucket_size` configuration directive. -- `node['nginx']['proxy_read_timeout']` - defines a timeout (between two - successive read operations) for reading a response from the proxied server. -- `node['nginx']['client_body_buffer_size']` - used for config value of - `client_body_buffer_size`. -- `node['nginx']['client_max_body_size']` - specifies the maximum accepted body - size of a client request, as indicated by the request header Content-Length. -- `node['nginx']['repo_source']` - when installed from a package this attribute affects - which yum repositories, if any, will be added before installing the nginx package. The - default value of 'epel' will use the `yum::epel` recipe, 'nginx' will use the - `nginx::repo` recipe, 'passenger' will use the 'nginx::repo_passenger' recipe, and setting no value will not add any additional repositories. -* `node['nginx']['sts_max_age']` - Enable Strict Transport Security for all apps (See: http://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security). This attribute adds the following header: - - Strict-Transport-Security max-age=SECONDS - -to all incoming requests and takes an integer (in seconds) as its argument. -* `node['nginx']['default']['modules']` - Array specifying which -modules to enable via the conf-enabled config include function. -Currently the only valid value is "socketproxy". - -Other configurations - -- `node['nginx']['extra_configs']` - a Hash of key/values to nginx configuration. - -Rate Limiting - -- `node['nginx']['enable_rate_limiting']` - set to true to enable rate - limiting (`limit_req_zone` in nginx.conf) -- `node['nginx']['rate_limiting_zone_name']` - sets the zone in - `limit_req_zone`. -- `node['nginx']['rate_limiting_backoff']` - sets the backoff time for - `limit_req_zone`. -- `node['nginx']['rate_limit']` - set the rate limit amount for - `limit_req_zone`. - -### gzip module - -- `node['nginx']['gzip']` - Whether to use gzip, can be "on" or "off" -- `node['nginx']['gzip_http_version']` - used for config value of `gzip_http_version`. -- `node['nginx']['gzip_comp_level']` - used for config value of `gzip_comp_level`. -- `node['nginx']['gzip_proxied']` - used for config value of `gzip_proxied`. -- `node['nginx']['gzip_vary']` - used for config value of `gzip_vary`. -- `node['nginx']['gzip_buffers']` - used for config value of `gzip_buffers`. -- `node['nginx']['gzip_types']` - used for config value of `gzip_types` - must be an Array. -- `node['nginx']['gzip_min_length']` - used for config value of `gzip_min_length`. -- `node['nginx']['gzip_disable']` - used for config value of `gzip_disable`. -- `node['nginx']['gzip_static']` - used for config value of `gzip_static` (`http_gzip_static_module` must be enabled) -### Attributes set in recipes - -#### nginx::source -- `node['nginx']['daemon_disable']` - Whether the daemon should be - disabled which can be true or false; disable the daemon (run in the - foreground) when using a service supervisor such as runit or - bluepill for "init_style". This is automatically set in the - `nginx::source` recipe when the init style is not bluepill or runit. - -#### nginx::authorized_ips -- `node['nginx']['remote_ip_var']` - The remote ip variable name to - use. -- `node['nginx']['authorized_ips']` - IPs authorized by the module - -#### nginx::http_realip_module -From: http://nginx.org/en/docs/http/ngx_http_realip_module.html - -- `node['nginx']['realip']['header']` - Header to use for the RealIp - Module; only accepts "X-Forwarded-For" or "X-Real-IP" -- `node['nginx']['realip']['addresses']` - Addresses to use for the - `http_realip` configuration. -- `node['nginx']['realip']['real_ip_recursive']` - If recursive search is enabled, the original client address that matches one of the trusted addresses is replaced by the last non-trusted address sent in the request header field. Can be on "on" or "off" (default). - -### source -These attributes are used in the `nginx::source` recipe. Some of them -are dynamically modified during the run. See `attributes/source.rb` -for default values. - -- `node['nginx']['source']['url']` - (versioned) URL for the Nginx - source code. By default this will use the version specified as - `node['nginx']['version']`. -- `node['nginx']['source']['prefix']` - (versioned) prefix for - installing nginx from source -- `node['nginx']['source']['conf_path']` - location of the main config - file, in `node['nginx']['dir']` by default. -- `node['nginx']['source']['modules']` - Array of modules that should - be compiled into Nginx by including their recipes in - `nginx::source`. -- `node['nginx']['source']['default_configure_flags']` - The default - flags passed to the configure script when building Nginx. -- `node['nginx']['configure_flags']` - Preserved for compatibility and - dynamically generated from the - `node['nginx']['source']['default_configure_flags']` in the - `nginx::source` recipe. -* `node['nginx']['source']['use_existing_user']` - set to `true` if you - do not want `nginx::source` recipe to create system user with name - `node['nginx']['user']`. - -### geoip -These attributes are used in the `nginx::http_geoip_module` recipe. -Please note that the `country_dat_checksum` and `city_dat_checksum` -are based on downloads from a datacenter in Fremont, CA, USA. You -really should override these with checksums for the geo tarballs from -your node location. - -**Note** The upstream, maxmind.com, may block access for repeated - downloads of the data files. It is recommended that you download and - host the data files, and change the URLs in the attributes. - -- `node['nginx']['geoip']['path']` - Location where to install the - geoip libraries. -- `node['nginx']['geoip']['enable_city']` - Whether to enable City - data -- `node['nginx']['geoip']['country_dat_url']` - Country data tarball - URL -- `node['nginx']['geoip']['country_dat_checksum']` - Country data - tarball checksum -- `node['nginx']['geoip']['city_dat_url']` - City data tarball URL -- `node['nginx']['geoip']['city_dat_checksum']` - City data tarball - checksum -- `node['nginx']['geoip']['lib_version']` - Version of the GeoIP - library to install -- `node['nginx']['geoip']['lib_url']` - (Versioned) Tarball URL of the - GeoIP library -- `node['nginx']['geoip']['lib_checksum']` - Checksum of the GeoIP - library tarball - -### upload_progress -These attributes are used in the `nginx::upload_progress_module` -recipe. - -- `node['nginx']['upload_progress']['url']` - URL for the tarball. -- `node['nginx']['upload_progress']['checksum']` - Checksum of the - tarball. -- `node['nginx']['upload_progress']['javascript_output']` - Output in javascript. - Default is `true` for backwards compatibility. -- `node['nginx']['upload_progress']['zone_name']` - Zone name which will - be used to store the per-connection tracking information. - Default is `proxied`. -- `node['nginx']['upload_progress']['zone_size']` - Zone size in bytes. - Default is `1m` (1 megabyte). - -### passenger -These attributes are used in the `nginx::passenger` recipe. - -- `node['nginx']['passenger']['version']` - passenger gem version -- `node['nginx']['passenger']['root']` - passenger gem root path -- `node['nginx']['passenger']['install_rake']` - set to false if rake already present on system -- `node['nginx']['passenger']['max_pool_size']` - maximum passenger - pool size (default=10) -- `node['nginx']['passenger']['ruby']` - Ruby path for Passenger to - use (default=`$(which ruby)`) -- `node['nginx']['passenger']['spawn_method']` - passenger spawn - method to use (default=`smart-lv2`) -- `node['nginx']['passenger']['buffer_response']` - turns on or off - response buffering (default=`on`) -- `node['nginx']['passenger']['max_pool_size']` - passenger maximum - pool size (default=`6`) -- `node['nginx']['passenger']['min_instances']` - minimum instances - (default=`1`) -- `node['nginx']['passenger']['max_instances_per_app']` - maximum - instances per app (default=`0`) -- `node['nginx']['passenger']['pool_idle_time']` - passenger pool idle - time (default=`300`) -- `node['nginx']['passenger']['max_requests']` - maximum requests - (default=`0`) -- `node['nginx']['passenger']['nodejs']` - Nodejs path for Passenger to - use (default=nil) - -Basic configuration to use the official Phusion Passenger repositories: -- `node['nginx']['repo_source']` - 'passenger' -- `node['nginx']['package_name']` - 'nginx-extras' -- `node['nginx']['passenger']['install_method']` - 'package' - -### echo -These attributes are used in the `nginx::http_echo_module` recipe. - -- `node['nginx']['echo']['version']` - The version of `http_echo` you - want (default: 0.40) -- `node['nginx']['echo']['url']` - URL for the tarball. -- `node['nginx']['echo']['checksum']` - Checksum of the tarball. - -### status -These attributes are used in the `nginx::http_stub_status_module` recipe. - -- `node['nginx']['status']['port']` - The port on which nginx will - serve the status info (default: 8090) - -### syslog -These attributes are used in the `nginx::syslog_module` recipe. - -- `node['nginx']['syslog']['git_repo']` - The git repository url to use - for the syslog patches. -- `node['nginx']['syslog']['git_revision']` - The revision on the git - repository to checkout. - -### openssl_source -These attributes are used in the `nginx::openssl_source` recipe. - -- `node['nginx']['openssl_source']['version']` - The version of OpenSSL - you want to download and use (default: 1.0.1e) -- `node['nginx']['openssl_source']['url']` - The url for the OpenSSL source - - -## socketproxy.rb - -These attributes are used in the `nginx::socketproxy` recipe. - -* `node['nginx']['socketproxy']['root']` - The directory (on your server) where socketproxy apps are deployed. -* `node['nginx']['socketproxy']['default_app']` - Static assets directory for requests to "/" that don't meet any proxy_pass filter requirements. -* `node['nginx']['socketproxy']['apps']['app_name']['prepend_slash']` - Prepend a slash to requests to app "app_name" before sending them to the socketproxy socket. -* `node['nginx']['socketproxy']['apps']['app_name']['context_name']` - URI (e.g. "app_name" in order to achieve "http://mydomain.com/app_name") at which to host the application "app_name" -* `node['nginx']['socketproxy']['apps']['app_name']['subdir']` - Directory (under `node['nginx']['socketproxy']['root']`) in which to find the application. - -Recipes -------- -This cookbook provides three main recipes for installing Nginx. - -- `default.rb` - *Use this recipe* if you have a native package for - Nginx. -- `repo.rb` - The developer of Nginx also maintain - [stable packages](http://nginx.org/en/download.html) for several - platforms. -- `source.rb` - *Use this recipe* if you do not have a native package for - Nginx, or if you want to install a newer version than is available, - or if you have custom module compilation needs. - -Several recipes are related to the `source` recipe specifically. See -that recipe's section below for a description. - -### default -The default recipe will install Nginx as a native package for the -system through the package manager and sets up the configuration -according to the Debian site enable/disable style with `sites-enabled` -using the `nxensite` and `nxdissite` scripts. The nginx service will -be managed with the normal init scripts that are presumably included -in the native package. - -Includes the `ohai_plugin` recipe so the plugin is available. - -### socketproxy - -This will add socketproxy support to your nginx proxy setup. Do not -include this recipe directly. Instead, add it to the -`node['nginx']['default']['modules']` array (see below). - -### ohai_plugin - -This recipe provides an Ohai plugin as a template. It is included by -both the `default` and `source` recipes. - -### authorized_ips -Sets up configuration for the `authorized_ip` nginx module. - -### source -This recipe is responsible for building Nginx from source. It ensures -that the required packages to build Nginx are installed (pcre, -openssl, compile tools). The source will be downloaded from the -`node['nginx']['source']['url']`. The `node['nginx']['user']` will be -created as a system user. If you want to use existing user set -`node['nginx']['source']['use_existing_user']` to `true`. The appropriate -configuration and log directories and config files will be created -as well according to the attributes `node['nginx']['dir']` and -`node['nginx']['log_dir']`. - -The recipe attempts to detect whether additional modules should be -added to the configure command through recipe inclusion (see below), -and whether the version or configuration flags have changed and should -trigger a recompile. - -The nginx service will be set up according to -`node['nginx']['init_style']`. Available options are: - -- runit: uses runit cookbook and sets up `runit_service`. -- bluepill: uses bluepill cookbook and sets up `bluepill_service`. -- anything else (e.g., "init") will use the nginx init script - template. - -**RHEL/CentOS** This recipe should work on RHEL/CentOS with "init" as - the init style. - -The following recipes are used to build module support into Nginx. To -use a module in the `nginx::source` recipe, add its recipe name to the -attribute `node['nginx']['source']['modules']`. - -- `ipv6.rb` - enables IPv6 support -- `http_echo_module.rb` - downloads the `http_echo_module` module and - enables it as a module when compiling nginx. -- `http_geoip_module.rb` - installs the GeoIP libraries and data files - and enables the module for compilation. -- `http_gzip_static_module.rb` - enables the module for compilation. Be sure to set `node['nginx']['gzip_static'] = 'yes'`. -- `http_perl_module.rb` - enables embedded Perl for compilation. -- `http_realip_module.rb` - enables the module for compilation and - creates the configuration. -- `http_ssl_module.rb` - enables SSL for compilation. -- `http_stub_status_module.rb` - provides `nginx_status` configuration - and enables the module for compilation. -- `naxsi_module` - enables the naxsi module for the web application - firewall for nginx. -- `passenger` - builds the passenger gem and configuration for - "`mod_passenger`". -- `syslog` - enables syslog support for nginx. This only works with - source builds. See https://github.com/yaoweibin/nginx_syslog_patch -- `upload_progress_module.rb` - builds the `upload_progress` module - and enables it as a module when compiling nginx. -- `openssl_source.rb` - downloads and uses custom OpenSSL source - when compiling nginx - -Definitions ------------ - -The cookbook provides a new definition. At some point in the future this definition may be refactored into a lightweight resource and provider as suggested by [foodcritic rule FC015](http://acrmp.github.com/foodcritic/#FC015). - -### nginx\_site - -Enable or disable a Server Block in -`#{node['nginx']['dir']}/sites-available` by calling nxensite or -nxdissite (introduced by this cookbook) to manage the symbolic link in -`#{node['nginx']['dir']}/sites-enabled`. - -The template for the site must be managed as a separate resource. - -### Parameters: - -* `name` - Name of the site. -* `enable` - Default true, which uses `nxensite` to enable the site. If false, the site will be disabled with `nxdissite`. - - -Adding New Modules ------------------- -To add a new module to be compiled into nginx in the source recipe, -the node's run state is manipulated in a recipe, and the module as a -recipe should be added to `node['nginx']['source']['modules']`. For -example: - -```ruby -node.run_state['nginx_configure_flags'] = - node.run_state['nginx_configure_flags'] | ['--with-http_stub_status_module'] -``` - -The recipe will be included by `recipe[nginx::source]` automatically, -adding the configure flags. Add any other configuration templates or -other resources as required. See the recipes described above for -examples. - - -Ohai Plugin ------------ -The `ohai_plugin` recipe includes an Ohai plugin. It will be -automatically installed and activated, providing the following -attributes via ohai, no matter how nginx is installed (source or -package): - -- `node['nginx']['version']` - version of nginx -- `node['nginx']['configure_arguments']` - options passed to - `./configure` when nginx was built -- `node['nginx']['prefix']` - installation prefix -- `node['nginx']['conf_path']` - configuration file path - -In the source recipe, it is used to determine whether control -attributes for building nginx have changed. - - -Usage ------ -Include the recipe on your node or role that fits how you wish to -install Nginx on your system per the recipes section above. Modify the -attributes as required in your role to change how various -configuration is applied per the attributes section above. In general, -override attributes in the role should be used when changing -attributes. - -There's some redundancy in that the config handling hasn't been -separated from the installation method (yet), so use only one of the -recipes, default or source. - - -License & Authors ------------------ -- Author:: Joshua Timberman () -- Author:: Adam Jacob () -- Author:: AJ Christensen () -- Author:: Jamie Winsor () -- Author:: Mike Fiedler () - -```text -Copyright 2008-2014, 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/nginx/attributes/set_misc.rb b/cookbooks/nginx/attributes/set_misc.rb deleted file mode 100644 index 33fb21f..0000000 --- a/cookbooks/nginx/attributes/set_misc.rb +++ /dev/null @@ -1,8 +0,0 @@ -# -# Cookbook Name:: nginx -# Attributes:: set_misc -# - -default['nginx']['set_misc']['version'] = '0.24' -default['nginx']['set_misc']['url'] = "https://github.com/agentzh/set-misc-nginx-module/archive/v#{node['nginx']['set_misc']['version']}.tar.gz" -default['nginx']['set_misc']['checksum'] = 'da404a7dac5fa4a0a86f42b4ec7648b607f4cd66' diff --git a/cookbooks/nginx/definitions/nginx_site.rb b/cookbooks/nginx/definitions/nginx_site.rb deleted file mode 100644 index a0e9e5c..0000000 --- a/cookbooks/nginx/definitions/nginx_site.rb +++ /dev/null @@ -1,50 +0,0 @@ -# -# Cookbook Name:: nginx -# Definition:: nginx_site -# -# Author:: AJ Christensen -# -# Copyright 2008-2013, 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. -# - -define :nginx_site, :enable => true, :timing => :delayed do - if params[:enable] - - if params[:template] - template "#{node['nginx']['dir']}/sites-available/#{params[:name]}" do - source params[:template] - variables(params[:variables]) - end - end - - execute "nxensite #{params[:name]}" do - command "#{node['nginx']['script_dir']}/nxensite #{params[:name]}" - notifies :reload, 'service[nginx]', params[:timing] - not_if do - ::File.symlink?("#{node['nginx']['dir']}/sites-enabled/#{params[:name]}") || - ::File.symlink?("#{node['nginx']['dir']}/sites-enabled/000-#{params[:name]}") - end - end - else - execute "nxdissite #{params[:name]}" do - command "#{node['nginx']['script_dir']}/nxdissite #{params[:name]}" - notifies :reload, 'service[nginx]', params[:timing] - only_if do - ::File.symlink?("#{node['nginx']['dir']}/sites-enabled/#{params[:name]}") || - ::File.symlink?("#{node['nginx']['dir']}/sites-enabled/000-#{params[:name]}") - end - end - end -end diff --git a/cookbooks/nginx/files/default/mime.types b/cookbooks/nginx/files/default/mime.types deleted file mode 100644 index 6437e2d..0000000 --- a/cookbooks/nginx/files/default/mime.types +++ /dev/null @@ -1,78 +0,0 @@ -types { - text/html html htm shtml; - text/css css; - text/xml xml; - image/gif gif; - image/jpeg jpeg jpg; - application/javascript js; - application/json json; - application/atom+xml atom; - application/rss+xml rss; - text/cache.manifest manifest; - text/mathml mml; - text/plain txt; - text/vnd.sun.j2me.app-descriptor jad; - text/vnd.wap.wml wml; - text/x-component htc; - image/png png; - image/tiff tif tiff; - image/vnd.wap.wbmp wbmp; - image/x-icon ico; - image/x-jng jng; - image/x-ms-bmp bmp; - image/svg+xml svg svgz; - image/webp webp; - application/java-archive jar war ear; - application/mac-binhex40 hqx; - application/msword doc; - application/pdf pdf; - application/postscript ps eps ai; - application/rtf rtf; - application/vnd.ms-excel xls; - application/vnd.ms-powerpoint ppt; - application/vnd.wap.wmlc wmlc; - application/vnd.google-earth.kml+xml kml; - application/vnd.google-earth.kmz kmz; - application/x-7z-compressed 7z; - application/x-cocoa cco; - application/x-java-archive-diff jardiff; - application/x-java-jnlp-file jnlp; - application/x-makeself run; - application/x-perl pl pm; - application/x-pilot prc pdb; - application/x-rar-compressed rar; - application/x-redhat-package-manager rpm; - application/x-sea sea; - application/x-shockwave-flash swf; - application/x-stuffit sit; - application/x-tcl tcl tk; - application/x-x509-ca-cert der pem crt; - application/x-xpinstall xpi; - application/xhtml+xml xhtml; - application/zip zip; - application/octet-stream bin exe dll; - application/octet-stream deb; - application/octet-stream dmg; - application/octet-stream iso img; - application/octet-stream msi msp msm; - font/ttf ttf; - font/opentype otf; - application/x-font-woff woff; - application/vnd.ms-fontobject eot; - audio/midi mid midi kar; - audio/mpeg mp3; - audio/ogg ogg; - audio/x-m4a m4a; - audio/x-realaudio ra; - video/3gpp 3gpp 3gp; - video/mp4 mp4; - video/mpeg mpeg mpg; - video/quicktime mov; - video/webm webm; - video/x-flv flv; - video/x-m4v m4v; - video/x-mng mng; - video/x-ms-asf asx asf; - video/x-ms-wmv wmv; - video/x-msvideo avi; -} diff --git a/cookbooks/nginx/libraries/matchers.rb b/cookbooks/nginx/libraries/matchers.rb deleted file mode 100644 index a72f01e..0000000 --- a/cookbooks/nginx/libraries/matchers.rb +++ /dev/null @@ -1,20 +0,0 @@ -if defined?(ChefSpec) - # Custom ChefSpec matchers - module ChefSpec::Matchers - RSpec::Matchers.define :enable_nginx_site do |site| - match do |chef_run| - chef_run.resource_collection.all_resources.any? do |resource| - resource.resource_name == :execute && resource.name =~ /.*nxensite.*#{site}/ - end - end - end - - RSpec::Matchers.define :disable_nginx_site do |site| - match do |chef_run| - chef_run.resource_collection.all_resources.any? do |resource| - resource.resource_name == :execute && resource.name =~ /.*nxdissite.*#{site}/ - end - end - end - end -end diff --git a/cookbooks/nginx/metadata.json b/cookbooks/nginx/metadata.json deleted file mode 100644 index 0daff0e..0000000 --- a/cookbooks/nginx/metadata.json +++ /dev/null @@ -1,351 +0,0 @@ -{ - "name": "nginx", - "description": "Installs and configures nginx", - "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", - "oracle": ">= 0.0.0", - "redhat": ">= 0.0.0", - "scientific": ">= 0.0.0", - "ubuntu": ">= 0.0.0" - }, - "dependencies": { - "apt": "~> 2.2", - "bluepill": "~> 2.3", - "build-essential": "~> 2.0", - "ohai": "~> 2.0", - "runit": "~> 1.2", - "yum-epel": "~> 0.3" - }, - "recommendations": { - - }, - "suggestions": { - - }, - "conflicting": { - - }, - "providing": { - - }, - "replacing": { - - }, - "attributes": { - "nginx/dir": { - "display_name": "Nginx Directory", - "description": "Location of nginx configuration files", - "default": "/etc/nginx", - "choice": [ - - ], - "calculated": false, - "type": "string", - "required": "optional", - "recipes": [ - - ] - }, - "nginx/log_dir": { - "display_name": "Nginx Log Directory", - "description": "Location for nginx logs", - "default": "/var/log/nginx", - "choice": [ - - ], - "calculated": false, - "type": "string", - "required": "optional", - "recipes": [ - - ] - }, - "nginx/user": { - "display_name": "Nginx User", - "description": "User nginx will run as", - "default": "www-data", - "choice": [ - - ], - "calculated": false, - "type": "string", - "required": "optional", - "recipes": [ - - ] - }, - "nginx/binary": { - "display_name": "Nginx Binary", - "description": "Location of the nginx server binary", - "default": "/usr/sbin/nginx", - "choice": [ - - ], - "calculated": false, - "type": "string", - "required": "optional", - "recipes": [ - - ] - }, - "nginx/gzip": { - "display_name": "Nginx Gzip", - "description": "Whether gzip is enabled", - "default": "on", - "choice": [ - - ], - "calculated": false, - "type": "string", - "required": "optional", - "recipes": [ - - ] - }, - "nginx/gzip_http_version": { - "display_name": "Nginx Gzip HTTP Version", - "description": "Version of HTTP Gzip", - "default": "1.0", - "choice": [ - - ], - "calculated": false, - "type": "string", - "required": "optional", - "recipes": [ - - ] - }, - "nginx/gzip_comp_level": { - "display_name": "Nginx Gzip Compression Level", - "description": "Amount of compression to use", - "default": "2", - "choice": [ - - ], - "calculated": false, - "type": "string", - "required": "optional", - "recipes": [ - - ] - }, - "nginx/gzip_proxied": { - "display_name": "Nginx Gzip Proxied", - "description": "Whether gzip is proxied", - "default": "any", - "choice": [ - - ], - "calculated": false, - "type": "string", - "required": "optional", - "recipes": [ - - ] - }, - "nginx/gzip_types": { - "display_name": "Nginx Gzip Types", - "description": "Supported MIME-types for gzip", - "type": "array", - "default": [ - "text/plain", - "text/css", - "application/x-javascript", - "text/xml", - "application/xml", - "application/xml+rss", - "text/javascript", - "application/javascript", - "application/json" - ], - "choice": [ - - ], - "calculated": false, - "required": "optional", - "recipes": [ - - ] - }, - "nginx/keepalive": { - "display_name": "Nginx Keepalive", - "description": "Whether to enable keepalive", - "default": "on", - "choice": [ - - ], - "calculated": false, - "type": "string", - "required": "optional", - "recipes": [ - - ] - }, - "nginx/keepalive_timeout": { - "display_name": "Nginx Keepalive Timeout", - "default": "65", - "choice": [ - - ], - "calculated": false, - "type": "string", - "required": "optional", - "recipes": [ - - ] - }, - "nginx/worker_processes": { - "display_name": "Nginx Worker Processes", - "description": "Number of worker processes", - "default": "1", - "choice": [ - - ], - "calculated": false, - "type": "string", - "required": "optional", - "recipes": [ - - ] - }, - "nginx/worker_connections": { - "display_name": "Nginx Worker Connections", - "description": "Number of connections per worker", - "default": "1024", - "choice": [ - - ], - "calculated": false, - "type": "string", - "required": "optional", - "recipes": [ - - ] - }, - "nginx/server_names_hash_bucket_size": { - "display_name": "Nginx Server Names Hash Bucket Size", - "default": "64", - "choice": [ - - ], - "calculated": false, - "type": "string", - "required": "optional", - "recipes": [ - - ] - }, - "nginx/types_hash_max_size": { - "display_name": "Nginx Types Hash Max Size", - "default": "2048", - "choice": [ - - ], - "calculated": false, - "type": "string", - "required": "optional", - "recipes": [ - - ] - }, - "nginx/types_hash_bucket_size": { - "display_name": "Nginx Types Hash Bucket Size", - "default": "64", - "choice": [ - - ], - "calculated": false, - "type": "string", - "required": "optional", - "recipes": [ - - ] - }, - "nginx/disable_access_log": { - "display_name": "Disable Access Log", - "default": "false", - "choice": [ - - ], - "calculated": false, - "type": "string", - "required": "optional", - "recipes": [ - - ] - }, - "nginx/default_site_enabled": { - "display_name": "Default site enabled", - "default": "true", - "choice": [ - - ], - "calculated": false, - "type": "string", - "required": "optional", - "recipes": [ - - ] - }, - "nginx/sendfile": { - "display_name": "Nginx sendfile", - "description": "Whether to enable sendfile", - "default": "on", - "choice": [ - - ], - "calculated": false, - "type": "string", - "required": "optional", - "recipes": [ - - ] - }, - "nginx/tcp_nopush": { - "display_name": "Nginx tcp_nopush", - "description": "Whether to enable tcp_nopush", - "default": "on", - "choice": [ - - ], - "calculated": false, - "type": "string", - "required": "optional", - "recipes": [ - - ] - }, - "nginx/tcp_nodelay": { - "display_name": "Nginx tcp_nodelay", - "description": "Whether to enable tcp_nodelay", - "default": "on", - "choice": [ - - ], - "calculated": false, - "type": "string", - "required": "optional", - "recipes": [ - - ] - } - }, - "groupings": { - - }, - "recipes": { - "nginx": "Installs nginx package and sets up configuration with Debian apache style with sites-enabled/sites-available", - "nginx::source": "Installs nginx from source and sets up configuration with Debian apache style with sites-enabled/sites-available" - }, - "version": "2.7.6", - "source_url": "", - "issues_url": "" -} diff --git a/cookbooks/nginx/metadata.rb b/cookbooks/nginx/metadata.rb deleted file mode 100644 index 7a66a31..0000000 --- a/cookbooks/nginx/metadata.rb +++ /dev/null @@ -1,125 +0,0 @@ -name 'nginx' -maintainer 'Chef Software, Inc.' -maintainer_email 'cookbooks@chef.io' -license 'Apache 2.0' -description 'Installs and configures nginx' -version '2.7.6' - -recipe 'nginx', 'Installs nginx package and sets up configuration with Debian apache style with sites-enabled/sites-available' -recipe 'nginx::source', 'Installs nginx from source and sets up configuration with Debian apache style with sites-enabled/sites-available' - -depends 'apt', '~> 2.2' -depends 'bluepill', '~> 2.3' -depends 'build-essential', '~> 2.0' -depends 'ohai', '~> 2.0' -depends 'runit', '~> 1.2' -depends 'yum-epel', '~> 0.3' - -supports 'amazon' -supports 'centos' -supports 'debian' -supports 'fedora' -supports 'oracle' -supports 'redhat' -supports 'scientific' -supports 'ubuntu' - -attribute 'nginx/dir', - :display_name => 'Nginx Directory', - :description => 'Location of nginx configuration files', - :default => '/etc/nginx' - -attribute 'nginx/log_dir', - :display_name => 'Nginx Log Directory', - :description => 'Location for nginx logs', - :default => '/var/log/nginx' - -attribute 'nginx/user', - :display_name => 'Nginx User', - :description => 'User nginx will run as', - :default => 'www-data' - -attribute 'nginx/binary', - :display_name => 'Nginx Binary', - :description => 'Location of the nginx server binary', - :default => '/usr/sbin/nginx' - -attribute 'nginx/gzip', - :display_name => 'Nginx Gzip', - :description => 'Whether gzip is enabled', - :default => 'on' - -attribute 'nginx/gzip_http_version', - :display_name => 'Nginx Gzip HTTP Version', - :description => 'Version of HTTP Gzip', - :default => '1.0' - -attribute 'nginx/gzip_comp_level', - :display_name => 'Nginx Gzip Compression Level', - :description => 'Amount of compression to use', - :default => '2' - -attribute 'nginx/gzip_proxied', - :display_name => 'Nginx Gzip Proxied', - :description => 'Whether gzip is proxied', - :default => 'any' - -attribute 'nginx/gzip_types', - :display_name => 'Nginx Gzip Types', - :description => 'Supported MIME-types for gzip', - :type => 'array', - :default => ['text/plain', 'text/css', 'application/x-javascript', 'text/xml', 'application/xml', 'application/xml+rss', 'text/javascript', 'application/javascript', 'application/json'] - -attribute 'nginx/keepalive', - :display_name => 'Nginx Keepalive', - :description => 'Whether to enable keepalive', - :default => 'on' - -attribute 'nginx/keepalive_timeout', - :display_name => 'Nginx Keepalive Timeout', - :default => '65' - -attribute 'nginx/worker_processes', - :display_name => 'Nginx Worker Processes', - :description => 'Number of worker processes', - :default => '1' - -attribute 'nginx/worker_connections', - :display_name => 'Nginx Worker Connections', - :description => 'Number of connections per worker', - :default => '1024' - -attribute 'nginx/server_names_hash_bucket_size', - :display_name => 'Nginx Server Names Hash Bucket Size', - :default => '64' - -attribute 'nginx/types_hash_max_size', - :display_name => 'Nginx Types Hash Max Size', - :default => '2048' - -attribute 'nginx/types_hash_bucket_size', - :display_name => 'Nginx Types Hash Bucket Size', - :default => '64' - -attribute 'nginx/disable_access_log', - :display_name => 'Disable Access Log', - :default => 'false' - -attribute 'nginx/default_site_enabled', - :display_name => 'Default site enabled', - :default => 'true' - -attribute 'nginx/sendfile', - :display_name => 'Nginx sendfile', - :description => 'Whether to enable sendfile', - :default => 'on' - -attribute 'nginx/tcp_nopush', - :display_name => 'Nginx tcp_nopush', - :description => 'Whether to enable tcp_nopush', - :default => 'on' - -attribute 'nginx/tcp_nodelay', - :display_name => 'Nginx tcp_nodelay', - :description => 'Whether to enable tcp_nodelay', - :default => 'on' diff --git a/cookbooks/nginx/recipes/package.rb b/cookbooks/nginx/recipes/package.rb deleted file mode 100644 index eddc8c1..0000000 --- a/cookbooks/nginx/recipes/package.rb +++ /dev/null @@ -1,52 +0,0 @@ -# -# Cookbook Name:: nginx -# Recipe:: package -# Author:: AJ Christensen -# -# Copyright 2008-2013, 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. -# - -include_recipe 'nginx::ohai_plugin' - -if platform_family?('rhel') - if node['nginx']['repo_source'] == 'epel' - include_recipe 'yum-epel' - elsif node['nginx']['repo_source'] == 'nginx' - include_recipe 'nginx::repo' - package_install_opts = '--disablerepo=* --enablerepo=nginx' - elsif node['nginx']['repo_source'].to_s.empty? - log "node['nginx']['repo_source'] was not set, no additional yum repositories will be installed." do - level :debug - end - else - fail ArgumentError, "Unknown value '#{node['nginx']['repo_source']}' was passed to the nginx cookbook." - end -elsif platform_family?('debian') - include_recipe 'nginx::repo_passenger' if node['nginx']['repo_source'] == 'passenger' - include_recipe 'nginx::repo' if node['nginx']['repo_source'] == 'nginx' -end - -package node['nginx']['package_name'] do - options package_install_opts - notifies :reload, 'ohai[reload_nginx]', :immediately - not_if 'which nginx' -end - -service 'nginx' do - supports :status => true, :restart => true, :reload => true - action :enable -end - -include_recipe 'nginx::commons' diff --git a/cookbooks/nginx/templates/default/nginx.pill.erb b/cookbooks/nginx/templates/default/nginx.pill.erb deleted file mode 100644 index ed90493..0000000 --- a/cookbooks/nginx/templates/default/nginx.pill.erb +++ /dev/null @@ -1,15 +0,0 @@ -Bluepill.application("nginx", :log_file => "<%= node['nginx']['log_dir'] %>/bluepill-nginx.log") do |app| - app.process("nginx") do |process| - process.pid_file = "<%= node['nginx']['pid'] %>" - process.working_dir = "<%= node['nginx']['source']['prefix'] %>" - process.start_command = "<%= node['nginx']['binary'] %> -c <%= node['nginx']['dir'] %>/nginx.conf" - process.stop_command = "kill -QUIT {{PID}}" - process.restart_command = "kill -HUP {{PID}}" - process.daemonize = true - process.stdout = process.stderr = "<%= node['nginx']['log_dir'] %>/nginx.log" - - process.monitor_children do |child_process| - child_process.stop_command = "kill -QUIT {{PID}}" - end - end -end diff --git a/cookbooks/nginx/templates/default/plugins/nginx.rb.erb b/cookbooks/nginx/templates/default/plugins/nginx.rb.erb deleted file mode 100644 index 4e2d4f7..0000000 --- a/cookbooks/nginx/templates/default/plugins/nginx.rb.erb +++ /dev/null @@ -1,66 +0,0 @@ -# -# Author:: Jamie Winsor () -# -# Copyright 2012, Riot Games -# -# 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 "nginx" -provides "nginx/version" -provides "nginx/configure_arguments" -provides "nginx/prefix" -provides "nginx/conf_path" - -def parse_flags(flags) - prefix = nil - conf_path = nil - - flags.each do |flag| - case flag - when /^--prefix=(.+)$/ - prefix = $1 - when /^--conf-path=(.+)$/ - conf_path = $1 - end - end - - [ prefix, conf_path ] -end - -nginx Mash.new unless nginx -nginx[:version] = nil unless nginx[:version] -nginx[:configure_arguments] = Array.new unless nginx[:configure_arguments] -nginx[:prefix] = nil unless nginx[:prefix] -nginx[:conf_path] = nil unless nginx[:conf_path] - -status, stdout, stderr = run_command(:no_status_check => true, :command => "<%= node['nginx']['binary'] %> -V") - -if status == 0 - stderr.split("\n").each do |line| - case line - when /^configure arguments:(.+)/ - # This could be better: I'm splitting on configure arguments which removes them and also - # adds a blank string at index 0 of the array. This is why we drop index 0 and map to - # add the '--' prefix back to the configure argument. - nginx[:configure_arguments] = $1.split(/\s--/).drop(1).map { |ca| "--#{ca}" } - - prefix, conf_path = parse_flags(nginx[:configure_arguments]) - - nginx[:prefix] = prefix - nginx[:conf_path] = conf_path - when /^nginx version: nginx\/(\d+\.\d+\.\d+)/ - nginx[:version] = $1 - end - end -end diff --git a/cookbooks/nginx/templates/gentoo/nginx.init.erb b/cookbooks/nginx/templates/gentoo/nginx.init.erb deleted file mode 100644 index 57a6c31..0000000 --- a/cookbooks/nginx/templates/gentoo/nginx.init.erb +++ /dev/null @@ -1,87 +0,0 @@ -#!/sbin/runscript -# Copyright 1999-2012 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/www-servers/nginx/files/nginx.initd,v 1.1 2012/02/11 10:17:30 hollow Exp $ - -extra_commands="configtest" -extra_started_commands="upgrade reload" - -description="Robust, small and high performance http and reverse proxy server" -description_configtest="Run nginx' internal config check." -description_upgrade="Upgrade the nginx binary without losing connections." -description_reload="Reload the nginx configuration without losing connections." - -nginx_config=<%= node['nginx']['source']['conf_path'] %> - -command=<%= node['nginx']['binary'] %> -command_args="-c ${nginx_config}" -pidfile=<%= node['nginx']['pid'] %> - -depend() { - need net - use dns logger netmount -} - -start_pre() { - if [ "${RC_CMD}" != "restart" ]; then - configtest || return 1 - fi -} - -stop_pre() { - if [ "${RC_CMD}" = "restart" ]; then - configtest || return 1 - fi -} - -stop_post() { - rm -f ${pidfile} -} - -reload() { - configtest || return 1 - ebegin "Refreshing nginx' configuration" - kill -HUP `cat ${pidfile}` &>/dev/null - eend $? "Failed to reload nginx" -} - -upgrade() { - configtest || return 1 - ebegin "Upgrading nginx" - - einfo "Sending USR2 to old binary" - kill -USR2 `cat ${pidfile}` &>/dev/null - - einfo "Sleeping 3 seconds before pid-files checking" - sleep 3 - - if [ ! -f ${pidfile}.oldbin ]; then - eerror "File with old pid not found" - return 1 - fi - - if [ ! -f ${pidfile} ]; then - eerror "New binary failed to start" - return 1 - fi - - einfo "Sleeping 3 seconds before WINCH" - sleep 3 ; kill -WINCH `cat ${pidfile}.oldbin` - - einfo "Sending QUIT to old binary" - kill -QUIT `cat ${pidfile}.oldbin` - - einfo "Upgrade completed" - eend $? "Upgrade failed" -} - -configtest() { - ebegin "Checking nginx' configuration" - ${command} -c ${nginx_config} -t -q - - if [ $? -ne 0 ]; then - ${command} -c ${nginx_config} -t - fi - - eend $? "failed, please correct errors above" -} diff --git a/cookbooks/nginx/templates/suse/nginx.init.erb b/cookbooks/nginx/templates/suse/nginx.init.erb deleted file mode 100644 index e3e6ec9..0000000 --- a/cookbooks/nginx/templates/suse/nginx.init.erb +++ /dev/null @@ -1,115 +0,0 @@ -#!/bin/sh -# -# nginx -# -### BEGIN INIT INFO -# Provides: nginx -# Required-Start: $local_fs $remote_fs $network $syslog -# Required-Stop: $local_fs $remote_fs $network $syslog -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: starts the nginx web server -# Description: starts nginx using start-stop-daemon -### END INIT INFO - -# Source function library. -. /etc/rc.status - -rc_reset - -# Check that networking is up. -[ "$NETWORKING" = "no" ] && exit -exec=<%= node['nginx']['binary'] %> -prog=$(basename $exec) - -# default options, overruled by items in sysconfig -NGINX_GLOBAL="" - -[ -e /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx - -lockfile=/var/lock/subsys/nginx - -start() { - [ -x $exec ] || exit 5 - echo -n $"Starting $prog: " - # if not running, start it up here, usually something like "daemon $exec" - options="" - if [ "${NGINX_GLOBAL}" != "" ]; then - options="-g ${NGINX_GLOBAL}" - fi - $exec $options - retval=$? - echo - [ $retval -eq 0 ] && touch $lockfile - rc_status -v -} - -stop() { - echo -n $"Stopping $prog: " - $exec -s stop - retval=$? - echo - [ $retval -eq 0 ] && rm -f $lockfile - rc_status -v -} - -restart() { - stop - start - rc_status -} - -reload() { - echo -n $"Reloading $prog: " - $exec -s reload - retval=$? - echo - [ $retval -eq 0 ] && rm -f $lockfile - rc_status -v -} - -configtest() { - if [ "$#" -ne 0 ] ; then - case "$1" in - -q) - FLAG=$1 - ;; - *) - ;; - esac - shift - fi - ${exec} -t $FLAG - RETVAL=$? - return $RETVAL -} - -# See how we were called. -case "$1" in - start) - start - ;; - stop) - stop - ;; - status) - status nginx - ;; - restart) - restart - ;; - reload|force-reload) - reload - ;; - condrestart) - [ -f $lockfile ] && restart || : - ;; - configtest) - configtest - ;; - *) - echo $"Usage: $0 {start|stop|status|restart|reload|force-reload|condrestart|configtest}" - exit 1 -esac - -exit $? diff --git a/cookbooks/ohai/.foodcritic b/cookbooks/ohai/.foodcritic new file mode 100644 index 0000000..0480ab5 --- /dev/null +++ b/cookbooks/ohai/.foodcritic @@ -0,0 +1,2 @@ +~FC016 +~FC009 diff --git a/cookbooks/ohai/CHANGELOG.md b/cookbooks/ohai/CHANGELOG.md index d4d23ac..d79cc1a 100644 --- a/cookbooks/ohai/CHANGELOG.md +++ b/cookbooks/ohai/CHANGELOG.md @@ -1,7 +1,89 @@ # ohai Cookbook CHANGELOG + This file is used to list changes made in each version of the ohai cookbook. +## 5.0.4 (2017-04-25) + +- Fix lack of .rb extension when deleting plugins. + +## 5.0.3 (2017-04-06) + +- Use class_eval again in the custom resource to provide Chef 12.5/12.6 compatibility +- Remove kind_of and use name_property not name_attribute +- Fix failures on Chef 13 + +## 5.0.2 (2017-03-24) + +- Remove class_eval + +## 5.0.1 (2017-03-14) + +- Test with Delivery Local Mode +- Bump the dependency to 12.7+ due to failures on 12.5-12.6 + +## 5.0.0 (2017-02-23) + +- Require Chef 12.5+ and remove compat_resource dependency + +## 4.2.3 (2016-12-02) +- Prevent chef_version metadata from failing runs in Opsworks +- Better explain how to resolve the plugin_path issue +- Add suse as a supported platform +- Require at least compat_resource 12.14.7 + +## 4.2.2 (2016-09-19) +- Ignore case in plugin path check on Windows + +## 4.2.1 (2016-09-08) +- Fix typo in compile warning text +- Depend on the latest compat_resource (12.14) +- Remove Chef 11 compat in the metadata +- Require Chef 12.1 not 12.0 +- Define ohai_plugin matcher for Chefspec + +## v4.2.0 (2016-07-19) + +- Added the ability to specify the source cookbook for the cookbook_file or template used in the ohai_plugin resource. +- Added chef_version to the metadata +- Added testing on openSUSE and switched from Rubocop to Cookstyle + +## v4.1.1 (2016-06-16) + +- Fixed error in notifies reload for the delete action +- Bump the compat_resource requirement from 12.9+ to 12.10+ to prevent random failures + +## v4.1.0 (2016-05-26) + +- Added the ability to use templates and pass in variables with the plugin custom resource + +## v4.0.2 (2016-05-23) + +- Resolve failures on Windows nodes + +## v4.0.1 (2016-05-19) + +- Added .rb to the name of the plugins so they actually load +- Added testing to ensure the plugins are being loaded in the chef run + +## v4.0.0 (2016-05-18) + +### BREAKING CHANGE: + +The 4.0 release of the Ohai cookbook removes the previous cookbook_file behavior that required forking the cookbook and adding your own plugins. Instead the cookbook ships with a new ohai_plugin custom resource for installing plugins. In addition to this new custom resource the cookbook now requires Chef 12+. See the readme and test recipe for examples. If you require Chef 11 support you'll need to pin to version 3.0 in your environment. + +## v3.0.1 (2016-03-14) + +- Fixed the Chefspec matchers + +## v3.0.0 (2016-03-14) + +- Change the default value for `node['ohai']['hints_path']` to use the Ohai config value. This should be the same value in most use cases, but if a custom path is specified in the chef client config this value will get used automatically by the cookbook. +- Removed backwards compatibility with Chefspec < 4.1 in the matchers library +- Fix bad link to the custom Ohai plugin documentation in the readme +- Improve documentation for `node['ohai']['plugin_path']` + ## v2.1.0 (2016-01-26) + - Properly handle creating ohai hints without specifying the content. Previously if the content wasn't specified a deprecation notice would be thrown and the file would not be created - Simplified the test suite and added inspec tests to ensure hints are created, especially if the content is not specified - Added FreeBSD and Windows as supported platform in the metadata and add them to the Test Kitchen config @@ -9,9 +91,11 @@ This file is used to list changes made in each version of the ohai cookbook. - Updated testing Gems to the latest releases in the Gemfile ## v2.0.4 (2015-10-30) + - Resolved deprecation warnings with the Chefspec matchers ## v2.0.3 (2015-10-21) + - Validate the hints before loading them to avoid failures - Added supported platforms to the metadata - Updated .gitignore file @@ -32,36 +116,47 @@ This file is used to list changes made in each version of the ohai cookbook. - Added basic convergence Chefspec test ## v2.0.1 (2014-06-07) + - [COOK-4683] Remove warnings about reopening resource Please note, this changes the name of a remote_directory resource. It is not expected that anyone would be explicitly notifying this resource but, please review [PR #16](https://github.com/chef-cookbooks/ohai/pull/16/files) for more info. ## v2.0.0 (2014-02-25) + '[COOK-3865] - create lwrp ohai_hint' ## v1.1.12 + - Dummy release due to a Community Site upload failure ## v1.1.10 + ### Bug + - **[COOK-3091](https://tickets.chef.io/browse/COOK-3091)** - Fix checking `Chef::Config[:config_file]` ## v1.1.8 + - [COOK-1918] - Ohai cookbook to distribute plugins fails on windows - [COOK-2096] - Ohai cookbook sets unix-only default path attribute ## v1.1.6 + - [COOK-2057] - distribution from another cookbok fails if ohai attributes are loaded after the other cookbook ## v1.1.4 + - [COOK-1128] - readme update, Replace reference to deprecated chef cookbook with one to chef-client ## v1.1.2 + - [COOK-1424] - prevent plugin_path growth to infinity ## v1.1.0 + - [COOK-1174] - custom_plugins is only conditionally available - [COOK-1383] - allow plugins from other cookbooks ## v1.0.2 + - [COOK-463] ohai cookbook default recipe should only reload plugins if there were updates diff --git a/cookbooks/ohai/MAINTAINERS.md b/cookbooks/ohai/MAINTAINERS.md index c6a51ae..645ed14 100644 --- a/cookbooks/ohai/MAINTAINERS.md +++ b/cookbooks/ohai/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/ohai/README.md b/cookbooks/ohai/README.md index eca46f7..fdb7180 100644 --- a/cookbooks/ohai/README.md +++ b/cookbooks/ohai/README.md @@ -1,59 +1,120 @@ # ohai Cookbook -[![Build Status](https://travis-ci.org/chef-cookbooks/ohai.svg?branch=master)](https://travis-ci.org/chef-cookbooks/ohai) [![Cookbook Version](https://img.shields.io/cookbook/v/ohai.svg)](https://supermarket.chef.io/cookbooks/ohai) -Creates a configured plugin path for distributing custom Ohai plugins, and reloads them via Ohai within the context of a Chef Client run during the compile phase (if needed). +[![Build Status](https://travis-ci.org/chef-cookbooks/ohai.svg?branch=master)](https://travis-ci.org/chef-cookbooks/ohai) [![Build status](https://ci.appveyor.com/api/projects/status/lgok2kr6l007s8hf/branch/master?svg=true)](https://ci.appveyor.com/project/ChefWindowsCookbooks/ohai/branch/master) [![Cookbook Version](https://img.shields.io/cookbook/v/ohai.svg)](https://supermarket.chef.io/cookbooks/ohai) + +Contains custom resources for adding Ohai hints and installing custom Ohai plugins. Handles path creation as well as the reloading of Ohai so that new data will be available during the same run. ## Requirements + ### Platforms + - Debian/Ubuntu - RHEL/CentOS/Scientific/Amazon/Oracle +- openSUSE / SUSE Enterprise Linux - FreeBSD - Windows ### Chef -- Chef 11+ + +- Chef 12.5+ ### Cookbooks + - none -## Attributes -- `node['ohai']['plugin_path']` - location to drop off plugins directory, default is `/etc/chef/ohai_plugins`. This is not FHS-compliant, an FHS location would be something like `/var/lib/ohai/plugins`, or `/var/lib/chef/ohai_plugins` or similar. +## Custom Resources - Neither an FHS location or the default value of this attribute are in the default Ohai plugin path. Set the Ohai plugin path with the config setting "`Ohai::Config[:plugin_path]`" in the Chef config file (the `chef-client::config` recipe does this automatically for you!). The attribute is not set to the default plugin path that Ohai ships with because we don't want to risk destroying existing essential plugins for Ohai. - -- `node['ohai']['plugins']` - sources of plugins, defaults to the `files/default/plugins` directory of this cookbook. You can add additional cookbooks by adding the name of the cookbook as a key and the path of the files directory as the value. You have to make sure that you don't have any file conflicts between multiple cookbooks. The last one to write wins. -- `node['ohai']['hints_path']` - location to drop off hints directory, default is `/etc/chef/ohai/hints`. - -## Usage -Put the recipe `ohai` at the start of the node's run list to make sure that custom plugins are loaded early on in the Chef run and data is available for later recipes. - -The execution of the custom plugins occurs within the recipe during the compile phase, so you can write new plugins and use the data they return in your Chef recipes. - -For information on how to write custom plugins for Ohai, please see the Chef wiki pages. - -[http://wiki.chef.io/display/chef/Writing+Ohai+Plugins](http://wiki.chef.io/display/chef/Writing+Ohai+Plugins) - -_PLEASE NOTE_ - This recipe reloads the Ohai plugins a 2nd time during the Chef run if: -- The "`Ohai::Config[:plugin_path]`" config setting has _NOT_ been properly set in the Chef config file -- The "`Ohai::Config[:plugin_path]`" config setting has been properly set in the Chef config file and there are updated plugins dropped off at "`node['ohai']['plugin_path']`". - -## LWRP ### `ohai_hint` -Create hints file. You can find usage examples at `test/cookbooks/ohai_test/recipes/*.rb`. + +Creates Ohai hint files, which are consumed by Ohai plugins in order to determine if they should run or not. #### Resource Attributes + - `hint_name` - The name of hints file and key. Should be string, default is name of resource. -- `content` - Values of hints. It will be used as automatic attributes. Should be Hash, default is empty Hash class. +- `content` - Values of hints. It will be used as automatic attributes. Should be Hash, default is empty Hash +- `compile_time` - Should the resource run at compile time. This defaults to true + +#### Examples + +Hint file installed to the default directory: + +```ruby +ohai_hint 'ec2' +``` + +Hint file not installed at compile time: + +```ruby +ohai_hint 'ec2' do + compile_time false +end +``` + +Hint file installed with content: + +```ruby +ohai_hint 'raid_present' do + content Hash[:a, 'test_content'] +end +``` #### ChefSpec Matchers + You can check for the creation or deletion of ohai hints with chefspec using these custom matches: + - create_ohai_hint - delete_ohai_hint -## Example -For an example implementation, inspect the ohai_plugin.rb recipe in the nginx community cookbook. +### `ohai_plugin` + +Installs custom Ohai plugins. + +#### Resource Attributes + +- `plugin_name` - The name to give the plugin on the filesystem. Should be string, default is name of resource. +- `path` - The path to your custom plugin directory. Defaults to a directory named 'plugins' under the directory 'ohai' in the Chef config dir. +- `source_file` - The source file for the plugin in your cookbook if not NAME.rb. +- `cookbook` - The cookbook where the source file exists if not the cookbook where the ohai_plugin resource is running from. +- `resource` - The resource type for the plugin file. Either `:cookbook_file` or `:template`. Defaults to `:cookbook_file`. +- `variables` - Usable only if `resource` is `:template`. Defines the template's variables. +- `compile_time` - Should the resource run at compile time. This defaults to `true`. + +#### examples + +Simple Ohai plugin installation: + +```ruby +ohai_plugin 'my_custom_plugin' +``` + +Installation where the resource doesn't match the filename and you install to a custom plugins dir: + +```ruby +ohai_plugin 'My Ohai Plugin' do + name 'my_custom_plugin' + path '/my/custom/path/' +end +``` + +Installation using a template: + +```ruby +ohai_plugin 'My Templated Plugin' do + name 'templated_plugin' + resource :template + variables node_type: :web_server +end +``` + +#### ChefSpec Matchers + +You can check for the creation or deletion of ohai plugins with chefspec using these custom matches: + +- create_ohai_plugin +- delete_ohai_plugin ## License & Authors + **Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io)) **Copyright:** 2011-2016, Chef Software, Inc. diff --git a/cookbooks/ohai/attributes/default.rb b/cookbooks/ohai/attributes/default.rb deleted file mode 100644 index 6880a48..0000000 --- a/cookbooks/ohai/attributes/default.rb +++ /dev/null @@ -1,31 +0,0 @@ -# -# Cookbook Name:: ohai -# Attribute:: default -# -# 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. -# - -# FHS location would be /var/lib/chef/ohai_plugins or similar. -case node['platform_family'] -when 'windows' - default['ohai']['plugin_path'] = "#{ENV['systemdrive']}/chef/ohai_plugins" - default['ohai']['hints_path'] = "#{ENV['systemdrive']}/chef/ohai/hints" -else - default['ohai']['plugin_path'] = '/etc/chef/ohai_plugins' - default['ohai']['hints_path'] = '/etc/chef/ohai/hints' -end - -# The list of plugins and their respective file locations -default['ohai']['plugins']['ohai'] = 'plugins' diff --git a/cookbooks/ohai/files/default/plugins/README b/cookbooks/ohai/files/default/plugins/README deleted file mode 100644 index 72f12e3..0000000 --- a/cookbooks/ohai/files/default/plugins/README +++ /dev/null @@ -1 +0,0 @@ -This directory contains custom plugins for Ohai. diff --git a/cookbooks/ohai/libraries/matchers.rb b/cookbooks/ohai/libraries/matchers.rb index 6f06502..a888dd5 100644 --- a/cookbooks/ohai/libraries/matchers.rb +++ b/cookbooks/ohai/libraries/matchers.rb @@ -1,14 +1,27 @@ -# encoding: utf-8 +# +# Cookbook:: ohai +# Library:: matchers +# +# Author:: Tim Smith () +# +# Copyright:: 2016-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. +# 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 defined?(ChefSpec) - if ChefSpec.respond_to?(:define_matcher) - # ChefSpec >= 4.1 - ChefSpec.define_matcher(:ohai_hint) - elsif defined?(ChefSpec::Runner) && - ChefSpec::Runner.respond_to?(:define_runner_method) - # ChefSpec < 4.1 - ChefSpec::Runner.define_runner_method(:ohai_hint) - end + ChefSpec.define_matcher :ohai_hint + ChefSpec.define_matcher :ohai_plugin def create_ohai_hint(resource) ChefSpec::Matchers::ResourceMatcher.new(:ohai_hint, :create, resource) @@ -18,4 +31,11 @@ if defined?(ChefSpec) ChefSpec::Matchers::ResourceMatcher.new(:ohai_hint, :delete, resource) end + def create_ohai_plugin(resource) + ChefSpec::Matchers::ResourceMatcher.new(:ohai_plugin, :create, resource) + end + + def delete_ohai_plugin(resource) + ChefSpec::Matchers::ResourceMatcher.new(:ohai_plugin, :delete, resource) + end end diff --git a/cookbooks/ohai/metadata.json b/cookbooks/ohai/metadata.json index e9fb4ef..e457c14 100644 --- a/cookbooks/ohai/metadata.json +++ b/cookbooks/ohai/metadata.json @@ -1 +1 @@ -{"name":"ohai","version":"2.1.0","description":"Distributes a directory of custom ohai plugins","long_description":"# ohai Cookbook\n[![Build Status](https://travis-ci.org/chef-cookbooks/ohai.svg?branch=master)](https://travis-ci.org/chef-cookbooks/ohai) [![Cookbook Version](https://img.shields.io/cookbook/v/ohai.svg)](https://supermarket.chef.io/cookbooks/ohai)\n\nCreates a configured plugin path for distributing custom Ohai plugins, and reloads them via Ohai within the context of a Chef Client run during the compile phase (if needed).\n\n## Requirements\n### Platforms\n- Debian/Ubuntu\n- RHEL/CentOS/Scientific/Amazon/Oracle\n- FreeBSD\n- Windows\n\n### Chef\n- Chef 11+\n\n### Cookbooks\n- none\n\n## Attributes\n- `node['ohai']['plugin_path']` - location to drop off plugins directory, default is `/etc/chef/ohai_plugins`. This is not FHS-compliant, an FHS location would be something like `/var/lib/ohai/plugins`, or `/var/lib/chef/ohai_plugins` or similar.\n\n Neither an FHS location or the default value of this attribute are in the default Ohai plugin path. Set the Ohai plugin path with the config setting \"`Ohai::Config[:plugin_path]`\" in the Chef config file (the `chef-client::config` recipe does this automatically for you!). The attribute is not set to the default plugin path that Ohai ships with because we don't want to risk destroying existing essential plugins for Ohai.\n\n- `node['ohai']['plugins']` - sources of plugins, defaults to the `files/default/plugins` directory of this cookbook. You can add additional cookbooks by adding the name of the cookbook as a key and the path of the files directory as the value. You have to make sure that you don't have any file conflicts between multiple cookbooks. The last one to write wins.\n- `node['ohai']['hints_path']` - location to drop off hints directory, default is `/etc/chef/ohai/hints`.\n\n## Usage\nPut the recipe `ohai` at the start of the node's run list to make sure that custom plugins are loaded early on in the Chef run and data is available for later recipes.\n\nThe execution of the custom plugins occurs within the recipe during the compile phase, so you can write new plugins and use the data they return in your Chef recipes.\n\nFor information on how to write custom plugins for Ohai, please see the Chef wiki pages.\n\n[http://wiki.chef.io/display/chef/Writing+Ohai+Plugins](http://wiki.chef.io/display/chef/Writing+Ohai+Plugins)\n\n_PLEASE NOTE_ - This recipe reloads the Ohai plugins a 2nd time during the Chef run if:\n- The \"`Ohai::Config[:plugin_path]`\" config setting has _NOT_ been properly set in the Chef config file\n- The \"`Ohai::Config[:plugin_path]`\" config setting has been properly set in the Chef config file and there are updated plugins dropped off at \"`node['ohai']['plugin_path']`\".\n\n## LWRP\n### `ohai_hint`\nCreate hints file. You can find usage examples at `test/cookbooks/ohai_test/recipes/*.rb`.\n\n#### Resource Attributes\n- `hint_name` - The name of hints file and key. Should be string, default is name of resource.\n- `content` - Values of hints. It will be used as automatic attributes. Should be Hash, default is empty Hash class.\n\n#### ChefSpec Matchers\nYou can check for the creation or deletion of ohai hints with chefspec using these custom matches:\n- create_ohai_hint\n- delete_ohai_hint\n\n## Example\nFor an example implementation, inspect the ohai_plugin.rb recipe in the nginx community cookbook.\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":{"ubuntu":">= 0.0.0","debian":">= 0.0.0","centos":">= 0.0.0","redhat":">= 0.0.0","amazon":">= 0.0.0","scientific":">= 0.0.0","fedora":">= 0.0.0","oracle":">= 0.0.0","freebsd":">= 0.0.0","windows":">= 0.0.0"},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{"ohai::default":"Distributes a directory of custom ohai plugins"}} \ No newline at end of file +{"name":"ohai","version":"5.0.4","description":"Provides custom resources for installing Ohai hints and plugins","long_description":"# ohai Cookbook\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/ohai.svg?branch=master)](https://travis-ci.org/chef-cookbooks/ohai) [![Build status](https://ci.appveyor.com/api/projects/status/lgok2kr6l007s8hf/branch/master?svg=true)](https://ci.appveyor.com/project/ChefWindowsCookbooks/ohai/branch/master) [![Cookbook Version](https://img.shields.io/cookbook/v/ohai.svg)](https://supermarket.chef.io/cookbooks/ohai)\n\nContains custom resources for adding Ohai hints and installing custom Ohai plugins. Handles path creation as well as the reloading of Ohai so that new data will be available during the same run.\n\n## Requirements\n\n### Platforms\n\n- Debian/Ubuntu\n- RHEL/CentOS/Scientific/Amazon/Oracle\n- openSUSE / SUSE Enterprise Linux\n- FreeBSD\n- Windows\n\n### Chef\n\n- Chef 12.5+\n\n### Cookbooks\n\n- none\n\n## Custom Resources\n\n### `ohai_hint`\n\nCreates Ohai hint files, which are consumed by Ohai plugins in order to determine if they should run or not.\n\n#### Resource Attributes\n\n- `hint_name` - The name of hints file and key. Should be string, default is name of resource.\n- `content` - Values of hints. It will be used as automatic attributes. Should be Hash, default is empty Hash\n- `compile_time` - Should the resource run at compile time. This defaults to true\n\n#### Examples\n\nHint file installed to the default directory:\n\n```ruby\nohai_hint 'ec2'\n```\n\nHint file not installed at compile time:\n\n```ruby\nohai_hint 'ec2' do\n compile_time false\nend\n```\n\nHint file installed with content:\n\n```ruby\nohai_hint 'raid_present' do\n content Hash[:a, 'test_content']\nend\n```\n\n#### ChefSpec Matchers\n\nYou can check for the creation or deletion of ohai hints with chefspec using these custom matches:\n\n- create_ohai_hint\n- delete_ohai_hint\n\n### `ohai_plugin`\n\nInstalls custom Ohai plugins.\n\n#### Resource Attributes\n\n- `plugin_name` - The name to give the plugin on the filesystem. Should be string, default is name of resource.\n- `path` - The path to your custom plugin directory. Defaults to a directory named 'plugins' under the directory 'ohai' in the Chef config dir.\n- `source_file` - The source file for the plugin in your cookbook if not NAME.rb.\n- `cookbook` - The cookbook where the source file exists if not the cookbook where the ohai_plugin resource is running from.\n- `resource` - The resource type for the plugin file. Either `:cookbook_file` or `:template`. Defaults to `:cookbook_file`.\n- `variables` - Usable only if `resource` is `:template`. Defines the template's variables.\n- `compile_time` - Should the resource run at compile time. This defaults to `true`.\n\n#### examples\n\nSimple Ohai plugin installation:\n\n```ruby\nohai_plugin 'my_custom_plugin'\n```\n\nInstallation where the resource doesn't match the filename and you install to a custom plugins dir:\n\n```ruby\nohai_plugin 'My Ohai Plugin' do\n name 'my_custom_plugin'\n path '/my/custom/path/'\nend\n```\n\nInstallation using a template:\n\n```ruby\nohai_plugin 'My Templated Plugin' do\n name 'templated_plugin'\n resource :template\n variables node_type: :web_server\nend\n```\n\n#### ChefSpec Matchers\n\nYou can check for the creation or deletion of ohai plugins with chefspec using these custom matches:\n\n- create_ohai_plugin\n- delete_ohai_plugin\n\n## License & Authors\n\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":{"ubuntu":">= 0.0.0","debian":">= 0.0.0","centos":">= 0.0.0","redhat":">= 0.0.0","amazon":">= 0.0.0","scientific":">= 0.0.0","fedora":">= 0.0.0","oracle":">= 0.0.0","suse":">= 0.0.0","opensuse":">= 0.0.0","opensuseleap":">= 0.0.0","freebsd":">= 0.0.0","windows":">= 0.0.0","zlinux":">= 0.0.0"},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{},"source_url":"https://github.com/chef-cookbooks/ohai","issues_url":"https://github.com/chef-cookbooks/ohai/issues","chef_version":[[">= 12.5"]],"ohai_version":[]} \ No newline at end of file diff --git a/cookbooks/ohai/providers/hint.rb b/cookbooks/ohai/providers/hint.rb deleted file mode 100644 index c83ea38..0000000 --- a/cookbooks/ohai/providers/hint.rb +++ /dev/null @@ -1,46 +0,0 @@ -def why_run_supported? - true -end - -def ohai_hint_path - ::File.join(node['ohai']['hints_path'], "#{new_resource.name}.json") -end - -def build_content - # passing nil to file produces deprecation warnings so pass an empty string - return '' if new_resource.content.nil? || new_resource.content.empty? - JSON.pretty_generate(new_resource.content) -end - -use_inline_resources - -action :create do - # don't create the file if the existing file was empty and so is the new one - # this avoids bogus content updates on every chef run - unless (@current_resource.content && @current_resource.content.empty?) && new_resource.content.nil? - directory node['ohai']['hints_path'] do - action :create - recursive true - end - - file ohai_hint_path do - action :create - content build_content - end - end -end - -def load_current_resource - @current_resource = Chef::Resource::OhaiHint.new(new_resource.name) - if ::File.exist?(ohai_hint_path) - Chef::Log.debug("Existing ohai hint at #{ohai_hint_path} found. Attempting to parse JSON") - begin - @current_resource.content(JSON.parse(::File.read(ohai_hint_path))) - rescue JSON::ParserError - @current_resource.content({}) - Chef::Log.debug("Could not parse JSON in ohai hint at #{ohai_hint_path}. It's probably an empty hint file") - end - end - - @current_resource -end diff --git a/cookbooks/ohai/recipes/default.rb b/cookbooks/ohai/recipes/default.rb index f54332b..6f83639 100644 --- a/cookbooks/ohai/recipes/default.rb +++ b/cookbooks/ohai/recipes/default.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: ohai +# Cookbook:: ohai # Recipe:: default # -# Copyright 2011-2016, 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. @@ -17,36 +17,4 @@ # limitations under the License. # -reload_ohai = false -# Add plugin_path from node attributes if missing, and ensure a reload of -# ohai in that case -unless Ohai::Config[:plugin_path].include?(node['ohai']['plugin_path']) - Ohai::Config[:plugin_path] = [node['ohai']['plugin_path'], Ohai::Config[:plugin_path]].flatten.compact - reload_ohai ||= true -end -Chef::Log.info("ohai plugins will be at: #{node['ohai']['plugin_path']}") - -# This is done during the compile phase so new plugins can be used in -# resources later in the run. -node['ohai']['plugins'].each_pair do |source_cookbook, path| - rd = remote_directory "#{node['ohai']['plugin_path']} for cookbook #{source_cookbook}" do - path node['ohai']['plugin_path'] - cookbook source_cookbook - source path - mode '0755' unless platform_family?('windows') - recursive true - purge false - action :nothing - end - - rd.run_action(:create) - reload_ohai ||= rd.updated? -end - -resource = ohai 'custom_plugins' do - action :nothing -end - -# Reload ohai if the client's plugin_path did not contain -# node['ohai']['plugin_path'], or new plugins were loaded -resource.run_action(:reload) if reload_ohai +Chef::Log.warn('The Ohai cookbook default recipe has no content as of the 4.0 release. See the readme for instructions on using the custom resources.') diff --git a/cookbooks/ohai/resources/hint.rb b/cookbooks/ohai/resources/hint.rb index abfd70c..02b43c9 100644 --- a/cookbooks/ohai/resources/hint.rb +++ b/cookbooks/ohai/resources/hint.rb @@ -1,5 +1,55 @@ -actions :create, :delete -default_action :create +property :hint_name, String, name_property: true +property :content, Hash +property :compile_time, [true, false], default: true -attribute :hint_name, kind_of: String, name_attribute: true -attribute :content, kind_of: Hash +action :create do + directory ::Ohai::Config.ohai.hints_path.first do + action :create + recursive true + end + + file ohai_hint_path do + action :create + content build_content + end +end + +action :delete do + file ohai_hint_path do + action :delete + notifies :reload, ohai[reload ohai post hint removal] + end + + ohai 'reload ohai post hint removal' do + action :nothing + end +end + +action_class.class_eval do + def ohai_hint_path + path = ::File.join(::Ohai::Config.ohai.hints_path.first, new_resource.hint_name) + path << '.json' unless path.end_with?('.json') + path + end + + def build_content + # passing nil to file produces deprecation warnings so pass an empty string + return nil if new_resource.content.nil? || new_resource.content.empty? + JSON.pretty_generate(new_resource.content) + end + + def file_content(path) + return JSON.parse(::File.read(path)) + rescue JSON::ParserError + Chef::Log.debug("Could not parse JSON in ohai hint at #{ohai_hint_path}. It's probably an empty hint file") + return nil + 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/ohai/resources/plugin.rb b/cookbooks/ohai/resources/plugin.rb new file mode 100644 index 0000000..734a220 --- /dev/null +++ b/cookbooks/ohai/resources/plugin.rb @@ -0,0 +1,117 @@ +property :plugin_name, String, name_property: true +property :path, String +property :source_file, String +property :cookbook, String +property :resource, [:cookbook_file, :template], default: :cookbook_file +property :variables, Hash +property :compile_time, [true, false], default: true + +action :create do + # why create_if_missing you ask? + # no one can agree on perms and this allows them to manage the perms elsewhere + directory desired_plugin_path do + action :create + recursive true + not_if { ::File.exist?(desired_plugin_path) } + end + + if new_resource.resource.eql?(:cookbook_file) + cookbook_file ::File.join(desired_plugin_path, new_resource.plugin_name + '.rb') do + cookbook new_resource.cookbook + source new_resource.source_file || "#{new_resource.plugin_name}.rb" + notifies :reload, "ohai[#{new_resource.plugin_name}]", :immediately + end + elsif new_resource.resource.eql?(:template) + template ::File.join(desired_plugin_path, new_resource.plugin_name + '.rb') do + cookbook new_resource.cookbook + source new_resource.source_file || "#{new_resource.plugin_name}.rb" + variables new_resource.variables + notifies :reload, "ohai[#{new_resource.plugin_name}]", :immediately + end + end + + # Add the plugin path to the ohai plugin path if need be and warn + # the user that this is going to result in a reload every run + unless in_plugin_path?(desired_plugin_path) + plugin_path_warning + Chef::Log.warn("Adding #{desired_plugin_path} to the Ohai plugin path for this chef-client run only") + add_to_plugin_path(desired_plugin_path) + reload_required = true + end + + ohai new_resource.plugin_name do + action :nothing + action :reload if reload_required + end +end + +action :delete do + file ::File.join(desired_plugin_path, new_resource.plugin_name + '.rb') do + action :delete + notifies :reload, 'ohai[reload ohai post plugin removal]' + end + + ohai 'reload ohai post plugin removal' do + action :nothing + end +end + +action_class.class_eval do + # return the path property if specified or + # CHEF_CONFIG_PATH/ohai/plugins if a path isn't specified + def desired_plugin_path + if new_resource.path + new_resource.path + else + ::File.join(chef_config_path, 'ohai', 'plugins') + end + end + + # return the chef config files dir or fail hard + def chef_config_path + if Chef::Config['config_file'] + ::File.dirname(Chef::Config['config_file']) + else + Chef::Application.fatal!("No chef config file defined. Are you running \ +chef-solo? If so you will need to define a path for the ohai_plugin as the \ +path cannot be determined") + end + end + + # is the desired plugin dir in the ohai config plugin dir array? + def in_plugin_path?(path) + # get the directory where we plan to stick the plugin (not the actual file path) + desired_dir = ::File.directory?(path) ? path : ::File.dirname(path) + + case node['platform'] + when 'windows' + ::Ohai::Config.ohai['plugin_path'].map(&:downcase).include?(desired_dir.downcase) + else + ::Ohai::Config.ohai['plugin_path'].include?(desired_dir) + end + end + + def add_to_plugin_path(path) + ::Ohai::Config.ohai['plugin_path'] << path # new format + end + + # we need to warn the user that unless the path for this plugin is in Ohai's + # plugin path already we're going to have to reload Ohai on every Chef run. + # Ideally in future versions of Ohai /etc/chef/ohai/plugins is in the path. + def plugin_path_warning + Chef::Log.warn("The Ohai plugin_path does not include #{desired_plugin_path}. \ +Ohai will reload on each chef-client run in order to add this directory to the \ +path unless you modify your client.rb configuration to add this directory to \ +plugin_path. The plugin_path can be set via the chef-client::config recipe. \ +See 'Ohai Settings' at https://docs.chef.io/config_rb_client.html#ohai-settings \ +for more details.") + 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/packagecloud/.gitignore b/cookbooks/packagecloud/.gitignore deleted file mode 100644 index 03daae1..0000000 --- a/cookbooks/packagecloud/.gitignore +++ /dev/null @@ -1,19 +0,0 @@ -*~ -*# -.#* -\#*# -.*.sw[a-z] -*.un~ -pkg/ - -# Berkshelf -.vagrant -/cookbooks -Berksfile.lock - -# Bundler -Gemfile.lock -bin/* -.bundle/* - -.kitchen diff --git a/cookbooks/packagecloud/.kitchen.yml b/cookbooks/packagecloud/.kitchen.yml deleted file mode 100644 index bc6c500..0000000 --- a/cookbooks/packagecloud/.kitchen.yml +++ /dev/null @@ -1,79 +0,0 @@ ---- -driver_plugin: vagrant -driver_config: - require_chef_omnibus: true - -platforms: -- name: ubuntu-10.04 - driver_config: - box: opscode-ubuntu-10.04 - box_url: https://opscode-vm-bento.s3.amazonaws.com/vagrant/opscode_ubuntu-10.04_provisionerless.box - run_list: - - recipe[packagecloud_test::lucid_deps] - - recipe[packagecloud_test::deb] - - recipe[packagecloud_test::rubygems_private] - -- name: ubuntu-12.04 - driver_config: - box: opscode-ubuntu-12.04 - box_url: https://opscode-vm-bento.s3.amazonaws.com/vagrant/opscode_ubuntu-12.04_provisionerless.box - run_list: - - recipe[packagecloud_test::precise_deps] - - recipe[packagecloud_test::deb] - - recipe[packagecloud_test::rubygems_private] - -- name: ubuntu-14.04 - driver_config: - box: opscode-ubuntu-14.04 - box_url: http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_ubuntu-14.04_chef-provisionerless.box - run_list: - - recipe[packagecloud_test::trusty_deps] - - recipe[packagecloud_test::deb] - - recipe[packagecloud_test::rubygems] - -- name: centos-without-epel-5.10 - driver_config: - box_url: http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-5.10_chef-provisionerless.box - run_list: - - recipe[packagecloud_test::rpm] - - recipe[packagecloud_test::rubygems] - -- name: centos-with-epel-5.10 - driver_config: - box_url: http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-5.10_chef-provisionerless.box - run_list: - - recipe[packagecloud_test::epel5] - - recipe[packagecloud_test::rpm] - - recipe[packagecloud_test::rubygems_private] - -- name: centos-6.5 - run_list: - - recipe[packagecloud_test::rpm] - - recipe[packagecloud_test::rubygems] - -- name: centos-7.0 - run_list: - - recipe[packagecloud_test::rpm] - - recipe[packagecloud_test::rubygems_private] - -- name: amazon-2014.09 - driver_plugin: ec2 - driver_config: - image_id: ami-b5a7ea85 - username: ec2-user - aws_access_key_id: <%= ENV['AWS_ACCESS_KEY_ID'] %> - aws_secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %> - aws_ssh_key_id: <%= ENV['AWS_KEYPAIR_NAME'] %> - ssh_key: <%= ENV['AWS_SSH_KEY_PATH'] %> - availability_zone: us-west-2a - region: us-west-2 - flavor_id: t2.micro - security_group_ids: sg-598e583c - run_list: - - recipe[packagecloud_test::rpm] - - recipe[packagecloud_test::rubygems] - -suites: -- name: default - run_list: - attributes: {} diff --git a/cookbooks/packagecloud/.rubocop.yml b/cookbooks/packagecloud/.rubocop.yml deleted file mode 100644 index 0fde6a5..0000000 --- a/cookbooks/packagecloud/.rubocop.yml +++ /dev/null @@ -1,28 +0,0 @@ -AllCops: - Include: - - Berksfile - - Gemfile - - Rakefile - - Thorfile - - Guardfile - Exclude: - - vendor/** - -ClassLength: - Enabled: false -Documentation: - Enabled: false -Encoding: - Enabled: false -HashSyntax: - Enabled: false -LineLength: - Enabled: false -MethodLength: - Enabled: false -SignalException: - Enabled: false -TrailingComma: - Enabled: false -WordArray: - Enabled: false diff --git a/cookbooks/packagecloud/.travis.yml b/cookbooks/packagecloud/.travis.yml deleted file mode 100644 index 7d2bad2..0000000 --- a/cookbooks/packagecloud/.travis.yml +++ /dev/null @@ -1,7 +0,0 @@ -language: ruby -rvm: - - 1.9.3 - - 2.0.0 -bundler_args: --without integration -script: - - bundle exec rake travis diff --git a/cookbooks/packagecloud/Berksfile b/cookbooks/packagecloud/Berksfile deleted file mode 100644 index 47c2da6..0000000 --- a/cookbooks/packagecloud/Berksfile +++ /dev/null @@ -1,5 +0,0 @@ -source 'https://api.berkshelf.com' - -metadata - -cookbook 'packagecloud_test', :path => 'test/fixtures/cookbooks/packagecloud_test' diff --git a/cookbooks/packagecloud/CHANGELOG.md b/cookbooks/packagecloud/CHANGELOG.md deleted file mode 100644 index a6002f3..0000000 --- a/cookbooks/packagecloud/CHANGELOG.md +++ /dev/null @@ -1,18 +0,0 @@ -packagecloud -=============== -This is the Changelog for the packagecloud cookbook - -v0.2.0 (2015-02-17) -------------------- -Rework GPG paths to support new GPG endpoints for repos with repo-specific GPG -keys. Old endpoints/URLs still work, too. - - -v0.0.1 (2014-06-05) -------------------- -Initial release. - - -v0.0.1 (2014-06-05) -------------------- -Initial release! diff --git a/cookbooks/packagecloud/Gemfile b/cookbooks/packagecloud/Gemfile deleted file mode 100644 index 51dbdc7..0000000 --- a/cookbooks/packagecloud/Gemfile +++ /dev/null @@ -1,16 +0,0 @@ -source 'https://rubygems.org' - -gem 'rake' -gem 'berkshelf', '~> 3.1.4' -gem 'kitchen-ec2' -gem 'stove' - -group :test do - gem 'foodcritic', '~> 4.0.0' - gem 'rubocop', '~> 0.24.1' -end - -group :integration do - gem 'test-kitchen', '~> 1.2.1' - gem 'kitchen-vagrant', '~> 0.15.0' -end diff --git a/cookbooks/packagecloud/LICENSE b/cookbooks/packagecloud/LICENSE deleted file mode 100644 index 56c3277..0000000 --- a/cookbooks/packagecloud/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright (C) 2014 Computology, 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/packagecloud/README.md b/cookbooks/packagecloud/README.md deleted file mode 100644 index f9d32b8..0000000 --- a/cookbooks/packagecloud/README.md +++ /dev/null @@ -1,91 +0,0 @@ -# packagecloud cookbook - -This cookbook provides an LWRP for installing https://packagecloud.io repositories. - -NOTE: Please see the Changelog below for important changes if upgrading from 0.0.19 to 0.1.0. - -## Usage - -Be sure to depend on `packagecloud` in `metadata.rb` so that the packagecloud -resource will be loaded. - -For public repos: - -```ruby -packagecloud_repo "computology/packagecloud-cookbook-test-public" do - type "deb" -end -``` - -For private repos, you need to supply a `master_token`: - -```ruby -packagecloud_repo "computology/packagecloud-cookbook-test-private" do - type "deb" - master_token "762748f7ae0bfdb086dd539575bdc8cffdca78c6a9af0db9" -end -``` - -For packagecloud:enterprise users, add `base_url` to your resource: - -``` -packagecloud_repo "computology/packagecloud-cookbook-test-private" do - base_url "https://packages.example.com" - type "deb" - master_token "762748f7ae0bfdb086dd539575bdc8cffdca78c6a9af0db9" -end -``` - -For forcing the os and dist for repository install: - -``` -packagecloud_repo 'computology/packagecloud-cookbook-test-public' do - type 'rpm' - force_os 'rhel' - force_dist '6.5' -end -``` - -Valid options for `type` include `deb`, `rpm`, and `gem`. - -## Interactions with other cookbooks - -On CentOS 5, the official chef yum cookbook overwrites the file -`/etc/yum.conf` setting some default values. When it does this, the `cachedir` -value is changed from the CentOS5 default to the default value in the -cookbook. The result of this change is that any packagecloud repository -installed *before* a repository installed with the yum cookbook will appear as -though it's gpg keys were not imported. - -There are a few potential workarounds for this: - -- Pass the "-y" flag to package resource using the `options` attribute. This - should cause yum to import the GPG key automatically if it was not imported - already. -- Move your packagecloud repos so that they are installed last, after any/all - repos installed via the yum cookbook. -- Set the cachedir option in the chef yum cookbook to the system default value - of `/var/cache/yum` using the `yum_globalconfig` resource. - -CentOS 6 and 7 are not affected as the default `cachedir` value provided by -the yum chef cookbook is set to the system default, unless you use the -`yum_globalconfig` resource to set a custom cachedir. If you do set a custom -`cachedir`, you should make sure to setup packagecloud repos after that -resource is set so that the GPG keys end up in the right place. - -## Changelog - -packagecloud cookbook versions 0.0.19 used an attribute called -`default['packagecloud']['hostname']` for caching the local machine's hostname -to avoid regenerating read tokens. - -This attribute has been removed as it is confusing and in some edge cases, -buggy. - -Beginning in 0.1.0, you can use -`default['packagecloud']['hostname_override']` to specify a hostname if ohai -is unable to determine the hostname of the node on its own. - - -## Credits -Computology, LLC. diff --git a/cookbooks/packagecloud/Rakefile b/cookbooks/packagecloud/Rakefile deleted file mode 100644 index 0300fef..0000000 --- a/cookbooks/packagecloud/Rakefile +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env rake - -# Style tests. Rubocop and Foodcritic -namespace :style do - begin - require 'rubocop/rake_task' - desc 'Run Ruby style checks' - RuboCop::RakeTask.new(:ruby) - rescue LoadError - puts '>>>>> Rubocop gem not loaded, omitting tasks' unless ENV['CI'] - end - - begin - require 'foodcritic' - - desc 'Run Chef style checks' - FoodCritic::Rake::LintTask.new(:chef) do |t| - t.options = { - fail_tags: ['any'], - tags: ['~FC003'] - } - end - rescue LoadError - puts '>>>>> foodcritic gem not loaded, omitting tasks' unless ENV['CI'] - end -end - -desc 'Run all style checks' -task style: ['style:chef', 'style:ruby'] - -# Integration tests. Kitchen.ci -namespace :integration do - begin - require 'kitchen/rake_tasks' - - desc 'Run kitchen integration tests' - Kitchen::RakeTasks.new - rescue LoadError - puts '>>>>> Kitchen gem not loaded, omitting tasks' unless ENV['CI'] - end -end - -desc 'Run all tests on Travis' -task travis: ['style'] - -# Default -task default: ['style', 'integration:kitchen:all'] diff --git a/cookbooks/packagecloud/THANKS b/cookbooks/packagecloud/THANKS deleted file mode 100644 index 81877d1..0000000 --- a/cookbooks/packagecloud/THANKS +++ /dev/null @@ -1,6 +0,0 @@ -The following people have contributed to packagecloud chef cookbook (If you're not listed here and you should be, please let us know!): - -THANKS ------- -Guilhem Lettron (@guilhem) -Michael S. Fischer (@mfischer-zd) diff --git a/cookbooks/packagecloud/Thorfile b/cookbooks/packagecloud/Thorfile deleted file mode 100644 index cb1aeae..0000000 --- a/cookbooks/packagecloud/Thorfile +++ /dev/null @@ -1,5 +0,0 @@ -# encoding: utf-8 - -require 'bundler' -require 'bundler/setup' -require 'berkshelf/thor' diff --git a/cookbooks/packagecloud/Vagrantfile b/cookbooks/packagecloud/Vagrantfile deleted file mode 100644 index e8bfb6c..0000000 --- a/cookbooks/packagecloud/Vagrantfile +++ /dev/null @@ -1,85 +0,0 @@ -# -*- mode: ruby -*- -# vi: set ft=ruby : - -# Vagrantfile API/syntax version. Don't touch unless you know what you're doing! -VAGRANTFILE_API_VERSION = "2" - -Vagrant.require_version ">= 1.5.0" - -Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| - # All Vagrant configuration is done here. The most common configuration - # options are documented and commented below. For a complete reference, - # please see the online documentation at vagrantup.com. - - config.vm.hostname = "packagecloud-berkshelf" - - # Set the version of chef to install using the vagrant-omnibus plugin - config.omnibus.chef_version = :latest - - # Every Vagrant virtual environment requires a box to build off of. - config.vm.box = "opscode_ubuntu-12.04_provisionerless" - - # The url from where the 'config.vm.box' box will be fetched if it - # doesn't already exist on the user's system. - config.vm.box_url = "https://opscode-vm-bento.s3.amazonaws.com/vagrant/opscode_ubuntu-12.04_provisionerless.box" - - # Assign this VM to a host-only network IP, allowing you to access it - # via the IP. Host-only networks can talk to the host machine as well as - # any other machines on the same network, but cannot be accessed (through this - # network interface) by any external networks. - config.vm.network :private_network, type: "dhcp" - - # Create a forwarded port mapping which allows access to a specific port - # within the machine from a port on the host machine. In the example below, - # accessing "localhost:8080" will access port 80 on the guest machine. - - # Share an additional folder to the guest VM. The first argument is - # the path on the host to the actual folder. The second argument is - # the path on the guest to mount the folder. And the optional third - # argument is a set of non-required options. - # config.vm.synced_folder "../data", "/vagrant_data" - - # Provider-specific configuration so you can fine-tune various - # backing providers for Vagrant. These expose provider-specific options. - # Example for VirtualBox: - # - # config.vm.provider :virtualbox do |vb| - # # Don't boot with headless mode - # vb.gui = true - # - # # Use VBoxManage to customize the VM. For example to change memory: - # vb.customize ["modifyvm", :id, "--memory", "1024"] - # end - # - # View the documentation for the provider you're using for more - # information on available options. - - # The path to the Berksfile to use with Vagrant Berkshelf - # config.berkshelf.berksfile_path = "./Berksfile" - - # Enabling the Berkshelf plugin. To enable this globally, add this configuration - # option to your ~/.vagrant.d/Vagrantfile file - config.berkshelf.enabled = true - - # An array of symbols representing groups of cookbook described in the Vagrantfile - # to exclusively install and copy to Vagrant's shelf. - # config.berkshelf.only = [] - - # An array of symbols representing groups of cookbook described in the Vagrantfile - # to skip installing and copying to Vagrant's shelf. - # config.berkshelf.except = [] - - config.vm.provision :chef_solo do |chef| - chef.json = { - mysql: { - server_root_password: 'rootpass', - server_debian_password: 'debpass', - server_repl_password: 'replpass' - } - } - - chef.run_list = [ - "recipe[packagecloud::default]" - ] - end -end diff --git a/cookbooks/packagecloud/attributes/default.rb b/cookbooks/packagecloud/attributes/default.rb deleted file mode 100644 index 21b1d16..0000000 --- a/cookbooks/packagecloud/attributes/default.rb +++ /dev/null @@ -1,8 +0,0 @@ -default['packagecloud']['base_repo_path'] = "/install/repositories/" -default['packagecloud']['gpg_key_path'] = "/gpgkey" -default['packagecloud']['hostname_override'] = nil - -default['packagecloud']['default_type'] = value_for_platform_family( - 'debian' => 'deb', - ['rhel', 'fedora'] => 'rpm' -) diff --git a/cookbooks/packagecloud/chefignore b/cookbooks/packagecloud/chefignore deleted file mode 100644 index fef04fc..0000000 --- a/cookbooks/packagecloud/chefignore +++ /dev/null @@ -1,98 +0,0 @@ -# Put files/directories that should be ignored in this file when uploading -# or sharing to the community site. -# Lines that start with '# ' are comments. - -# OS generated files # -###################### -.DS_Store -Icon? -nohup.out -ehthumbs.db -Thumbs.db - -# SASS # -######## -.sass-cache - -# EDITORS # -########### -\#* -.#* -*~ -*.sw[a-z] -*.bak -REVISION -TAGS* -tmtags -*_flymake.* -*_flymake -*.tmproj -.project -.settings -mkmf.log - -## COMPILED ## -############## -a.out -*.o -*.pyc -*.so -*.com -*.class -*.dll -*.exe -*/rdoc/ - -# Testing # -########### -.watchr -.rspec -spec/* -spec/fixtures/* -test/* -features/* -Guardfile -Procfile - -# SCM # -####### -.git -*/.git -.gitignore -.gitmodules -.gitconfig -.gitattributes -.svn -*/.bzr/* -*/.hg/* -*/.svn/* - -# Berkshelf # -############# -cookbooks/* -tmp - -# Cookbooks # -############# -CONTRIBUTING -CHANGELOG* - -# Strainer # -############ -Colanderfile -Strainerfile -.colander -.strainer - -# Vagrant # -########### -.vagrant -Vagrantfile - -# Travis # -########## -.travis.yml - -# tmux # -########## -.tmux diff --git a/cookbooks/packagecloud/libraries/helper.rb b/cookbooks/packagecloud/libraries/helper.rb deleted file mode 100644 index e548748..0000000 --- a/cookbooks/packagecloud/libraries/helper.rb +++ /dev/null @@ -1,43 +0,0 @@ -require 'net/https' - -module PackageCloud - module Helper - def get(uri, params) - uri.query = URI.encode_www_form(params) - req = Net::HTTP::Get.new(uri.request_uri) - - req.basic_auth uri.user, uri.password if uri.user - - http = Net::HTTP.new(uri.hostname, uri.port) - http.use_ssl = true - - resp = http.start { |h| h.request(req) } - - case resp - when Net::HTTPSuccess - resp - else - raise resp.inspect - end - end - - def post(uri, params) - req = Net::HTTP::Post.new(uri.request_uri) - req.form_data = params - - req.basic_auth uri.user, uri.password if uri.user - - http = Net::HTTP.new(uri.hostname, uri.port) - http.use_ssl = true - - resp = http.start { |h| h.request(req) } - - case resp - when Net::HTTPSuccess - resp - else - raise resp.inspect - end - end - end -end diff --git a/cookbooks/packagecloud/libraries/matcher.rb b/cookbooks/packagecloud/libraries/matcher.rb deleted file mode 100644 index e518177..0000000 --- a/cookbooks/packagecloud/libraries/matcher.rb +++ /dev/null @@ -1,7 +0,0 @@ -if defined?(ChefSpec) - - def create_packagecloud_repo(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:packagecloud_repo, :add, resource_name) - end - -end diff --git a/cookbooks/packagecloud/metadata.json b/cookbooks/packagecloud/metadata.json deleted file mode 100644 index e5d00e7..0000000 --- a/cookbooks/packagecloud/metadata.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "packagecloud", - "description": "Installs/Configures packagecloud.io repositories.", - "long_description": "Installs/Configures packagecloud.io repositories.", - "maintainer": "Joe Damato", - "maintainer_email": "joe@packagecloud.io", - "license": "Apache 2.0", - "platforms": { - - }, - "dependencies": { - - }, - "recommendations": { - - }, - "suggestions": { - - }, - "conflicting": { - - }, - "providing": { - - }, - "replacing": { - - }, - "attributes": { - - }, - "groupings": { - - }, - "recipes": { - - }, - "version": "0.2.0", - "source_url": "https://github.com/computology/packagecloud-cookbook", - "issues_url": "https://github.com/computology/packagecloud-cookbook/issues", - "privacy": false, - "chef_versions": [ - - ], - "ohai_versions": [ - - ] -} diff --git a/cookbooks/packagecloud/metadata.rb b/cookbooks/packagecloud/metadata.rb deleted file mode 100644 index 32e6d79..0000000 --- a/cookbooks/packagecloud/metadata.rb +++ /dev/null @@ -1,9 +0,0 @@ -name 'packagecloud' -maintainer 'Joe Damato' -maintainer_email 'joe@packagecloud.io' -license 'Apache 2.0' -description 'Installs/Configures packagecloud.io repositories.' -long_description 'Installs/Configures packagecloud.io repositories.' -version '0.2.0' -source_url 'https://github.com/computology/packagecloud-cookbook' if respond_to?(:source_url) -issues_url 'https://github.com/computology/packagecloud-cookbook/issues' if respond_to?(:issues_url) diff --git a/cookbooks/packagecloud/providers/repo.rb b/cookbooks/packagecloud/providers/repo.rb deleted file mode 100644 index c6c23e7..0000000 --- a/cookbooks/packagecloud/providers/repo.rb +++ /dev/null @@ -1,224 +0,0 @@ -include ::PackageCloud::Helper - -require 'uri' - -use_inline_resources if defined?(use_inline_resources) - -action :add do - case new_resource.type - when 'deb' - install_deb - when 'rpm' - install_rpm - when 'gem' - install_gem - else - raise "#{new_resource.type} is an unknown package type." - end -end - -def gpg_url(base_url, repo, format, master_token) - base_install_url = ::File.join(base_url, node['packagecloud']['base_repo_path']) - ext = (format == :deb) ? 'list' : 'repo' - gpg_key_url_endpoint = construct_uri_with_options({base_url: base_install_url, repo: repo, endpoint: "gpg_key_url.#{ext}"}) - if !master_token.nil? - gpg_key_url_endpoint.user = master_token - gpg_key_url_endpoint.password = '' - end - - URI(get(gpg_key_url_endpoint, install_endpoint_params).body.chomp) -end - -def install_deb - base_url = new_resource.base_url - repo_url = construct_uri_with_options({base_url: base_url, repo: new_resource.repository, endpoint: node['platform']}) - - Chef::Log.debug("#{new_resource.name} deb repo url = #{repo_url}") - - package 'wget' - package 'apt-transport-https' - - repo_url = read_token(repo_url) - - template "/etc/apt/sources.list.d/#{filename}.list" do - source 'apt.erb' - cookbook 'packagecloud' - mode '0644' - variables :base_url => repo_url.to_s, - :distribution => node['lsb']['codename'], - :component => 'main' - - notifies :run, "execute[apt-key-add-#{filename}]", :immediately - notifies :run, "execute[apt-get-update-#{filename}]", :immediately - end - - gpg_url = gpg_url(new_resource.base_url, new_resource.repository, :deb, new_resource.master_token) - - execute "apt-key-add-#{filename}" do - command "wget --auth-no-challenge -qO - #{gpg_url.to_s} | apt-key add -" - action :nothing - end - - execute "apt-get-update-#{filename}" do - command "apt-get update -o Dir::Etc::sourcelist=\"sources.list.d/#{filename}.list\"" \ - " -o Dir::Etc::sourceparts=\"-\"" \ - " -o APT::Get::List-Cleanup=\"0\"" - action :nothing - end -end - -def install_rpm - given_base_url = new_resource.base_url - base_repo_url = ::File.join(given_base_url, node['packagecloud']['base_repo_path']) - base_url_endpoint = construct_uri_with_options({base_url: base_repo_url, repo: new_resource.repository, endpoint: 'rpm_base_url'}) - - if new_resource.master_token - base_url_endpoint.user = new_resource.master_token - base_url_endpoint.password = '' - end - - base_url = URI(get(base_url_endpoint, install_endpoint_params).body.chomp) - - Chef::Log.debug("#{new_resource.name} rpm base url = #{base_url}") - - package 'pygpgme' do - ignore_failure true - end - - log 'pygpgme_warning' do - message 'The pygpgme package could not be installed. This means GPG verification is not possible for any RPM installed on your system. ' \ - 'To fix this, add a repository with pygpgme. Usualy, the EPEL repository for your system will have this. ' \ - 'More information: https://fedoraproject.org/wiki/EPEL#How_can_I_use_these_extra_packages.3F and https://github.com/opscode-cookbooks/yum-epel' - - level :warn - not_if 'rpm -qa | grep -qw pygpgme' - end - - ruby_block 'disable repo_gpgcheck if no pygpgme' do - block do - template = run_context.resource_collection.find(:template => "/etc/yum.repos.d/#{filename}.repo") - template.variables[:repo_gpgcheck] = 0 - end - not_if 'rpm -qa | grep -qw pygpgme' - end - - gpg_url = gpg_url(new_resource.base_url, new_resource.repository, :rpm, new_resource.master_token) - - template "/etc/yum.repos.d/#{filename}.repo" do - source 'yum.erb' - cookbook 'packagecloud' - mode '0644' - variables :base_url => base_url.to_s, - :name => filename, - :gpg_url => gpg_url.to_s, - :repo_gpgcheck => 1, - :description => filename, - :priority => new_resource.priority, - :metadata_expire => new_resource.metadata_expire - - notifies :run, "execute[yum-makecache-#{filename}]", :immediately - notifies :create, "ruby_block[yum-cache-reload-#{filename}]", :immediately - end - - # get the metadata for this repo only - execute "yum-makecache-#{filename}" do - command "yum -q makecache -y --disablerepo=* --enablerepo=#{filename}" - action :nothing - end - - # reload internal Chef yum cache - ruby_block "yum-cache-reload-#{filename}" do - block { Chef::Provider::Package::Yum::YumCache.instance.reload } - action :nothing - end -end - -def install_gem - base_url = new_resource.base_url - - repo_url = construct_uri_with_options({base_url: base_url, repo: new_resource.repository}) - repo_url = read_token(repo_url, true).to_s - - - execute "install packagecloud #{new_resource.name} repo as gem source" do - command "gem source --add #{repo_url}" - not_if "gem source --list | grep #{repo_url}" - end -end - - -def read_token(repo_url, gems=false) - return repo_url unless new_resource.master_token - - base_url = new_resource.base_url - - base_repo_url = ::File.join(base_url, node['packagecloud']['base_repo_path']) - - uri = construct_uri_with_options({base_url: base_repo_url, repo: new_resource.repository, endpoint: 'tokens.text'}) - uri.user = new_resource.master_token - uri.password = '' - - resp = post(uri, install_endpoint_params) - - Chef::Log.debug("#{new_resource.name} TOKEN = #{resp.body.chomp}") - - if is_rhel5? && !gems - repo_url - else - repo_url.user = resp.body.chomp - repo_url.password = '' - repo_url - end -end - -def install_endpoint_params - dist = new_resource.force_dist || value_for_platform_family( - 'debian' => node['lsb']['codename'], - ['rhel', 'fedora'] => node['platform_version'], - ) - - hostname = node['packagecloud']['hostname_override'] || - node['fqdn'] || - node['hostname'] - - if !hostname - raise("Can't determine hostname! Set node['packagecloud']['hostname_override'] " \ - "if it cannot be automatically determined by Ohai.") - end - - { :os => os_platform, - :dist => dist, - :name => hostname } -end - -def os_platform - new_resource.force_os || node['platform'] -end - -def filename - new_resource.name.gsub(/[^0-9A-z.\-]/, '_') -end - -def is_rhel5? - platform_family?('rhel') && node['platform_version'].to_i == 5 -end - -def construct_uri_with_options(options) - required_options = [:base_url, :repo] - - required_options.each do |opt| - if !options[opt] - raise ArgumentError, - "A required option :#{opt} was not specified" - end - end - - options[:base_url] = append_trailing_slash(options[:base_url]) - options[:repo] = append_trailing_slash(options[:repo]) - - URI.join(options.delete(:base_url), options.inject([]) {|mem, opt| mem << opt[1]}.join) -end - -def append_trailing_slash(str) - str.end_with?("/") ? str : str + "/" -end diff --git a/cookbooks/packagecloud/resources/repo.rb b/cookbooks/packagecloud/resources/repo.rb deleted file mode 100644 index 783223f..0000000 --- a/cookbooks/packagecloud/resources/repo.rb +++ /dev/null @@ -1,11 +0,0 @@ -actions :add -default_action :add - -attribute :repository, :kind_of => String, :name_attribute => true -attribute :master_token, :kind_of => String -attribute :force_os, :kind_of => String -attribute :force_dist, :kind_of => String -attribute :type, :kind_of => String, :equal_to => ['deb', 'rpm', 'gem'], :default => node['packagecloud']['default_type'] -attribute :base_url, :kind_of => String, :default => "https://packagecloud.io" -attribute :priority, :kind_of => [Fixnum, TrueClass, FalseClass], :default => false -attribute :metadata_expire, :kind_of => String, :regex => [/^\d+[d|h|m]?$/], :default => nil diff --git a/cookbooks/packagecloud/templates/default/apt.erb b/cookbooks/packagecloud/templates/default/apt.erb deleted file mode 100644 index a38981c..0000000 --- a/cookbooks/packagecloud/templates/default/apt.erb +++ /dev/null @@ -1,2 +0,0 @@ -deb <%= @base_url %> <%= @distribution %> <%= @component %> -deb-src <%= @base_url %> <%= @distribution %> <%= @component %> diff --git a/cookbooks/packagecloud/templates/default/yum.erb b/cookbooks/packagecloud/templates/default/yum.erb deleted file mode 100644 index 81c3f68..0000000 --- a/cookbooks/packagecloud/templates/default/yum.erb +++ /dev/null @@ -1,15 +0,0 @@ -[<%= @name %>] -name=<%= @description %> -baseurl=<%= @base_url %> -repo_gpgcheck=<%= @repo_gpgcheck %> -<% if @priority -%> -priority=<%=@priority %> -<% end -%> -gpgcheck=0 -enabled=1 -gpgkey=<%= @gpg_url %> -sslverify=1 -sslcacert=/etc/pki/tls/certs/ca-bundle.crt -<% if @metadata_expire %> -metadata_expire=<%= @metadata_expire %> -<% end %> diff --git a/cookbooks/rsyslog/CHANGELOG.md b/cookbooks/rsyslog/CHANGELOG.md deleted file mode 100644 index c718777..0000000 --- a/cookbooks/rsyslog/CHANGELOG.md +++ /dev/null @@ -1,193 +0,0 @@ -rsyslog Cookbook CHANGELOG -========================== -This file is used to list changes made in each version of the rsyslog cookbook. - -v.2.2.0 (2015-10-05) ----------- -- Add why-run support to the file_input LWRP -- Added support for rsyslog under systemd on Ubuntu 15.04+ -- Added new attribute node['rsyslog']['custom_remote']. See readme for additional information -- Added source_url and issues_url metadata for Supermarket -- Fixed 49-relp.conf to honor logs_to_forward so it didn't just forward everything -- Updated contributing and testing docs -- Set the minimum supported Chef release to 11.0 -- Added maintainers.toml and maintainers.md files -- Added Amazon Linux, Oracle, and Scientific Linux to the metadata -- Removed all pre-Ruby 1.9 hash rockets -- Updated development dependencies in the -- Fix a bad example attribute in the readme -- Updated Travis CI config to test on all modern Ruby releases - -v.2.1.0 (2015-07-22) ----------- -- Fixed minor markdown errors in the readme -- Allow the server to listen on both TCP and UDP. For both set node['rsyslog']['protocol'] to 'udptcp' -- Move the include for /etc/rsyslog.d/ to the very end of the rsyslog.conf config -- Added the ability to bind to a specific IP when running the server on UDP with node['rsyslog']['bind'] -- Sync the comments in the rsyslog.conf file with the latest upstream rsyslog release -- Change emerg to log to :omusrmsg:* vs. * on modern rsyslog releases to avoid deprecation warnings - -v.2.0.0 (2015-05-18) --------------------- -Note: This version includes several breaking changes for Ubuntu users. Be sure to take care when deploying these changes to production systems. - -- 49-relp.conf now properly uses the list of servers discovered in the client recipe -- Fixed a typo that prevented file-input.conf from properly templating -- Added allow_non_local attribute to allow non-local messages. This defaults to false, which preserves the previous functionality -- The rsyslog directory permissions are now properly set using the user/group attributes instead of root/root -- Properly drop permissions on Ubuntu systems to syslog/syslog. Introduces 2 new attributes to control the user/group: priv_user and priv_group -- Remove logging to /dev/xconsole in 50-default.conf on Ubuntu systems. This is generally not something you'd want to do and produces error messages at startup. - -v.1.15.0 (2015-02-23) ---------------------- -- Change minimum supported Fedora release to 20 to align with the Fedora product lifecycle -- Add supports CentOS to metadata -- Update Rubocop and Test Kitchen dependencies to the latest versions -- Update Chefspec to 4.0 -- Fix CentOS 5 support in the Kitchen config -- Fix rsyslog service notification in the file_input LWRP - -v.1.14.0 (2015-01-30) ---------------------- -- Don't attempt to use journald on Amazon Linux since Amazon Linux doesn't use systemd -- Fixed setting bad permissions on the working directory by using the rsyslog user/group variables. -- Fixed bad variable in the 49-relp.conf template that prevented Chef converges from completing. -- Removed the 'reload' action from the rsyslog service as newer rsyslog releases don't support reload. -- Updated Chefspecs to remove deprecation warnings and added additional tests. -- Removed node name from the comment block in the config files. -- Added a new file_input LWRP for defining configs. -- Added support for chef solo search cookbook. - -v1.13.0 (2014-11-25) --------------------- -- Rsyslog's working directory is now an attribute and is set to the appropriate directory on RHEL based distros -- The working directory is now 0700 vs 0755 for additional security -- Add the ActionQueueMaxDiskSpace directive with a default of 1GB to prevent out of disk events during large buffering -- Updated RHEL / Fedora facilities to match those shipped by the distros -- Updated modules to match those used by journald (systemd) on Fedora 19+ and CentOS 7 -- Added an attribute additional_directives to pass a hash of configs. This is currently only being used to pass directives necessary for journald support on RHEL 7 / Fedora 19+ -- Added basic SUSE support -- Fixed logic that prevented Ubuntu from properly dropping privileges in Ubuntu >= 11.04 -- Removed references to rsyslog v3 in the config template -- Added a chefignore file -- Updated Gemfile with newer releases of Test Kitchen, Rubocop, and Berkshelf -- Added Fedora 20, Debian 6/7, CentOS 7, and Ubuntu 12.04/14.04 to the Test Kitchen config -- Removed an attribute that was in the Readme twice -- Updated Travis to Ruby 2.1.1 to better match Chef 12 -- Updated the Berksfile to point to Supermarket -- Refactored the specs to be more dry - -v1.12.2 (2014-02-28) --------------------- -Fixing bug fix in rsyslog.conf - - -v1.12.0 (2014-02-27) --------------------- -- [COOK-4021] Allow specifying default templates for local and remote -- [COOK-4126] rsyslog cookbook fails restarts due to not using upstart - - -v1.11.0 (2014-02-19) --------------------- -### Bug -- **[COOK-4256](https://tickets.opscode.com/browse/COOK-4256)** - Fix syntax errors in default.conf on rhel - -### New Feature -- **[COOK-4022](https://tickets.opscode.com/browse/COOK-4022)** - Add use_local_ipv4 option to allow selecting internal interface on cloud systems -- **[COOK-4018](https://tickets.opscode.com/browse/COOK-4018)** - rsyslog TLS encryption support - - -v1.10.2 -------- -No change. Version bump for toolchain. - - -v1.10.0 -------- -### New Feature -- **[COOK-4021](https://tickets.opscode.com/browse/COOK-4021)** - Allow specifying default templates for local and remote - -### Improvement -- **[COOK-3876](https://tickets.opscode.com/browse/COOK-3876)** - Cater for setting rate limits - - -v1.9.0 ------- -### New Feature -- **[COOK-3736](https://tickets.opscode.com/browse/COOK-3736)** - Support OmniOS - -### Improvement -- **[COOK-3609](https://tickets.opscode.com/browse/COOK-3609)** - Add actionqueue to remote rsyslog configurations - -### Bug -- **[COOK-3608](https://tickets.opscode.com/browse/COOK-3608)** - Add 50-default template knobs -- **[COOK-3600](https://tickets.opscode.com/browse/COOK-3600)** - SmartOS support - - -v1.8.0 ------- -### Improvement -- **[COOK-3573](https://tickets.opscode.com/browse/COOK-3573)** - Add Test Kitchen, Specs, and Travis CI - -### New Feature -- **[COOK-3435](https://tickets.opscode.com/browse/COOK-3435)** - Add support for relp - -v1.7.0 ------- -### Improvement -- **[COOK-3253](https://tickets.opscode.com/browse/COOK-3253)** - Enable repeated message reduction -- **[COOK-3190](https://tickets.opscode.com/browse/COOK-3190)** - Allow specifying which logs to send to remote server -- **[COOK-2355](https://tickets.opscode.com/browse/COOK-2355)** - Support forwarding events to more than one server - -v1.6.0 ------- -### New Feature -- [COOK-2831]: enable high precision timestamps - -### Bug -- [COOK-2377]: calling node.save has adverse affects on nodes relying on a searched node's ohai attributes -- [COOK-2521]: rsyslog cookbook incorrectly sets directory ownership to rsyslog user -- [COOK-2540]: Syslogd needs to be disabled before starting rsyslogd on RHEL 5 - -### Improvement -- [COOK-2356]: rsyslog service supports status. Service should use it. -- [COOK-2357]: rsyslog cookbook copies in wrong defaults file on Ubuntu !9.10/10.04 - -v1.5.0 ------- -- [COOK-2141] - Add `$PreserveFQDN` configuration directive - -v1.4.0 ------- -- [COOK-1877] - RHEL 6 support and refactoring - -v1.3.0 ------- -- [COOK-1189] - template change does not restart rsyslog on Ubuntu - -This actually went into 1.2.0 with action `:reload`, but that change has been reverted and the action is back to `:restart`. - -v1.2.0 ------- -- [COOK-1678] - syslog user does not exist on debian 6.0 and ubuntu versions lower than 11.04 -- [COOK-1650] - enable max message size configuration via attribute - -v1.1.0 ------- -Changes from COOK-1167: - -- More versatile server discovery - use the IP as an attribute, or use search (see README) -- Removed cron dependency. -- Removed log archival; logrotate is recommended. -- Add an attribute to select the per-host directory in the log dir -- Works with Chef Solo now. -- Set debian/ubuntu default user and group. Drop privileges to `syslog.adm`. - - -v1.0.0 ------- -- [COOK-836] - use an attribute to specify the role to search for instead of relying on the rsyslog['server'] attribute. -- Clean up attribute usage to use strings instead of symbols. -- Update this README. -- Better handling for chef-solo. diff --git a/cookbooks/rsyslog/README.md b/cookbooks/rsyslog/README.md deleted file mode 100644 index 7dedf03..0000000 --- a/cookbooks/rsyslog/README.md +++ /dev/null @@ -1,276 +0,0 @@ -rsyslog Cookbook -================ -[![Build Status](https://travis-ci.org/chef-cookbooks/rsyslog.svg?branch=master)](http://travis-ci.org/chef-cookbooks/rsyslog) -[![Cookbook Version](https://img.shields.io/cookbook/v/rsyslog.svg)](https://supermarket.chef.io/cookbooks/rsyslog) - -Installs and configures rsyslog to replace sysklogd for client and/or server use. By default, the service will be configured to log to files on local disk. See the Recipes and Examples sections for other uses. - - -Requirements ------------- -#### Platforms -- Debian/Ubuntu -- RHEL/CentOS/Scientific/Amazon/Oracle -- Fedora 20+ -- OmniOS r151006c - -#### Chef -- Chef 11+ - -#### Cookbooks -- none - -#### Other -To use the `recipe[rsyslog::client]` recipe, you'll need to set up the `rsyslog.server_search` or `rsyslog.server_ip` attributes. See the __Recipes__ and __Examples__ sections below. - - -Attributes ----------- -See `attributes/default.rb` for default values. - -* `node['rsyslog']['log_dir']` - If the node is an rsyslog server, this specifies the directory where the logs should be stored. -* `node['rsyslog']['working_dir']` - The temporary working directory where messages are buffered -* `node['rsyslog']['server']` - Determined automatically and set to true on the server. -* `node['rsyslog']['server_ip']` - If not defined then search will be used to determine rsyslog server. Default is `nil`. This can be a string or an array. -* `node['rsyslog']['server_search']` - Specify the criteria for the server search operation. Default is `role:loghost`. -* `node['rsyslog']['protocol']` - Specify whether to use `udp` or `tcp` for remote loghost. Default is `tcp`. To use both specify both in a string e.g. 'udptcp'. -* `node['rsyslog']['bind']` - Specify the address to which the server should be listening; only use with `node['rsyslog']['protocol'] = 'udp'` because the feature does not work with the `tcp` protocol ([more info](http://www.rsyslog.com/doc/master/configuration/modules/imtcp.html#caveats-known-bugs)). -* `node['rsyslog']['port']` - Specify the port which rsyslog should connect to a remote loghost. -* `node['rsyslog']['remote_logs']` - Specify whether to send all logs to a remote server (client option). Default is `true`. -* `node['rsyslog']['per_host_dir']` - "PerHost" directories for template statements in `35-server-per-host.conf`. Default value is the previous cookbook version's value, to preserve compatibility. See __server__ recipe below. -* `node['rsyslog']['priv_seperation']` - Whether to use privilege separation or not. -* `node['rsyslog']['priv_user']` - User to run as when using privilege separation. Defult is `node['rsyslog']['user']` -* `node['rsyslog']['priv_group']` - Group to run as when using privilege separation. Defult is `node['rsyslog']['group']` -* `node['rsyslog']['max_message_size']` - Specify the maximum allowed message size. Default is 2k. -* `node['rsyslog']['user']` - Who should own the configuration files and directories -* `node['rsyslog']['group']` - Who should group-own the configuration files and directories -* `node['rsyslog']['defaults_file']` - The full path to the defaults/sysconfig file for the service. -* `node['rsyslog']['service_name']` - The platform-specific name of the service -* `node['rsyslog']['preserve_fqdn']` - Value of the `$PreserveFQDN` configuration directive in `/etc/rsyslog.conf`. Default is 'off' for compatibility purposes. -* `node['rsyslog']['high_precision_timestamps']` - Enable high precision timestamps, instead of the "old style" format. Default is 'false'. -* `node['rsyslog']['repeated_msg_reduction']` - Value of `$RepeatedMsgReduction` configuration directive in `/etc/rsyslog.conf`. Default is 'on' -* `node['rsyslog']['logs_to_forward']` - Specifies what logs should be sent to the remote rsyslog server. Default is all ( \*.\* ). -* `node['rsyslog']['default_log_dir']` - log directory used in `50-default.conf` template, defaults to `/var/log` -* `node['rsyslog']['default_facility_logs']` - Hash containing log facilities and destinations used in `50-default.conf` template. -* `node['rsyslog']['default_file_template']` - The name of a pre-defined log format template (ie - RSYSLOG_FileFormat), used for local log files. -* `node['rsyslog']['default_remote_template']` - The name of a pre-defined log format template (ie - RSYSLOG_FileFormat), used for sending to remote servers. -* `node['rsyslog']['rate_limit_interval']` - Value of the $SystemLogRateLimitInterval configuration directive in `/etc/rsyslog.conf`. Default is nil, leaving it to the platform default. -* `node['rsyslog']['rate_limit_burst']` - Value of the $SystemLogRateLimitBurst configuration directive in `/etc/rsyslog.conf`. Default is nil, leaving it to the platform default. -* `node['rsyslog']['action_queue_max_disk_space']` - Max amount of disk space the disk-assisted queue is allowed to use ([more info](http://www.rsyslog.com/doc/queues.html)). -* `node['rsyslog']['enable_tls']` - Whether or not to enable TLS encryption. When enabled, forces protocol to `tcp`. Default is `false`. -* `node['rsyslog']['tls_ca_file']` - Path to TLS CA file. Required for both server and clients. -* `node['rsyslog']['tls_certificate_file']` - Path to TLS certificate file. Required for server, optional for clients. -* `node['rsyslog']['tls_key_file']` - Path to TLS key file. Required for server, optional for clients. -* `node['rsyslog']['tls_auth_mode']` - Value for `$InputTCPServerStreamDriverAuthMode`/`$ActionSendStreamDriverAuthMode`, determines whether client certs are validated. Defaults to `anon` (no validation). -* `node['rsyslog']['use_local_ipv4']` - Whether or not to make use the remote local IPv4 address on cloud systems when searching for servers (where available). Default is 'false'. -* `node['rsyslog']['allow_non_local']` - Whether or not to allow non-local messages. If 'false', incoming messages are only allowed from 127.0.0.1. Default is 'false'. -* `node['rsyslog']['custom_remote']` - Array of hashes for configuring custom remote server targets -* `node['rsyslog']['additional_directives']` - Hash of additional directives and their values to place in the main rsyslog config file - -Recipes -------- -### default -Installs the rsyslog package, manages the rsyslog service and sets up basic configuration for a standalone machine. - -### client -Includes `recipe[rsyslog]`. - -Uses `node['rsyslog']['server_ip']` or Chef search (in that precedence order) to determine the remote syslog server's IP address. If search is used, the search query will look for the first `ipaddress` returned from the criteria specified in `node['rsyslog']['server_search']`. - -You can use `node['rsyslog']['custom_config']` to define custom entries for sending logs to remote servers. -Available attributes: -``` - 'server': Ip/hostname of remote syslog server (Required) - 'port': Port to send logs to - 'logs': Syslog log facilities to send (auth, authpriv, daemon, etc) - 'protocol': Can be tcp or udp - 'remote_template': Rsyslog template used for the messages -``` - -Example: - -```ruby -node['rsyslog']['custom_remote'] = [{ 'server' => '10.10.4.4', 'port' => '567', 'logs' => 'auth.*,mail.*', 'protocol' => 'udp', 'remote_template' => 'RSYSLOG_SyslogProtocol23Format'}, - { 'server' => '10.0.0.3', 'port' => '555', 'logs' => 'authpriv,daemon.*' } ] -``` - -The server key is required; if other keys are left out, the default global values will be used (eg `node['rsyslog']['port']` will be used if 'port' is omitted) - - -If the node itself is a rsyslog server ie it has `rsyslog.server` set to true then the configuration is skipped. - -If the node had an `/etc/rsyslog.d/35-server-per-host.conf` file previously configured, this file gets removed to prevent duplicate logging. - -Any previous logs are not cleaned up from the `log_dir`. - -### server -Configures the node to be a rsyslog server. The chosen rsyslog server node should be defined in the `server_ip` attribute or resolvable by the specified search criteria specified in `node['rsyslog']['server_search]` (so that nodes making use of the `client` recipe can find the server to log to). - -This recipe will create the logs in `node['rsyslog']['log_dir']`, and the configuration is in `/etc/rsyslog.d/server.conf`. This recipe also removes any previous configuration to a remote server by removing the `/etc/rsyslog.d/remote.conf` file. - -The cron job used in the previous version of this cookbook is removed, but it does not remove any existing cron job from your system (so it doesn't break anything unexpectedly). We recommend setting up logrotate for the logfiles instead. - -The `log_dir` will be concatenated with `per_host_dir` to store the logs for each client. Modify the attribute to have a value that is allowed by rsyslogs template matching values, see the rsyslog documentation for this. - -Directory structure: - -```erb -<%= @log_dir %>/<%= @per_host_dir %>/"logfile" -``` - -For example for the system with hostname `www`: - -```text -/srv/rsyslog/2011/11/19/www/messages -``` - -For example, to change this to just the hostname, set the attribute `node['rsyslog']['per_host_dir']` via a role: - -```ruby -"rsyslog" => { "per_host_dir" => "%HOSTNAME%" } -``` - -At this time, the server can only listen on UDP *or* TCP. - -Resources -========= - -file_input ----------- - -Configures a [text file input -monitor](http://www.rsyslog.com/doc/imfile.html) to push a log file into -rsyslog. - -Attributes: -* `name`: name of the resource, also used for the syslog tag. Required. -* `file`: file path for input file to monitor. Required. -* `priority`: config order priority. Defaults to `99`. -* `severity`: syslog severity. Must be one of `emergency`, `alert`, -`critical`, `error`, `warning`, `notice`, `info` or `debug`. If -undefined, rsyslog interprets this as `notice`. -* `facility`: syslog facility. Must be one of `auth`, `authpriv`, -`daemon`, `cron`, `ftp`, `lpr`, `kern`, `mail`, `news`, `syslog`, -`user`, `uucp`, `local0`, ... , `local7`. If undefined, rsyslog -interprets this as `local0`. -* `cookbook`: cookbook containing the template. Defaults to `rsyslog`. -* `source`: template file source. Defaults to `file-input.conf.erb` - - -Usage -===== -Use `recipe[rsyslog]` to install and start rsyslog as a basic configured service for standalone systems. - -Use `recipe[rsyslog::client]` to have nodes log to a remote server (which is found via the `server_ip` attribute or by the recipe's search call -- see __client__) - -Use `recipe[rsyslog::server]` to set up a rsyslog server. It will listen on `node['rsyslog']['port']` protocol `node['rsyslog']['protocol']`. - -If you set up a different kind of centralized loghost (syslog-ng, graylog2, logstash, etc), you can still send log messages to it as long as the port and protocol match up with the server software. See __Examples__ - -Use `rsyslog_file_input` within your recipes to forward log files to -your remote syslog server. - - -### Examples -A `base` role (e.g., roles/base.rb), applied to all nodes so they are syslog clients: - -```ruby -name "base" -description "Base role applied to all nodes -run_list("recipe[rsyslog::client]") -``` - -Then, a role for the loghost (should only be one): - -```ruby -name "loghost" -description "Central syslog server" -run_list("recipe[rsyslog::server]") -``` - -By default this will set up the clients search for a node with the `loghost` role to talk to the server on TCP port 514. Change the `protocol` and `port` rsyslog attributes to modify this. - -If you want to specify another syslog compatible server with a role other than loghost, simply fill free to use the `server_ip` attribute or the `server_search` attribute. - -Example role that sets the per host directory: - -```ruby -name "loghost" -description "Central syslog server" -run_list("recipe[rsyslog::server]") -default_attributes( - "rsyslog" => { "per_host_dir" => "%HOSTNAME%" } -) -``` - -Default rsyslog options are rendered for RHEL family platforms, in `/etc/rsyslog.d/50-default.conf` -with other platforms using a configuration like Debian family defaults. You can override these -log facilities and destinations using the `rsyslog['default_facility_logs']` hash. - -```ruby -name "facility_log_example" -run_list("recipe[rsyslog::default]") -default_attributes( - "rsyslog" => { - "default_facility_logs" => { - '*.info;mail.none;authpriv.none;cron.none' => "/var/log/messages", - 'authpriv' => '/var/log/secure', - 'mail.*' => '-/var/log/maillog', - '*.emerg' => '*' - } - } -) -``` - -Development ------------ -This section details "quick development" steps. For a detailed explanation, see [[Contributing.md]]. - -1. Clone this repository from GitHub: - - $ git clone git@github.com:chef-cookbooks/rsyslog.git - -2. Create a git branch - - $ git checkout -b my_bug_fix - -3. Install dependencies: - - $ bundle install - -4. Make your changes/patches/fixes, committing appropriately -5. **Write tests** -6. Run the tests: - - bundle exec foodcritic -f any . - - bundle exec rspec - - bundle exec rubocop - - bundle exec kitchen test - - In detail: - - Foodcritic will catch any Chef-specific style errors - - RSpec will run the unit tests - - Rubocop will check for Ruby-specific style errors - - Test Kitchen will run and converge the recipes - - -License & Authors ------------------ -- Author:: Joshua Timberman () -- Author:: Denis Barishev () -- Author:: Tim Smith () - -```text -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 - - 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/rsyslog/attributes/default.rb b/cookbooks/rsyslog/attributes/default.rb deleted file mode 100644 index 1bfe703..0000000 --- a/cookbooks/rsyslog/attributes/default.rb +++ /dev/null @@ -1,131 +0,0 @@ -# -# Cookbook Name:: rsyslog -# Attributes:: default -# -# 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 -# -# 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. -# - -default['rsyslog']['default_log_dir'] = '/var/log' -default['rsyslog']['log_dir'] = '/srv/rsyslog' -default['rsyslog']['working_dir'] = '/var/spool/rsyslog' -default['rsyslog']['server'] = false -default['rsyslog']['use_relp'] = false -default['rsyslog']['relp_port'] = 20_514 -default['rsyslog']['protocol'] = 'tcp' -default['rsyslog']['bind'] = '*' -default['rsyslog']['port'] = 514 -default['rsyslog']['server_ip'] = nil -default['rsyslog']['server_search'] = 'role:loghost' -default['rsyslog']['remote_logs'] = true -default['rsyslog']['per_host_dir'] = '%$YEAR%/%$MONTH%/%$DAY%/%HOSTNAME%' -default['rsyslog']['max_message_size'] = '2k' -default['rsyslog']['preserve_fqdn'] = 'off' -default['rsyslog']['high_precision_timestamps'] = false -default['rsyslog']['repeated_msg_reduction'] = 'on' -default['rsyslog']['logs_to_forward'] = '*.*' -default['rsyslog']['enable_imklog'] = true -default['rsyslog']['config_prefix'] = '/etc' -default['rsyslog']['default_file_template'] = nil -default['rsyslog']['default_remote_template'] = nil -default['rsyslog']['rate_limit_interval'] = nil -default['rsyslog']['rate_limit_burst'] = nil -default['rsyslog']['enable_tls'] = false -default['rsyslog']['action_queue_max_disk_space'] = '1G' -default['rsyslog']['tls_ca_file'] = nil -default['rsyslog']['tls_certificate_file'] = nil -default['rsyslog']['tls_key_file'] = nil -default['rsyslog']['tls_auth_mode'] = 'anon' -default['rsyslog']['use_local_ipv4'] = false -default['rsyslog']['allow_non_local'] = false -default['rsyslog']['custom_remote'] = [{}] -default['rsyslog']['additional_directives'] = {} - -# The most likely platform-specific attributes -default['rsyslog']['service_name'] = 'rsyslog' -default['rsyslog']['user'] = 'root' -default['rsyslog']['group'] = 'adm' -default['rsyslog']['priv_seperation'] = false -default['rsyslog']['priv_user'] = nil -default['rsyslog']['priv_group'] = nil -default['rsyslog']['modules'] = %w(imuxsock imklog) - -# platform family specific attributes -case node['platform_family'] -when 'rhel', 'fedora' - default['rsyslog']['working_dir'] = '/var/lib/rsyslog' - # format { facility => destination } - default['rsyslog']['default_facility_logs'] = { - '*.info;mail.none;authpriv.none;cron.none' => "#{node['rsyslog']['default_log_dir']}/messages", - 'authpriv.*' => "#{node['rsyslog']['default_log_dir']}/secure", - 'mail.*' => "-#{node['rsyslog']['default_log_dir']}/maillog", - 'cron.*' => "#{node['rsyslog']['default_log_dir']}/cron", - '*.emerg' => ':omusrmsg:*', - 'uucp,news.crit' => "#{node['rsyslog']['default_log_dir']}/spooler", - 'local7.*' => "#{node['rsyslog']['default_log_dir']}/boot.log" - } - # RHEL >= 7 and Fedora >= 19 use journald in systemd. Amazon Linux doesn't. - if node['platform'] != 'amazon' && (node['platform_version'].to_i == 7 || node['platform_version'].to_i >= 19) - default['rsyslog']['modules'] = %w(imuxsock imjournal) - default['rsyslog']['additional_directives'] = { 'OmitLocalLogging' => 'on', 'IMJournalStateFile' => 'imjournal.state' } - end -else - # format { facility => destination } - default['rsyslog']['default_facility_logs'] = { - 'auth,authpriv.*' => "#{node['rsyslog']['default_log_dir']}/auth.log", - '*.*;auth,authpriv.none' => "-#{node['rsyslog']['default_log_dir']}/syslog", - 'daemon.*' => "-#{node['rsyslog']['default_log_dir']}/daemon.log", - 'kern.*' => "-#{node['rsyslog']['default_log_dir']}/kern.log", - 'mail.*' => "-#{node['rsyslog']['default_log_dir']}/mail.log", - 'user.*' => "-#{node['rsyslog']['default_log_dir']}/user.log", - 'mail.info' => "-#{node['rsyslog']['default_log_dir']}/mail.info", - 'mail.warn' => "-#{node['rsyslog']['default_log_dir']}/mail.warn", - 'mail.err' => "#{node['rsyslog']['default_log_dir']}/mail.err", - 'news.crit' => "#{node['rsyslog']['default_log_dir']}/news/news.crit", - 'news.err' => "#{node['rsyslog']['default_log_dir']}/news/news.err", - 'news.notice' => "-#{node['rsyslog']['default_log_dir']}/news/news.notice", - '*.=debug;auth,authpriv.none;news.none;mail.none' => "-#{node['rsyslog']['default_log_dir']}/debug", - '*.=info;*.=notice;*.=warn;auth,authpriv.none;cron,daemon.none;mail,news.none' => "-#{node['rsyslog']['default_log_dir']}/messages", - '*.emerg' => ':omusrmsg:*' - } -end - -# rsyslog 3/4 do not support the new :omusrmsg:* format and need * instead -if (node['platform'] == 'ubuntu' && node['platform_version'].to_i < 12) || (node['platform_family'] == 'rhel' && node['platform_version'].to_i < 6) - default['rsyslog']['default_facility_logs']['*.emerg'] = '*' -end - -# platform specific attributes -case node['platform'] -when 'ubuntu' - # syslog user introduced with natty package - if node['platform_version'].to_f >= 11.04 - default['rsyslog']['user'] = 'syslog' - default['rsyslog']['group'] = 'adm' - default['rsyslog']['priv_seperation'] = true - default['rsyslog']['priv_group'] = 'syslog' - end -when 'arch' - default['rsyslog']['service_name'] = 'rsyslogd' -when 'smartos' - default['rsyslog']['config_prefix'] = '/opt/local/etc' - default['rsyslog']['modules'] = %w(immark imsolaris imtcp imudp) - default['rsyslog']['group'] = 'root' -when 'omnios' - default['rsyslog']['service_name'] = 'system/rsyslogd' - default['rsyslog']['modules'] = %w(immark imsolaris imtcp imudp) - default['rsyslog']['group'] = 'root' -when 'suse' - default['rsyslog']['service_name'] = 'syslog' -end diff --git a/cookbooks/rsyslog/libraries/helpers.rb b/cookbooks/rsyslog/libraries/helpers.rb deleted file mode 100644 index 176a6d8..0000000 --- a/cookbooks/rsyslog/libraries/helpers.rb +++ /dev/null @@ -1,25 +0,0 @@ -module RsyslogCookbook - # helpers for the various service providers on Ubuntu systems - module Helpers - def find_provider - if Chef::VersionConstraint.new('>= 15.04').include?(node['platform_version']) - service_provider = Chef::Provider::Service::Systemd - elsif Chef::VersionConstraint.new('>= 12.04').include?(node['platform_version']) - service_provider = Chef::Provider::Service::Upstart - else - service_provider = nil - end - service_provider - end - - def declare_rsyslog_service - service_provider = 'ubuntu' == node['platform'] ? find_provider : nil - - service node['rsyslog']['service_name'] do - supports restart: true, status: true - action [:enable, :start] - provider service_provider - end - end - end -end diff --git a/cookbooks/rsyslog/metadata.json b/cookbooks/rsyslog/metadata.json deleted file mode 100644 index 058e4b1..0000000 --- a/cookbooks/rsyslog/metadata.json +++ /dev/null @@ -1 +0,0 @@ -{"name":"rsyslog","version":"2.2.0","description":"Installs and configures rsyslog","long_description":"rsyslog Cookbook\n================\n[![Build Status](https://travis-ci.org/chef-cookbooks/rsyslog.svg?branch=master)](http://travis-ci.org/chef-cookbooks/rsyslog)\n[![Cookbook Version](https://img.shields.io/cookbook/v/rsyslog.svg)](https://supermarket.chef.io/cookbooks/rsyslog)\n\nInstalls and configures rsyslog to replace sysklogd for client and/or server use. By default, the service will be configured to log to files on local disk. See the Recipes and Examples sections for other uses.\n\n\nRequirements\n------------\n#### Platforms\n- Debian/Ubuntu\n- RHEL/CentOS/Scientific/Amazon/Oracle\n- Fedora 20+\n- OmniOS r151006c\n\n#### Chef\n- Chef 11+\n\n#### Cookbooks\n- none\n\n#### Other\nTo use the `recipe[rsyslog::client]` recipe, you'll need to set up the `rsyslog.server_search` or `rsyslog.server_ip` attributes. See the __Recipes__ and __Examples__ sections below.\n\n\nAttributes\n----------\nSee `attributes/default.rb` for default values.\n\n* `node['rsyslog']['log_dir']` - If the node is an rsyslog server, this specifies the directory where the logs should be stored.\n* `node['rsyslog']['working_dir']` - The temporary working directory where messages are buffered\n* `node['rsyslog']['server']` - Determined automatically and set to true on the server.\n* `node['rsyslog']['server_ip']` - If not defined then search will be used to determine rsyslog server. Default is `nil`. This can be a string or an array.\n* `node['rsyslog']['server_search']` - Specify the criteria for the server search operation. Default is `role:loghost`.\n* `node['rsyslog']['protocol']` - Specify whether to use `udp` or `tcp` for remote loghost. Default is `tcp`. To use both specify both in a string e.g. 'udptcp'.\n* `node['rsyslog']['bind']` - Specify the address to which the server should be listening; only use with `node['rsyslog']['protocol'] = 'udp'` because the feature does not work with the `tcp` protocol ([more info](http://www.rsyslog.com/doc/master/configuration/modules/imtcp.html#caveats-known-bugs)).\n* `node['rsyslog']['port']` - Specify the port which rsyslog should connect to a remote loghost.\n* `node['rsyslog']['remote_logs']` - Specify whether to send all logs to a remote server (client option). Default is `true`.\n* `node['rsyslog']['per_host_dir']` - \"PerHost\" directories for template statements in `35-server-per-host.conf`. Default value is the previous cookbook version's value, to preserve compatibility. See __server__ recipe below.\n* `node['rsyslog']['priv_seperation']` - Whether to use privilege separation or not.\n* `node['rsyslog']['priv_user']` - User to run as when using privilege separation. Defult is `node['rsyslog']['user']`\n* `node['rsyslog']['priv_group']` - Group to run as when using privilege separation. Defult is `node['rsyslog']['group']`\n* `node['rsyslog']['max_message_size']` - Specify the maximum allowed message size. Default is 2k.\n* `node['rsyslog']['user']` - Who should own the configuration files and directories\n* `node['rsyslog']['group']` - Who should group-own the configuration files and directories\n* `node['rsyslog']['defaults_file']` - The full path to the defaults/sysconfig file for the service.\n* `node['rsyslog']['service_name']` - The platform-specific name of the service\n* `node['rsyslog']['preserve_fqdn']` - Value of the `$PreserveFQDN` configuration directive in `/etc/rsyslog.conf`. Default is 'off' for compatibility purposes.\n* `node['rsyslog']['high_precision_timestamps']` - Enable high precision timestamps, instead of the \"old style\" format. Default is 'false'.\n* `node['rsyslog']['repeated_msg_reduction']` - Value of `$RepeatedMsgReduction` configuration directive in `/etc/rsyslog.conf`. Default is 'on'\n* `node['rsyslog']['logs_to_forward']` - Specifies what logs should be sent to the remote rsyslog server. Default is all ( \\*.\\* ).\n* `node['rsyslog']['default_log_dir']` - log directory used in `50-default.conf` template, defaults to `/var/log`\n* `node['rsyslog']['default_facility_logs']` - Hash containing log facilities and destinations used in `50-default.conf` template.\n* `node['rsyslog']['default_file_template']` - The name of a pre-defined log format template (ie - RSYSLOG_FileFormat), used for local log files.\n* `node['rsyslog']['default_remote_template']` - The name of a pre-defined log format template (ie - RSYSLOG_FileFormat), used for sending to remote servers.\n* `node['rsyslog']['rate_limit_interval']` - Value of the $SystemLogRateLimitInterval configuration directive in `/etc/rsyslog.conf`. Default is nil, leaving it to the platform default.\n* `node['rsyslog']['rate_limit_burst']` - Value of the $SystemLogRateLimitBurst configuration directive in `/etc/rsyslog.conf`. Default is nil, leaving it to the platform default.\n* `node['rsyslog']['action_queue_max_disk_space']` - Max amount of disk space the disk-assisted queue is allowed to use ([more info](http://www.rsyslog.com/doc/queues.html)).\n* `node['rsyslog']['enable_tls']` - Whether or not to enable TLS encryption. When enabled, forces protocol to `tcp`. Default is `false`.\n* `node['rsyslog']['tls_ca_file']` - Path to TLS CA file. Required for both server and clients.\n* `node['rsyslog']['tls_certificate_file']` - Path to TLS certificate file. Required for server, optional for clients.\n* `node['rsyslog']['tls_key_file']` - Path to TLS key file. Required for server, optional for clients.\n* `node['rsyslog']['tls_auth_mode']` - Value for `$InputTCPServerStreamDriverAuthMode`/`$ActionSendStreamDriverAuthMode`, determines whether client certs are validated. Defaults to `anon` (no validation).\n* `node['rsyslog']['use_local_ipv4']` - Whether or not to make use the remote local IPv4 address on cloud systems when searching for servers (where available). Default is 'false'.\n* `node['rsyslog']['allow_non_local']` - Whether or not to allow non-local messages. If 'false', incoming messages are only allowed from 127.0.0.1. Default is 'false'.\n* `node['rsyslog']['custom_remote']` - Array of hashes for configuring custom remote server targets\n* `node['rsyslog']['additional_directives']` - Hash of additional directives and their values to place in the main rsyslog config file\n\nRecipes\n-------\n### default\nInstalls the rsyslog package, manages the rsyslog service and sets up basic configuration for a standalone machine.\n\n### client\nIncludes `recipe[rsyslog]`.\n\nUses `node['rsyslog']['server_ip']` or Chef search (in that precedence order) to determine the remote syslog server's IP address. If search is used, the search query will look for the first `ipaddress` returned from the criteria specified in `node['rsyslog']['server_search']`.\n\nYou can use `node['rsyslog']['custom_config']` to define custom entries for sending logs to remote servers.\nAvailable attributes:\n```\n 'server': Ip/hostname of remote syslog server (Required)\n 'port': Port to send logs to\n 'logs': Syslog log facilities to send (auth, authpriv, daemon, etc)\n 'protocol': Can be tcp or udp\n 'remote_template': Rsyslog template used for the messages\n```\n\nExample:\n\n```ruby\nnode['rsyslog']['custom_remote'] = [{ 'server' => '10.10.4.4', 'port' => '567', 'logs' => 'auth.*,mail.*', 'protocol' => 'udp', 'remote_template' => 'RSYSLOG_SyslogProtocol23Format'},\n { 'server' => '10.0.0.3', 'port' => '555', 'logs' => 'authpriv,daemon.*' } ]\n```\n\nThe server key is required; if other keys are left out, the default global values will be used (eg `node['rsyslog']['port']` will be used if 'port' is omitted)\n\n\nIf the node itself is a rsyslog server ie it has `rsyslog.server` set to true then the configuration is skipped.\n\nIf the node had an `/etc/rsyslog.d/35-server-per-host.conf` file previously configured, this file gets removed to prevent duplicate logging.\n\nAny previous logs are not cleaned up from the `log_dir`.\n\n### server\nConfigures the node to be a rsyslog server. The chosen rsyslog server node should be defined in the `server_ip` attribute or resolvable by the specified search criteria specified in `node['rsyslog']['server_search]` (so that nodes making use of the `client` recipe can find the server to log to).\n\nThis recipe will create the logs in `node['rsyslog']['log_dir']`, and the configuration is in `/etc/rsyslog.d/server.conf`. This recipe also removes any previous configuration to a remote server by removing the `/etc/rsyslog.d/remote.conf` file.\n\nThe cron job used in the previous version of this cookbook is removed, but it does not remove any existing cron job from your system (so it doesn't break anything unexpectedly). We recommend setting up logrotate for the logfiles instead.\n\nThe `log_dir` will be concatenated with `per_host_dir` to store the logs for each client. Modify the attribute to have a value that is allowed by rsyslogs template matching values, see the rsyslog documentation for this.\n\nDirectory structure:\n\n```erb\n<%= @log_dir %>/<%= @per_host_dir %>/\"logfile\"\n```\n\nFor example for the system with hostname `www`:\n\n```text\n/srv/rsyslog/2011/11/19/www/messages\n```\n\nFor example, to change this to just the hostname, set the attribute `node['rsyslog']['per_host_dir']` via a role:\n\n```ruby\n\"rsyslog\" => { \"per_host_dir\" => \"%HOSTNAME%\" }\n```\n\nAt this time, the server can only listen on UDP *or* TCP.\n\nResources\n=========\n\nfile_input\n----------\n\nConfigures a [text file input\nmonitor](http://www.rsyslog.com/doc/imfile.html) to push a log file into\nrsyslog.\n\nAttributes:\n* `name`: name of the resource, also used for the syslog tag. Required.\n* `file`: file path for input file to monitor. Required.\n* `priority`: config order priority. Defaults to `99`.\n* `severity`: syslog severity. Must be one of `emergency`, `alert`,\n`critical`, `error`, `warning`, `notice`, `info` or `debug`. If\nundefined, rsyslog interprets this as `notice`.\n* `facility`: syslog facility. Must be one of `auth`, `authpriv`,\n`daemon`, `cron`, `ftp`, `lpr`, `kern`, `mail`, `news`, `syslog`,\n`user`, `uucp`, `local0`, ... , `local7`. If undefined, rsyslog\ninterprets this as `local0`.\n* `cookbook`: cookbook containing the template. Defaults to `rsyslog`.\n* `source`: template file source. Defaults to `file-input.conf.erb`\n\n\nUsage\n=====\nUse `recipe[rsyslog]` to install and start rsyslog as a basic configured service for standalone systems.\n\nUse `recipe[rsyslog::client]` to have nodes log to a remote server (which is found via the `server_ip` attribute or by the recipe's search call -- see __client__)\n\nUse `recipe[rsyslog::server]` to set up a rsyslog server. It will listen on `node['rsyslog']['port']` protocol `node['rsyslog']['protocol']`.\n\nIf you set up a different kind of centralized loghost (syslog-ng, graylog2, logstash, etc), you can still send log messages to it as long as the port and protocol match up with the server software. See __Examples__\n\nUse `rsyslog_file_input` within your recipes to forward log files to\nyour remote syslog server.\n\n\n### Examples\nA `base` role (e.g., roles/base.rb), applied to all nodes so they are syslog clients:\n\n```ruby\nname \"base\"\ndescription \"Base role applied to all nodes\nrun_list(\"recipe[rsyslog::client]\")\n```\n\nThen, a role for the loghost (should only be one):\n\n```ruby\nname \"loghost\"\ndescription \"Central syslog server\"\nrun_list(\"recipe[rsyslog::server]\")\n```\n\nBy default this will set up the clients search for a node with the `loghost` role to talk to the server on TCP port 514. Change the `protocol` and `port` rsyslog attributes to modify this.\n\nIf you want to specify another syslog compatible server with a role other than loghost, simply fill free to use the `server_ip` attribute or the `server_search` attribute.\n\nExample role that sets the per host directory:\n\n```ruby\nname \"loghost\"\ndescription \"Central syslog server\"\nrun_list(\"recipe[rsyslog::server]\")\ndefault_attributes(\n \"rsyslog\" => { \"per_host_dir\" => \"%HOSTNAME%\" }\n)\n```\n\nDefault rsyslog options are rendered for RHEL family platforms, in `/etc/rsyslog.d/50-default.conf`\nwith other platforms using a configuration like Debian family defaults. You can override these\nlog facilities and destinations using the `rsyslog['default_facility_logs']` hash.\n\n```ruby\nname \"facility_log_example\"\nrun_list(\"recipe[rsyslog::default]\")\ndefault_attributes(\n \"rsyslog\" => {\n \"default_facility_logs\" => {\n '*.info;mail.none;authpriv.none;cron.none' => \"/var/log/messages\",\n 'authpriv' => '/var/log/secure',\n 'mail.*' => '-/var/log/maillog',\n '*.emerg' => '*'\n }\n }\n)\n```\n\nDevelopment\n-----------\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/rsyslog.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 appropriately\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\nLicense & Authors\n-----------------\n- Author:: Joshua Timberman ()\n- Author:: Denis Barishev ()\n- Author:: Tim Smith ()\n\n```text\nCopyright:: 2009-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":{"ubuntu":">= 10.04","debian":">= 5.0","redhat":">= 5.0","centos":">= 5.0","fedora":">= 20.0","scientific":">= 0.0.0","amazon":">= 0.0.0","oracle":">= 0.0.0"},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{"rsyslog":{"display_name":"Rsyslog","description":"Hash of Rsyslog attributes","type":"hash"},"rsyslog/log_dir":{"display_name":"Rsyslog Log Directory","description":"Filesystem location of logs from clients","default":"/srv/rsyslog"},"rsyslog/server":{"display_name":"Rsyslog Server?","description":"Is this node an rsyslog server?","default":"false"},"rsyslog/server_ip":{"display_name":"Rsyslog Server IP Address","description":"Set rsyslog server ip address explicitly"},"rsyslog/server_search":{"display_name":"Rsyslog Server Search Criteria","description":"Set the search criteria for rsyslog server resolving","default":"role:loghost"},"rsyslog/protocol":{"display_name":"Rsyslog Protocol","description":"Set which network protocol to use for rsyslog","default":"tcp"},"rsyslog/port":{"display_name":"Rsyslog Port","description":"Port that Rsyslog listens for incoming connections","default":"514"},"rsyslog/remote_logs":{"display_name":"Remote Logs","description":"Specifies whether redirect all log from client to server","default":"true"},"rsyslog/user":{"display_name":"User","description":"The owner of Rsyslog config files and directories","default":"root"},"rsyslog/group":{"display_name":"Group","description":"The group-owner of Rsyslog config files and directories","default":"adm"},"rsyslog/service_name":{"display_name":"Service name","description":"The name of the service for the platform","default":"rsyslog"},"rsyslog/max_message_size":{"display_name":"Maximum Rsyslog message size","description":"Specifies the maximum size of allowable Rsyslog messages","default":"2k"},"rsyslog/preserve_fqdn":{"display_name":"Preserve FQDN","description":"Specifies if the short or full host name will be used. The default off setting is more compatible.","default":"off"},"rsyslog/repeated_msg_reduction":{"display_name":"Filter duplicated messages","description":"Specifies whether or not repeated messages should be reduced.","default":"on"},"rsyslog/priv_seperation":{"display_name":"Privilege separation","description":"Whether or not to make use of Rsyslog privilege separation","default":"false"},"rsyslog/default_file_template":{"display_name":"Default file log format template","description":"The name of a pre-defined log format template (ie - `RSYSLOG_FileFormat`), used for local log files."},"rsyslog/default_remote_template":{"display_name":"Default remote log format template","description":"The name of a pre-defined log format template (ie - `RSYSLOG_SyslogProtocol23Format`), used for remote log forwarding."},"rsyslog/enable_tls":{"display_name":"Enable TLS","description":"Whether or not to enable TLS encryption. When enabled, forces protocol to \"tcp\"","default":"false"},"rsyslog/tls_ca_file":{"display_name":"TLS CA file","description":"Path to TLS CA file. Required for both server and clients."},"rsyslog/tls_certificate_file":{"display_name":"TLS certificate file","description":"Path to TLS certificate file. Required for server, optional for clients."},"rsyslog/tls_key_file":{"display_name":"TLS key file","description":"Path to TLS key file. Required for server, optional for clients."},"rsyslog/tls_auth_mode":{"display_name":"TLS auth mode","description":"Value for \"$InputTCPServerStreamDriverAuthMode\"/\"$ActionSendStreamDriverAuthMode\", determines whether client certs are validated.","default":"anon"},"rsyslog/use_local_ipv4":{"display_name":"Try to use local IPv4 address","description":"Whether or not to make use the remote local IPv4 address on cloud systems when searching for servers (where available).","default":"false"},"rsyslog/allow_non_local":{"display_name":"Allow non-local messages","description":"Allow processing of messages coming any IP, not just 127.0.0.1","default":"false"}},"groupings":{},"recipes":{"rsyslog":"Installs rsyslog","rsyslog::client":"Sets up a client to log to a remote rsyslog server","rsyslog::server":"Sets up an rsyslog server"},"source_url":"https://github.com/chef-cookbooks/rsyslog","issues_url":"https://github.com/chef-cookbooks/rsyslog/issues"} \ No newline at end of file diff --git a/cookbooks/rsyslog/providers/file_input.rb b/cookbooks/rsyslog/providers/file_input.rb deleted file mode 100644 index a5b6543..0000000 --- a/cookbooks/rsyslog/providers/file_input.rb +++ /dev/null @@ -1,44 +0,0 @@ -# Cookbook Name:: rsyslog -# Provider:: file_input -# -# Copyright 2012-2015, Joseph Holsten -# -# 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. -# - -# support whyrun -def whyrun_supported? - true -end - -use_inline_resources - -include RsyslogCookbook::Helpers - -action :create do - declare_rsyslog_service - - template "/etc/rsyslog.d/#{new_resource.priority}-#{new_resource.name}.conf" do - mode '0664' - owner node['rsyslog']['user'] - group node['rsyslog']['group'] - source new_resource.source - cookbook new_resource.cookbook - variables 'file_name' => new_resource.file, - 'tag' => new_resource.name, - 'state_file' => new_resource.name, - 'severity' => new_resource.severity, - 'facility' => new_resource.facility - notifies :restart, resources('service[rsyslog]') - end -end diff --git a/cookbooks/rsyslog/recipes/client.rb b/cookbooks/rsyslog/recipes/client.rb deleted file mode 100644 index 4cc55e6..0000000 --- a/cookbooks/rsyslog/recipes/client.rb +++ /dev/null @@ -1,87 +0,0 @@ -# -# Cookbook Name:: rsyslog -# Recipe:: client -# -# 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 -# -# 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. -# - -# Do not run this recipe if the server attribute is set -return if node['rsyslog']['server'] - -include_recipe 'rsyslog::default' - -def chef_solo_search_installed? - klass = ::Search.const_get('Helper') - return klass.is_a?(Class) -rescue NameError - return false -end - -# On Chef Solo, we use the node['rsyslog']['server_ip'] attribute, and on -# normal Chef, we leverage the search query. -if Chef::Config[:solo] && !chef_solo_search_installed? - if node['rsyslog']['server_ip'] - server_ips = Array(node['rsyslog']['server_ip']) - else - Chef::Application.fatal!("Chef Solo does not support search. You must set node['rsyslog']['server_ip'] or use the chef-solo-search cookbook!") - end -else - results = search(:node, node['rsyslog']['server_search']).map do |server| - ipaddress = server['ipaddress'] - # If both server and client are on the same cloud and local network, they may be - # instructed to communicate via the internal interface by enabling `use_local_ipv4` - if node['rsyslog']['use_local_ipv4'] && server.attribute?('cloud') && server['cloud']['local_ipv4'] - ipaddress = server['cloud']['local_ipv4'] - end - ipaddress - end - server_ips = Array(node['rsyslog']['server_ip']) + Array(results) -end - -rsyslog_servers = [] - -server_ips.each do |ip| - rsyslog_servers << { 'server' => ip, 'port' => node['rsyslog']['port'], 'logs' => node['rsyslog']['logs_to_forward'], 'protocol' => node['rsyslog']['protocol'], 'remote_template' => node['rsyslog']['default_remote_template'] } -end - -unless node['rsyslog']['custom_remote'].first.empty? - node['rsyslog']['custom_remote'].each do |server| - if server['server'].nil? - Chef::Application.fatal!('Found a custom_remote server with no IP. Check your custom_remote attribute definition!') - end - end - rsyslog_servers += node['rsyslog']['custom_remote'] -end - -if rsyslog_servers.empty? - Chef::Application.fatal!('The rsyslog::client recipe was unable to determine the remote syslog server. Checked both the server_ip attribute and search!') -end - -remote_type = node['rsyslog']['use_relp'] ? 'relp' : 'remote' - -template "#{node['rsyslog']['config_prefix']}/rsyslog.d/49-remote.conf" do - source "49-#{remote_type}.conf.erb" - owner 'root' - group 'root' - mode '0644' - variables(servers: rsyslog_servers) - notifies :restart, "service[#{node['rsyslog']['service_name']}]" - only_if { node['rsyslog']['remote_logs'] } -end - -file "#{node['rsyslog']['config_prefix']}/rsyslog.d/server.conf" do - action :delete - notifies :restart, "service[#{node['rsyslog']['service_name']}]" -end diff --git a/cookbooks/rsyslog/recipes/default.rb b/cookbooks/rsyslog/recipes/default.rb deleted file mode 100644 index c35b194..0000000 --- a/cookbooks/rsyslog/recipes/default.rb +++ /dev/null @@ -1,89 +0,0 @@ -# -# Cookbook Name:: rsyslog -# Recipe:: default -# -# 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 -# -# 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. -# - -extend RsyslogCookbook::Helpers - -package 'rsyslog' -package 'rsyslog-relp' if node['rsyslog']['use_relp'] - -if node['rsyslog']['enable_tls'] && node['rsyslog']['tls_ca_file'] - Chef::Application.fatal!("Recipe rsyslog::default can not use 'enable_tls' with protocol '#{node['rsyslog']['protocol']}' (requires 'tcp')") unless node['rsyslog']['protocol'] == 'tcp' - package 'rsyslog-gnutls' -end - -directory "#{node['rsyslog']['config_prefix']}/rsyslog.d" do - owner 'root' - group 'root' - mode '0755' -end - -directory node['rsyslog']['working_dir'] do - owner node['rsyslog']['user'] - group node['rsyslog']['group'] - mode '0700' -end - -# Our main stub which then does its own rsyslog-specific -# include of things in /etc/rsyslog.d/* -template "#{node['rsyslog']['config_prefix']}/rsyslog.conf" do - source 'rsyslog.conf.erb' - owner 'root' - group 'root' - mode '0644' - notifies :restart, "service[#{node['rsyslog']['service_name']}]" -end - -template "#{node['rsyslog']['config_prefix']}/rsyslog.d/50-default.conf" do - source '50-default.conf.erb' - owner 'root' - group 'root' - mode '0644' - notifies :restart, "service[#{node['rsyslog']['service_name']}]" -end - -# syslog needs to be stopped before rsyslog can be started on RHEL versions before 6.0 -if platform_family?('rhel') && node['platform_version'].to_i < 6 - service 'syslog' do - action [:stop, :disable] - end -elsif platform_family?('smartos', 'omnios') - # syslog needs to be stopped before rsyslog can be started on SmartOS, OmniOS - service 'system-log' do - action :disable - end -end - -if platform_family?('omnios') - # manage the SMF manifest on OmniOS - template '/var/svc/manifest/system/rsyslogd.xml' do - source 'omnios-manifest.xml.erb' - owner 'root' - group 'root' - mode '0644' - notifies :run, 'execute[import rsyslog manifest]', :immediately - end - - execute 'import rsyslog manifest' do - action :nothing - command 'svccfg import /var/svc/manifest/system/rsyslogd.xml' - notifies :restart, "service[#{node['rsyslog']['service_name']}]" - end -end - -declare_rsyslog_service diff --git a/cookbooks/rsyslog/recipes/server.rb b/cookbooks/rsyslog/recipes/server.rb deleted file mode 100644 index ec1391a..0000000 --- a/cookbooks/rsyslog/recipes/server.rb +++ /dev/null @@ -1,44 +0,0 @@ -# -# Cookbook Name:: rsyslog -# Recipe:: server -# -# 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 -# -# 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. -# - -# Manually set this attribute -node.set['rsyslog']['server'] = true - -include_recipe 'rsyslog::default' - -directory node['rsyslog']['log_dir'] do - owner node['rsyslog']['user'] - group node['rsyslog']['group'] - mode '0755' - recursive true -end - -template "#{node['rsyslog']['config_prefix']}/rsyslog.d/35-server-per-host.conf" do - source '35-server-per-host.conf.erb' - owner 'root' - group 'root' - mode '0644' - notifies :restart, "service[#{node['rsyslog']['service_name']}]" -end - -file "#{node['rsyslog']['config_prefix']}/rsyslog.d/remote.conf" do - action :delete - notifies :restart, "service[#{node['rsyslog']['service_name']}]" - only_if { ::File.exist?("#{node['rsyslog']['config_prefix']}/rsyslog.d/remote.conf") } -end diff --git a/cookbooks/rsyslog/resources/file_input.rb b/cookbooks/rsyslog/resources/file_input.rb deleted file mode 100644 index 05a4d8b..0000000 --- a/cookbooks/rsyslog/resources/file_input.rb +++ /dev/null @@ -1,28 +0,0 @@ -# Cookbook Name:: rsyslog -# Resource:: file_input -# -# Copyright 2012-2015, Joseph Holsten -# -# 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 :name, kind_of: String, name_attribute: true, required: true -attribute :file, kind_of: String, required: true -attribute :priority, kind_of: Integer, default: 99 -attribute :severity, kind_of: String -attribute :facility, kind_of: String -attribute :cookbook, kind_of: String, default: 'rsyslog' -attribute :source, kind_of: String, default: 'file-input.conf.erb' diff --git a/cookbooks/rsyslog/templates/default/35-server-per-host.conf.erb b/cookbooks/rsyslog/templates/default/35-server-per-host.conf.erb deleted file mode 100644 index bdb3eca..0000000 --- a/cookbooks/rsyslog/templates/default/35-server-per-host.conf.erb +++ /dev/null @@ -1,62 +0,0 @@ -# Generated by Chef -# Local modifications will be overwritten - -<% if node['rsyslog']['use_relp'] -%> -$ModLoad imrelp -$InputRELPServerRun <%= node['rsyslog']['relp_port'] %> -<% end -%> -$DirGroup <%= node['rsyslog']['group'] %> -$DirCreateMode 0755 -$FileGroup <%= node['rsyslog']['group'] %> - -$template PerHostAuth,"<%= node['rsyslog']['log_dir'] %>/<%= node['rsyslog']['per_host_dir'] %>/auth.log" -$template PerHostCron,"<%= node['rsyslog']['log_dir'] %>/<%= node['rsyslog']['per_host_dir'] %>/cron.log" -$template PerHostSyslog,"<%= node['rsyslog']['log_dir'] %>/<%= node['rsyslog']['per_host_dir'] %>/syslog" -$template PerHostDaemon,"<%= node['rsyslog']['log_dir'] %>/<%= node['rsyslog']['per_host_dir'] %>/daemon.log" -$template PerHostKern,"<%= node['rsyslog']['log_dir'] %>/<%= node['rsyslog']['per_host_dir'] %>/kern.log" -$template PerHostLpr,"<%= node['rsyslog']['log_dir'] %>/<%= node['rsyslog']['per_host_dir'] %>/lpr.log" -$template PerHostUser,"<%= node['rsyslog']['log_dir'] %>/<%= node['rsyslog']['per_host_dir'] %>/user.log" -$template PerHostMail,"<%= node['rsyslog']['log_dir'] %>/<%= node['rsyslog']['per_host_dir'] %>/mail.log" -$template PerHostMailInfo,"<%= node['rsyslog']['log_dir'] %>/<%= node['rsyslog']['per_host_dir'] %>/mail.info" -$template PerHostMailWarn,"<%= node['rsyslog']['log_dir'] %>/<%= node['rsyslog']['per_host_dir'] %>/mail.warn" -$template PerHostMailErr,"<%= node['rsyslog']['log_dir'] %>/<%= node['rsyslog']['per_host_dir'] %>/mail.err" -$template PerHostNewsCrit,"<%= node['rsyslog']['log_dir'] %>/<%= node['rsyslog']['per_host_dir'] %>/news.crit" -$template PerHostNewsErr,"<%= node['rsyslog']['log_dir'] %>/<%= node['rsyslog']['per_host_dir'] %>/news.err" -$template PerHostNewsNotice,"<%= node['rsyslog']['log_dir'] %>/<%= node['rsyslog']['per_host_dir'] %>/news.notice" -$template PerHostDebug,"<%= node['rsyslog']['log_dir'] %>/<%= node['rsyslog']['per_host_dir'] %>/debug" -$template PerHostMessages,"<%= node['rsyslog']['log_dir'] %>/<%= node['rsyslog']['per_host_dir'] %>/messages" - -auth,authpriv.* ?PerHostAuth -*.*;auth,authpriv.none -?PerHostSyslog -cron.* ?PerHostCron -daemon.* -?PerHostDaemon -kern.* -?PerHostKern -lpr.* -?PerHostLpr -mail.* -?PerHostMail -user.* -?PerHostUser - -mail.info -?PerHostMailInfo -mail.warn ?PerHostMailWarn -mail.err ?PerHostMailErr - -news.crit ?PerHostNewsCrit -news.err ?PerHostNewsErr -news.notice -?PerHostNewsNotice - -*.=debug;\ - auth,authpriv.none;\ - news.none;mail.none -?PerHostDebug - -*.=info;*.=notice;*.=warn;\ - auth,authpriv.none;\ - cron,daemon.none;\ - mail,news.none -?PerHostMessages - - -<% unless node['rsyslog']['allow_non_local'] -%> -# -# Stop processing of all non-local messages. You can process remote messages -# on levels less than 35. -# -:fromhost-ip,!isequal,"127.0.0.1" ~ -<% end -%> diff --git a/cookbooks/rsyslog/templates/default/49-relp.conf.erb b/cookbooks/rsyslog/templates/default/49-relp.conf.erb deleted file mode 100644 index 22167bf..0000000 --- a/cookbooks/rsyslog/templates/default/49-relp.conf.erb +++ /dev/null @@ -1,10 +0,0 @@ -# Generated by Chef -$ModLoad omrelp -$ActionQueueType LinkedList # use asynchronous processing -$ActionQueueFileName srvrfwd # set file name, also enables disk mode -$ActionResumeRetryCount -1 # infinite retries on insert failure -$ActionQueueSaveOnShutdown on # save in-memory data if rsyslog shuts down - -<% @servers.each do |server| -%> -<%= node['rsyslog']['logs_to_forward'] %> :omrelp:<%= "#{server}:#{node['rsyslog']['relp_port']}" %><%= node['rsyslog']['default_remote_template'] ? ';' + node['rsyslog']['default_remote_template'] : nil %> -<% end -%> diff --git a/cookbooks/rsyslog/templates/default/49-remote.conf.erb b/cookbooks/rsyslog/templates/default/49-remote.conf.erb deleted file mode 100644 index dc3bcb5..0000000 --- a/cookbooks/rsyslog/templates/default/49-remote.conf.erb +++ /dev/null @@ -1,30 +0,0 @@ -# Generated by Chef -$ActionQueueType LinkedList # use asynchronous processing -$ActionQueueFileName srvrfwd # set file name, also enables disk mode -$ActionResumeRetryCount -1 # infinite retries on insert failure -$ActionQueueSaveOnShutdown on # save in-memory data if rsyslog shuts down -$ActionQueueMaxDiskSpace <%= node['rsyslog']['action_queue_max_disk_space'] %> # Don't use more than this much space for the queue -<% if node['rsyslog']['enable_tls'] && node['rsyslog']['tls_ca_file'] -%> -$DefaultNetstreamDriverCAFile <%= node['rsyslog']['tls_ca_file'] %> -<% if node['rsyslog']['tls_certificate_file'] -%> -$DefaultNetstreamDriverCertFile <%= node['rsyslog']['tls_certificate_file'] %> -<% end -%> -<% if node['rsyslog']['tls_key_file'] -%> -$DefaultNetstreamDriverKeyFile <%= node['rsyslog']['tls_key_file'] %> -<% end -%> - -$DefaultNetstreamDriver gtls -$ActionSendStreamDriverMode 1 -$ActionSendStreamDriverAuthMode <%= node['rsyslog']['tls_auth_mode'] %> -<% end -%> - -<% @servers.each do |server| -%> -<% case server['protocol'] -%> -<% when "tcp" -%> -<%= server['logs'] ? server['logs'] : node['rsyslog']['logs_to_forward'] %> @@<%= server['server'] %>:<%= server['port'] ? server['port'] : node['rsyslog']['port'] %><%= server['remote_template'] ? ';' + server['remote_template'] : nil %> -<% when "udp" -%> -<%= server['logs'] ? server['logs'] : node['rsyslog']['logs_to_forward'] %> @<%= server['server'] %>:<%= server['port'] ? server['port'] : node['rsyslog']['port'] %><%= server['remote_template'] ? ';' + server['remote_template'] : nil %> -<% else -%> -<%= server['logs'] ? server['logs'] : node['rsyslog']['logs_to_forward'] %><%= node['rsyslog']['protocol'] == "tcp" ? " @@" : " @" %><%= server['server'] %>:<%= server['port'] ? server['port'] : node['rsyslog']['port'] %><%= server['remote_template'] ? ';' + server['remote_template'] : nil %> -<% end -%> -<% end -%> diff --git a/cookbooks/rsyslog/templates/default/50-default.conf.erb b/cookbooks/rsyslog/templates/default/50-default.conf.erb deleted file mode 100644 index 38ef1b9..0000000 --- a/cookbooks/rsyslog/templates/default/50-default.conf.erb +++ /dev/null @@ -1,6 +0,0 @@ -# Generated by Chef -# For more information see rsyslog.conf(5) and /etc/rsyslog.conf - -<% node['rsyslog']['default_facility_logs'].each do |key, value| %> -<%= key %> <%= value %> -<% end %> diff --git a/cookbooks/rsyslog/templates/default/file-input.conf.erb b/cookbooks/rsyslog/templates/default/file-input.conf.erb deleted file mode 100644 index c500b8b..0000000 --- a/cookbooks/rsyslog/templates/default/file-input.conf.erb +++ /dev/null @@ -1,15 +0,0 @@ -# <%= @tag %>.conf - Syslog file inputs for <%= @tag %> -# -# Generated by Chef for <%= node['fqdn'] %> -# Local modifications will be overwritten. -$ModLoad imfile -$InputFileName <%= @file_name %> -$InputFileTag <%= @tag %>: -$InputFileStateFile <%= @state_file %> -<% if @severity %> -$InputFileSeverity <%= @severity %> -<% end %> -<% if @facility %> -$InputFileFacility <%= @facility %> -<% end %> -$InputRunFileMonitor diff --git a/cookbooks/rsyslog/templates/default/omnios-manifest.xml.erb b/cookbooks/rsyslog/templates/default/omnios-manifest.xml.erb deleted file mode 100644 index 4bff7e1..0000000 --- a/cookbooks/rsyslog/templates/default/omnios-manifest.xml.erb +++ /dev/null @@ -1,30 +0,0 @@ - - - - ' type='service' version='0'> - - - - - - - - - - - - - - - - - - - - - - diff --git a/cookbooks/rsyslog/templates/default/rsyslog.conf.erb b/cookbooks/rsyslog/templates/default/rsyslog.conf.erb deleted file mode 100644 index ca64812..0000000 --- a/cookbooks/rsyslog/templates/default/rsyslog.conf.erb +++ /dev/null @@ -1,117 +0,0 @@ -# Config generated by Chef - manual edits will be overwritten -# -# /etc/rsyslog.conf Configuration file for rsyslog. -# -# For more information see -# /usr/share/doc/rsyslog-doc/html/rsyslog_conf.html -# -# Default logging rules can be found in /etc/rsyslog.d/50-default.conf -# -# Set max message size -# -$MaxMessageSize <%= node['rsyslog']['max_message_size'] %> - -# -# Preserve FQDN -# -$PreserveFQDN <%= node['rsyslog']['preserve_fqdn'] %> - -################# -#### MODULES #### -################# - -<% if node['rsyslog']['modules'] && !node['rsyslog']['modules'].empty? %> - <% [*node['rsyslog']['modules']].each do |mod| %> -$ModLoad <%= mod %> - <% end %> -<% end %> - -<% if node['rsyslog']['server'] -%> - <% if node['rsyslog']['enable_tls'] && node['rsyslog']['tls_ca_file'] && - node['rsyslog']['tls_key_file'] && node['rsyslog']['tls_certificate_file'] -%> -$DefaultNetstreamDriver gtls -$DefaultNetstreamDriverCAFile <%= node['rsyslog']['tls_ca_file'] %> -$DefaultNetstreamDriverCertFile <%= node['rsyslog']['tls_certificate_file'] %> -$DefaultNetstreamDriverKeyFile <%= node['rsyslog']['tls_key_file'] %> - -$ModLoad imtcp - -$InputTCPServerStreamDriverMode 1 # run driver in TLS-only mode -$InputTCPServerStreamDriverAuthMode <%= node['rsyslog']['tls_auth_mode'] || 'anon' %> -$InputTCPServerRun <%= node['rsyslog']['port'] %> -# Provide <%= node['rsyslog']['protocol'].upcase %> log reception - <% else -%> -<% if node['rsyslog']['protocol'] =~ /tcp/ %> - $ModLoad imtcp - $InputTCPServerRun <%= node['rsyslog']['port'] %> -<% end -%> -<% if node['rsyslog']['protocol'] =~ /udp/ %> - $ModLoad imudp - $UDPServerAddress <%= node['rsyslog']['bind'] %> - $UDPServerRun <%= node['rsyslog']['port'] %> -<% end -%> - <% end -%> -<% end -%> - -########################### -#### GLOBAL DIRECTIVES #### -########################### - -<% if node["rsyslog"]["default_file_template"] -%> -# -# Default log format template -# -$ActionFileDefaultTemplate <%= node["rsyslog"]["default_file_template"] %> -<% elsif !node["rsyslog"]["high_precision_timestamps"] -%> -# -# Use traditional timestamp format. -# To enable high precision timestamps, comment out the following line. -# -$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat -<% end -%> - -# Filter duplicated messages -$RepeatedMsgReduction <%= node['rsyslog']['repeated_msg_reduction'] %> - -# -# Set temporary directory to buffer syslog queue -# -$WorkDirectory <%= node['rsyslog']['working_dir'] %> - -# -# Set the default permissions for all log files. -# -$FileOwner <%= node['rsyslog']['user'] %> -$FileGroup <%= node['rsyslog']['group'] %> -$FileCreateMode 0640 -$DirCreateMode 0755 -$Umask 0022 -<% if node['rsyslog']['priv_seperation'] %> -$PrivDropToUser <%= node['rsyslog']['priv_user'] || node['rsyslog']['user'] %> -$PrivDropToGroup <%= node['rsyslog']['priv_group'] || node['rsyslog']['group'] %> -<% end %> -<% unless node['rsyslog']['rate_limit_interval'].nil? %> -# -# Set the amount of time that is being measured for rate limiting -# -$SystemLogRateLimitInterval <%= node['rsyslog']['rate_limit_interval'] %> -<% end %> -<% unless node['rsyslog']['rate_limit_burst'].nil? %> -# -# Set the amount of messages, that have to occur in the time limit of -# SystemLogRateLimitInterval, to trigger rate limiting -# -$SystemLogRateLimitBurst <%= node['rsyslog']['rate_limit_burst'] %> -<% end %> - -# -# Set other directives -# -<% node['rsyslog']['additional_directives'].each_pair do |k,v| %> -$<%= k %> <%= v %> -<% end %> - -# -# Include all config files in <%= node['rsyslog']['config_prefix'] %>/rsyslog.d/ -# -$IncludeConfig <%= node['rsyslog']['config_prefix'] %>/rsyslog.d/*.conf diff --git a/cookbooks/rsyslog/templates/smartos/50-default.conf.erb b/cookbooks/rsyslog/templates/smartos/50-default.conf.erb deleted file mode 100644 index 083c1ba..0000000 --- a/cookbooks/rsyslog/templates/smartos/50-default.conf.erb +++ /dev/null @@ -1,18 +0,0 @@ -# Dropped of by Chef. Modifications will be lost. -# -# Default rules for rsyslog. -# -# For more information see rsyslog.conf(5) and <%= node['rsyslog']['config_prefix'] %>/rsyslog.conf - -*.err;kern.notice;auth.notice /dev/sysmsg -*.err;kern.debug;daemon.notice;mail.crit /var/adm/messages - -*.alert;kern.err;daemon.err operator -*.alert root - -*.emerg * - -mail.debug /var/log/syslog - -auth.info /var/log/auth.log -mail.info /var/log/postfix.log diff --git a/cookbooks/runit/CHANGELOG.md b/cookbooks/runit/CHANGELOG.md deleted file mode 100644 index 782f47d..0000000 --- a/cookbooks/runit/CHANGELOG.md +++ /dev/null @@ -1,232 +0,0 @@ -runit Cookbook CHANGELOG -======================== -This file is used to list changes made in each version of the runit cookbook. - -UNRELEASED ----------- - -v1.7.6 ----------- -* Ensure `supervise/ok` named pipe is properly removed when disabling a service, so that it can be enabled again (#166, #167, #172) -* Restore `restart_on_update` functionality originally added in [#20](https://github.com/hw-cookbooks/runit/pull/20) and lost in the 1.7.0 refactor. -* Update test cookbooks to fix broken tests revealed by restoring `restart_on_update` functionality. Now using socat instead of netcat. - -v1.7.4 (2015-10-13) ----------- -* Ensure the service directory exists so that we will succeed when enabling services (#153) -* Fix regression where env directory contents were being deleted when the `env` attribute is empty. (#144, #158) -* Add `log_dir` attribute, used only when `default_logger` is true. (#135) -* Ensure svlogd configuration is linked into correct path (#83, #135) -* Update README and CHANGELOG for v1.7.0 to warn against known regressions (#144, #157) -* Avoid mutating resource options for Chef 12 compatability (#147, #150, #156) -* Fix regression regarding waiting for the service socket before running (#138, #142) -* Reimplement idempotence checks for `runit_service` resources (#137, #141) -* Enhance ChefSpec unit test coverage with specs that step into the LWRP (#139) -* Deduplicate ServerSpec integration test coverage using example groups (#140) - -v1.7.2 (2015-06-19) ----------- -* Re-add missing runit_service actions start, stop, reload and status - -v1.7.0 (2015-06-18) ----------- - -**NOTE**: With the benefit of hindsight we can say that the changes contained in -this release merit a major version number change. Please be sure to test this -new version for compatibility with your systems before upgrading to version 1.7. - -* Modernize runit_service provider by rewriting pure Ruby as LWRP (#107) -* Modernize integration tests by rewriting Minitest suites as ServerSpec (#107) -* Fix regression in support for alternate sv binary on debian platforms (#92, #123) -* Fix regression in default logger's config location (#117) -* Tighten permissions on environment variable config files from 0644 to 0640 (#125) -* Add `start_down` and `delete_downfile` attributes to support configuring services with default state of 'down' (#105) - -v1.6.0 (2015-04-06) --------------------- -* Fedora 21 support -* Kitchen platform updates -* use imeyer’s packagecloud repo for RHEL -* fix converge_by usage -* do_action helper to set updated_by_last_action -* style fixes to provider - -v1.5.18 (2015-03-13) --------------------- -* Add helper methods to detect installation presence - -v1.5.16 (2015-02-11) --------------------- -* Allow removal of env files(nhuff) - -v1.5.14 (2015-01-15) --------------------- -* Provide create action(clako) - -v1.5.12 (2014-12-15) --------------------- -* prevent infinite loop inside docker container -* runit service failing inside docker container -* move to librarian-chef for kitchen dependency resolution -* update tests -* updates to chefspec matchers - -v1.5.10 (2014-03-07) --------------------- -PR #53- Fix runit RPM file location for Chef provisionless Centos 5.9 Box Image - - -v1.5.9 ------- -Fix runit RPM file location for Chef provisionless Centos 5.9 Box Image - -v1.5.8 ------- -Fixing string interpolation bug - - -v1.5.3 ------- -Fixing assignment/compare error - - -v1.5.1 ------- -### Bug -- **[COOK-3950](https://tickets.chef.io/browse/COOK-3950)** - runit cookbook should use full service path when checking running status - - -v1.5.0 ------- -### Improvement -- **[COOK-3267] - Improve testing suite in runit cookbook -- Updating test-kitchen harness -- Cleaning up style for rubocop - - -v1.4.4 ------- -fixing metadata version error. locking to < 3.0 - - -v1.4.2 ------- -Locking yum dependency to '< 3' - -v1.4.0 ------- -[COOK-3560] Allow the user to configure runit's timeout (-w) and verbose (-v) settings - - -v1.3.0 ------- -### Improvement -- **[COOK-3663](https://tickets.chef.io/browse/COOK-3663)** - Add ./check scripts support - -### Bug -- **[COOK-3271](https://tickets.chef.io/browse/COOK-3271)** - Fix an issue where runit fails to install rpm package on rehl systems - -v1.2.0 ------- -### New Feature -- **[COOK-3243](https://tickets.chef.io/browse/COOK-3243)** - Expose LSB init directory as a configurable - -### Bug -- **[COOK-3182](https://tickets.chef.io/browse/COOK-3182)** - Do not hardcode rpmbuild location - -### Improvement -- **[COOK-3175](https://tickets.chef.io/browse/COOK-3175)** - Add svlogd config file support -- **[COOK-3115](https://tickets.chef.io/browse/COOK-3115)** - Add ability to install 'runit' package from Yum - -v1.1.6 ------- -### Bug -- [COOK-2353]: Runit does not update run template if the service is already enabled -- [COOK-3013]: Runit install fails on rhel if converge is only partially successful - -v1.1.4 ------- -### Bug -- [COOK-2549]: cannot enable_service (lwrp) on Gentoo -- [COOK-2567]: Runit doesn't start at boot in Gentoo -- [COOK-2629]: runit tests have ruby 1.9 method chaning syntax -- [COOK-2867]: On debian, runit recipe will follow symlinks from /etc/init.d, overwrite /usr/bin/sv - -v1.1.2 ------- -- [COOK-2477] - runit cookbook should enable EPEL repo for CentOS 5 -- [COOK-2545] - Runit cookbook fails on Amazon Linux -- [COOK-2322] - runit init template is broken on debian - -v1.1.0 ------- -- [COOK-2353] - Runit does not update run template if the service is already enabled -- [COOK-2497] - add :nothing to allowed actions - -v1.0.6 ------- -- [COOK-2404] - allow sending sigquit -- [COOK-2431] - gentoo - it should create the runit-start template before calling it - -v1.0.4 ------- -- [COOK-2351] - add `run_template_name` to allow alternate run script template - -v1.0.2 ------- -- [COOK-2299] - runit_service resource does not properly start a non-running service - -v1.0.0 ------- -- [COOK-2254] - (formerly CHEF-154) Convert `runit_service` definition to a service resource named `runit_service`. - -This version has some backwards incompatible changes (hence the major -version bump). It is recommended that users pin the cookbook to the -previous version where it is a dependency until this version has been -tested in a non-production environment (use version 0.16.2): - - depends "runit", "<= 0.16.2" - -If you use Chef environments, pin the version in the appropriate -environment(s). - -**Changes of note** - -1. The "runit" recipe must be included before the runit_service resource -can be used. -2. The `runit_service` definition created a separate `service` -resource for notification purposes. This is still available, but the -only actions that can be notified are `:start`, `:stop`, and `:restart`. -3. The `:enable` action blocks waiting for supervise/ok after the -service symlink is created. -4. User-controlled services should be created per the runit -documentation; see README.md for an example. -5. Some parameters in the definition have changed names in the -resource. See below. - -The following parameters in the definition are renamed in the resource -to clarify their intent. - -- directory -> sv_dir -- active_directory -> service_dir -- template_name -> use service_name (name attribute) -- nolog -> set "log" to false -- start_command -> unused (was previously in the "service" resource) -- stop_command -> unused (was previously in the "service" resource) -- restart_command -> unused (was previously in the "service" resource) - -v0.16.2 -------- -- [COOK-1576] - Do not symlink /etc/init.d/servicename to /usr/bin/sv on debian -- [COOK-1960] - default_logger still looks for sv-service-log-run template -- [COOK-2035] - runit README change - -v0.16.0 -------- -- [COOK-794] default logger and `no_log` for `runit_service` definition -- [COOK-1165] - restart functionality does not work right on Gentoo due to the wrong directory in the attributes -- [COOK-1440] - Delegate service control to normal user - -v0.15.0 -------- -- [COOK-1008] - Added parameters for names of different templates in runit diff --git a/cookbooks/runit/README.md b/cookbooks/runit/README.md deleted file mode 100644 index 1322977..0000000 --- a/cookbooks/runit/README.md +++ /dev/null @@ -1,439 +0,0 @@ -runit Cookbook -============== -Installs runit and provides the `runit_service` service resource for managing processes (services) under runit. - -This cookbook does not use runit to replace system init, nor are ther plans to do so. - -For more information about runit: - -- http://smarden.org/runit/ - -#### A note regarding versions 1.7.0 and 1.7.2 - -With the benefit of hindsight we can say that the changes contained version 1.7.0 merited a major version number change, and that version 1.7.2 contains some still unresolved regressions compared to 1.6.0. Please be sure to test this new version for compatibility with your systems before upgrading to version 1.7. - -See [issue #144](https://github.com/hw-cookbooks/runit/issues/144) for some notes on how these versions behaved unexpectedly in one user's environment. - -Requirements ------------- -#### Platforms -- Debian/Ubuntu -- Gentoo -- RHEL - -#### Chef -- Chef 11+ - -#### Cookbooks -- packagecloud (for RHEL) - -Attributes ----------- -See `attributes/default.rb` for defaults generated per platform. - -- `node['runit']['sv_bin']` - Full path to the `sv` binary. -- `node['runit']['chpst_bin']` - Full path to the `chpst` binary. -- `node['runit']['service_dir']` - Full path to the default "services" directory where enabled services are linked. -- `node['runit']['sv_dir']` - Full path to the directory where service lives, which gets linked to `service_dir`. -- `node['runit']['lsb_init_dir']` - Full path to the directory where the LSB-compliant init script interface will be created. -- `node['runit']['start']` - Command to start the runsvdir service -- `node['runit']['stop]` - Command to stop the runsvdir service -- `node['runit']['reload']` - Command to reload the runsvdir service - -### Optional Attributes for RHEL systems - -- `node['runit']['prefer_local_yum']` - If `true`, assumes that a `runit` package is available on an already configured local yum repository. By default, the recipe installs the `runit` package from a Package Cloud repository (see below). This is set to the value of `node['runit']['use_package_from_yum']` for backwards compatibility, but otherwise defaults to `false`. - -Recipes -------- -### default -The default recipe installs runit and starts `runsvdir` to supervise the services in runit's service directory (e.g., `/etc/service`). - -On RHEL-family systems, it will install the runit RPM using [Ian Meyer's Package Cloud repository](https://packagecloud.io/imeyer/runit) for runit. This replaces the previous functionality where the RPM was build using his [runit RPM SPEC](https://github.com/imeyer/runit-rpm). However, if the attribute `node['runit']['prefer_local_yum']` is set to `true`, the packagecloud repository creation will be skipped and it is assumed that a `runit` package is available on an otherwise configured (outside this cookbook) local repository. - -On Debian family systems, the runit packages are maintained by the runit author, Gerrit Pape, and the recipe will use that for installation. - -On Gentoo, the runit ebuild package is installed. - -Resource/Provider ------------------ -This cookbook has a resource, `runit_service`, for managing services under runit. This service subclasses the Chef `service` resource. - -**This resource replaces the runit_service definition. See the CHANGELOG.md file in this cookbook for breaking change information and any actions you may need to take to update cookbooks using runit_service.** - -### Actions -- **enable** - enables the service, creating the required run scripts and symlinks. This is the default action. -- **start** - starts the service with `sv start` -- **stop** - stops the service with `sv stop` -- **disable** - stops the service with `sv down` and removes the service symlink -- **create** - create the service directory, but don't enable the service with symlink -- **restart** - restarts the service with `sv restart` -- **reload** - reloads the service with `sv force-reload` -- **once** - starts the service with `sv once`. -- **hup** - sends the `HUP` signal to the service with `sv hup` -- **cont** - sends the `CONT` signal to the service -- **term** - sends the `TERM` signal to the service -- **kill** - sends the `KILL` signal to the service -- **up** - starts the service with `sv up` -- **down** - downs the service with `sv down` -- **usr1** - sends the `USR1` signal to the service with `sv 1` -- **usr2** - sends the `USR2` signal to the service with `sv 2` - -Service management actions are taken with runit's "`sv`" program. - -Read the `sv(8)` [man page](http://smarden.org/runit/sv.8.html) for more information on the `sv` program. - -### Parameter Attributes - -The first three parameters, `sv_dir`, `service_dir`, and `sv_bin` will attempt to use the corresponding node attributes, and fall back to hardcoded default values that match the settings used on Debian platform systems. - -Many of these parameters are only used in the `:enable` action. - -- **sv_dir** - The base "service directory" for the services managed by - the resource. By default, this will attempt to use the - `node['runit']['sv_dir']` attribute, and falls back to `/etc/sv`. -- **service_dir** - The directory where services are symlinked to be - supervised by `runsvdir`. By default, this will attempt to use the - `node['runit']['service_dir']` attribute, and falls back to - `/etc/service`. -- **lsb_init_dir** - The directory where an LSB-compliant init script - interface will be created. By default, this will attempt to use the - `node['runit']['lsb_init_dir']` attribute, and falls back to - `/etc/init.d`. -- **sv_bin** - The path to the `sv` program binary. This will attempt - to use the `node['runit']['sv_bin']` attribute, and falls back to - `/usr/bin/sv`. -- **service_name** - *Name attribute*. The name of the service. This - will be used in the directory of the managed service in the - `sv_dir` and `service_dir`. -- **sv_timeout** - Override the default `sv` timeout of 7 seconds. -- **sv_verbose** - Whether to enable `sv` verbose mode. Default is - `false`. -- **sv_templates** - If true, the `:enable` action will create the - service directory with the appropriate templates. Default is - `true`. Set this to `false` if the service has a package that - provides its own service directory. See __Usage__ examples. -- **options** - Options passed as variables to templates, for - compatibility with legacy runit service definition. Default is an - empty hash. -- **env** - A hash of environment variables with their values as content - used in the service's `env` directory. Default is an empty hash. When - this hash is non-empty, the contents of the runit service's `env` - directory will be managed by Chef in order to conform to the declared - state. -- **log** - Whether to start the service's logger with svlogd, requires - a template `sv-service_name-log-run.erb` to configure the log's run - script. Default is true. -- **default_logger** - Whether a default `log/run` script should be set - up. If true, the default content of the run script will use - `svlogd` to write logs to `/var/log/service_name`. Default is false. -- **log_dir** - The directory where the `svlogd` log service will run. - Used when `default_logger` is `true`. Default is `/var/log/service_name` -- **log_size** - The maximum size a log file can grow to before it is - automatically rotated. See svlogd(8) for the default value. -- **log_num** - The maximum number of log files that will be retained - after rotation. See svlogd(8) for the default value. -- **log_min** - The minimum number of log files that will be retained - after rotation (if svlogd cannot create a new file and the minimum - has not been reached, it will block). Default is no minimum. -- **log_timeout** - The maximum age a log file can get to before it is - automatically rotated, whether it has reached `log_size` or not. - Default is no timeout. -- **log_processor** - A string containing a path to a program that - rotated log files will be fed through. See the **PROCESSOR** section - of svlogd(8) for details. Default is no processor. -- **log_socket** - An string containing an IP:port pair identifying a UDP - socket that log lines will be copied to. Default is none. -- **log_prefix** - A string that will be prepended to each line as it - is logged. Default is no prefix. -- **log_config_append** - A string containing optional additional lines to add - to the log service configuration. See svlogd(8) for more details. -- **cookbook** - A cookbook where templates are located instead of - where the resource is used. Applies for all the templates in the - `enable` action. -- **check** - whether the service has a check script, requires a - template `sv-service_name-check.erb` -- **finish** - whether the service has a finish script, requires a - template `sv-service_name-finish.erb` -- **control** - An array of signals to customize control of the service, - see [runsv man page](http://smarden.org/runit/runsv.8.html) on how - to use this. This requires that each template be created with the - name `sv-service_name-signal.erb`. -- **owner** - user that should own the templates created to enable the - service -- **group** - group that should own the templates created to enable the - service -- **run_template_name** - alternate filename of the run run script to - use replacing `service_name`. -- **log_template_name** - alternate filename of the log run script to - use replacing `service_name`. -- **check_script_template_name** - alternate filename of the check - script to use, replacing `service_name`. -- **finish_script_template_name** - alternate filename of the finish - script to use, replacing `service_name`. -- **control_template_names** - a hash of control signals (see *control* - above) and their alternate template name(s) replacing - `service_name`. -- **status_command** - The command used to check the status of the - service to see if it is enabled/running (if it's running, it's - enabled). This hardcodes the location of the sv program to - `/usr/bin/sv` due to the aforementioned cookbook load order. -- **restart_on_update** - Whether the service should be restarted when - the run script is updated. Defaults to `true`. Set to `false` if - the service shouldn't be restarted when the run script is updated. -- **start_down** - Set the default state of the runit service to 'down' by creating - `/down` file. Defaults to `false`. Services using `start_down` - will not be notified to restart when their run script is updated. -- **delete_downfile** - Delete previously created `/down` file - -Unlike previous versions of the cookbook using the `runit_service` definition, the `runit_service` resource can be notified. See __Usage__ examples below. - - -Usage ------ -To get runit installed on supported platforms, use `recipe[runit]`. Once it is installed, use the `runit_service` resource to set up services to be managed by runit. - -In order to use the `runit_service` resource in your cookbook(s), each service managed will also need to have `sv-service_name-run.erb` and `sv-service_name-log-run.erb` templates created. If the `log` parameter is false, the log run script isn't created. If the `log` parameter is true, and `default_logger` is also true, the log run -script will be created with the default content: - -```bash -#!/bin/sh -exec svlogd -tt /var/log/service_name -``` - -### Examples -These are example use cases of the `runit_service` resource described above. There are others in the `runit_test` cookbook that is included in the [git repository](https://github.com/hw-cookbooks/runit). - -**Default Example** - -This example uses all the defaults in the `:enable` action to set up the service. - -We'll set up `chef-client` to run as a service under runit, such as is done in the `chef-client` cookbook. This example will be more simple than in that cookbook. First, create the required run template, `chef-client/templates/default/sv-chef-client-run.erb`. - -```bash -#!/bin/sh -exec 2>&1 -exec /usr/bin/env chef-client -i 1800 -s 30 -``` - -Then create the required log/run template, `chef-client/templates/default/sv-chef-client-log-run.erb`. - -```bash -#!/bin/sh -exec svlogd -tt ./main -``` - -__Note__ This will cause output of the running process to go to `/etc/sv/chef-client/log/main/current`. Some people may not like this, see the following example. This is preserved for compatibility reasons. - -Finally, set up the service in the recipe with: - -```ruby -runit_service "chef-client" -``` - -**Default Logger Example** - -To use a default logger with svlogd which will log to `/var/log/chef-client/current`, instead, use the `default_logger` option. - -```ruby -runit_service "chef-client" do - default_logger true -end -``` - -**No Log Service** - -If there isn't an appendant log service, set `log` to false, and the log/run script won't be created. - -```ruby -runit_service "no-svlog" do - log false -end -``` - -**Check Script** - -To create a service that has a check script in its service directory, set the `check` parameter to `true`, and create a `sv-checker-check.erb` template. - -```ruby -runit_service "checker" do - check true -end -``` - -This will create `/etc/sv/checker/check`. - -**Finish Script** - -To create a service that has a finish script in its service directory, set the `finish` parameter to `true`, and create a `sv-finisher-finish.erb` template. - -```ruby -runit_service "finisher" do - finish true -end -``` - -This will create `/etc/sv/finisher/finish`. - -**Alternate service directory** - -If the service directory for the managed service isn't the `sv_dir` (`/etc/sv`), then specify it: - -```ruby -runit_service "custom_service" do - sv_dir "/etc/custom_service/runit" -end -``` - -**No Service Directory** - -If the service to manage has a package that provides its service directory, such as `git-daemon` on Debian systems, set `sv_templates` to false. - -```ruby -package "git-daemon-run" - -runit_service "git-daemon" do - sv_templates false -end -``` - -This will create the service symlink in `/etc/service`, but it will not manage any templates in the service directory. - -**User Controlled Services** - -To set up services controlled by a non-privileged user, we follow the recommended configuration in the [runit documentation](http://smarden.org/runit/faq.html#user) (Is it possible to allow a user other than root to control a service?). - -Suppose the user's name is floyd, and floyd wants to run floyds-app. Assuming that the floyd user and group are already managed with Chef, create a `runsvdir-floyd` runit_service. - -```ruby -runit_service "runsvdir-floyd" -``` - -Create the `sv-runsvdir-floyd-log-run.erb` template, or add `log false`. Also create the `sv-runsvdir-floyd-run.erb` with the following content: - -```bash -#!/bin/sh -exec 2>&1 -exec chpst -ufloyd runsvdir /home/floyd/service -``` - -Next, create the `runit_service` resource for floyd's app: - -```ruby -runit_service "floyds-app" do - sv_dir "/home/floyd/sv" - service_dir "/home/floyd/service" - owner "floyd" - group "floyd" -end -``` - -And now floyd can manage the service with sv: - -```text -$ id -uid=1000(floyd) gid=1001(floyd) groups=1001(floyd) -$ sv stop /home/floyd/service/floyds-app/ -ok: down: /home/floyd/service/floyds-app/: 0s, normally up -$ sv start /home/floyd/service/floyds-app/ -ok: run: /home/floyd/service/floyds-app/: (pid 5287) 0s -$ sv status /home/floyd/service/floyds-app/ -run: /home/floyd/service/floyds-app/: (pid 5287) 13s; run: log: (pid 4691) 726s -``` - -**Options** - -Next, let's set up memcached under runit with some additional options using the `options` parameter. First, the `memcached/templates/default/sv-memcached-run.erb` template: - -```bash -#!/bin/sh -exec 2>&1 -exec chpst -u <%= @options[:user] %> /usr/bin/memcached -v -m <%= @options[:memory] %> -p <%= @options[:port] %> -``` - -Note that the script uses `chpst` (which comes with runit) to set the user option, then starts memcached on the specified memory and port (see below). - -The log/run template, `memcached/templates/default/sv-memcached-log-run.erb`: - -```bash -#!/bin/sh -exec svlogd -tt ./main -``` - -Finally, the `runit_service` in our recipe: - -```ruby -runit_service "memcached" do - options({ - :memory => node[:memcached][:memory], - :port => node[:memcached][:port], - :user => node[:memcached][:user] - }.merge(params)) -end -``` - -This is where the user, port and memory options used in the run template are used. - -**Notifying Runit Services** - -In previous versions of this cookbook where the definition was used, it created a `service` resource that could be notified. With the `runit_service` resource, recipes need to use the full resource name. - -For example: - -```ruby -runit_service "my-service" - -template "/etc/my-service.conf" do - notifies :restart, "runit_service[my-service]" -end -``` - -Because the resource implements actions for various commands that `sv` can send to the service, any of those actions could be used for notification. For example, `chef-client` supports triggering a Chef run with a USR1 signal. - -```ruby -template "/tmp/chef-notifier" do - notifies :usr1, "runit_service[chef-client]" -end -``` - -For older implementations of services that used `runit_service` as a definition, but may support alternate service styles, use a conditional, such as based on an attribute: - -```ruby -service_to_notify = case node['nginx']['init_style'] - when "runit" - "runit_service[nginx]" - else - "service[nginx]" - end - -template "/etc/nginx/nginx.conf" do - notifies :restart, service_to_notify -end -``` - -**More Examples** - -For more examples, see the `runit_test` cookbook's `service` recipe in the [git repository](https://github.com/hw-cookbooks/runit). - - -License & Authors ------------------ -- Author:: Adam Jacob -- Author:: Joshua Timberman -- Author:: Sean OMeara - -```text -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. -``` diff --git a/cookbooks/runit/attributes/default.rb b/cookbooks/runit/attributes/default.rb deleted file mode 100644 index f201c8b..0000000 --- a/cookbooks/runit/attributes/default.rb +++ /dev/null @@ -1,62 +0,0 @@ -# -# Cookbook Name:: runit -# Attribute File:: sv_bin -# -# Copyright 2008-2009, 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. -# - -case node['platform_family'] -when 'debian' - default['runit']['sv_bin'] = '/usr/bin/sv' - default['runit']['chpst_bin'] = '/usr/bin/chpst' - default['runit']['service_dir'] = '/etc/service' - default['runit']['sv_dir'] = '/etc/sv' - default['runit']['lsb_init_dir'] = '/etc/init.d' - default['runit']['executable'] = '/sbin/runit' - - if node['platform'] == 'debian' - default['runit']['start'] = 'runsvdir-start' - default['runit']['stop'] = '' - default['runit']['reload'] = '' - elsif node['platform'] == 'ubuntu' - default['runit']['start'] = 'start runsvdir' - default['runit']['stop'] = 'stop runsvdir' - default['runit']['reload'] = 'reload runsvdir' - end - -when 'rhel', 'fedora' - default['runit']['sv_bin'] = '/sbin/sv' - default['runit']['chpst_bin'] = '/sbin/chpst' - default['runit']['service_dir'] = '/etc/service' - default['runit']['sv_dir'] = '/etc/sv' - default['runit']['lsb_init_dir'] = '/etc/init.d' - default['runit']['executable'] = '/sbin/runit' - default['runit']['prefer_local_yum'] = node['runit']['use_package_from_yum'] || false - default['runit']['start'] = '/etc/init.d/runit-start start' - default['runit']['stop'] = '/etc/init.d/runit-start stop' - default['runit']['reload'] = '/etc/init.d/runit-start reload' - -when 'gentoo' - default['runit']['sv_bin'] = '/usr/bin/sv' - default['runit']['chpst_bin'] = '/usr/bin/chpst' - default['runit']['service_dir'] = '/var/service' - default['runit']['sv_dir'] = '/etc/sv' - default['runit']['lsb_init_dir'] = '/etc/init.d' - default['runit']['executable'] = '/sbin/runit' - default['runit']['start'] = '/etc/init.d/runit-start start' - default['runit']['stop'] = '/etc/init.d/runit-start stop' - default['runit']['reload'] = '/etc/init.d/runit-start reload' - -end diff --git a/cookbooks/runit/files/default/runit.seed b/cookbooks/runit/files/default/runit.seed deleted file mode 100644 index 6492920..0000000 --- a/cookbooks/runit/files/default/runit.seed +++ /dev/null @@ -1 +0,0 @@ -runit runit/signalinit boolean true diff --git a/cookbooks/runit/files/default/runsvdir b/cookbooks/runit/files/default/runsvdir deleted file mode 100644 index e69de29..0000000 diff --git a/cookbooks/runit/files/ubuntu-6.10/runsvdir b/cookbooks/runit/files/ubuntu-6.10/runsvdir deleted file mode 100644 index 4040e34..0000000 --- a/cookbooks/runit/files/ubuntu-6.10/runsvdir +++ /dev/null @@ -1,6 +0,0 @@ -start on runlevel-2 -start on runlevel-3 -start on runlevel-4 -start on runlevel-5 -stop on shutdown -respawn /usr/sbin/runsvdir-start diff --git a/cookbooks/runit/files/ubuntu-7.04/runsvdir b/cookbooks/runit/files/ubuntu-7.04/runsvdir deleted file mode 100644 index ee173c9..0000000 --- a/cookbooks/runit/files/ubuntu-7.04/runsvdir +++ /dev/null @@ -1,7 +0,0 @@ -start on runlevel 2 -start on runlevel 3 -start on runlevel 4 -start on runlevel 5 -stop on shutdown -respawn -exec /usr/sbin/runsvdir-start diff --git a/cookbooks/runit/files/ubuntu-7.10/runsvdir b/cookbooks/runit/files/ubuntu-7.10/runsvdir deleted file mode 100644 index ee173c9..0000000 --- a/cookbooks/runit/files/ubuntu-7.10/runsvdir +++ /dev/null @@ -1,7 +0,0 @@ -start on runlevel 2 -start on runlevel 3 -start on runlevel 4 -start on runlevel 5 -stop on shutdown -respawn -exec /usr/sbin/runsvdir-start diff --git a/cookbooks/runit/files/ubuntu-8.04/runsvdir b/cookbooks/runit/files/ubuntu-8.04/runsvdir deleted file mode 100644 index ee173c9..0000000 --- a/cookbooks/runit/files/ubuntu-8.04/runsvdir +++ /dev/null @@ -1,7 +0,0 @@ -start on runlevel 2 -start on runlevel 3 -start on runlevel 4 -start on runlevel 5 -stop on shutdown -respawn -exec /usr/sbin/runsvdir-start diff --git a/cookbooks/runit/libraries/default.rb b/cookbooks/runit/libraries/default.rb deleted file mode 100644 index e69de29..0000000 diff --git a/cookbooks/runit/libraries/helpers.rb b/cookbooks/runit/libraries/helpers.rb deleted file mode 100644 index 0a40f58..0000000 --- a/cookbooks/runit/libraries/helpers.rb +++ /dev/null @@ -1,198 +0,0 @@ -# -# Cookbook:: runit -# Libraries:: helpers -# -# Author: Joshua Timberman -# Author: Sean OMeara -# Copyright 2008-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. -# - -module RunitCookbook - module Helpers - # include Chef::Mixin::ShellOut if it is not already included in the calling class - def self.included(klass) - unless klass.ancestors.include?(Chef::Mixin::ShellOut) - klass.class_eval { include Chef::Mixin::ShellOut } - end - end - - # Default settings for resource properties. - def parsed_sv_bin - return new_resource.sv_bin if new_resource.sv_bin - '/usr/bin/sv' - end - - def parsed_sv_dir - return new_resource.sv_dir if new_resource.sv_dir - '/etc/sv' - end - - def parsed_service_dir - return new_resource.service_dir if new_resource.service_dir - '/etc/service' - end - - def parsed_lsb_init_dir - return new_resource.lsb_init_dir if new_resource.lsb_init_dir - '/etc/init.d' - end - - # misc helper functions - def inside_docker? - results = `cat /proc/1/cgroup`.strip.split("\n") - results.any? { |val| /docker/ =~ val } - end - - def down_file - "#{sv_dir_name}/down" - end - - def env_dir - "#{sv_dir_name}/env" - end - - def extra_env_files? - files = [] - Dir.glob("#{sv_dir_name}/env/*").each do |f| - files << File.basename(f) - end - return true if files.sort != new_resource.env.keys.sort - false - end - - def zap_extra_env_files - Dir.glob("#{sv_dir_name}/env/*").each do |f| - unless new_resource.env.key?(File.basename(f)) - File.unlink(f) - Chef::Log.info("removing file #{f}") - end - end - end - - def wait_for_service - unless inside_docker? - sleep 1 until ::FileTest.pipe?("#{service_dir_name}/supervise/ok") - - if new_resource.log - sleep 1 until ::FileTest.pipe?("#{service_dir_name}/log/supervise/ok") - end - end - end - - def runit_sv_works? - sv = shell_out("#{sv_bin} --help") - sv.exitstatus == 100 && sv.stderr =~ /usage: sv .* command service/ - end - - def runit_send_signal(signal, friendly_name = nil) - friendly_name ||= signal - converge_by("send #{friendly_name} to #{new_resource}") do - shell_out!("#{sv_bin} #{sv_args}#{signal} #{service_dir_name}") - Chef::Log.info("#{new_resource} sent #{friendly_name}") - end - end - - def running? - cmd = shell_out("#{sv_bin} #{sv_args}status #{service_dir_name}") - (cmd.stdout =~ /^run:/ && cmd.exitstatus == 0) - end - - def log_running? - cmd = shell_out("#{sv_bin} #{sv_args}status #{service_dir_name}/log") - (cmd.stdout =~ /^run:/ && cmd.exitstatus == 0) - end - - def enabled? - ::File.exist?("#{service_dir_name}/run") - end - - def log_service_name - "#{new_resource.service_name}/log" - end - - def sv_dir_name - "#{parsed_sv_dir}/#{new_resource.service_name}" - end - - def sv_args - sv_args = '' - sv_args += "-w '#{new_resource.sv_timeout}' " unless new_resource.sv_timeout.nil? - sv_args += '-v ' if new_resource.sv_verbose - sv_args - end - - def sv_bin - parsed_sv_bin - end - - def service_dir_name - "#{new_resource.service_dir}/#{new_resource.service_name}" - end - - def log_dir_name - "#{new_resource.service_dir}/#{new_resource.service_name}/log" - end - - def template_cookbook - new_resource.cookbook.nil? ? new_resource.cookbook_name.to_s : new_resource.cookbook - end - - def default_logger_content - <<-EOS -#!/bin/sh -exec svlogd -tt #{new_resource.log_dir} - EOS - end - - def disable_service - shell_out("#{new_resource.sv_bin} #{sv_args}down #{service_dir_name}") - FileUtils.rm(service_dir_name) - - # per the documentation, a service should be removed from supervision - # within 5 seconds of removing the service dir symlink, so we'll sleep for 6. - # otherwise, runit recreates the 'ok' named pipe too quickly - sleep(6) - # runit will recreate the supervise directory and - # pipes when the service is reenabled - FileUtils.rm("#{sv_dir_name}/supervise/ok") - end - - def start_service - shell_out!("#{new_resource.sv_bin} #{sv_args}start #{service_dir_name}") - end - - def stop_service - shell_out!("#{new_resource.sv_bin} #{sv_args}stop #{service_dir_name}") - end - - def restart_service - shell_out!("#{new_resource.sv_bin} #{sv_args}restart #{service_dir_name}") - end - - def restart_log_service - shell_out!("#{new_resource.sv_bin} #{sv_args}restart #{service_dir_name}/log") - end - - def reload_service - shell_out!("#{new_resource.sv_bin} #{sv_args}force-reload #{service_dir_name}") - end - - def reload_log_service - if log_running? - shell_out!("#{new_resource.sv_bin} #{sv_args}force-reload #{service_dir_name}/log") - end - end - end -end diff --git a/cookbooks/runit/libraries/matchers.rb b/cookbooks/runit/libraries/matchers.rb deleted file mode 100644 index 760156e..0000000 --- a/cookbooks/runit/libraries/matchers.rb +++ /dev/null @@ -1,69 +0,0 @@ -if defined?(ChefSpec) - - ChefSpec.define_matcher(:runit_service) - - def start_runit_service(service) - ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :start, service) - end - - def stop_runit_service(service) - ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :stop, service) - end - - def enable_runit_service(service) - ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :enable, service) - end - - def disable_runit_service(service) - ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :disable, service) - end - - def restart_runit_service(service) - ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :restart, service) - end - - def reload_runit_service(service) - ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :reload, service) - end - - def status_runit_service(service) - ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :status, service) - end - - def once_runit_service(service) - ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :once, service) - end - - def hup_runit_service(service) - ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :hup, service) - end - - def cont_runit_service(service) - ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :cont, service) - end - - def term_runit_service(service) - ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :term, service) - end - - def kill_runit_service(service) - ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :kill, service) - end - - def up_runit_service(service) - ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :up, service) - end - - def down_runit_service(service) - ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :down, service) - end - - def usr1_runit_service(service) - ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :usr1, service) - end - - def usr2_runit_service(service) - ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :usr2, service) - end - -end diff --git a/cookbooks/runit/libraries/provider_runit_service.rb b/cookbooks/runit/libraries/provider_runit_service.rb deleted file mode 100644 index ab59470..0000000 --- a/cookbooks/runit/libraries/provider_runit_service.rb +++ /dev/null @@ -1,348 +0,0 @@ -# -# Cookbook Name:: runit -# Provider:: service -# -# Author:: Joshua Timberman -# Author:: Sean OMeara -# 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. -# 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 - class RunitService < Chef::Provider::LWRPBase - unless defined?(VALID_SIGNALS) - # Mapping of valid signals with optional friendly name - VALID_SIGNALS = Mash.new( - :down => nil, - :hup => nil, - :int => nil, - :term => nil, - :kill => nil, - :quit => nil, - :up => nil, - :once => nil, - :cont => nil, - 1 => :usr1, - 2 => :usr2 - ) - end - - use_inline_resources if defined?(use_inline_resources) - - def whyrun_supported? - true - end - - # Mix in helpers from libraries/helpers.rb - include RunitCookbook::Helpers - - # actions - action :create do - ruby_block 'restart_service' do - block do - action_enable - restart_service - end - action :nothing - only_if { new_resource.restart_on_update && !new_resource.start_down } - end - - ruby_block 'restart_log_service' do - block do - action_enable - restart_log_service - end - action :nothing - only_if { new_resource.restart_on_update && !new_resource.start_down } - end - - # sv_templates - if new_resource.sv_templates - - directory sv_dir_name do - owner new_resource.owner - group new_resource.group - mode '0755' - recursive true - action :create - end - - template "#{sv_dir_name}/run" do - owner new_resource.owner - group new_resource.group - source "sv-#{new_resource.run_template_name}-run.erb" - cookbook template_cookbook - mode '0755' - variables(options: new_resource.options) - action :create - notifies :run, 'ruby_block[restart_service]', :delayed - end - - # log stuff - if new_resource.log - directory "#{sv_dir_name}/log" do - owner new_resource.owner - group new_resource.group - recursive true - action :create - end - - directory "#{sv_dir_name}/log/main" do - owner new_resource.owner - group new_resource.group - mode '0755' - recursive true - action :create - end - - directory new_resource.log_dir do - owner new_resource.owner - group new_resource.group - mode '00755' - recursive true - action :create - end - - template "#{sv_dir_name}/log/config" do - owner new_resource.owner - group new_resource.group - mode '00644' - cookbook 'runit' - source 'log-config.erb' - variables(config: new_resource) - notifies :run, 'ruby_block[restart_log_service]', :delayed - action :create - end - - link "#{new_resource.log_dir}/config" do - to "#{sv_dir_name}/log/config" - end - - if new_resource.default_logger - file "#{sv_dir_name}/log/run" do - content default_logger_content - owner new_resource.owner - group new_resource.group - mode '00755' - action :create - notifies :run, 'ruby_block[restart_log_service]', :delayed - end - else - template "#{sv_dir_name}/log/run" do - owner new_resource.owner - group new_resource.group - mode '00755' - source "sv-#{new_resource.log_template_name}-log-run.erb" - cookbook template_cookbook - variables(options: new_resource.options) - action :create - notifies :run, 'ruby_block[restart_log_service]', :delayed - end - end - - end - - # environment stuff - directory "#{sv_dir_name}/env" do - owner new_resource.owner - group new_resource.group - mode '00755' - action :create - end - - new_resource.env.map do |var, value| - file "#{sv_dir_name}/env/#{var}" do - owner new_resource.owner - group new_resource.group - content value - mode 00640 - action :create - end - end - - ruby_block "zap extra env files for #{new_resource.name} service" do - block { zap_extra_env_files } - only_if { extra_env_files? } - not_if { new_resource.env.empty? } - action :run - end - - if new_resource.check - template "#{sv_dir_name}/check" do - owner new_resource.owner - group new_resource.group - mode '00755' - cookbook template_cookbook - source "sv-#{new_resource.check_script_template_name}-check.erb" - variables(options: new_resource.options) - action :create - end - end - - if new_resource.finish - template "#{sv_dir_name}/finish" do - owner new_resource.owner - group new_resource.group - mode '00755' - source "sv-#{new_resource.finish_script_template_name}-finish.erb" - cookbook template_cookbook - variables(options: new_resource.options) if new_resource.options.respond_to?(:has_key?) - action :create - end - end - - directory "#{sv_dir_name}/control" do - owner new_resource.owner - group new_resource.group - mode '00755' - action :create - end - - new_resource.control.map do |signal| - template "#{sv_dir_name}/control/#{signal}" do - owner new_resource.owner - group new_resource.group - mode '0755' - source "sv-#{new_resource.control_template_names[signal]}-#{signal}.erb" - cookbook template_cookbook - variables(options: new_resource.options) - action :create - end - end - - # lsb_init - if node['platform'] == 'debian' - ruby_block "unlink #{parsed_lsb_init_dir}/#{new_resource.service_name}" do - block { ::File.unlink("#{parsed_lsb_init_dir}/#{new_resource.service_name}") } - only_if { ::File.symlink?("#{parsed_lsb_init_dir}/#{new_resource.service_name}") } - end - - template "#{parsed_lsb_init_dir}/#{new_resource.service_name}" do - owner 'root' - group 'root' - mode '00755' - cookbook 'runit' - source 'init.d.erb' - variables( - name: new_resource.service_name, - sv_bin: new_resource.sv_bin, - init_dir: ::File.join(parsed_lsb_init_dir, '') - ) - action :create - end - else - link "#{parsed_lsb_init_dir}/#{new_resource.service_name}" do - to sv_bin - action :create - end - end - - # Create/Delete service down file - # To prevent unexpected behavior, require users to explicitly set - # delete_downfile to remove any down file that may already exist - df_action = :nothing - if new_resource.start_down - df_action = :create - elsif new_resource.delete_downfile - df_action = :delete - end - - file down_file do - mode 00644 - backup false - content '# File created and managed by chef!' - action df_action - end - end - end - - action :disable do - ruby_block "disable #{new_resource.service_name}" do - block { disable_service } - only_if { enabled? } - end - end - - action :enable do - # FIXME: remove action_create in next major version - action_create - - directory new_resource.service_dir - - link "#{service_dir_name}" do - to sv_dir_name - action :create - end - - ruby_block "wait for #{new_resource.service_name} service socket" do - block do - wait_for_service - end - action :run - end - end - - # signals - VALID_SIGNALS.each do |signal, signal_name| - action(signal_name || signal) do - if running? - Chef::Log.info "#{new_resource} signalled (#{(signal_name || signal).to_s.upcase})" - runit_send_signal(signal, signal_name) - else - Chef::Log.debug "#{new_resource} not running - nothing to do" - end - end - end - - action :nothing do - end - - action :restart do - restart_service - end - - action :start do - if running? - Chef::Log.debug "#{new_resource} already running - nothing to do" - else - start_service - Chef::Log.info "#{new_resource} started" - end - end - - action :stop do - if running? - stop_service - Chef::Log.info "#{new_resource} stopped" - else - Chef::Log.debug "#{new_resource} already stopped - nothing to do" - end - end - - action :reload do - if running? - reload_service - Chef::Log.info "#{new_resource} reloaded" - else - Chef::Log.debug "#{new_resource} not running - nothing to do" - end - end - - action :status do - running? - end - end - end -end diff --git a/cookbooks/runit/libraries/resource_runit_service.rb b/cookbooks/runit/libraries/resource_runit_service.rb deleted file mode 100644 index e111f0e..0000000 --- a/cookbooks/runit/libraries/resource_runit_service.rb +++ /dev/null @@ -1,267 +0,0 @@ -# -# Cookbook Name:: runit -# Provider:: service -# -# Copyright 2011, Joshua Timberman -# Copyright 2011, 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 'chef/resource' -require 'chef/resource/service' - -class Chef - class Resource - # Missing top-level class documentation comment - class RunitService < Chef::Resource::Service - def initialize(name, run_context = nil) - super - runit_node = runit_attributes_from_node(run_context) - @resource_name = :runit_service - @provider = Chef::Provider::RunitService - @supports = { restart: true, reload: true, status: true } - @action = :enable - @allowed_actions = [:nothing, :start, :stop, :enable, :disable, :restart, :reload, :status, :once, :hup, :cont, :term, :kill, :up, :down, :usr1, :usr2, :create] - - # sv_bin, sv_dir, service_dir and lsb_init_dir may have been set in the - # node attributes - @sv_bin = runit_node[:sv_bin] || '/usr/bin/sv' - @sv_dir = runit_node[:sv_dir] || '/etc/sv' - @service_dir = runit_node[:service_dir] || '/etc/service' - @lsb_init_dir = runit_node[:lsb_init_dir] || '/etc/init.d' - - @control = [] - @options = {} - @env = {} - @log = true - @cookbook = nil - @check = false - @start_down = false - @delete_downfile = false - @finish = false - @owner = nil - @group = nil - @enabled = false - @running = false - @default_logger = false - @restart_on_update = true - @run_template_name = @service_name - @log_template_name = @service_name - @check_script_template_name = @service_name - @finish_script_template_name = @service_name - @control_template_names = {} - @status_command = "#{@sv_bin} status #{@service_dir}" - @sv_templates = true - @sv_timeout = nil - @sv_verbose = false - @log_dir = ::File.join('/var/log/', @service_name) - @log_size = nil - @log_num = nil - @log_min = nil - @log_timeout = nil - @log_processor = nil - @log_socket = nil - @log_prefix = nil - @log_config_append = nil - - # - # Backward Compat Hack - # - # This ensures a 'service' resource exists for all 'runit_service' resources. - # This should allow all recipes using the previous 'runit_service' definition to - # continue operating. - # - unless run_context.nil? - service_dir_name = ::File.join(@service_dir, @name) - @service_mirror = Chef::Resource::Service.new(name, run_context) - @service_mirror.provider(Chef::Provider::Service::Simple) - @service_mirror.supports(@supports) - @service_mirror.start_command("#{@sv_bin} start #{service_dir_name}") - @service_mirror.stop_command("#{@sv_bin} stop #{service_dir_name}") - @service_mirror.restart_command("#{@sv_bin} restart #{service_dir_name}") - @service_mirror.status_command("#{@sv_bin} status #{service_dir_name}") - @service_mirror.action(:nothing) - run_context.resource_collection.insert(@service_mirror) - end - end - - def sv_bin(arg = nil) - set_or_return(:sv_bin, arg, kind_of: [String]) - end - - def sv_dir(arg = nil) - set_or_return(:sv_dir, arg, kind_of: [String, FalseClass]) - end - - def sv_timeout(arg = nil) - set_or_return(:sv_timeout, arg, kind_of: [Fixnum]) - end - - def sv_verbose(arg = nil) - set_or_return(:sv_verbose, arg, kind_of: [TrueClass, FalseClass]) - end - - def service_dir(arg = nil) - set_or_return(:service_dir, arg, kind_of: [String]) - end - - def lsb_init_dir(arg = nil) - set_or_return(:lsb_init_dir, arg, kind_of: [String]) - end - - def control(arg = nil) - set_or_return(:control, arg, kind_of: [Array]) - end - - def options(arg = nil) - default_opts = @env.empty? ? @options : @options.merge(env_dir: ::File.join(@sv_dir, @service_name, 'env')) - - merged_opts = arg.respond_to?(:merge) ? default_opts.merge(arg) : default_opts - - set_or_return( - :options, - merged_opts, - kind_of: [Hash], - default: default_opts - ) - end - - def env(arg = nil) - set_or_return(:env, arg, kind_of: [Hash]) - end - - ## set log to current instance value if nothing is passed. - def log(arg = @log) - set_or_return(:log, arg, kind_of: [TrueClass, FalseClass]) - end - - def cookbook(arg = nil) - set_or_return(:cookbook, arg, kind_of: [String]) - end - - def finish(arg = nil) - set_or_return(:finish, arg, kind_of: [TrueClass, FalseClass]) - end - - def check(arg = nil) - set_or_return(:check, arg, kind_of: [TrueClass, FalseClass]) - end - - def start_down(arg = nil) - set_or_return(:start_down, arg, kind_of: [TrueClass, FalseClass]) - end - - def delete_downfile(arg = nil) - set_or_return(:delete_downfile, arg, kind_of: [TrueClass, FalseClass]) - end - - def owner(arg = nil) - set_or_return(:owner, arg, regex: [Chef::Config[:user_valid_regex]]) - end - - def group(arg = nil) - set_or_return(:group, arg, regex: [Chef::Config[:group_valid_regex]]) - end - - def default_logger(arg = nil) - set_or_return(:default_logger, arg, kind_of: [TrueClass, FalseClass]) - end - - def restart_on_update(arg = nil) - set_or_return(:restart_on_update, arg, kind_of: [TrueClass, FalseClass]) - end - - def run_template_name(arg = nil) - set_or_return(:run_template_name, arg, kind_of: [String]) - end - alias_method :template_name, :run_template_name - - def log_template_name(arg = nil) - set_or_return(:log_template_name, arg, kind_of: [String]) - end - - def check_script_template_name(arg = nil) - set_or_return(:check_script_template_name, arg, kind_of: [String]) - end - - def finish_script_template_name(arg = nil) - set_or_return(:finish_script_template_name, arg, kind_of: [String]) - end - - def control_template_names(arg = nil) - set_or_return( - :control_template_names, - arg, - kind_of: [Hash], - default: set_control_template_names - ) - end - - def set_control_template_names - @control.each do |signal| - @control_template_names[signal] ||= @service_name - end - @control_template_names - end - - def sv_templates(arg = nil) - set_or_return(:sv_templates, arg, kind_of: [TrueClass, FalseClass]) - end - - def log_dir(arg = nil) - set_or_return(:log_dir, arg, kind_of: [String]) - end - - def log_size(arg = nil) - set_or_return(:log_size, arg, kind_of: [Integer]) - end - - def log_num(arg = nil) - set_or_return(:log_num, arg, kind_of: [Integer]) - end - - def log_min(arg = nil) - set_or_return(:log_min, arg, kind_of: [Integer]) - end - - def log_timeout(arg = nil) - set_or_return(:log_timeout, arg, kind_of: [Integer]) - end - - def log_processor(arg = nil) - set_or_return(:log_processor, arg, kind_of: [String]) - end - - def log_socket(arg = nil) - set_or_return(:log_socket, arg, kind_of: [String, Hash]) - end - - def log_prefix(arg = nil) - set_or_return(:log_prefix, arg, kind_of: [String]) - end - - def log_config_append(arg = nil) - set_or_return(:log_config_append, arg, kind_of: [String]) - end - - def runit_attributes_from_node(run_context) - if run_context && run_context.node && run_context.node[:runit] - run_context.node[:runit] - else - {} - end - end - end - end -end diff --git a/cookbooks/runit/metadata.json b/cookbooks/runit/metadata.json deleted file mode 100644 index 6553a97..0000000 --- a/cookbooks/runit/metadata.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "runit", - "description": "Installs runit and provides runit_service definition", - "long_description": "runit Cookbook\n==============\nInstalls runit and provides the `runit_service` service resource for managing processes (services) under runit.\n\nThis cookbook does not use runit to replace system init, nor are ther plans to do so.\n\nFor more information about runit:\n\n- http://smarden.org/runit/\n\n#### A note regarding versions 1.7.0 and 1.7.2\n\nWith the benefit of hindsight we can say that the changes contained version 1.7.0 merited a major version number change, and that version 1.7.2 contains some still unresolved regressions compared to 1.6.0. Please be sure to test this new version for compatibility with your systems before upgrading to version 1.7.\n\nSee [issue #144](https://github.com/hw-cookbooks/runit/issues/144) for some notes on how these versions behaved unexpectedly in one user's environment.\n\nRequirements\n------------\n#### Platforms\n- Debian/Ubuntu\n- Gentoo\n- RHEL\n\n#### Chef\n- Chef 11+\n\n#### Cookbooks\n- packagecloud (for RHEL)\n\nAttributes\n----------\nSee `attributes/default.rb` for defaults generated per platform.\n\n- `node['runit']['sv_bin']` - Full path to the `sv` binary.\n- `node['runit']['chpst_bin']` - Full path to the `chpst` binary.\n- `node['runit']['service_dir']` - Full path to the default \"services\" directory where enabled services are linked.\n- `node['runit']['sv_dir']` - Full path to the directory where service lives, which gets linked to `service_dir`.\n- `node['runit']['lsb_init_dir']` - Full path to the directory where the LSB-compliant init script interface will be created.\n- `node['runit']['start']` - Command to start the runsvdir service\n- `node['runit']['stop]` - Command to stop the runsvdir service\n- `node['runit']['reload']` - Command to reload the runsvdir service\n\n### Optional Attributes for RHEL systems\n\n- `node['runit']['prefer_local_yum']` - If `true`, assumes that a `runit` package is available on an already configured local yum repository. By default, the recipe installs the `runit` package from a Package Cloud repository (see below). This is set to the value of `node['runit']['use_package_from_yum']` for backwards compatibility, but otherwise defaults to `false`.\n\nRecipes\n-------\n### default\nThe default recipe installs runit and starts `runsvdir` to supervise the services in runit's service directory (e.g., `/etc/service`).\n\nOn RHEL-family systems, it will install the runit RPM using [Ian Meyer's Package Cloud repository](https://packagecloud.io/imeyer/runit) for runit. This replaces the previous functionality where the RPM was build using his [runit RPM SPEC](https://github.com/imeyer/runit-rpm). However, if the attribute `node['runit']['prefer_local_yum']` is set to `true`, the packagecloud repository creation will be skipped and it is assumed that a `runit` package is available on an otherwise configured (outside this cookbook) local repository.\n\nOn Debian family systems, the runit packages are maintained by the runit author, Gerrit Pape, and the recipe will use that for installation.\n\nOn Gentoo, the runit ebuild package is installed.\n\nResource/Provider\n-----------------\nThis cookbook has a resource, `runit_service`, for managing services under runit. This service subclasses the Chef `service` resource.\n\n**This resource replaces the runit_service definition. See the CHANGELOG.md file in this cookbook for breaking change information and any actions you may need to take to update cookbooks using runit_service.**\n\n### Actions\n- **enable** - enables the service, creating the required run scripts and symlinks. This is the default action.\n- **start** - starts the service with `sv start`\n- **stop** - stops the service with `sv stop`\n- **disable** - stops the service with `sv down` and removes the service symlink\n- **create** - create the service directory, but don't enable the service with symlink\n- **restart** - restarts the service with `sv restart`\n- **reload** - reloads the service with `sv force-reload`\n- **once** - starts the service with `sv once`.\n- **hup** - sends the `HUP` signal to the service with `sv hup`\n- **cont** - sends the `CONT` signal to the service\n- **term** - sends the `TERM` signal to the service\n- **kill** - sends the `KILL` signal to the service\n- **up** - starts the service with `sv up`\n- **down** - downs the service with `sv down`\n- **usr1** - sends the `USR1` signal to the service with `sv 1`\n- **usr2** - sends the `USR2` signal to the service with `sv 2`\n\nService management actions are taken with runit's \"`sv`\" program.\n\nRead the `sv(8)` [man page](http://smarden.org/runit/sv.8.html) for more information on the `sv` program.\n\n### Parameter Attributes\n\nThe first three parameters, `sv_dir`, `service_dir`, and `sv_bin` will attempt to use the corresponding node attributes, and fall back to hardcoded default values that match the settings used on Debian platform systems.\n\nMany of these parameters are only used in the `:enable` action.\n\n- **sv_dir** - The base \"service directory\" for the services managed by\n the resource. By default, this will attempt to use the\n `node['runit']['sv_dir']` attribute, and falls back to `/etc/sv`.\n- **service_dir** - The directory where services are symlinked to be\n supervised by `runsvdir`. By default, this will attempt to use the\n `node['runit']['service_dir']` attribute, and falls back to\n `/etc/service`.\n- **lsb_init_dir** - The directory where an LSB-compliant init script\n interface will be created. By default, this will attempt to use the\n `node['runit']['lsb_init_dir']` attribute, and falls back to\n `/etc/init.d`.\n- **sv_bin** - The path to the `sv` program binary. This will attempt\n to use the `node['runit']['sv_bin']` attribute, and falls back to\n `/usr/bin/sv`.\n- **service_name** - *Name attribute*. The name of the service. This\n will be used in the directory of the managed service in the\n `sv_dir` and `service_dir`.\n- **sv_timeout** - Override the default `sv` timeout of 7 seconds.\n- **sv_verbose** - Whether to enable `sv` verbose mode. Default is\n `false`.\n- **sv_templates** - If true, the `:enable` action will create the\n service directory with the appropriate templates. Default is\n `true`. Set this to `false` if the service has a package that\n provides its own service directory. See __Usage__ examples.\n- **options** - Options passed as variables to templates, for\n compatibility with legacy runit service definition. Default is an\n empty hash.\n- **env** - A hash of environment variables with their values as content\n used in the service's `env` directory. Default is an empty hash. When\n this hash is non-empty, the contents of the runit service's `env`\n directory will be managed by Chef in order to conform to the declared\n state.\n- **log** - Whether to start the service's logger with svlogd, requires\n a template `sv-service_name-log-run.erb` to configure the log's run\n script. Default is true.\n- **default_logger** - Whether a default `log/run` script should be set\n up. If true, the default content of the run script will use\n `svlogd` to write logs to `/var/log/service_name`. Default is false.\n- **log_dir** - The directory where the `svlogd` log service will run.\n Used when `default_logger` is `true`. Default is `/var/log/service_name`\n- **log_size** - The maximum size a log file can grow to before it is\n automatically rotated. See svlogd(8) for the default value.\n- **log_num** - The maximum number of log files that will be retained\n after rotation. See svlogd(8) for the default value.\n- **log_min** - The minimum number of log files that will be retained\n after rotation (if svlogd cannot create a new file and the minimum\n has not been reached, it will block). Default is no minimum.\n- **log_timeout** - The maximum age a log file can get to before it is\n automatically rotated, whether it has reached `log_size` or not.\n Default is no timeout.\n- **log_processor** - A string containing a path to a program that\n rotated log files will be fed through. See the **PROCESSOR** section\n of svlogd(8) for details. Default is no processor.\n- **log_socket** - An string containing an IP:port pair identifying a UDP\n socket that log lines will be copied to. Default is none.\n- **log_prefix** - A string that will be prepended to each line as it\n is logged. Default is no prefix.\n- **log_config_append** - A string containing optional additional lines to add\n to the log service configuration. See svlogd(8) for more details.\n- **cookbook** - A cookbook where templates are located instead of\n where the resource is used. Applies for all the templates in the\n `enable` action.\n- **check** - whether the service has a check script, requires a\n template `sv-service_name-check.erb`\n- **finish** - whether the service has a finish script, requires a\n template `sv-service_name-finish.erb`\n- **control** - An array of signals to customize control of the service,\n see [runsv man page](http://smarden.org/runit/runsv.8.html) on how\n to use this. This requires that each template be created with the\n name `sv-service_name-signal.erb`.\n- **owner** - user that should own the templates created to enable the\n service\n- **group** - group that should own the templates created to enable the\n service\n- **run_template_name** - alternate filename of the run run script to\n use replacing `service_name`.\n- **log_template_name** - alternate filename of the log run script to\n use replacing `service_name`.\n- **check_script_template_name** - alternate filename of the check\n script to use, replacing `service_name`.\n- **finish_script_template_name** - alternate filename of the finish\n script to use, replacing `service_name`.\n- **control_template_names** - a hash of control signals (see *control*\n above) and their alternate template name(s) replacing\n `service_name`.\n- **status_command** - The command used to check the status of the\n service to see if it is enabled/running (if it's running, it's\n enabled). This hardcodes the location of the sv program to\n `/usr/bin/sv` due to the aforementioned cookbook load order.\n- **restart_on_update** - Whether the service should be restarted when\n the run script is updated. Defaults to `true`. Set to `false` if\n the service shouldn't be restarted when the run script is updated.\n- **start_down** - Set the default state of the runit service to 'down' by creating\n `/down` file. Defaults to `false`. Services using `start_down`\n will not be notified to restart when their run script is updated.\n- **delete_downfile** - Delete previously created `/down` file\n\nUnlike previous versions of the cookbook using the `runit_service` definition, the `runit_service` resource can be notified. See __Usage__ examples below.\n\n\nUsage\n-----\nTo get runit installed on supported platforms, use `recipe[runit]`. Once it is installed, use the `runit_service` resource to set up services to be managed by runit.\n\nIn order to use the `runit_service` resource in your cookbook(s), each service managed will also need to have `sv-service_name-run.erb` and `sv-service_name-log-run.erb` templates created. If the `log` parameter is false, the log run script isn't created. If the `log` parameter is true, and `default_logger` is also true, the log run\nscript will be created with the default content:\n\n```bash\n#!/bin/sh\nexec svlogd -tt /var/log/service_name\n```\n\n### Examples\nThese are example use cases of the `runit_service` resource described above. There are others in the `runit_test` cookbook that is included in the [git repository](https://github.com/hw-cookbooks/runit).\n\n**Default Example**\n\nThis example uses all the defaults in the `:enable` action to set up the service.\n\nWe'll set up `chef-client` to run as a service under runit, such as is done in the `chef-client` cookbook. This example will be more simple than in that cookbook. First, create the required run template, `chef-client/templates/default/sv-chef-client-run.erb`.\n\n```bash\n#!/bin/sh\nexec 2>&1\nexec /usr/bin/env chef-client -i 1800 -s 30\n```\n\nThen create the required log/run template, `chef-client/templates/default/sv-chef-client-log-run.erb`.\n\n```bash\n#!/bin/sh\nexec svlogd -tt ./main\n```\n\n__Note__ This will cause output of the running process to go to `/etc/sv/chef-client/log/main/current`. Some people may not like this, see the following example. This is preserved for compatibility reasons.\n\nFinally, set up the service in the recipe with:\n\n```ruby\nrunit_service \"chef-client\"\n```\n\n**Default Logger Example**\n\nTo use a default logger with svlogd which will log to `/var/log/chef-client/current`, instead, use the `default_logger` option.\n\n```ruby\nrunit_service \"chef-client\" do\n default_logger true\nend\n```\n\n**No Log Service**\n\nIf there isn't an appendant log service, set `log` to false, and the log/run script won't be created.\n\n```ruby\nrunit_service \"no-svlog\" do\n log false\nend\n```\n\n**Check Script**\n\nTo create a service that has a check script in its service directory, set the `check` parameter to `true`, and create a `sv-checker-check.erb` template.\n\n```ruby\nrunit_service \"checker\" do\n check true\nend\n```\n\nThis will create `/etc/sv/checker/check`.\n\n**Finish Script**\n\nTo create a service that has a finish script in its service directory, set the `finish` parameter to `true`, and create a `sv-finisher-finish.erb` template.\n\n```ruby\nrunit_service \"finisher\" do\n finish true\nend\n```\n\nThis will create `/etc/sv/finisher/finish`.\n\n**Alternate service directory**\n\nIf the service directory for the managed service isn't the `sv_dir` (`/etc/sv`), then specify it:\n\n```ruby\nrunit_service \"custom_service\" do\n sv_dir \"/etc/custom_service/runit\"\nend\n```\n\n**No Service Directory**\n\nIf the service to manage has a package that provides its service directory, such as `git-daemon` on Debian systems, set `sv_templates` to false.\n\n```ruby\npackage \"git-daemon-run\"\n\nrunit_service \"git-daemon\" do\n sv_templates false\nend\n```\n\nThis will create the service symlink in `/etc/service`, but it will not manage any templates in the service directory.\n\n**User Controlled Services**\n\nTo set up services controlled by a non-privileged user, we follow the recommended configuration in the [runit documentation](http://smarden.org/runit/faq.html#user) (Is it possible to allow a user other than root to control a service?).\n\nSuppose the user's name is floyd, and floyd wants to run floyds-app. Assuming that the floyd user and group are already managed with Chef, create a `runsvdir-floyd` runit_service.\n\n```ruby\nrunit_service \"runsvdir-floyd\"\n```\n\nCreate the `sv-runsvdir-floyd-log-run.erb` template, or add `log false`. Also create the `sv-runsvdir-floyd-run.erb` with the following content:\n\n```bash\n#!/bin/sh\nexec 2>&1\nexec chpst -ufloyd runsvdir /home/floyd/service\n```\n\nNext, create the `runit_service` resource for floyd's app:\n\n```ruby\nrunit_service \"floyds-app\" do\n sv_dir \"/home/floyd/sv\"\n service_dir \"/home/floyd/service\"\n owner \"floyd\"\n group \"floyd\"\nend\n```\n\nAnd now floyd can manage the service with sv:\n\n```text\n$ id\nuid=1000(floyd) gid=1001(floyd) groups=1001(floyd)\n$ sv stop /home/floyd/service/floyds-app/\nok: down: /home/floyd/service/floyds-app/: 0s, normally up\n$ sv start /home/floyd/service/floyds-app/\nok: run: /home/floyd/service/floyds-app/: (pid 5287) 0s\n$ sv status /home/floyd/service/floyds-app/\nrun: /home/floyd/service/floyds-app/: (pid 5287) 13s; run: log: (pid 4691) 726s\n```\n\n**Options**\n\nNext, let's set up memcached under runit with some additional options using the `options` parameter. First, the `memcached/templates/default/sv-memcached-run.erb` template:\n\n```bash\n#!/bin/sh\nexec 2>&1\nexec chpst -u <%= @options[:user] %> /usr/bin/memcached -v -m <%= @options[:memory] %> -p <%= @options[:port] %>\n```\n\nNote that the script uses `chpst` (which comes with runit) to set the user option, then starts memcached on the specified memory and port (see below).\n\nThe log/run template, `memcached/templates/default/sv-memcached-log-run.erb`:\n\n```bash\n#!/bin/sh\nexec svlogd -tt ./main\n```\n\nFinally, the `runit_service` in our recipe:\n\n```ruby\nrunit_service \"memcached\" do\n options({\n :memory => node[:memcached][:memory],\n :port => node[:memcached][:port],\n :user => node[:memcached][:user]\n }.merge(params))\nend\n```\n\nThis is where the user, port and memory options used in the run template are used.\n\n**Notifying Runit Services**\n\nIn previous versions of this cookbook where the definition was used, it created a `service` resource that could be notified. With the `runit_service` resource, recipes need to use the full resource name.\n\nFor example:\n\n```ruby\nrunit_service \"my-service\"\n\ntemplate \"/etc/my-service.conf\" do\n notifies :restart, \"runit_service[my-service]\"\nend\n```\n\nBecause the resource implements actions for various commands that `sv` can send to the service, any of those actions could be used for notification. For example, `chef-client` supports triggering a Chef run with a USR1 signal.\n\n```ruby\ntemplate \"/tmp/chef-notifier\" do\n notifies :usr1, \"runit_service[chef-client]\"\nend\n```\n\nFor older implementations of services that used `runit_service` as a definition, but may support alternate service styles, use a conditional, such as based on an attribute:\n\n```ruby\nservice_to_notify = case node['nginx']['init_style']\n when \"runit\"\n \"runit_service[nginx]\"\n else\n \"service[nginx]\"\n end\n\ntemplate \"/etc/nginx/nginx.conf\" do\n notifies :restart, service_to_notify\nend\n```\n\n**More Examples**\n\nFor more examples, see the `runit_test` cookbook's `service` recipe in the [git repository](https://github.com/hw-cookbooks/runit).\n\n\nLicense & Authors\n-----------------\n- Author:: Adam Jacob \n- Author:: Joshua Timberman \n- Author:: Sean OMeara \n\n```text\nCopyright:: 2008-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": "Heavy Water Operations, LLC.", - "maintainer_email": "support@hw-ops.com", - "license": "Apache 2.0", - "platforms": { - "ubuntu": ">= 0.0.0", - "debian": ">= 0.0.0", - "gentoo": ">= 0.0.0", - "centos": ">= 0.0.0", - "redhat": ">= 0.0.0", - "amazon": ">= 0.0.0", - "scientific": ">= 0.0.0", - "oracle": ">= 0.0.0", - "enterpriseenterprise": ">= 0.0.0" - }, - "dependencies": { - "packagecloud": ">= 0.0.0" - }, - "recommendations": { - - }, - "suggestions": { - - }, - "conflicting": { - - }, - "providing": { - - }, - "replacing": { - - }, - "attributes": { - - }, - "groupings": { - - }, - "recipes": { - "runit": "Installs and configures runit" - }, - "version": "1.7.6", - "source_url": "", - "issues_url": "" -} diff --git a/cookbooks/runit/metadata.rb b/cookbooks/runit/metadata.rb deleted file mode 100644 index 65bb21d..0000000 --- a/cookbooks/runit/metadata.rb +++ /dev/null @@ -1,15 +0,0 @@ -name 'runit' -maintainer 'Heavy Water Operations, LLC.' -maintainer_email 'support@hw-ops.com' -license 'Apache 2.0' -description 'Installs runit and provides runit_service definition' -long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -version '1.7.6' - -recipe 'runit', 'Installs and configures runit' - -%w(ubuntu debian gentoo centos redhat amazon scientific oracle enterpriseenterprise).each do |os| - supports os -end - -depends 'packagecloud' diff --git a/cookbooks/runit/recipes/default.rb b/cookbooks/runit/recipes/default.rb deleted file mode 100644 index 2c18881..0000000 --- a/cookbooks/runit/recipes/default.rb +++ /dev/null @@ -1,91 +0,0 @@ -# -# Cookbook Name:: runit -# Recipe:: default -# -# Copyright 2008-2010, 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. -# - -service 'runit' do - action :nothing -end - -execute 'start-runsvdir' do - command value_for_platform( - 'debian' => { 'default' => 'runsvdir-start' }, - 'ubuntu' => { 'default' => 'start runsvdir' }, - 'gentoo' => { 'default' => '/etc/init.d/runit-start start' } - ) - action :nothing -end - -execute 'runit-hup-init' do - command 'telinit q' - only_if 'grep ^SV /etc/inittab' - action :nothing -end - -case node['platform_family'] -when 'rhel', 'fedora' - - packagecloud_repo 'imeyer/runit' unless node['runit']['prefer_local_yum'] - package 'runit' - - if node['platform_version'].to_i == 7 - service 'runsvdir-start' do - action [:start, :enable] - end - end - -when 'debian', 'gentoo' - - if platform?('gentoo') - template '/etc/init.d/runit-start' do - source 'runit-start.sh.erb' - mode 0755 - end - - service 'runit-start' do - action :nothing - end - end - - package 'runit' do - action :install - response_file 'runit.seed' if platform?('ubuntu', 'debian') - notifies value_for_platform( - 'debian' => { '4.0' => :run, 'default' => :nothing }, - 'ubuntu' => { - 'default' => :nothing, - '9.04' => :run, - '8.10' => :run, - '8.04' => :run }, - 'gentoo' => { 'default' => :run } - ), 'execute[start-runsvdir]', :immediately - notifies value_for_platform( - 'debian' => { 'squeeze/sid' => :run, 'default' => :nothing }, - 'default' => :nothing - ), 'execute[runit-hup-init]', :immediately - notifies :enable, 'service[runit-start]' if platform?('gentoo') - end - - if node['platform'] =~ /ubuntu/i && node['platform_version'].to_f <= 8.04 - cookbook_file '/etc/event.d/runsvdir' do - source 'runsvdir' - mode 0644 - notifies :run, 'execute[start-runsvdir]', :immediately - only_if { ::File.directory?('/etc/event.d') } - end - end -end diff --git a/cookbooks/runit/templates/debian/init.d.erb b/cookbooks/runit/templates/debian/init.d.erb deleted file mode 100644 index 491d53f..0000000 --- a/cookbooks/runit/templates/debian/init.d.erb +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/sh -### BEGIN INIT INFO -# Provides: <%= @name %> -# Required-Start: -# Required-Stop: -# Default-Start: -# Default-Stop: -# Short-Description: initscript for runit-managed <%= @name %> service -### END INIT INFO - -# Author: Chef Software, Inc. - -PATH=/sbin:/usr/sbin:/bin:/usr/bin -DESC="runit-managed <%= @name %>" -NAME=<%= @name %> -RUNIT=<%= @sv_bin %> -SCRIPTNAME=<%= @init_dir %>$NAME - -# Exit if runit is not installed -[ -x $RUNIT ] || exit 0 - -# Load the VERBOSE setting and other rcS variables -. /lib/init/vars.sh - -# Define LSB log_* functions. -# Depend on lsb-base (>= 3.0-6) to ensure that this file is present. -. /lib/lsb/init-functions - - -case "$1" in - start) - [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME" - $RUNIT start $NAME - [ "$VERBOSE" != no ] && log_end_msg $? - ;; - stop) - [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" - $RUNIT stop $NAME - [ "$VERBOSE" != no ] && log_end_msg $? - ;; - status) - $RUNIT status $NAME && exit 0 || exit $? - ;; - reload) - [ "$VERBOSE" != no ] && log_daemon_msg "Reloading $DESC" "$NAME" - $RUNIT reload $NAME - [ "$VERBOSE" != no ] && log_end_msg $? - ;; - force-reload) - [ "$VERBOSE" != no ] && log_daemon_msg "Force reloading $DESC" "$NAME" - $RUNIT force-reload $NAME - [ "$VERBOSE" != no ] && log_end_msg $? - ;; - restart) - [ "$VERBOSE" != no ] && log_daemon_msg "Restarting $DESC" "$NAME" - $RUNIT restart $NAME - [ "$VERBOSE" != no ] && log_end_msg $? - ;; - *) - echo "Usage: $SCRIPTNAME {start|stop|status|reload|force-reload|restart}" >&2 - exit 3 - ;; -esac - -: - diff --git a/cookbooks/runit/templates/default/log-config.erb b/cookbooks/runit/templates/default/log-config.erb deleted file mode 100644 index 68322b6..0000000 --- a/cookbooks/runit/templates/default/log-config.erb +++ /dev/null @@ -1,24 +0,0 @@ -<% if @config.log_size -%> -s<%= @config.log_size %> -<% end -%> -<% if @config.log_num -%> -n<%= @config.log_num %> -<% end -%> -<% if @config.log_min -%> -N<%= @config.log_min %> -<% end -%> -<% if @config.log_timeout -%> -t<%= @config.log_timeout %> -<% end -%> -<% if @config.log_processor -%> -!<%= @config.log_processor %> -<% end -%> -<% if @config.log_socket -%> -u<%= @config.log_socket %> -<% end -%> -<% if @config.log_prefix -%> -p<%= @config.log_prefix %> -<% end -%> -<% if @config.log_config_append -%> -<%= @config.log_config_append %> -<% end -%> diff --git a/cookbooks/runit/templates/gentoo/runit-start.sh.erb b/cookbooks/runit/templates/gentoo/runit-start.sh.erb deleted file mode 100644 index a6c11b3..0000000 --- a/cookbooks/runit/templates/gentoo/runit-start.sh.erb +++ /dev/null @@ -1,32 +0,0 @@ -#!/sbin/runscript -# Copyright 1999-2006 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: $ - -depend() { - after net -} - -start() { - ebegin "Starting runsvdir" - start-stop-daemon --start --exec /usr/bin/runsvdir \ - --background --make-pidfile \ - --pidfile /var/run/runsvdir.pid -- <%= node.runit.sv_dir %> - eend $? -} - -stop() { - local ret1 ret2 - ebegin "Stopping runsvdir" - start-stop-daemon --stop --oknodo --pidfile /var/run/runsvdir.pid - ret1=$? - eend ${ret1} - - ebegin "Stopping services and logging" - sv shutdown -w 10 <%= node.runit.sv_dir %>/* - ret2=$? - eend ${ret2} - - return $((ret1+ret2)) -} - diff --git a/cookbooks/wordpress/metadata.rb b/cookbooks/wordpress/metadata.rb index e7e8515..603c779 100644 --- a/cookbooks/wordpress/metadata.rb +++ b/cookbooks/wordpress/metadata.rb @@ -4,7 +4,7 @@ maintainer_email "cookbooks@opscode.com" license "Apache 2.0" description "Installs/Configures WordPress" long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -version "3.0.0" +version "3.1.0" recipe "WordPress", "Installs and configures WordPress LAMP stack on a single system" recipe "WordPress::languages", "Install WordPress translation files" @@ -20,7 +20,7 @@ depends "mysql2_chef_gem", ">= 1.0.1" depends "build-essential" depends "iis", ">= 1.6.2" depends "tar", ">= 0.3.1" -depends "nginx", "~> 2.7.4" +depends "chef_nginx" depends "php-fpm" depends 'selinux', '~> 0.7' diff --git a/cookbooks/wordpress/recipes/nginx.rb b/cookbooks/wordpress/recipes/nginx.rb index 7820a2b..83c32c1 100644 --- a/cookbooks/wordpress/recipes/nginx.rb +++ b/cookbooks/wordpress/recipes/nginx.rb @@ -37,7 +37,7 @@ end include_recipe "php::module_mysql" node.set_unless['nginx']['default_site_enabled'] = false -include_recipe "nginx" +include_recipe "chef_nginx" include_recipe "wordpress::app" diff --git a/cookbooks/yum-epel/CHANGELOG.md b/cookbooks/yum-epel/CHANGELOG.md index d5f01c2..7c4b6ac 100644 --- a/cookbooks/yum-epel/CHANGELOG.md +++ b/cookbooks/yum-epel/CHANGELOG.md @@ -2,9 +2,43 @@ This file is used to list changes made in each version of the yum-epel cookbook. +## 2.1.1 (2017-01-05) + +- Revert how mirror list strings are generated to fix RHEL 7 + +## 2.1.0 (2016-12-22) + +- Test in Travis using the current build of chef/chef docker image +- Test on older Chef +- allow the use of any valid property via attributes +- fixing tests +- output versions in the job that is being ran +- cops + +## 2.0.0 (2016-11-26) + +- Clarify that we require Chef 12.1+ not 12.0+ +- Use compat_resource instead of the yum cookbook +- Add integration testing with inspec + +## 1.0.2 (2016-10-21) + +- Remove upper bound on yum constraint + +## 1.0.1 (2016-09-11) + +- Fix epel-testing attributes + +## 1.0.0 (2016-09-06) + +- Add chef_version metadata +- Testing updates +- Remove support for Chef 11 + ## v0.7.1 (2016-08-19) + - Remove bats testing -- Fix attribute settings +- Fix attribute settings - Cleanup travis file ## v0.7.0 (2016-04-27) diff --git a/cookbooks/yum-epel/MAINTAINERS.md b/cookbooks/yum-epel/MAINTAINERS.md index 2cf4d2f..8412458 100644 --- a/cookbooks/yum-epel/MAINTAINERS.md +++ b/cookbooks/yum-epel/MAINTAINERS.md @@ -2,8 +2,8 @@ # 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 +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) diff --git a/cookbooks/yum-epel/README.md b/cookbooks/yum-epel/README.md index d6f37a1..a4d41ad 100644 --- a/cookbooks/yum-epel/README.md +++ b/cookbooks/yum-epel/README.md @@ -1,4 +1,5 @@ # 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) 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). @@ -6,20 +7,32 @@ Extra Packages for Enterprise Linux (or EPEL) is a Fedora Special Interest Group 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`. ## Requirements + ### Platforms + - RHEL/CentOS and derivatives ### Chef -- Chef 11+ + +- Chef 12.1+ ### Cookbooks -- yum version 3.6.3 or higher + +- compat_resource ## Attributes + The following attributes are set by default ```ruby -default['yum-epel']['repositories'] = %w{epel epel-debuginfo epel-source epel-testing epel-testing-debuginfo epel-testing-source} +default['yum-epel']['repos'] = %w( + epel + epel-debuginfo + epel-source + epel-testing + epel-testing-debuginfo + epel-testing-source +) ``` ```ruby @@ -139,6 +152,7 @@ include_recipe 'yum-epel' ``` ## License & Authors + **Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io)) **Copyright:** 2011-2016, Chef Software, Inc. diff --git a/cookbooks/yum-epel/attributes/default.rb b/cookbooks/yum-epel/attributes/default.rb index 5b03a69..960a280 100644 --- a/cookbooks/yum-epel/attributes/default.rb +++ b/cookbooks/yum-epel/attributes/default.rb @@ -1 +1,8 @@ -default['yum-epel']['repositories'] = %w(epel epel-debuginfo epel-source epel-testing epel-testing-debuginfo epel-testing-source) +default['yum-epel']['repos'] = %w( + epel + epel-debuginfo + epel-source + epel-testing + epel-testing-debuginfo + epel-testing-source +) diff --git a/cookbooks/yum-epel/attributes/epel-debuginfo.rb b/cookbooks/yum-epel/attributes/epel-debuginfo.rb index 1f51fdd..b1142e5 100644 --- a/cookbooks/yum-epel/attributes/epel-debuginfo.rb +++ b/cookbooks/yum-epel/attributes/epel-debuginfo.rb @@ -1,12 +1,12 @@ default['yum']['epel-debuginfo']['repositoryid'] = 'epel-debuginfo' -default['yum']['epel-debuginfo']['description'] = 'Extra Packages for $releasever - $basearch - Debug' - -if node['platform'] == 'amazon' +default['yum']['epel-debuginfo']['description'] = "Extra Packages for #{node['platform_version'].to_i} - $basearch - Debug" +case node['platform'] +when '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 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}") + default['yum']['epel-debuginfo']['gpgkey'] = "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 diff --git a/cookbooks/yum-epel/attributes/epel-source.rb b/cookbooks/yum-epel/attributes/epel-source.rb index 670bcc0..11ef8e4 100644 --- a/cookbooks/yum-epel/attributes/epel-source.rb +++ b/cookbooks/yum-epel/attributes/epel-source.rb @@ -1,13 +1,13 @@ default['yum']['epel-source']['repositoryid'] = 'epel-source' -default['yum']['epel-source']['description'] = 'Extra Packages for $releasever - $basearch - Source' -if node['platform'] == 'amazon' +default['yum']['epel-source']['description'] = "Extra Packages for #{node['platform_version'].to_i} - $basearch - Source" +case node['platform'] +when '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 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}") + default['yum']['epel-source']['gpgkey'] = "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 diff --git a/cookbooks/yum-epel/attributes/epel-testing-debuginfo.rb b/cookbooks/yum-epel/attributes/epel-testing-debuginfo.rb index fa8234b..54e9b9b 100644 --- a/cookbooks/yum-epel/attributes/epel-testing-debuginfo.rb +++ b/cookbooks/yum-epel/attributes/epel-testing-debuginfo.rb @@ -1,13 +1,13 @@ default['yum']['epel-testing-debuginfo']['repositoryid'] = 'epel-testing-debuginfo' -default['yum']['epel-testing-debuginfo']['description'] = 'Extra Packages for $releasever - $basearch - Testing Debug' -if node['platform'] == 'amazon' +default['yum']['epel-testing-debuginfo']['description'] = "Extra Packages for #{node['platform_version'].to_i} - $basearch - Testing Debug" +case node['platform'] +when '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 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}") + default['yum']['epel-testing-debuginfo']['gpgkey'] = "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 diff --git a/cookbooks/yum-epel/attributes/epel-testing-source.rb b/cookbooks/yum-epel/attributes/epel-testing-source.rb index 731ef06..f92031b 100644 --- a/cookbooks/yum-epel/attributes/epel-testing-source.rb +++ b/cookbooks/yum-epel/attributes/epel-testing-source.rb @@ -1,11 +1,12 @@ default['yum']['epel-testing-source']['repositoryid'] = 'epel-testing-source' -default['yum']['epel-testing-source']['description'] = 'Extra Packages for $releasever - $basearch - Testing Source' -if node['platform'] == 'amazon' +default['yum']['epel-testing-source']['description'] = "Extra Packages for #{node['platform_version'].to_i} - $basearch - Testing Source" +case node['platform'] +when '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 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}") + default['yum']['epel-testing-source']['gpgkey'] = "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 diff --git a/cookbooks/yum-epel/attributes/epel-testing.rb b/cookbooks/yum-epel/attributes/epel-testing.rb index 2a3c6d8..ee9d496 100644 --- a/cookbooks/yum-epel/attributes/epel-testing.rb +++ b/cookbooks/yum-epel/attributes/epel-testing.rb @@ -1,13 +1,13 @@ default['yum']['epel-testing']['repositoryid'] = 'epel-testing' -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' +default['yum']['epel-testing']['description'] = "Extra Packages for #{node['platform_version'].to_i} - $basearch - Testing " +case node['platform'] +when 'amazon' + default['yum']['epel-testing']['mirrorlist'] = 'http://mirrors.fedoraproject.org/mirrorlist?repo=testing-epel6&arch=$basearch' + default['yum']['epel-testing']['gpgkey'] = 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6' else - 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}") + default['yum']['epel-testing']['mirrorlist'] = "http://mirrors.fedoraproject.org/mirrorlist?repo=testing-epel#{node['platform_version'].to_i}&arch=$basearch" + default['yum']['epel-testing']['gpgkey'] = "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 diff --git a/cookbooks/yum-epel/attributes/epel.rb b/cookbooks/yum-epel/attributes/epel.rb index 9ee912f..ab17be5 100644 --- a/cookbooks/yum-epel/attributes/epel.rb +++ b/cookbooks/yum-epel/attributes/epel.rb @@ -1,20 +1,19 @@ default['yum']['epel']['repositoryid'] = 'epel' -default['yum']['epel']['description'] = 'Extra Packages for $releasever - $basearch' - +default['yum']['epel']['description'] = "Extra Packages for #{node['platform_version'].to_i} - $basearch" 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 - if node['platform'] == 'amazon' + case node['platform'] + when '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}") + default['yum']['epel']['gpgkey'] = "https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-#{node['platform_version'].to_i}" end end - default['yum']['epel']['failovermethod'] = 'priority' default['yum']['epel']['gpgcheck'] = true default['yum']['epel']['enabled'] = true diff --git a/cookbooks/yum-epel/metadata.json b/cookbooks/yum-epel/metadata.json index e4c155c..2f8805e 100644 --- a/cookbooks/yum-epel/metadata.json +++ b/cookbooks/yum-epel/metadata.json @@ -1 +1 @@ -{"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 +{"name":"yum-epel","version":"2.1.1","description":"Installs and configures the EPEL Yum repository","long_description":"# yum-epel Cookbook\n\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\n### Platforms\n\n- RHEL/CentOS and derivatives\n\n### Chef\n\n- Chef 12.1+\n\n### Cookbooks\n\n- compat_resource\n\n## Attributes\n\nThe following attributes are set by default\n\n```ruby\ndefault['yum-epel']['repos'] = %w(\n epel\n epel-debuginfo\n epel-source\n epel-testing\n epel-testing-debuginfo\n epel-testing-source\n)\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\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":{"compat_resource":">= 12.16.3"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{}} \ No newline at end of file diff --git a/cookbooks/yum-epel/recipes/default.rb b/cookbooks/yum-epel/recipes/default.rb index 8347394..02f75f3 100644 --- a/cookbooks/yum-epel/recipes/default.rb +++ b/cookbooks/yum-epel/recipes/default.rb @@ -1,9 +1,9 @@ # # Author:: Sean OMeara () -# Cookbook Name:: yum-epel +# Cookbook:: yum-epel # Recipe:: default # -# Copyright 2013-2016, 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. @@ -17,46 +17,11 @@ # See the License for the specific language governing permissions and # limitations under the License. -node['yum-epel']['repositories'].each do |repo| +node['yum-epel']['repos'].each do |repo| next unless node['yum'][repo]['managed'] - yum_repository repo do - baseurl node['yum'][repo]['baseurl'] unless node['yum'][repo]['baseurl'].nil? - cost node['yum'][repo]['cost'] unless node['yum'][repo]['cost'].nil? - description node['yum'][repo]['description'] unless node['yum'][repo]['description'].nil? - enabled node['yum'][repo]['enabled'] unless node['yum'][repo]['enabled'].nil? - enablegroups node['yum'][repo]['enablegroups'] unless node['yum'][repo]['enablegroups'].nil? - exclude node['yum'][repo]['exclude'] unless node['yum'][repo]['exclude'].nil? - failovermethod node['yum'][repo]['failovermethod'] unless node['yum'][repo]['failovermethod'].nil? - fastestmirror_enabled node['yum'][repo]['fastestmirror_enabled'] unless node['yum'][repo]['fastestmirror_enabled'].nil? - gpgcheck node['yum'][repo]['gpgcheck'] unless node['yum'][repo]['gpgcheck'].nil? - gpgkey node['yum'][repo]['gpgkey'] unless node['yum'][repo]['gpgkey'].nil? - http_caching node['yum'][repo]['http_caching'] unless node['yum'][repo]['http_caching'].nil? - 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? - mirrorlist node['yum'][repo]['mirrorlist'] unless node['yum'][repo]['mirrorlist'].nil? - mirrorlist_expire node['yum'][repo]['mirrorlist_expire'] unless node['yum'][repo]['mirrorlist_expire'].nil? - password node['yum'][repo]['password'] unless node['yum'][repo]['password'].nil? - priority node['yum'][repo]['priority'] unless node['yum'][repo]['priority'].nil? - proxy node['yum'][repo]['proxy'] unless node['yum'][repo]['proxy'].nil? - proxy_username node['yum'][repo]['proxy_username'] unless node['yum'][repo]['proxy_username'].nil? - proxy_password node['yum'][repo]['proxy_password'] unless node['yum'][repo]['proxy_password'].nil? - report_instanceid node['yum'][repo]['report_instanceid'] unless node['yum'][repo]['report_instanceid'].nil? - repositoryid node['yum'][repo]['repositoryid'] unless node['yum'][repo]['repositoryid'].nil? - skip_if_unavailable node['yum'][repo]['skip_if_unavailable'] unless node['yum'][repo]['skip_if_unavailable'].nil? - source node['yum'][repo]['source'] unless node['yum'][repo]['source'].nil? - sslcacert node['yum'][repo]['sslcacert'] unless node['yum'][repo]['sslcacert'].nil? - sslclientcert node['yum'][repo]['sslclientcert'] unless node['yum'][repo]['sslclientcert'].nil? - sslclientkey node['yum'][repo]['sslclientkey'] unless node['yum'][repo]['sslclientkey'].nil? - sslverify node['yum'][repo]['sslverify'] unless node['yum'][repo]['sslverify'].nil? - timeout node['yum'][repo]['timeout'] unless node['yum'][repo]['timeout'].nil? - username node['yum'][repo]['username'] unless node['yum'][repo]['username'].nil? - - action :create + node['yum'][repo].each do |config, value| + send(config.to_sym, value) unless value.nil? || config == 'managed' + end end end diff --git a/cookbooks/zypper/CHANGELOG.md b/cookbooks/zypper/CHANGELOG.md new file mode 100644 index 0000000..072be23 --- /dev/null +++ b/cookbooks/zypper/CHANGELOG.md @@ -0,0 +1,25 @@ +# zypper CHANGELOG + +## 0.4.0 + +- [tas50] - Add Whyrun support +- [bluca] - Add repository priority attribute + +## 0.3.0 + +- [tas50] - Add issues_url, source_url, and chef_version to the metadata +- [tas50] - Add Chefspec matchers for the repo LWRP +- [tas50] - Add testing and metadata supports attribute for opensuseleap + +## 0.2.1 + +- [gimler] - Use --non-interactive mode when running zypper refresh + +## 0.2.0 + +- [jarosser06] - Added Key attribute to allow importing a gpg key for a new repo +- [jarosser06] - Renamed alias attribute to repo_name + +## 0.1.0 + +- [jarosser06] - Initial release of zypper diff --git a/cookbooks/zypper/README.md b/cookbooks/zypper/README.md new file mode 100644 index 0000000..c3979ba --- /dev/null +++ b/cookbooks/zypper/README.md @@ -0,0 +1,126 @@ +# zypper Cookbook + +Cookbook that provides a lwrp for zypper repositories and also a recipe to install and configure the smt-client for SLES. + +## Requirements + +### Platforms + +- SLES 11+ +- openSUSE 13+ +- openSUSE Leap + +### Chef + +- Chef 11+ + +### Cookbooks + +- none + +## Attributes + +### zypper::smt_client + +Key | Type | Description | Default +------------------------------- | ------ | ------------------- | ------------ +['zypper']['smt_host'] | String | uri of the SMT host | nil + +## Resource/Provider + +## zypper_repo + +### Actions + +- **add** - adds a repo +- **delete** - removes a repo + +### Attributes + +- **repo_name** - repo alias (name attribute) +- **uri** - uri of the repo +- **autorefresh** - enable autorefresh +- **key** - location of repo key to import +- **priority** - priority of the repo + +## Example Usage + +```ruby +zypper_repo 'remove_dvd_repo' do + action :remove + repo_name 'SLES11SP3-x64 DVD1 Online' +end + +zypper_repo 'add_dvd_repo' do + repo_name 'SLES11SP3-x64 DVD1 Online' + uri 'http://demeter.uni-regensburg.de/SLES11SP3-x64/DVD1/' +end + +zypper_repo 'jenkins' do + key 'http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key' + uri 'http://pkg.jenkins-ci.org/opensuse/' +end +``` + +### zypper::smt_client + +Just include `zypper::smt_client` in your node's `run_list` and set the `smt_host` attribute to your smt server: + +```json +{ + "name":"my_node", + "normal": { + "zypper": { + "smt_host": "smt.example.com" + } + }, + "run_list": [ + "recipe[zypper]" + ] +} +``` + +## Testing + +To test with test kitchen you need to have a SLES Vagrant box already on your system(checkout github.com/opscode/bento). In order to test the smt recipe with your smt server set the SMT_HOST env variable to your smt host: + +```shell +export SMT_HOST=smt.example.com +``` + +## Contributing + +1. Fork the repository on Github +2. Create a named feature branch (like `add_component_x`) +3. Write you change +4. Write tests for your change (if applicable) +5. Run the tests, ensuring they all pass +6. Submit a Pull Request using Github + +## License and Authors + +- Author:: Jim Rosser(jarosser06@gmail.com) + +```text +copyright (C) 2014-2016 Jim Rosser + +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. +``` diff --git a/cookbooks/zypper/attributes/default.rb b/cookbooks/zypper/attributes/default.rb new file mode 100644 index 0000000..7c4d803 --- /dev/null +++ b/cookbooks/zypper/attributes/default.rb @@ -0,0 +1 @@ +default['zypper']['smt_host'] = nil diff --git a/cookbooks/zypper/libraries/matchers.rb b/cookbooks/zypper/libraries/matchers.rb new file mode 100644 index 0000000..7618d98 --- /dev/null +++ b/cookbooks/zypper/libraries/matchers.rb @@ -0,0 +1,12 @@ + +if defined?(ChefSpec) + ChefSpec.define_matcher :zypper_repo + + def add_zypper_repo(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:zypper_repo, :add, resource_name) + end + + def remove_zypper_repo(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:zypper_repo, :remove, resource_name) + end +end diff --git a/cookbooks/zypper/metadata.json b/cookbooks/zypper/metadata.json new file mode 100644 index 0000000..b73eb46 --- /dev/null +++ b/cookbooks/zypper/metadata.json @@ -0,0 +1 @@ +{"name":"zypper","version":"0.4.0","description":"Provides resources for managing zypper repositories","long_description":"# zypper Cookbook\n\nCookbook that provides a lwrp for zypper repositories and also a recipe to install and configure the smt-client for SLES.\n\n## Requirements\n\n### Platforms\n\n- SLES 11+\n- openSUSE 13+\n- openSUSE Leap\n\n### Chef\n\n- Chef 11+\n\n### Cookbooks\n\n- none\n\n## Attributes\n\n### zypper::smt_client\n\nKey | Type | Description | Default\n------------------------------- | ------ | ------------------- | ------------\n['zypper']['smt_host'] | String | uri of the SMT host | nil\n\n## Resource/Provider\n\n## zypper_repo\n\n### Actions\n\n- **add** - adds a repo\n- **delete** - removes a repo\n\n### Attributes\n\n- **repo_name** - repo alias (name attribute)\n- **uri** - uri of the repo\n- **autorefresh** - enable autorefresh\n- **key** - location of repo key to import\n- **priority** - priority of the repo\n\n## Example Usage\n\n```ruby\nzypper_repo 'remove_dvd_repo' do\n action :remove\n repo_name 'SLES11SP3-x64 DVD1 Online'\nend\n\nzypper_repo 'add_dvd_repo' do\n repo_name 'SLES11SP3-x64 DVD1 Online'\n uri 'http://demeter.uni-regensburg.de/SLES11SP3-x64/DVD1/'\nend\n\nzypper_repo 'jenkins' do\n key 'http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key'\n uri 'http://pkg.jenkins-ci.org/opensuse/'\nend\n```\n\n### zypper::smt_client\n\nJust include `zypper::smt_client` in your node's `run_list` and set the `smt_host` attribute to your smt server:\n\n```json\n{\n \"name\":\"my_node\",\n \"normal\": {\n \"zypper\": {\n \"smt_host\": \"smt.example.com\"\n }\n },\n \"run_list\": [\n \"recipe[zypper]\"\n ]\n}\n```\n\n## Testing\n\nTo test with test kitchen you need to have a SLES Vagrant box already on your system(checkout github.com/opscode/bento). In order to test the smt recipe with your smt server set the SMT_HOST env variable to your smt host:\n\n```shell\nexport SMT_HOST=smt.example.com\n```\n\n## Contributing\n\n1. Fork the repository on Github\n2. Create a named feature branch (like `add_component_x`)\n3. Write you change\n4. Write tests for your change (if applicable)\n5. Run the tests, ensuring they all pass\n6. Submit a Pull Request using Github\n\n## License and Authors\n\n- Author:: Jim Rosser(jarosser06@gmail.com)\n\n```text\ncopyright (C) 2014-2016 Jim Rosser\n\nPermission is hereby granted, free of charge, to any person\nobtaining a copy of this software and associated documentation\nfiles (the “Software”), to deal in the Software without restriction,\nincluding without limitation the rights to use, copy, modify, merge,\npublish, distribute, sublicense, and/or sell copies of the Software,\nand to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\nOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\nHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\nOTHER DEALINGS IN THE SOFTWARE.\n```\n","maintainer":"Jim Rosser","maintainer_email":"jarosser06@gmail.com","license":"MIT","platforms":{"suse":">= 0.0.0","opensuse":">= 0.0.0","opensuseleap":">= 0.0.0"},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{},"source_url":"https://github.com/jarosser06/chef-zypper","issues_url":"https://github.com/jarosser06/chef-zypper/issues","chef_version":[[">= 11"]],"ohai_version":[]} \ No newline at end of file diff --git a/cookbooks/zypper/providers/repo.rb b/cookbooks/zypper/providers/repo.rb new file mode 100644 index 0000000..7eaf84d --- /dev/null +++ b/cookbooks/zypper/providers/repo.rb @@ -0,0 +1,68 @@ +require 'mixlib/shellout' + +use_inline_resources + +def whyrun_supported? + true +end + +action :add do + unless repo_exist? + converge_by("add zypper repository '#{new_resource.repo_name}'") do + unless new_resource.key.nil? + install_curl + import_key + end + command = 'zypper ar' + command << ' -f' if new_resource.autorefresh + command << " #{new_resource.uri} \"#{new_resource.repo_name}\"" + shellout = Mixlib::ShellOut.new(command, user: 'root').run_command + if shellout.stderr.empty? + set_priority + else + Chef::Log.error("Error adding repo: #{shellout.stderr}") + end + end + end +end + +action :remove do + if repo_exist? + converge_by("remove zypper repository '#{new_resource.repo_name}'") do + command = "zypper rr \"#{new_resource.repo_name}\"" + shellout = Mixlib::ShellOut.new(command, user: 'root').run_command + Chef::Log.error("Error removing repo: #{shellout.stderr}") unless shellout.stderr.empty? + end + end +end + +def repo_exist? + command = "zypper repos | grep \"#{new_resource.repo_name}\"" + shellout = Mixlib::ShellOut.new(command, user: 'root').run_command + if shellout.stdout.empty? + false + else + true + end +end + +def install_curl + # Make sure curl is installed + pkg = Chef::Resource::Package.new('curl', run_context) + pkg.run_action :install +end + +def import_key + cmd = Chef::Resource::Execute.new("import key for #{new_resource.repo_name}", + run_context) + cmd.command "rpm --import #{new_resource.key}" + cmd.run_action :run +end + +def set_priority + return if new_resource.priority.nil? || new_resource.priority <= 0 + command = 'zypper mr' + command << " -p #{new_resource.priority} \"#{new_resource.repo_name}\"" + shellout = Mixlib::ShellOut.new(command, user: 'root').run_command + Chef::Log.error("Error setting repo priority: #{shellout.stderr}") unless shellout.stderr.empty? +end diff --git a/cookbooks/zypper/recipes/default.rb b/cookbooks/zypper/recipes/default.rb new file mode 100644 index 0000000..ecead57 --- /dev/null +++ b/cookbooks/zypper/recipes/default.rb @@ -0,0 +1,30 @@ +# +# Cookbook Name:: zypper +# Recipe:: default +# +# Copyright 2014 - 2016, Jim Rosser +# +# 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. +# + +execute 'zypper_refresh' do + command 'zypper --non-interactive refresh' + user 'root' +end diff --git a/cookbooks/zypper/recipes/smt_client.rb b/cookbooks/zypper/recipes/smt_client.rb new file mode 100644 index 0000000..75308e6 --- /dev/null +++ b/cookbooks/zypper/recipes/smt_client.rb @@ -0,0 +1,50 @@ +# +# Cookbook Name:: zypper +# Recipe:: smt_client +# +# Copyright 2014 - 2016, Jim Rosser +# +# 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. +# +package 'smt-client' + +client_setup = "#{Chef::Config[:file_cache_path]}/clientSetup4SMT.sh" +register_log = '/root/.suse_register.log' + +remote_file client_setup do + action :create + source "http://#{node['zypper']['smt_host']}/repo/tools/clientSetup4SMT.sh" + mode 0544 + owner 'root' + not_if { ::File.exist? register_log } +end + +execute 'register_smt' do + command "yes | #{client_setup} --host #{node['zypper']['smt_host']}" + user 'root' + creates register_log + notifies :run, 'execute[initial_smt_agent]', :immediately +end + +execute 'initial_smt_agent' do + user 'root' + command 'smt-agent' + action :nothing +end diff --git a/cookbooks/zypper/resources/repo.rb b/cookbooks/zypper/resources/repo.rb new file mode 100644 index 0000000..2aeb372 --- /dev/null +++ b/cookbooks/zypper/resources/repo.rb @@ -0,0 +1,8 @@ +actions :add, :remove +default_action :add + +attribute :repo_name, kind_of: String, name_attribute: true +attribute :autorefresh, kind_of: [TrueClass, FalseClass] +attribute :uri, kind_of: String +attribute :key, kind_of: String, default: nil +attribute :priority, kind_of: Integer, default: nil From 8ba12e1ba2ee9c9e75ff32a6acfd2418e93a7bec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 28 Apr 2017 12:00:22 +0200 Subject: [PATCH 30/83] Pass the user and group to the git resource The clone is done by root otherwise --- site-cookbooks/kosmos-hubot/recipes/default.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/site-cookbooks/kosmos-hubot/recipes/default.rb b/site-cookbooks/kosmos-hubot/recipes/default.rb index d84b940..5a6b7e9 100644 --- a/site-cookbooks/kosmos-hubot/recipes/default.rb +++ b/site-cookbooks/kosmos-hubot/recipes/default.rb @@ -38,6 +38,8 @@ application hal8000_path do group "hubot" git do + user "hubot" + group "hubot" repository "https://github.com/67P/hal8000.git" revision "master" end @@ -120,6 +122,8 @@ application botka_freenode_path do group "hubot" git do + user "hubot" + group "hubot" repository "https://github.com/67P/botka.git" revision "master" end From c9879a60e2c2dded5dbc3a88ef5771d84442cac4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 28 Apr 2017 12:01:07 +0200 Subject: [PATCH 31/83] Run sockethub as its own user --- site-cookbooks/sockethub/recipes/default.rb | 29 ++++++++++++++++----- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/site-cookbooks/sockethub/recipes/default.rb b/site-cookbooks/sockethub/recipes/default.rb index daa6b63..4c7d4c6 100644 --- a/site-cookbooks/sockethub/recipes/default.rb +++ b/site-cookbooks/sockethub/recipes/default.rb @@ -2,26 +2,41 @@ # Cookbook Name:: sockethub # Recipe:: default # -# Copyright 2015, Kosmos +# Copyright 2015-2017, Kosmos # # All rights reserved - Do Not Redistribute # include_recipe 'kosmos-nodejs' include_recipe 'kosmos-redis' -package "git" + +group "sockethub" do + gid 7625 +end + +user "sockethub" do + comment "sockethub user" + uid 7625 + gid 7625 + manage_home true + shell "/bin/bash" +end path_to_deploy = "/opt/sockethub" application path_to_deploy do - owner "www-data" - group "www-data" + owner "sockethub" + group "sockethub" git do + user "sockethub" + group "sockethub" repository 'https://github.com/sockethub/sockethub.git' revision 'v1.0.5' end - npm_install + npm_install do + user "sockethub" + end execute "systemctl daemon-reload" do command "systemctl daemon-reload" @@ -34,8 +49,8 @@ application path_to_deploy do group 'root' mode '0644' variables( - :user => owner, - :group => group, + :user => "sockethub", + :group => "sockethub", :app_dir => path_to_deploy, :entry => "/usr/local/bin/node /usr/local/bin/npm start", :environment => { 'DEBUG' => '*', From d6cc8509bc34954ae1ad3fa90d258e265e85cb75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 28 Apr 2017 12:01:17 +0200 Subject: [PATCH 32/83] Don't run the Let's Encrypt set up in development --- site-cookbooks/sockethub/recipes/proxy.rb | 25 +++++++++++++---------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/site-cookbooks/sockethub/recipes/proxy.rb b/site-cookbooks/sockethub/recipes/proxy.rb index 88025da..c1fb46c 100644 --- a/site-cookbooks/sockethub/recipes/proxy.rb +++ b/site-cookbooks/sockethub/recipes/proxy.rb @@ -2,14 +2,14 @@ # Cookbook Name:: sockethub # Recipe:: proxy # -# Copyright 2015, Kosmos +# Copyright 2015-2017, Kosmos # # All rights reserved - Do Not Redistribute # -include_recipe "kosmos-base::letsencrypt" - unless node.chef_environment == "development" + include_recipe "kosmos-base::letsencrypt" + include_recipe "firewall" firewall_rule 'sockethub' do port node['sockethub']['external_port'].to_i @@ -21,9 +21,10 @@ end include_recipe 'kosmos-nginx' directory "/var/www/sockethub" do - owner node["nginx"]["user"] - group node["nginx"]["group"] - action :create + owner node["nginx"]["user"] + group node["nginx"]["group"] + action :create + recursive true end include_recipe 'kosmos-nginx' @@ -40,11 +41,13 @@ template "#{node['nginx']['dir']}/sites-available/sockethub" do notifies :reload, 'service[nginx]', :delayed end -execute "letsencrypt cert for sockethub.kosmos.org" do - command "./certbot-auto certonly --webroot --agree-tos --email ops@5apps.com --webroot-path /var/www/sockethub -d sockethub.kosmos.org -n" - cwd "/usr/local/certbot" - not_if { File.exist? "/etc/letsencrypt/live/sockethub.kosmos.org/fullchain.pem" } - notifies :reload, "service[nginx]", :delayed +unless node.chef_environment == "development" + execute "letsencrypt cert for sockethub.kosmos.org" do + command "./certbot-auto certonly --webroot --agree-tos --email ops@5apps.com --webroot-path /var/www/sockethub -d sockethub.kosmos.org -n" + cwd "/usr/local/certbot" + not_if { File.exist? "/etc/letsencrypt/live/sockethub.kosmos.org/fullchain.pem" } + notifies :reload, "service[nginx]", :delayed + end end nginx_site 'sockethub' do From 099debe5c3333736bc82ad37ecd933ba5e3608c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 28 Apr 2017 12:01:51 +0200 Subject: [PATCH 33/83] Depend on the new chef_nginx cookbook --- site-cookbooks/kosmos-nginx/metadata.rb | 4 ++-- site-cookbooks/kosmos-nginx/recipes/default.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/site-cookbooks/kosmos-nginx/metadata.rb b/site-cookbooks/kosmos-nginx/metadata.rb index 2cd518b..f3f01df 100644 --- a/site-cookbooks/kosmos-nginx/metadata.rb +++ b/site-cookbooks/kosmos-nginx/metadata.rb @@ -4,8 +4,8 @@ maintainer_email 'mail@kosmos.org' license 'All rights reserved' description 'Installs/Configures kosmos-nginx' long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -version '0.1.0' +version '0.2.0' -depends 'nginx' +depends 'chef_nginx' depends 'firewall' depends 'openssl' diff --git a/site-cookbooks/kosmos-nginx/recipes/default.rb b/site-cookbooks/kosmos-nginx/recipes/default.rb index 9faa21f..7731995 100644 --- a/site-cookbooks/kosmos-nginx/recipes/default.rb +++ b/site-cookbooks/kosmos-nginx/recipes/default.rb @@ -24,7 +24,7 @@ EOF node.override['nginx']['repo_source'] = 'nginx' # Install from official repo node.override['nginx']['upstream_repository'] = "http://nginx.org/packages/mainline/#{node['platform']}" -include_recipe 'nginx' +include_recipe 'chef_nginx' # Generate Strong Diffie-Hellman Group (increases security) # https://weakdh.org/sysadmin.html From 17f9b897bfe36acd6a5f94b71007d2397370bf58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 28 Apr 2017 12:04:28 +0200 Subject: [PATCH 34/83] Update test-kitchen gem --- Gemfile.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 1f2dab4..df86242 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,7 +3,7 @@ GEM specs: addressable (2.5.0) public_suffix (~> 2.0, >= 2.0.2) - artifactory (2.7.0) + artifactory (2.8.1) ast (2.3.0) attribute_struct (0.3.4) bogo (>= 0.1.31, < 0.3.0) @@ -199,15 +199,15 @@ GEM sfl syslog-logger (1.6.8) systemu (2.6.5) - test-kitchen (1.15.0) + test-kitchen (1.16.0) mixlib-install (>= 1.2, < 3.0) mixlib-shellout (>= 1.2, < 3.0) net-scp (~> 1.1) net-ssh (>= 2.9, < 5.0) net-ssh-gateway (~> 1.2) safe_yaml (~> 1.0) - thor (~> 0.18) - thor (0.19.4) + thor (~> 0.19, < 0.19.2) + thor (0.19.1) unf (0.1.4) unf_ext unf_ext (0.0.7.2) @@ -227,4 +227,4 @@ DEPENDENCIES test-kitchen BUNDLED WITH - 1.14.3 + 1.14.6 From 4641e77438fd28ea2e41254f92b116e174cbc647 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 28 Apr 2017 12:04:58 +0200 Subject: [PATCH 35/83] Update cookstyle cookbook --- Gemfile.lock | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index df86242..393eab1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -77,7 +77,7 @@ GEM colored (1.2) command_line_reporter (3.3.6) colored (>= 1.2) - cookstyle (1.3.0) + cookstyle (1.3.1) rubocop (= 0.47.1) diff-lcs (1.3) domain_name (0.5.20170223) @@ -157,7 +157,9 @@ GEM proxifier (1.0.3) public_suffix (2.0.5) rack (2.0.1) - rainbow (2.2.1) + rainbow (2.2.2) + rake + rake (12.0.0) rspec (3.5.0) rspec-core (~> 3.5.0) rspec-expectations (~> 3.5.0) @@ -211,7 +213,7 @@ GEM unf (0.1.4) unf_ext unf_ext (0.0.7.2) - unicode-display_width (1.1.3) + unicode-display_width (1.2.1) uuidtools (2.1.5) wmi-lite (1.0.0) From 2f0ff1f5598df9f33b5bf863d1655fbf296eaad5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 28 Apr 2017 15:42:18 +0200 Subject: [PATCH 36/83] Fixed code styling --- .../5apps-hubot/recipes/xmpp_botka.rb | 36 +++---- .../5apps-hubot/recipes/xmpp_schlupp.rb | 36 +++---- .../5apps-xmpp_server/recipes/letsencrypt.rb | 2 +- site-cookbooks/backup/recipes/default.rb | 14 +-- site-cookbooks/ipfs/attributes/default.rb | 2 +- site-cookbooks/ipfs/metadata.rb | 2 +- site-cookbooks/ipfs/recipes/default.rb | 2 +- site-cookbooks/ipfs/resources/config.rb | 5 +- .../default/serverspec/ipfs_spec.rb | 2 - .../kosmos-hubot/recipes/default.rb | 94 +++++++++---------- .../kosmos-ipfs/recipes/letsencrypt.rb | 2 +- .../kosmos-mastodon/recipes/default.rb | 12 +-- .../kosmos-mastodon/recipes/nginx.rb | 1 - .../kosmos-mediawiki/recipes/default.rb | 6 +- .../kosmos-wordpress/recipes/nginx.rb | 34 +++---- site-cookbooks/sockethub/recipes/default.rb | 13 ++- 16 files changed, 130 insertions(+), 133 deletions(-) diff --git a/site-cookbooks/5apps-hubot/recipes/xmpp_botka.rb b/site-cookbooks/5apps-hubot/recipes/xmpp_botka.rb index 0df8447..06fafc8 100644 --- a/site-cookbooks/5apps-hubot/recipes/xmpp_botka.rb +++ b/site-cookbooks/5apps-hubot/recipes/xmpp_botka.rb @@ -50,7 +50,7 @@ application botka_xmpp_path do group "hubot" content [ "hubot-help", - "hubot-remotestorage-logger" + "hubot-remotestorage-logger", ].to_json end @@ -76,23 +76,23 @@ application botka_xmpp_path do group 'root' mode '0644' variables( - :user => "hubot", - :group => "hubot", - :app_dir => botka_xmpp_path, - :entry => "#{botka_xmpp_path}/bin/hubot -a xmpp --name botka", - :environment => { "HUBOT_XMPP_USERNAME" => "botka@5apps.com/hubot", - "HUBOT_XMPP_PASSWORD" => botka_xmpp_data_bag_item['password'], - "HUBOT_XMPP_ROOMS" => "5info@muc.5apps.com,5ops@muc.5apps.com,core@muc.5apps.com,deploy@muc.5apps.com,storage@muc.5apps.com,watercooler@muc.5apps.com,hilti@muc.5apps.com,gymapp@muc.5apps.com", - "HUBOT_XMPP_HOST" => "xmpp.5apps.com", - "HUBOT_RSS_PRINTSUMMARY" => "false", - "EXPRESS_PORT" => "8082", - "HUBOT_RSS_HEADER" => "Update:", - "HUBOT_AUTH_ADMIN" => "basti,garret,greg", - "REDIS_URL" => "redis://localhost:6379/5apps_botka_xmpp", - "RS_LOGGER_USER" => "5apps@5apps.com", - "RS_LOGGER_TOKEN" => botka_xmpp_data_bag_item['rs_logger_token'], - "RS_LOGGER_SERVER_NAME" => "5apps", - "WEBHOOK_TOKEN" => botka_xmpp_data_bag_item['webhook_token'] } + user: "hubot", + group: "hubot", + app_dir: botka_xmpp_path, + entry: "#{botka_xmpp_path}/bin/hubot -a xmpp --name botka", + environment: { "HUBOT_XMPP_USERNAME" => "botka@5apps.com/hubot", + "HUBOT_XMPP_PASSWORD" => botka_xmpp_data_bag_item['password'], + "HUBOT_XMPP_ROOMS" => "5info@muc.5apps.com,5ops@muc.5apps.com,core@muc.5apps.com,deploy@muc.5apps.com,storage@muc.5apps.com,watercooler@muc.5apps.com,hilti@muc.5apps.com,gymapp@muc.5apps.com", + "HUBOT_XMPP_HOST" => "xmpp.5apps.com", + "HUBOT_RSS_PRINTSUMMARY" => "false", + "EXPRESS_PORT" => "8082", + "HUBOT_RSS_HEADER" => "Update:", + "HUBOT_AUTH_ADMIN" => "basti,garret,greg", + "REDIS_URL" => "redis://localhost:6379/5apps_botka_xmpp", + "RS_LOGGER_USER" => "5apps@5apps.com", + "RS_LOGGER_TOKEN" => botka_xmpp_data_bag_item['rs_logger_token'], + "RS_LOGGER_SERVER_NAME" => "5apps", + "WEBHOOK_TOKEN" => botka_xmpp_data_bag_item['webhook_token'] } ) notifies :run, "execute[systemctl daemon-reload]", :delayed diff --git a/site-cookbooks/5apps-hubot/recipes/xmpp_schlupp.rb b/site-cookbooks/5apps-hubot/recipes/xmpp_schlupp.rb index f344b37..6fe34b5 100644 --- a/site-cookbooks/5apps-hubot/recipes/xmpp_schlupp.rb +++ b/site-cookbooks/5apps-hubot/recipes/xmpp_schlupp.rb @@ -59,7 +59,7 @@ application schlupp_xmpp_path do "hubot-seen", "hubot-rss-reader", "hubot-incoming-webhook", - "hubot-yubikey-invalidation" + "hubot-yubikey-invalidation", ].to_json end @@ -78,23 +78,23 @@ application schlupp_xmpp_path do group 'root' mode '0644' variables( - :user => "hubot", - :group => "hubot", - :app_dir => schlupp_xmpp_path, - :entry => "#{schlupp_xmpp_path}/bin/hubot -a xmpp --name schlupp", - :environment => { "HUBOT_XMPP_USERNAME" => "schlupp@5apps.com/hubot", - "HUBOT_XMPP_PASSWORD" => schlupp_xmpp_data_bag_item['password'], - "HUBOT_XMPP_ROOMS" => "5info@muc.5apps.com,5ops@muc.5apps.com,core@muc.5apps.com,deploy@muc.5apps.com,storage@muc.5apps.com,watercooler@muc.5apps.com,hilti@muc.5apps.com,test@muc.5apps.com,gymapp@muc.5apps.com", - "HUBOT_XMPP_HOST" => "xmpp.5apps.com", - "HUBOT_RSS_PRINTSUMMARY" => "false", - "EXPRESS_PORT" => "8083", - "HUBOT_RSS_HEADER" => "Update:", - "HUBOT_AUTH_ADMIN" => "basti,garret,greg", - "REDIS_URL" => "redis://localhost:6379/5apps_schlupp_xmpp", - "RS_OPS_TOKEN" => schlupp_xmpp_data_bag_item['rs_ops_token'], - "WEBHOOK_TOKEN" => schlupp_xmpp_data_bag_item['webhook_token'], - "AIRTABLE_API_KEY" => schlupp_xmpp_data_bag_item['airtable_api_key'], - "GITHUB_TOKEN" => schlupp_xmpp_data_bag_item['github_token'] } + user: "hubot", + group: "hubot", + app_dir: schlupp_xmpp_path, + entry: "#{schlupp_xmpp_path}/bin/hubot -a xmpp --name schlupp", + environment: { "HUBOT_XMPP_USERNAME" => "schlupp@5apps.com/hubot", + "HUBOT_XMPP_PASSWORD" => schlupp_xmpp_data_bag_item['password'], + "HUBOT_XMPP_ROOMS" => "5info@muc.5apps.com,5ops@muc.5apps.com,core@muc.5apps.com,deploy@muc.5apps.com,storage@muc.5apps.com,watercooler@muc.5apps.com,hilti@muc.5apps.com,test@muc.5apps.com,gymapp@muc.5apps.com", + "HUBOT_XMPP_HOST" => "xmpp.5apps.com", + "HUBOT_RSS_PRINTSUMMARY" => "false", + "EXPRESS_PORT" => express_port, + "HUBOT_RSS_HEADER" => "Update:", + "HUBOT_AUTH_ADMIN" => "basti,garret,greg", + "REDIS_URL" => "redis://localhost:6379/5apps_schlupp_xmpp", + "RS_OPS_TOKEN" => schlupp_xmpp_data_bag_item['rs_ops_token'], + "WEBHOOK_TOKEN" => schlupp_xmpp_data_bag_item['webhook_token'], + "AIRTABLE_API_KEY" => schlupp_xmpp_data_bag_item['airtable_api_key'], + "GITHUB_TOKEN" => schlupp_xmpp_data_bag_item['github_token'] } ) notifies :run, "execute[systemctl daemon-reload]", :delayed diff --git a/site-cookbooks/5apps-xmpp_server/recipes/letsencrypt.rb b/site-cookbooks/5apps-xmpp_server/recipes/letsencrypt.rb index 25eb7ca..4ff8fff 100644 --- a/site-cookbooks/5apps-xmpp_server/recipes/letsencrypt.rb +++ b/site-cookbooks/5apps-xmpp_server/recipes/letsencrypt.rb @@ -29,7 +29,7 @@ execute "letsencrypt cert for xmpp.5apps.com" do cwd "/usr/local/certbot" only_if do File.exist?("#{node['nginx']['dir']}/sites-enabled/xmpp.5apps.com") && - ! File.exist?("/etc/letsencrypt/live/xmpp.5apps.com/fullchain.pem") + !File.exist?("/etc/letsencrypt/live/xmpp.5apps.com/fullchain.pem") end notifies :create, "template[#{node['nginx']['dir']}/sites-available/xmpp.5apps.com]", :delayed notifies :run, "execute[copy the tls cert to prosody folder]", :delayed diff --git a/site-cookbooks/backup/recipes/default.rb b/site-cookbooks/backup/recipes/default.rb index 6272a7c..fa51649 100644 --- a/site-cookbooks/backup/recipes/default.rb +++ b/site-cookbooks/backup/recipes/default.rb @@ -28,12 +28,12 @@ gem_package 'backup' do end backup_data = Chef::EncryptedDataBagItem.load('credentials', 'backup') +backup_dir = node["backup"]["dir"] +directory backup_dir +directory "#{backup_dir}/models" +directory "#{backup_dir}/log" -directory node["backup"]["dir"] -directory "#{node["backup"]["dir"]}/models" -directory "#{node["backup"]["dir"]}/log" - -template "#{node["backup"]["dir"]}/config.rb" do +template "#{backup_dir}/config.rb" do source "config.rb.erb" mode 0640 sensitive true @@ -46,7 +46,7 @@ template "#{node["backup"]["dir"]}/config.rb" do end if node["backup"]["default_model"] - template "#{node["backup"]["dir"]}/models/default.rb" do + template "#{backup_dir}/models/default.rb" do source "backup.rb.erb" mode 0640 end @@ -54,7 +54,7 @@ if node["backup"]["default_model"] cron "default backup model" do hour node['backup']['cron']['hour'] minute node['backup']['cron']['minute'] - command "/usr/bin/env HOME=/home/user PATH=/usr/local/bin:/usr/local/ruby/bin:/usr/bin:/bin:$PATH /bin/sh -l -c 'backup perform -t default --root-path #{node["backup"]["dir"]} >> /var/log/backup.log 2>&1'" + command "/usr/bin/env HOME=/home/user PATH=/usr/local/bin:/usr/local/ruby/bin:/usr/bin:/bin:$PATH /bin/sh -l -c 'backup perform -t default --root-path #{backup_dir} >> /var/log/backup.log 2>&1'" end include_recipe 'logrotate' diff --git a/site-cookbooks/ipfs/attributes/default.rb b/site-cookbooks/ipfs/attributes/default.rb index 6ccba68..4f8f402 100644 --- a/site-cookbooks/ipfs/attributes/default.rb +++ b/site-cookbooks/ipfs/attributes/default.rb @@ -17,5 +17,5 @@ node.default['ipfs']['config']['swarm']['addr_filter'] = [ "/ip4/198.18.0.0/ipcidr/15", "/ip4/198.51.100.0/ipcidr/24", "/ip4/203.0.113.0/ipcidr/24", - "/ip4/240.0.0.0/ipcidr/4" + "/ip4/240.0.0.0/ipcidr/4", ] diff --git a/site-cookbooks/ipfs/metadata.rb b/site-cookbooks/ipfs/metadata.rb index c0410c6..92e7b3e 100644 --- a/site-cookbooks/ipfs/metadata.rb +++ b/site-cookbooks/ipfs/metadata.rb @@ -6,6 +6,6 @@ description 'Installs/Configures ipfs' long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) version '0.1.0' -supports ['ubuntu', 'debian'] +supports %w(ubuntu debian) depends 'ark' diff --git a/site-cookbooks/ipfs/recipes/default.rb b/site-cookbooks/ipfs/recipes/default.rb index 70fb43b..ed48382 100644 --- a/site-cookbooks/ipfs/recipes/default.rb +++ b/site-cookbooks/ipfs/recipes/default.rb @@ -34,7 +34,7 @@ execute "ipfs init --empty-repo" do end if platform?('ubuntu') && node[:platform_version].to_f < 15.04 || - platform?('debian') && node['platform_version'].to_f < 8 + platform?('debian') && node['platform_version'].to_f < 8 template "ipfs.initd.service.erb" do path "/etc/init.d/ipfs" source 'ipfs.initd.service.erb' diff --git a/site-cookbooks/ipfs/resources/config.rb b/site-cookbooks/ipfs/resources/config.rb index 67df68a..cb936ae 100644 --- a/site-cookbooks/ipfs/resources/config.rb +++ b/site-cookbooks/ipfs/resources/config.rb @@ -15,8 +15,9 @@ action :create do not_if do require 'json' require 'mixlib/shellout' - cmd = Mixlib::ShellOut.new("ipfs", "config", key, user: 'ipfs', - env: {"IPFS_PATH" => "/home/ipfs/.ipfs"}) + cmd = Mixlib::ShellOut.new("ipfs", "config", key, + user: 'ipfs', + env: { "IPFS_PATH" => "/home/ipfs/.ipfs" }) cmd.run_command begin JSON.parse(cmd.stdout) == value diff --git a/site-cookbooks/ipfs/test/integration/default/serverspec/ipfs_spec.rb b/site-cookbooks/ipfs/test/integration/default/serverspec/ipfs_spec.rb index 3bc17ee..ab11365 100644 --- a/site-cookbooks/ipfs/test/integration/default/serverspec/ipfs_spec.rb +++ b/site-cookbooks/ipfs/test/integration/default/serverspec/ipfs_spec.rb @@ -4,7 +4,6 @@ require 'serverspec' set :backend, :exec describe "IPFS" do - # It is in the PATH describe command("which ipfs") do its(:exit_status) { should eq 0 } @@ -22,5 +21,4 @@ describe "IPFS" do expect(service("ipfs")).to be_running expect(service("ipfs")).to be_enabled end - end diff --git a/site-cookbooks/kosmos-hubot/recipes/default.rb b/site-cookbooks/kosmos-hubot/recipes/default.rb index 5a6b7e9..594625b 100644 --- a/site-cookbooks/kosmos-hubot/recipes/default.rb +++ b/site-cookbooks/kosmos-hubot/recipes/default.rb @@ -59,7 +59,7 @@ application hal8000_path do "hubot-seen", "hubot-rss-reader", "hubot-incoming-webhook", - "hubot-auth" + "hubot-auth", ].to_json end @@ -78,32 +78,32 @@ application hal8000_path do group 'root' mode '0644' variables( - :user => "hubot", - :group => "hubot", - :app_dir => hal8000_path, - :entry => "#{hal8000_path}/bin/hubot -a irc", - :environment => { "HUBOT_IRC_SERVER" => "irc.freenode.net", - "HUBOT_IRC_ROOMS" => "#5apps,#kosmos,#kosmos-dev,#remotestorage,#hackerbeach,#unhosted,#sockethub", - "HUBOT_IRC_NICK" => "hal8000", - "HUBOT_IRC_NICKSERV_USERNAME" => "hal8000", - "HUBOT_IRC_NICKSERV_PASSWORD" => hal8000_freenode_data_bag_item['nickserv_password'], - "HUBOT_IRC_UNFLOOD" => "100", - "HUBOT_RSS_PRINTSUMMARY" => "false", - "HUBOT_RSS_IRCCOLORS" => "true", - # "HUBOT_LOG_LEVEL" => "error", - "EXPRESS_PORT" => "8080", - "HUBOT_RSS_HEADER" => "Update:", - "HUBOT_AUTH_ADMIN" => "bkero,derbumi,galfert,gregkare,jaaan,slvrbckt,raucao", - "OA_ASSET_FROM_ADDRESS" => "akRWZJMETdM2U5UGKadKhv1PAj2npoGja1m", - "OA_DEFAULT_QUANTITY" => "100", - "OA_ASSET_ID" => "AbDn6L2AUGnDreUuNkGFEqcxnsoUP4HCjm", - "OA_SERVER_URL" => "http://localhost:4562", - "OA_SERVER_USERNAME" => "kosmos", - "OA_SERVER_PASSWORD" => "asEjdak1yqw", - "OA_MAX_QUANTITY" => "5000", - "OA_BOT_KEYWORD" => "kredits", - "OA_PLUSPLUS_ROOMS" => "#kosmos", - "WEBHOOK_TOKEN" => hal8000_freenode_data_bag_item['webhook_token'] } + user: "hubot", + group: "hubot", + app_dir: hal8000_path, + entry: "#{hal8000_path}/bin/hubot -a irc", + environment: { "HUBOT_IRC_SERVER" => "irc.freenode.net", + "HUBOT_IRC_ROOMS" => "#5apps,#kosmos,#kosmos-dev,#remotestorage,#hackerbeach,#unhosted,#sockethub", + "HUBOT_IRC_NICK" => "hal8000", + "HUBOT_IRC_NICKSERV_USERNAME" => "hal8000", + "HUBOT_IRC_NICKSERV_PASSWORD" => hal8000_freenode_data_bag_item['nickserv_password'], + "HUBOT_IRC_UNFLOOD" => "100", + "HUBOT_RSS_PRINTSUMMARY" => "false", + "HUBOT_RSS_IRCCOLORS" => "true", + # "HUBOT_LOG_LEVEL" => "error", + "EXPRESS_PORT" => "8080", + "HUBOT_RSS_HEADER" => "Update:", + "HUBOT_AUTH_ADMIN" => "bkero,derbumi,galfert,gregkare,jaaan,slvrbckt,raucao", + "OA_ASSET_FROM_ADDRESS" => "akRWZJMETdM2U5UGKadKhv1PAj2npoGja1m", + "OA_DEFAULT_QUANTITY" => "100", + "OA_ASSET_ID" => "AbDn6L2AUGnDreUuNkGFEqcxnsoUP4HCjm", + "OA_SERVER_URL" => "http://localhost:4562", + "OA_SERVER_USERNAME" => "kosmos", + "OA_SERVER_PASSWORD" => "asEjdak1yqw", + "OA_MAX_QUANTITY" => "5000", + "OA_BOT_KEYWORD" => "kredits", + "OA_PLUSPLUS_ROOMS" => "#kosmos", + "WEBHOOK_TOKEN" => hal8000_freenode_data_bag_item['webhook_token'] } ) notifies :run, "execute[systemctl daemon-reload]", :delayed notifies :restart, "service[hal8000_nodejs]", :delayed @@ -134,7 +134,7 @@ application botka_freenode_path do group "hubot" content [ "hubot-help", - "hubot-remotestorage-logger" + "hubot-remotestorage-logger", ].to_json end @@ -153,25 +153,25 @@ application botka_freenode_path do group 'root' mode '0644' variables( - :user => "hubot", - :group => "hubot", - :app_dir => botka_freenode_path, - :entry => "#{botka_freenode_path}/bin/hubot -a irc", - :environment => { "HUBOT_IRC_SERVER" => "irc.freenode.net", - "HUBOT_IRC_ROOMS" => "#5apps,#kosmos,#kosmos-dev,#remotestorage,#hackerbeach,#unhosted,#sockethub,#opensourcedesign,#openknot,#emberjs,#mastodon,#indieweb", - "HUBOT_IRC_NICK" => "botka", - "HUBOT_IRC_NICKSERV_USERNAME" => "botka", - "HUBOT_IRC_NICKSERV_PASSWORD" => botka_freenode_data_bag_item['nickserv_password'], - "HUBOT_IRC_UNFLOOD" => "100", - "HUBOT_RSS_PRINTSUMMARY" => "false", - "HUBOT_RSS_IRCCOLORS" => "true", - # "HUBOT_LOG_LEVEL" => "error", - "EXPRESS_PORT" => "8082", - "HUBOT_AUTH_ADMIN" => "bkero,derbumi,galfert,gregkare,jaaan,slvrbckt,raucao", - "RS_LOGGER_USER" => "kosmos@5apps.com", - "RS_LOGGER_TOKEN" => botka_freenode_data_bag_item['rs_logger_token'], - "RS_LOGGER_SERVER_NAME" => "freenode", - "RS_LOGGER_PUBLIC" => "true" } + user: "hubot", + group: "hubot", + app_dir: botka_freenode_path, + entry: "#{botka_freenode_path}/bin/hubot -a irc", + environment: { "HUBOT_IRC_SERVER" => "irc.freenode.net", + "HUBOT_IRC_ROOMS" => "#5apps,#kosmos,#kosmos-dev,#remotestorage,#hackerbeach,#unhosted,#sockethub,#opensourcedesign,#openknot,#emberjs,#mastodon,#indieweb", + "HUBOT_IRC_NICK" => "botka", + "HUBOT_IRC_NICKSERV_USERNAME" => "botka", + "HUBOT_IRC_NICKSERV_PASSWORD" => botka_freenode_data_bag_item['nickserv_password'], + "HUBOT_IRC_UNFLOOD" => "100", + "HUBOT_RSS_PRINTSUMMARY" => "false", + "HUBOT_RSS_IRCCOLORS" => "true", + # "HUBOT_LOG_LEVEL" => "error", + "EXPRESS_PORT" => "8082", + "HUBOT_AUTH_ADMIN" => "bkero,derbumi,galfert,gregkare,jaaan,slvrbckt,raucao", + "RS_LOGGER_USER" => "kosmos@5apps.com", + "RS_LOGGER_TOKEN" => botka_freenode_data_bag_item['rs_logger_token'], + "RS_LOGGER_SERVER_NAME" => "freenode", + "RS_LOGGER_PUBLIC" => "true" } ) notifies :run, "execute[systemctl daemon-reload]", :delayed notifies :restart, "service[botka_freenode_nodejs]", :delayed diff --git a/site-cookbooks/kosmos-ipfs/recipes/letsencrypt.rb b/site-cookbooks/kosmos-ipfs/recipes/letsencrypt.rb index d33cb9e..4df8101 100644 --- a/site-cookbooks/kosmos-ipfs/recipes/letsencrypt.rb +++ b/site-cookbooks/kosmos-ipfs/recipes/letsencrypt.rb @@ -54,7 +54,7 @@ unless node.chef_environment == "development" cwd "/usr/local/certbot" only_if do File.exist?("#{node['nginx']['dir']}/sites-enabled/ipfs.kosmos.org") && - ! File.exist?("/etc/letsencrypt/live/ipfs.kosmos.org/fullchain.pem") + !File.exist?("/etc/letsencrypt/live/ipfs.kosmos.org/fullchain.pem") end notifies :create, "template[#{node['nginx']['dir']}/sites-available/ipfs.kosmos.org]", :delayed end diff --git a/site-cookbooks/kosmos-mastodon/recipes/default.rb b/site-cookbooks/kosmos-mastodon/recipes/default.rb index d10b36f..bb62af4 100644 --- a/site-cookbooks/kosmos-mastodon/recipes/default.rb +++ b/site-cookbooks/kosmos-mastodon/recipes/default.rb @@ -19,10 +19,10 @@ end postgresql_database 'mastodon' do connection( - :host => '127.0.0.1', - :port => 5432, - :username => 'postgres', - :password => node['postgresql']['password']['postgres'] + host: '127.0.0.1', + port: 5432, + username: 'postgres', + password: node['postgresql']['password']['postgres'] ) action :create end @@ -70,7 +70,7 @@ application mastodon_path do otp_secret: mastodon_credentials['otp_secret'], smtp_login: mastodon_credentials['smtp_user_name'], smtp_password: mastodon_credentials['smtp_password'], - smtp_from_address: "mail@#{node["kosmos-mastodon"]["server_name"]}", + smtp_from_address: "mail@#{node['kosmos-mastodon']['server_name']}", s3_bucket: "kosmos-social", aws_access_key_id: mastodon_credentials['aws_access_key_id'], aws_secret_access_key: mastodon_credentials['aws_secret_access_key'], @@ -91,7 +91,7 @@ application mastodon_path do bundle_install do user "mastodon" deployment true - without %w{development test} + without %w(development test) end npm_install do diff --git a/site-cookbooks/kosmos-mastodon/recipes/nginx.rb b/site-cookbooks/kosmos-mastodon/recipes/nginx.rb index c7db150..6db9868 100644 --- a/site-cookbooks/kosmos-mastodon/recipes/nginx.rb +++ b/site-cookbooks/kosmos-mastodon/recipes/nginx.rb @@ -42,7 +42,6 @@ unless node.chef_environment == "development" command "./certbot-auto certonly --webroot --agree-tos --email ops@5apps.com --webroot-path /var/www/mastodon -d #{server_name} -n" cwd "/usr/local/certbot" not_if { File.exist? "/etc/letsencrypt/live/#{server_name}/fullchain.pem" } - notifies :reload, "service[nginx]", :delayed notifies :create, "template[#{node['nginx']['dir']}/sites-available/mastodon]", :immediately end end diff --git a/site-cookbooks/kosmos-mediawiki/recipes/default.rb b/site-cookbooks/kosmos-mediawiki/recipes/default.rb index ffb8c4e..89630f2 100644 --- a/site-cookbooks/kosmos-mediawiki/recipes/default.rb +++ b/site-cookbooks/kosmos-mediawiki/recipes/default.rb @@ -14,7 +14,7 @@ include_recipe 'ark' # # sudo su - /var/www/mediawiki-1.xx.y/maintenance/update.php node.override['mediawiki']['version'] = "1.28.0" -node.override['mediawiki']['webdir'] = "#{node["mediawiki"]["docroot_dir"]}/mediawiki-#{node['mediawiki']['version']}" +node.override['mediawiki']['webdir'] = "#{node['mediawiki']['docroot_dir']}/mediawiki-#{node['mediawiki']['version']}" node.override['mediawiki']['tarball']['name'] = "mediawiki-#{node['mediawiki']['version']}.tar.gz" node.override['mediawiki']['tarball']['url'] = "https://releases.wikimedia.org/mediawiki/1.28/#{node['mediawiki']['tarball']['name']}" node.override['mediawiki']['language_code'] = 'en' @@ -53,7 +53,7 @@ include_recipe "mediawiki::nginx" include_recipe "kosmos-base::letsencrypt" execute "letsencrypt cert for wiki.kosmos.org" do - command "./certbot-auto certonly --webroot --agree-tos --email ops@5apps.com --webroot-path #{node["mediawiki"]["docroot_dir"]} -d wiki.kosmos.org -n" + command "./certbot-auto certonly --webroot --agree-tos --email ops@5apps.com --webroot-path #{node['mediawiki']['docroot_dir']} -d wiki.kosmos.org -n" cwd "/usr/local/certbot" not_if { File.exist? "/etc/letsencrypt/live/wiki.kosmos.org/fullchain.pem" } notifies :reload, "service[nginx]", :delayed @@ -112,7 +112,7 @@ end ruby_block "configuration" do block do file = Chef::Util::FileEdit.new("#{node['mediawiki']['webdir']}/LocalSettings.php") - file.search_file_replace_line(/\$wgLogo\ =\ \"\$wgResourceBasePath\/resources\/assets\/wiki.png\";/, + file.search_file_replace_line(%r{\$wgLogo\ =\ \"\$wgResourceBasePath\/resources\/assets\/wiki.png\";}, "$wgLogo = \"$wgResourceBasePath/skins/common/images/kosmos.png\";") file.insert_line_if_no_match(/# Our config/, <<-EOF diff --git a/site-cookbooks/kosmos-wordpress/recipes/nginx.rb b/site-cookbooks/kosmos-wordpress/recipes/nginx.rb index 71fbd51..a2b1828 100644 --- a/site-cookbooks/kosmos-wordpress/recipes/nginx.rb +++ b/site-cookbooks/kosmos-wordpress/recipes/nginx.rb @@ -13,30 +13,30 @@ include_recipe "php-fpm::configure" include_recipe 'php-fpm::repository' unless node['php-fpm']['skip_repository_install'] include_recipe "kosmos-base::letsencrypt" -if node['php-fpm']['package_name'].nil? - if platform_family?("rhel") - php_fpm_package_name = "php-fpm" - else - php_fpm_package_name = "php5-fpm" - end -else - php_fpm_package_name = node['php-fpm']['package_name'] -end +php_fpm_package_name = if node['php-fpm']['package_name'].nil? + if platform_family?("rhel") + "php-fpm" + else + "php5-fpm" + end + else + node['php-fpm']['package_name'] + end package php_fpm_package_name do action :upgrade end -if node['php-fpm']['service_name'].nil? - php_fpm_service_name = php_fpm_package_name -else - php_fpm_service_name = node['php-fpm']['service_name'] -end +php_fpm_service_name = if node['php-fpm']['service_name'].nil? + php_fpm_package_name + else + node['php-fpm']['service_name'] + end service "php-fpm" do service_name php_fpm_service_name - supports :start => true, :stop => true, :restart => true, :reload => true - action [ :enable, :start ] + supports start: true, stop: true, restart: true, reload: true + action [:enable, :start] end php_fpm_pool "www" do @@ -47,7 +47,7 @@ php_fpm_pool "wordpress" do listen "127.0.0.1:9001" user node['wordpress']['install']['user'] group node['wordpress']['install']['group'] - if node['platform'] == 'ubuntu' and node['platform_version'] == '10.04' + if node['platform'] == 'ubuntu' && node['platform_version'] == '10.04' process_manager 'dynamic' end listen_owner node['wordpress']['install']['user'] diff --git a/site-cookbooks/sockethub/recipes/default.rb b/site-cookbooks/sockethub/recipes/default.rb index 4c7d4c6..16ca322 100644 --- a/site-cookbooks/sockethub/recipes/default.rb +++ b/site-cookbooks/sockethub/recipes/default.rb @@ -49,13 +49,12 @@ application path_to_deploy do group 'root' mode '0644' variables( - :user => "sockethub", - :group => "sockethub", - :app_dir => path_to_deploy, - :entry => "/usr/local/bin/node /usr/local/bin/npm start", - :environment => { 'DEBUG' => '*', - 'PORT' => node['sockethub']['port'] } - + user: "sockethub", + group: "sockethub", + app_dir: path_to_deploy, + entry: "/usr/local/bin/node /usr/local/bin/npm start", + environment: { 'DEBUG' => '*', + 'PORT' => node['sockethub']['port'] } ) notifies :run, "execute[systemctl daemon-reload]", :delayed notifies :restart, "service[sockethub_nodejs]", :delayed From d7bdd5cdf34c864dcd4549c00710d3d9d3b6af75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 28 Apr 2017 15:44:26 +0200 Subject: [PATCH 37/83] Add an nginx vhost with a Let's Encrypt certificate for schlupp --- .../5apps-hubot/recipes/xmpp_schlupp.rb | 42 ++++++++++++++++++- .../default/nginx_conf_hubot.5apps.com.erb | 41 ++++++++++++++++++ 2 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 site-cookbooks/5apps-hubot/templates/default/nginx_conf_hubot.5apps.com.erb diff --git a/site-cookbooks/5apps-hubot/recipes/xmpp_schlupp.rb b/site-cookbooks/5apps-hubot/recipes/xmpp_schlupp.rb index 6fe34b5..32a2749 100644 --- a/site-cookbooks/5apps-hubot/recipes/xmpp_schlupp.rb +++ b/site-cookbooks/5apps-hubot/recipes/xmpp_schlupp.rb @@ -7,10 +7,12 @@ # All rights reserved - Do Not Redistribute # +express_port = 8083 + unless node.chef_environment == "development" include_recipe "firewall" firewall_rule 'hubot_express_schlupp_xmpp' do - port 8083 + port express_port protocol :tcp command :allow end @@ -105,3 +107,41 @@ application schlupp_xmpp_path do action [:enable, :start] end end + +# nginx reverse proxy +unless node.chef_environment == "development" + include_recipe "kosmos-base::letsencrypt" +end + +include_recipe 'kosmos-nginx' + +directory "/var/www/hubot.5apps.com/.well-known/acme-challenge" do + owner node["nginx"]["user"] + group node["nginx"]["group"] + recursive true + action :create +end + +template "#{node['nginx']['dir']}/sites-available/hubot.5apps.com" do + source 'nginx_conf_hubot.5apps.com.erb' + owner node["nginx"]["user"] + mode 0640 + variables express_port: express_port, + server_name: 'hubot.5apps.com', + ssl_cert: "/etc/letsencrypt/live/hubot.5apps.com/fullchain.pem", + ssl_key: "/etc/letsencrypt/live/hubot.5apps.com/privkey.pem" + notifies :reload, 'service[nginx]', :delayed +end + +nginx_site 'hubot.5apps.com' do + enable true +end + +unless node.chef_environment == "development" + execute "letsencrypt cert for hubot.5apps.com" do + command "./certbot-auto certonly --webroot --agree-tos --email ops@5apps.com --webroot-path /var/www/hubot.5apps.com -d hubot.5apps.com -n" + cwd "/usr/local/certbot" + not_if { File.exist? "/etc/letsencrypt/live/hubot.5apps.com/fullchain.pem" } + notifies :create, "template[#{node['nginx']['dir']}/sites-available/hubot.5apps.com]", :immediately + end +end diff --git a/site-cookbooks/5apps-hubot/templates/default/nginx_conf_hubot.5apps.com.erb b/site-cookbooks/5apps-hubot/templates/default/nginx_conf_hubot.5apps.com.erb new file mode 100644 index 0000000..dcb44cb --- /dev/null +++ b/site-cookbooks/5apps-hubot/templates/default/nginx_conf_hubot.5apps.com.erb @@ -0,0 +1,41 @@ +# Generated by Chef +upstream _express_schlupp { + server localhost:<%= @express_port %>; +} + +server { + listen 80; # For Let's Encrypt + server_name <%= @server_name %>; + + location /.well-known { + root "/var/www/hubot.5apps.com"; + } + location / { + return 301 https://$host$request_uri; + } +} + +server { + <% if File.exist?(@ssl_cert) && File.exist?(@ssl_key) -%> + listen 443 ssl http2; + add_header Strict-Transport-Security "max-age=15768000"; + <% end -%> + + server_name <%= @server_name %>; + + access_log <%= node[:nginx][:log_dir] %>/hubot.5apps.com.access.log json; + error_log <%= node[:nginx][:log_dir] %>/hubot.5apps.com.error.log warn; + + location / { + # Increase number of buffers. Default is 8 + proxy_buffers 1024 8k; + + proxy_pass http://_express_schlupp; + proxy_http_version 1.1; + } + + <% if File.exist?(@ssl_cert) && File.exist?(@ssl_key) -%> + ssl_certificate <%= @ssl_cert %>; + ssl_certificate_key <%= @ssl_key %>; + <% end -%> +} From 11b812fbb8bcf41a0c2192c30dfd4e0527d72111 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Tue, 2 May 2017 11:39:43 +0200 Subject: [PATCH 38/83] Update sudo and users cookbooks --- Batali | 4 +- batali.manifest | 12 +- cookbooks/sudo/CHANGELOG.md | 9 + cookbooks/sudo/README.md | 56 +----- cookbooks/sudo/files/{default => }/README | 0 cookbooks/sudo/metadata.json | 2 +- cookbooks/sudo/providers/default.rb | 4 +- cookbooks/sudo/recipes/default.rb | 1 - cookbooks/sudo/templates/default/sudoer.erb | 2 +- cookbooks/users/.foodcritic | 1 - cookbooks/users/CHANGELOG.md | 49 ++++- cookbooks/users/README.md | 17 +- cookbooks/users/libraries/helpers.rb | 16 +- cookbooks/users/libraries/osx_helper.rb | 29 +++ cookbooks/users/metadata.json | 2 +- cookbooks/users/providers/manage.rb | 172 ------------------ cookbooks/users/recipes/default.rb | 2 +- cookbooks/users/recipes/sysadmins.rb | 13 +- cookbooks/users/resources/manage.rb | 169 +++++++++++++++-- .../{default => }/authorized_keys.erb | 0 .../templates/{default => }/private_key.erb | 0 .../{default => }/public_key.pub.erb | 0 22 files changed, 282 insertions(+), 278 deletions(-) rename cookbooks/sudo/files/{default => }/README (100%) delete mode 100644 cookbooks/users/.foodcritic create mode 100644 cookbooks/users/libraries/osx_helper.rb delete mode 100644 cookbooks/users/providers/manage.rb rename cookbooks/users/templates/{default => }/authorized_keys.erb (100%) rename cookbooks/users/templates/{default => }/private_key.erb (100%) rename cookbooks/users/templates/{default => }/public_key.pub.erb (100%) diff --git a/Batali b/Batali index 2e8ac02..2268d4f 100644 --- a/Batali +++ b/Batali @@ -19,8 +19,8 @@ Batali.define do cookbook 'application_javascript' cookbook 'application_ruby' cookbook 'application_git', '~> 1.1.0' # 1.2.0 doesn't work with knife-solo - cookbook 'users' - cookbook 'sudo' + cookbook 'users', '~> 5.0.0' + cookbook 'sudo', '~> 3.4.0' cookbook 'hostname' cookbook 'redis', git: 'https://github.com/phlipper/chef-redis.git', diff --git a/batali.manifest b/batali.manifest index b6dcb72..44e7752 100644 --- a/batali.manifest +++ b/batali.manifest @@ -900,11 +900,11 @@ "dependencies": [ ], - "version": "4.0.3", + "version": "5.0.0", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/users/versions/4.0.3/download", - "version": "4.0.3" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/users/versions/5.0.0/download", + "version": "5.0.0" } }, { @@ -912,11 +912,11 @@ "dependencies": [ ], - "version": "3.3.1", + "version": "3.4.0", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/sudo/versions/3.3.1/download", - "version": "3.3.1" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/sudo/versions/3.4.0/download", + "version": "3.4.0" } }, { diff --git a/cookbooks/sudo/CHANGELOG.md b/cookbooks/sudo/CHANGELOG.md index 7283d9f..7ae8ead 100644 --- a/cookbooks/sudo/CHANGELOG.md +++ b/cookbooks/sudo/CHANGELOG.md @@ -2,6 +2,15 @@ This file is used to list changes made in each version of the sudo cookbook. +## 3.4.0 (2017-04-26) + +- Add lwrp support for only env_keep add/subtract +- Readme improvements +- Move the files out of the default directory since Chef >= 12 doesn't require this +- Test with Local Delivery instead of Rake +- Cookstyle fixes +- Update apache2 license string + ## 3.3.1 (2017-01-17) - fixed command_aliases in README diff --git a/cookbooks/sudo/README.md b/cookbooks/sudo/README.md index a78f833..e93af1e 100644 --- a/cookbooks/sudo/README.md +++ b/cookbooks/sudo/README.md @@ -2,9 +2,7 @@ [![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. - -It also exposes an LWRP for adding and managing sudoers. +The default recipe installs the `sudo` package and configures the `/etc/sudoers` file. The cookbook also includes a sudo resource to adding and removing individual sudo entries. ## Requirements @@ -25,6 +23,7 @@ It also exposes an LWRP for adding and managing sudoers. - None ## Attributes + - `node['authorization']['sudo']['groups']` - groups to enable sudo access (default: `[ "sysadmin" ]`) - `node['authorization']['sudo']['users']` - users to enable sudo access (default: `[]`) - `node['authorization']['sudo']['passwordless']` - use passwordless sudo (default: `false`) @@ -34,7 +33,9 @@ It also exposes an LWRP for adding and managing sudoers. - `node['authorization']['sudo']['setenv']` - Whether to permit preserving of environment with `sudo -E` (default: `false`) ## Usage + ### Attributes + To use attributes for defining sudoers, set the attributes above on the node (or role) itself: ```json @@ -105,6 +106,7 @@ default_attributes( **Note that the template for the sudoers file has the group "sysadmin" with ALL:ALL permission, though the group by default does not exist.** ### Sudoers Defaults + Configure 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: _Debian_ @@ -113,12 +115,6 @@ _Debian_ node.default['authorization']['sudo']['sudoers_defaults'] = ['env_reset'] ``` -_Ubuntu 10.04_ - -```ruby -node.default['authorization']['sudo']['sudoers_defaults'] = ['env_reset'] -``` - _Ubuntu 12.04_ ```ruby @@ -188,7 +184,8 @@ node.default['authorization']['sudo']['sudoers_defaults'] = [ ] ``` -### LWRP +### Sudo Resource + **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`. There are two ways for rendering a sudoer-fragment using this LWRP: @@ -225,7 +222,8 @@ In either case, the following file would be generated in `/etc/sudoers.d/tomcat` %tomcat ALL=(app_user) /etc/init.d/tomcat restart ``` -#### LWRP Attributes +#### Resource Properties + @@ -321,42 +319,8 @@ case it is not already **If you use the template attribute, all other attributes will be ignored except for the variables attribute.** -## Development -This section details "quick development" steps. For a detailed explanation, see [[Contributing.md]]. -- Clone this repository from GitHub: - - ``` - $ git clone git@github.com:chef-cookbooks/sudo.git - ``` - -- Create a git branch - - ``` - $ git checkout -b my_bug_fix - ``` - -- Install dependencies: - - ``` - $ bundle install - ``` - -- Make your changes/patches/fixes, committing appropiately -- **Write tests** -- Run the tests: - - `bundle exec foodcritic -f any .` - - `bundle exec rspec` - - `bundle exec rubocop` - - `bundle exec kitchen test` - - In detail: - - - Foodcritic will catch any Chef-specific style errors - - RSpec will run the unit tests - - Rubocop will check for Ruby-specific style errors - - Test Kitchen will run and converge the recipes - ## License & Authors + **Author:** Bryan W. Berry [bryan.berry@gmail.com](mailto:bryan.berry@gmail.com) **Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io)) diff --git a/cookbooks/sudo/files/default/README b/cookbooks/sudo/files/README similarity index 100% rename from cookbooks/sudo/files/default/README rename to cookbooks/sudo/files/README diff --git a/cookbooks/sudo/metadata.json b/cookbooks/sudo/metadata.json index f1afd08..f96d2e8 100644 --- a/cookbooks/sudo/metadata.json +++ b/cookbooks/sudo/metadata.json @@ -1 +1 @@ -{"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 +{"name":"sudo","version":"3.4.0","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 default recipe installs the `sudo` package and configures the `/etc/sudoers` file. The cookbook also includes a sudo resource to adding and removing individual sudo entries.\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\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\n### Attributes\n\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\n\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 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### Sudo Resource\n\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#### Resource Properties\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 \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## License & Authors\n\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"},"source_url":"https://github.com/chef-cookbooks/sudo","issues_url":"https://github.com/chef-cookbooks/sudo/issues","chef_version":[[">= 12.1"]],"ohai_version":[]} \ No newline at end of file diff --git a/cookbooks/sudo/providers/default.rb b/cookbooks/sudo/providers/default.rb index e8f524a..4b6a16f 100644 --- a/cookbooks/sudo/providers/default.rb +++ b/cookbooks/sudo/providers/default.rb @@ -47,7 +47,7 @@ def validate_fragment!(resource) file.rewind cmd = Mixlib::ShellOut.new("visudo -cf #{file.path}").run_command - unless cmd.exitstatus.zero? + unless cmd.exitstatus == 0 Chef::Log.error("Fragment validation failed: \n\n") Chef::Log.error(file.read) Chef::Application.fatal!("Template #{file.path} failed fragment validation!") @@ -77,7 +77,7 @@ def render_sudoer action :nothing end else - sudoer = new_resource.user || "%#{new_resource.group}".squeeze('%') + sudoer = new_resource.user || ("%#{new_resource.group}".squeeze('%') if new_resource.group) resource = template "#{node['authorization']['sudo']['prefix']}/sudoers.d/#{sudo_filename}" do source 'sudoer.erb' diff --git a/cookbooks/sudo/recipes/default.rb b/cookbooks/sudo/recipes/default.rb index 249afd1..ed109bc 100644 --- a/cookbooks/sudo/recipes/default.rb +++ b/cookbooks/sudo/recipes/default.rb @@ -31,7 +31,6 @@ if node['authorization']['sudo']['include_sudoers_d'] end cookbook_file "#{prefix}/sudoers.d/README" do - source 'README' mode '0440' owner 'root' group node['root_group'] diff --git a/cookbooks/sudo/templates/default/sudoer.erb b/cookbooks/sudo/templates/default/sudoer.erb index 02c9898..6d2cdfb 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 %>) <%= 'NOEXEC:' if @noexec %><%= 'NOPASSWD:' if @nopasswd %><%= 'SETENV:' if @setenv %><%= command %> +<% if @sudoer %><%= @sudoer %> <%= @host %>=(<%= @runas %>) <%= 'NOEXEC:' if @noexec %><%= 'NOPASSWD:' if @nopasswd %><%= 'SETENV:' if @setenv %><%= command %><% end -%> <% end -%> <% unless @defaults.empty? %> diff --git a/cookbooks/users/.foodcritic b/cookbooks/users/.foodcritic deleted file mode 100644 index 698ef4c..0000000 --- a/cookbooks/users/.foodcritic +++ /dev/null @@ -1 +0,0 @@ -~FC003 diff --git a/cookbooks/users/CHANGELOG.md b/cookbooks/users/CHANGELOG.md index ecde6bd..8e6eae3 100644 --- a/cookbooks/users/CHANGELOG.md +++ b/cookbooks/users/CHANGELOG.md @@ -1,16 +1,37 @@ # users Cookbook CHANGELOG + This file is used to list changes made in each version of the users cookbook. +## 5.0.0 (2017-04-17) + +### Breaking changes + +- The users_manage LWRP has been converted to a custom resource, which requires Chef 12.5 or later +- The sysadmins recipe contains no resources now and will do nothing + +### Other changes + +- Added integration tests with Inspec +- Fixed all deprecation warnings +- Fixed group creation on macOS when the group already exists +- Added suse platforms as supported in the metadata +- Switched to a SPDX apache-2.0 license string +- Moved all templates out of the default directory as we don't support Chef 11 anymore + ## 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 @@ -19,27 +40,32 @@ This file is used to list changes made in each version of the users cookbook. - 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. +- @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 -- fix rubocop errors based on https://github.com/bbatsov/rubocop/issues/2608 +- fix rubocop errors based on - fix kitchen configurations for testing ## v2.0.1 (2016-1-8) + - Fixed provider to work on Mac OS X -- funzoneq - add correct default shell for FreeBSD if not provided -- Added kitchen.dokken to speed up platform testing +- funzoneq - add correct default shell for FreeBSD if not provided +- Added kitchen.dokken to speed up platform testing ## v2.0.0 (2015-12-11) + - Removed Chef 10 compatibility code - Removed the nodes fqdn from the authorized_keys file - Removed a trailing comma in a readme example @@ -48,12 +74,15 @@ This file is used to list changes made in each version of the users cookbook. - Resolved foodcritic warnings ## v1.8.2 (2015-03-18) + - No changes, just republishing 1.8.1 ## v1.8.1 (2015-03-12) + - Add `source_url` and `issues_url` to the metadata.rb so Supermarket can display appropriate links ## v1.8.0 (2015-03-09) + - Expose LWRP state attributes - [COOK-4401] - Add unit tests with ChefSpec - [COOK-4404] - Determine file system and add manage_nfs_home_dirs attribute to disable managing NFS mounted home directories @@ -65,40 +94,52 @@ This file is used to list changes made in each version of the users cookbook. - Updates for RSpec 3 ## v1.7.0 (2014-02-14) + - [COOK-4139] - users_manage resource always notifies - [COOK-4078] - users cookbook fails in why-run mode for .ssh directory - [COOK-3959] - Add support for Mac OS X to users cookbook ## v1.6.0 + ### Bug + - **[COOK-3744](https://tickets.opscode.com/browse/COOK-3744)** - Allow passing an action option via the `data_bag` to the user resource ## v1.5.2 + ### Bug + - **[COOK-3215](https://tickets.opscode.com/browse/COOK-3215)** - Make `group_id` optional ## v1.5.0 + - [COOK-2427] - Mistakenly released instead of sudo :-). ## v1.4.0 + - [COOK-2479] - Permit users cookbook to work with chef-solo if edelight/chef-solo-search is installed - [COOK-2486] - specify precedence when setting node attribute ## v1.3.0 + - [COOK-1842] - allow specifying private SSH keys - [COOK-2021] - Empty default recipe for including users LWRPs ## v1.2.0 + - [COOK-1398] - Provider manage.rb ignores username attribute - [COOK-1582] - ssh_keys should take an array in addition to a string separated by new lines ## v1.1.4 + - [COOK-1396] - removed users get recreated - [COOK-1433] - resolve foodcritic warnings - [COOK-1583] - set passwords for users ## v1.1.2 + - [COOK-1076] - authorized_keys template not found in another cookbook ## v1.1.0 + - [COOK-623] - LWRP conversion diff --git a/cookbooks/users/README.md b/cookbooks/users/README.md index 73979f1..e85cc66 100644 --- a/cookbooks/users/README.md +++ b/cookbooks/users/README.md @@ -12,21 +12,22 @@ This cookbook is concerned with the management of OS users and groups from datab A data bag populated with user objects must exist. The default data bag in this recipe is `users`. See USAGE. -### Chef - -- Chef 12.1+ - -### Platform Support +### Platforms The following platforms have been tested with Test Kitchen: -- Debian / Ubuntu and derivatives +- Debian / Ubuntu derivatives - RHEL and derivatives - Fedora +- openSUSE / SUSE Linux Enterprises - FreeBSD / OpenBSD - Mac OS X -### Cookbook Dependencies +### Chef + +- Chef 12.5+ + +### Cookbooks - none @@ -303,7 +304,7 @@ The Apache cookbook can set up authentication using OpenIDs, which is set up usi **Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io)) -**Copyright:** 2009-2016, Chef Software, Inc. +**Copyright:** 2009-2017, Chef Software, Inc. ``` Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/cookbooks/users/libraries/helpers.rb b/cookbooks/users/libraries/helpers.rb index e0a358b..bf7b37e 100644 --- a/cookbooks/users/libraries/helpers.rb +++ b/cookbooks/users/libraries/helpers.rb @@ -1,5 +1,3 @@ -require 'mixlib/shellout' - module Users # Helpers for Users module Helpers @@ -28,8 +26,16 @@ module Users def validate_id(id) id.to_i.to_s == id ? id.to_i : id end + + # Returns the appropriate base user home directory per platform + # + # @return [ String] + def home_basedir + if platform_family?('mac_os_x') + '/Users' + else + '/home' + end + end end end - -Chef::Resource.send(:include, ::Users::Helpers) -Chef::Provider.send(:include, ::Users::Helpers) diff --git a/cookbooks/users/libraries/osx_helper.rb b/cookbooks/users/libraries/osx_helper.rb new file mode 100644 index 0000000..d195e76 --- /dev/null +++ b/cookbooks/users/libraries/osx_helper.rb @@ -0,0 +1,29 @@ +module Users + # Helpers for Users + module OsxHelper + def dscl(*args) + host = '.' + stdout_result = '' + stderr_result = '' + cmd = "dscl #{host} -#{args.join(' ')}" + status = shell_out(cmd) + status.stdout.each_line { |line| stdout_result << line } + status.stderr.each_line { |line| stderr_result << line } + [cmd, status, stdout_result, stderr_result] + end + + def safe_dscl(*args) + result = dscl(*args) + return '' if (args.first =~ /^delete/) && (result[1].exitstatus != 0) + raise(Chef::Exceptions::Group, "dscl error: #{result.inspect}") unless result[1].exitstatus == 0 + raise(Chef::Exceptions::Group, "dscl error: #{result.inspect}") if result[2] =~ /No such key: / + result[2] + end + + def gid_used?(gid) + return false unless gid + groups_gids = safe_dscl('list /Groups gid') + !!(groups_gids =~ Regexp.new("#{Regexp.escape(gid.to_s)}\n")) + end + end +end diff --git a/cookbooks/users/metadata.json b/cookbooks/users/metadata.json index 260994b..789307a 100644 --- a/cookbooks/users/metadata.json +++ b/cookbooks/users/metadata.json @@ -1 +1 @@ -{"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 +{"name":"users","version":"5.0.0","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### Platforms\n\nThe following platforms have been tested with Test Kitchen:\n\n- Debian / Ubuntu derivatives\n- RHEL and derivatives\n- Fedora\n- openSUSE / SUSE Linux Enterprises\n- FreeBSD / OpenBSD\n- Mac OS X\n\n### Chef\n\n- Chef 12.5+\n\n### Cookbooks\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-2017, 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","suse":">= 0.0.0","opensuse":">= 0.0.0","opensuseleap":">= 0.0.0"},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{},"source_url":"https://github.com/chef-cookbooks/users","issues_url":"https://github.com/chef-cookbooks/users/issues","chef_version":[[">= 12.5"]],"ohai_version":[]} \ No newline at end of file diff --git a/cookbooks/users/providers/manage.rb b/cookbooks/users/providers/manage.rb deleted file mode 100644 index 83a018c..0000000 --- a/cookbooks/users/providers/manage.rb +++ /dev/null @@ -1,172 +0,0 @@ -# -# Cookbook:: users -# Provider:: manage -# -# 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. -# 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 - -def whyrun_supported? - true -end - -action :remove do - 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 - -action :create do - users_groups = {} - users_groups[new_resource.group_name] = [] - - 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 - - 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 - - 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 - end - - group new_resource.group_name do - gid new_resource.group_id if new_resource.group_id - members users_groups[new_resource.group_name] - end -end - -private - -def manage_home_files?(home_dir, _user) - # Don't manage home dir if it's NFS mount - # and manage_nfs_home_dirs is disabled - if home_dir == '/dev/null' - false - elsif fs_remote?(home_dir) - new_resource.manage_nfs_home_dirs ? true : false - else - true - end -end diff --git a/cookbooks/users/recipes/default.rb b/cookbooks/users/recipes/default.rb index 59e688c..317ccf7 100644 --- a/cookbooks/users/recipes/default.rb +++ b/cookbooks/users/recipes/default.rb @@ -2,7 +2,7 @@ # Cookbook:: users # Recipe:: default # -# Copyright:: 2009-2016, Chef Software, Inc. +# Copyright:: 2009-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/users/recipes/sysadmins.rb b/cookbooks/users/recipes/sysadmins.rb index 03f248a..85ba4e7 100644 --- a/cookbooks/users/recipes/sysadmins.rb +++ b/cookbooks/users/recipes/sysadmins.rb @@ -2,8 +2,8 @@ # Cookbook:: users # Recipe:: sysadmins # -# Copyright:: 2011-2016, Eric G. Wolfe -# Copyright:: 2009-2016, Chef Software, Inc. +# Copyright:: 2011-2017, Eric G. Wolfe +# Copyright:: 2009-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,11 +18,4 @@ # 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 - group_id 2300 - action [:remove, :create] -end +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.') diff --git a/cookbooks/users/resources/manage.rb b/cookbooks/users/resources/manage.rb index 69e1378..5361920 100644 --- a/cookbooks/users/resources/manage.rb +++ b/cookbooks/users/resources/manage.rb @@ -2,7 +2,7 @@ # Cookbook:: users # Resources:: manage # -# Copyright:: 2011-2016, Eric G. Wolfe +# Copyright:: 2011-2017, 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. @@ -17,24 +17,159 @@ # limitations under the License. # -# Data bag user object needs an "action": "remove" tag to actually be removed by the action. -actions :create, :remove -default_action :create - -state_attrs :cookbook, - :data_bag, - :group_id, - :group_name, - :search_group - # :data_bag is the object to search # :search_group is the groups name to search for, defaults to resource name # :group_name is the string name of the group to create, defaults to resource name # :group_id is the numeric id of the group to create, default is to allow the OS to pick next # :cookbook is the name of the cookbook that the authorized_keys template should be found in -attribute :data_bag, kind_of: String, default: 'users' -attribute :search_group, kind_of: String, name_attribute: true -attribute :group_name, kind_of: String, name_attribute: true -attribute :group_id, kind_of: Integer -attribute :cookbook, kind_of: String, default: 'users' -attribute :manage_nfs_home_dirs, kind_of: [TrueClass, FalseClass], default: true +property :data_bag, String, default: 'users' +property :search_group, String, name_property: true +property :group_name, String, name_property: true +property :group_id, Integer +property :cookbook, String, default: 'users' +property :manage_nfs_home_dirs, [true, false], default: true + +action :create do + users_groups = {} + users_groups[new_resource.group_name] = [] + + 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 + + # Check if we need to prepend shell with /usr/local/? + if platform_family? 'freebsd' + 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 + case node['platform_family'] + when 'mac_os_x' + gid validate_id(u['gid']) unless gid_used?(validate_id(u['gid'])) || new_resource.group_name == u['username'] + else + gid validate_id(u['gid']) + end + 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 + + 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 + + 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 + end + + group new_resource.group_name do + case node['platform_family'] + when 'mac_os_x' + gid new_resource.group_id unless gid_used?(new_resource.group_id) + else + gid new_resource.group_id + end + members users_groups[new_resource.group_name] + end +end + +action :remove do + 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 + +action_class.class_eval do + include ::Users::Helpers + include ::Users::OsxHelper + + def manage_home_files?(home_dir, _user) + # Don't manage home dir if it's NFS mount + # and manage_nfs_home_dirs is disabled + if home_dir == '/dev/null' + false + elsif fs_remote?(home_dir) + new_resource.manage_nfs_home_dirs ? true : false + else + true + end + end +end diff --git a/cookbooks/users/templates/default/authorized_keys.erb b/cookbooks/users/templates/authorized_keys.erb similarity index 100% rename from cookbooks/users/templates/default/authorized_keys.erb rename to cookbooks/users/templates/authorized_keys.erb diff --git a/cookbooks/users/templates/default/private_key.erb b/cookbooks/users/templates/private_key.erb similarity index 100% rename from cookbooks/users/templates/default/private_key.erb rename to cookbooks/users/templates/private_key.erb diff --git a/cookbooks/users/templates/default/public_key.pub.erb b/cookbooks/users/templates/public_key.pub.erb similarity index 100% rename from cookbooks/users/templates/default/public_key.pub.erb rename to cookbooks/users/templates/public_key.pub.erb From 030b2501ebbf03ab9f654d77ec4265a4e39ba000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Tue, 2 May 2017 11:46:56 +0200 Subject: [PATCH 39/83] Fix implicit dependency on firewall cookbook in kosmos-base Also delete ufw cookbook, we're not using it --- Batali | 3 +- batali.manifest | 21 +-- cookbooks/firewall/.foodcritic | 3 + cookbooks/firewall/CHANGELOG.md | 11 ++ cookbooks/firewall/README.md | 7 +- cookbooks/firewall/attributes/default.rb | 2 + cookbooks/firewall/attributes/iptables.rb | 4 +- cookbooks/firewall/attributes/ufw.rb | 4 +- cookbooks/firewall/attributes/windows.rb | 4 +- .../firewall/libraries/helpers_firewalld.rb | 4 +- cookbooks/firewall/libraries/helpers_ufw.rb | 2 +- .../libraries/provider_firewall_firewalld.rb | 140 +++++++------- .../libraries/provider_firewall_iptables.rb | 116 +++++++----- .../provider_firewall_iptables_ubuntu.rb | 111 ++++++----- .../provider_firewall_iptables_ubuntu1404.rb | 111 ++++++----- .../libraries/provider_firewall_rule.rb | 14 +- .../libraries/provider_firewall_ufw.rb | 141 +++++++------- .../libraries/provider_firewall_windows.rb | 40 ++-- cookbooks/firewall/metadata.json | 2 +- cookbooks/firewall/recipes/default.rb | 15 ++ .../recipes/disable_firewall.rb} | 10 +- cookbooks/ufw/.foodcritic | 1 - cookbooks/ufw/CHANGELOG.md | 47 ----- cookbooks/ufw/CONTRIBUTING.md | 2 - cookbooks/ufw/MAINTAINERS.md | 15 -- cookbooks/ufw/README.md | 173 ------------------ cookbooks/ufw/attributes/default.rb | 3 - cookbooks/ufw/metadata.json | 1 - cookbooks/ufw/recipes/databag.rb | 58 ------ cookbooks/ufw/recipes/default.rb | 71 ------- cookbooks/ufw/recipes/recipes.rb | 41 ----- cookbooks/ufw/recipes/securitylevel.rb | 41 ----- site-cookbooks/kosmos-base/metadata.rb | 2 +- 33 files changed, 442 insertions(+), 778 deletions(-) create mode 100644 cookbooks/firewall/.foodcritic rename cookbooks/{ufw/recipes/disable.rb => firewall/recipes/disable_firewall.rb} (78%) delete mode 100644 cookbooks/ufw/.foodcritic delete mode 100644 cookbooks/ufw/CHANGELOG.md delete mode 100644 cookbooks/ufw/CONTRIBUTING.md delete mode 100644 cookbooks/ufw/MAINTAINERS.md delete mode 100644 cookbooks/ufw/README.md delete mode 100644 cookbooks/ufw/attributes/default.rb delete mode 100644 cookbooks/ufw/metadata.json delete mode 100644 cookbooks/ufw/recipes/databag.rb delete mode 100644 cookbooks/ufw/recipes/default.rb delete mode 100644 cookbooks/ufw/recipes/recipes.rb delete mode 100644 cookbooks/ufw/recipes/securitylevel.rb diff --git a/Batali b/Batali index 2268d4f..e065c45 100644 --- a/Batali +++ b/Batali @@ -25,8 +25,7 @@ Batali.define do cookbook 'redis', git: 'https://github.com/phlipper/chef-redis.git', ref: 'v0.5.6' - cookbook 'ufw' - cookbook 'firewall' + cookbook 'firewall', '~> 2.6.1' cookbook 'chef_nginx' cookbook 'build-essential' cookbook 'mysql' diff --git a/batali.manifest b/batali.manifest index 44e7752..8f3c5f8 100644 --- a/batali.manifest +++ b/batali.manifest @@ -962,21 +962,6 @@ "subdirectory": null } }, - { - "name": "ufw", - "dependencies": [ - [ - "firewall", - ">= 2.0" - ] - ], - "version": "3.1.0", - "source": { - "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/ufw/versions/3.1.0/download", - "version": "3.1.0" - } - }, { "name": "firewall", "dependencies": [ @@ -985,11 +970,11 @@ ">= 0.0.0" ] ], - "version": "2.5.4", + "version": "2.6.1", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/firewall/versions/2.5.4/download", - "version": "2.5.4" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/firewall/versions/2.6.1/download", + "version": "2.6.1" } }, { diff --git a/cookbooks/firewall/.foodcritic b/cookbooks/firewall/.foodcritic new file mode 100644 index 0000000..b56b353 --- /dev/null +++ b/cookbooks/firewall/.foodcritic @@ -0,0 +1,3 @@ +~FC001 +~FC057 +~FC019 diff --git a/cookbooks/firewall/CHANGELOG.md b/cookbooks/firewall/CHANGELOG.md index bcc623c..e8dd996 100644 --- a/cookbooks/firewall/CHANGELOG.md +++ b/cookbooks/firewall/CHANGELOG.md @@ -2,6 +2,17 @@ firewall Cookbook CHANGELOG ======================= This file is used to list changes made in each version of the firewall cookbook. +v2.6.1 (2017-04-21) +------------------- +* Add recipe to disable firewall (#164) + +v2.6.0 (2017-04-17) +------------------- +* Initial Chef 13.x support (#160, #159) +* Allow loopback and icmp, when enabled (#161) +* Address various newer rubocop and foodcritic complaints +* Convert rule provider away from DSL (#159) + v2.5.4 (2017-02-13) ------------------- * Update Test Kitchen platforms to the latest diff --git a/cookbooks/firewall/README.md b/cookbooks/firewall/README.md index 532968a..6e60bed 100644 --- a/cookbooks/firewall/README.md +++ b/cookbooks/firewall/README.md @@ -84,13 +84,18 @@ keys must be unique but we need multiple commit lines. # Recipes ### default -The default recipe creates a firewall resource with action install, and if `node['firewall']['allow_ssh']`, opens port 22 from the world. +The default recipe creates a firewall resource with action install. + +### disable_firewall +Used to disable platform specific firewall. Many clouds have their own firewall configured outside of the OS instance such as AWS Security Groups. # Attributes * `default['firewall']['allow_ssh'] = false`, set true to open port 22 for SSH when the default recipe runs * `default['firewall']['allow_mosh'] = false`, set to true to open UDP ports 60000 - 61000 for [Mosh][0] when the default recipe runs * `default['firewall']['allow_winrm'] = false`, set true to open port 5989 for WinRM when the default recipe runs +* `default['firewall']['allow_loopback'] = false`, set to true to allow all traffic on the loopback interface +* `default['firewall']['allow_icmp'] = false`, set true to allow icmp protocol on supported OSes (note: ufw and windows implementations don't support this) * `default['firewall']['ubuntu_iptables'] = false`, set to true to use iptables on Ubuntu / Debian when using the default recipe * `default['firewall']['redhat7_iptables'] = false`, set to true to use iptables on Red Hat / CentOS 7 when using the default recipe diff --git a/cookbooks/firewall/attributes/default.rb b/cookbooks/firewall/attributes/default.rb index b8bfcbe..7f72dcf 100644 --- a/cookbooks/firewall/attributes/default.rb +++ b/cookbooks/firewall/attributes/default.rb @@ -1,3 +1,5 @@ default['firewall']['allow_ssh'] = false default['firewall']['allow_winrm'] = false default['firewall']['allow_mosh'] = false +default['firewall']['allow_loopback'] = false +default['firewall']['allow_icmp'] = false diff --git a/cookbooks/firewall/attributes/iptables.rb b/cookbooks/firewall/attributes/iptables.rb index 32113fc..f26ac55 100644 --- a/cookbooks/firewall/attributes/iptables.rb +++ b/cookbooks/firewall/attributes/iptables.rb @@ -1,14 +1,14 @@ default['firewall']['iptables']['defaults'][:policy] = { input: 'DROP', forward: 'DROP', - output: 'ACCEPT' + output: 'ACCEPT', } default['firewall']['iptables']['defaults'][:ruleset] = { '*filter' => 1, ":INPUT #{node['firewall']['iptables']['defaults'][:policy][:input]}" => 2, ":FORWARD #{node['firewall']['iptables']['defaults'][:policy][:forward]}" => 3, ":OUTPUT #{node['firewall']['iptables']['defaults'][:policy][:output]}" => 4, - 'COMMIT_FILTER' => 100 + 'COMMIT_FILTER' => 100, } default['firewall']['ubuntu_iptables'] = false diff --git a/cookbooks/firewall/attributes/ufw.rb b/cookbooks/firewall/attributes/ufw.rb index 957613a..35c8366 100644 --- a/cookbooks/firewall/attributes/ufw.rb +++ b/cookbooks/firewall/attributes/ufw.rb @@ -7,6 +7,6 @@ default['firewall']['ufw']['defaults'] = { input: 'DROP', output: 'ACCEPT', forward: 'DROP', - application: 'SKIP' - } + application: 'SKIP', + }, } diff --git a/cookbooks/firewall/attributes/windows.rb b/cookbooks/firewall/attributes/windows.rb index 68c6c05..382dd82 100644 --- a/cookbooks/firewall/attributes/windows.rb +++ b/cookbooks/firewall/attributes/windows.rb @@ -3,6 +3,6 @@ default['firewall']['windows']['defaults'] = { policy: { input: 'blockinbound', - output: 'allowoutbound' - } + output: 'allowoutbound', + }, } diff --git a/cookbooks/firewall/libraries/helpers_firewalld.rb b/cookbooks/firewall/libraries/helpers_firewalld.rb index aa3019f..2033033 100644 --- a/cookbooks/firewall/libraries/helpers_firewalld.rb +++ b/cookbooks/firewall/libraries/helpers_firewalld.rb @@ -18,14 +18,14 @@ module FirewallCookbook end def firewalld_default_zone?(z) - raise false unless firewalld_active? + return 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? + raise 'firewalld not active' unless firewalld_active? shell_out!('firewall-cmd', "--set-default-zone=#{z}") end diff --git a/cookbooks/firewall/libraries/helpers_ufw.rb b/cookbooks/firewall/libraries/helpers_ufw.rb index 3844272..9e035c5 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|esp|ah|ipv6|none)$') + if new_resource.protocol && !new_resource.protocol.to_s.downcase.match('^(tcp|udp|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} " diff --git a/cookbooks/firewall/libraries/provider_firewall_firewalld.rb b/cookbooks/firewall/libraries/provider_firewall_firewalld.rb index 0a9fb40..b8fc8c5 100644 --- a/cookbooks/firewall/libraries/provider_firewall_firewalld.rb +++ b/cookbooks/firewall/libraries/provider_firewall_firewalld.rb @@ -27,36 +27,39 @@ class Chef false end - action :install do - next if disabled?(new_resource) + def action_install + return if disabled?(new_resource) - converge_by('install firewalld, create template for /etc/sysconfig') do - package 'firewalld' do - action :install - options new_resource.package_options - end + firewalld_package = package 'firewalld' do + action :nothing + options new_resource.package_options + end + firewalld_package.run_action(:install) + new_resource.updated_by_last_action(firewalld_package.updated_by_last_action?) - service 'firewalld' do - action [:enable, :start] - end + unless ::File.exist?(firewalld_rules_filename) + rules_file = lookup_or_create_rulesfile + rules_file.content '# created by chef to allow service to start' + rules_file.run_action(:create) + new_resource.updated_by_last_action(rules_file.updated_by_last_action?) + end - file "create empty #{firewalld_rules_filename}" do - path firewalld_rules_filename - content '# created by chef to allow service to start' - not_if { ::File.exist?(firewalld_rules_filename) } - end + firewalld_service = lookup_or_create_service + [:enable, :start].each do |a| + firewalld_service.run_action(a) + new_resource.updated_by_last_action(firewalld_service.updated_by_last_action?) end end - action :restart do - next if disabled?(new_resource) + def action_restart + return if disabled?(new_resource) # ensure it's initialized new_resource.rules({}) unless new_resource.rules new_resource.rules['firewalld'] = {} unless new_resource.rules['firewalld'] # 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 = Chef.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) @@ -79,23 +82,15 @@ class Chef end # ensure a file resource exists with the current firewalld rules - begin - firewalld_file = run_context.resource_collection.find(file: firewalld_rules_filename) - rescue - firewalld_file = file firewalld_rules_filename do - action :nothing - end - end - firewalld_file.content build_rule_file(new_resource.rules['firewalld']) - firewalld_file.run_action(:create) + rules_file = lookup_or_create_rulesfile + rules_file.content build_rule_file(new_resource.rules['firewalld']) + rules_file.run_action(:create) # ensure the service is running without waiting. - firewall_service = service 'firewalld' do - action :nothing - end + firewalld_service = lookup_or_create_service [:enable, :start].each do |a| - firewall_service.run_action(a) - new_resource.updated_by_last_action(firewall_service.updated_by_last_action?) + firewalld_service.run_action(a) + new_resource.updated_by_last_action(firewalld_service.updated_by_last_action?) end # mark updated if we changed the zone @@ -105,20 +100,19 @@ class Chef end # if the file was changed, load new ruleset - if firewalld_file.updated_by_last_action? - firewalld_flush! - # TODO: support logging + return unless rules_file.updated_by_last_action? + firewalld_flush! + # TODO: support logging - new_resource.rules['firewalld'].sort_by { |_k, v| v }.map { |k, _v| k }.each do |cmd| - firewalld_rule!(cmd) - end - - new_resource.updated_by_last_action(true) + new_resource.rules['firewalld'].sort_by { |_k, v| v }.map { |k, _v| k }.each do |cmd| + firewalld_rule!(cmd) end + + new_resource.updated_by_last_action(true) end - action :disable do - next if disabled?(new_resource) + def action_disable + return if disabled?(new_resource) if firewalld_active? firewalld_flush! @@ -126,38 +120,60 @@ class Chef new_resource.updated_by_last_action(true) end - service 'firewalld' do - action [:disable, :stop] + # ensure the service is stopped without waiting. + firewalld_service = lookup_or_create_service + [:disable, :stop].each do |a| + firewalld_service.run_action(a) + new_resource.updated_by_last_action(firewalld_service.updated_by_last_action?) end - file "create empty #{firewalld_rules_filename}" do - path firewalld_rules_filename - content '# created by chef to allow service to start' - action :create - end + rules_file = lookup_or_create_rulesfile + rules_file.content '# created by chef to allow service to start' + rules_file.run_action(:create) + new_resource.updated_by_last_action(rules_file.updated_by_last_action?) end - action :flush do - next if disabled?(new_resource) - next unless firewalld_active? + def action_flush + return if disabled?(new_resource) + return unless firewalld_active? firewalld_flush! new_resource.updated_by_last_action(true) - file "create empty #{firewalld_rules_filename}" do - path firewalld_rules_filename - content '# created by chef to allow service to start' - action :create - end + rules_file = lookup_or_create_rulesfile + rules_file.content '# created by chef to allow service to start' + rules_file.run_action(:create) + new_resource.updated_by_last_action(rules_file.updated_by_last_action?) end - action :save do - next if disabled?(new_resource) + def action_save + return if disabled?(new_resource) + return if firewalld_all_rules_permanent! - unless firewalld_all_rules_permanent! - firewalld_save! - new_resource.updated_by_last_action(true) + firewalld_save! + new_resource.updated_by_last_action(true) + end + + def lookup_or_create_service + begin + firewalld_service = Chef.run_context.resource_collection.find(service: 'firewalld') + rescue + firewalld_service = service 'firewalld' do + action :nothing + end end + firewalld_service + end + + def lookup_or_create_rulesfile + begin + firewalld_file = Chef.run_context.resource_collection.find(file: firewalld_rules_filename) + rescue + firewalld_file = file firewalld_rules_filename do + action :nothing + end + end + firewalld_file end end end diff --git a/cookbooks/firewall/libraries/provider_firewall_iptables.rb b/cookbooks/firewall/libraries/provider_firewall_iptables.rb index afa90af..6c1cb81 100644 --- a/cookbooks/firewall/libraries/provider_firewall_iptables.rb +++ b/cookbooks/firewall/libraries/provider_firewall_iptables.rb @@ -30,34 +30,38 @@ class Chef false end - action :install do - next if disabled?(new_resource) + def action_install + return if disabled?(new_resource) - converge_by('install iptables and enable/start services') do - # can't pass an array without breaking chef 11 support - iptables_packages(new_resource).each do |p| - package p do - action :install - end + # Ensure the package is installed + iptables_packages(new_resource).each do |p| + iptables_pkg = package p do + action :nothing + end + iptables_pkg.run_action(:install) + new_resource.updated_by_last_action(true) if iptables_pkg.updated_by_last_action? + end + + iptables_commands(new_resource).each do |svc| + # must create empty file for service to start + unless ::File.exist?("/etc/sysconfig/#{svc}") + # must create empty file for service to start + iptables_file = lookup_or_create_rulesfile(svc) + iptables_file.content '# created by chef to allow service to start' + iptables_file.run_action(:create) + new_resource.updated_by_last_action(true) if iptables_file.updated_by_last_action? end - iptables_commands(new_resource).each do |svc| - # must create empty file for service to start - file "create empty /etc/sysconfig/#{svc}" do - path "/etc/sysconfig/#{svc}" - content '# created by chef to allow service to start' - not_if { ::File.exist?("/etc/sysconfig/#{svc}") } - end - - service svc do - action [:enable, :start] - end + iptables_service = lookup_or_create_service(svc) + [:enable, :start].each do |a| + iptables_service.run_action(a) + new_resource.updated_by_last_action(true) if iptables_service.updated_by_last_action? end end end - action :restart do - next if disabled?(new_resource) + def action_restart + return if disabled?(new_resource) # prints all the firewall rules log_iptables(new_resource) @@ -67,7 +71,7 @@ class Chef 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 = Chef.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) @@ -91,65 +95,77 @@ class Chef end iptables_commands(new_resource).each do |iptables_type| - iptables_filename = "/etc/sysconfig/#{iptables_type}" - # 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 - # this takes the commands in each hash entry and builds a rule file + iptables_file = lookup_or_create_rulesfile(iptables_type) iptables_file.content build_rule_file(new_resource.rules[iptables_type]) iptables_file.run_action(:create) # if the file was unchanged, skip loop iteration, otherwise restart iptables next unless iptables_file.updated_by_last_action? - service_affected = service iptables_type do - action :nothing - end - - new_resource.notifies(:restart, service_affected, :delayed) + iptables_service = lookup_or_create_service(iptables_type) + new_resource.notifies(:restart, iptables_service, :delayed) new_resource.updated_by_last_action(true) end end - action :disable do - next if disabled?(new_resource) + def action_disable + return if disabled?(new_resource) iptables_flush!(new_resource) iptables_default_allow!(new_resource) new_resource.updated_by_last_action(true) iptables_commands(new_resource).each do |svc| - service svc do - action [:disable, :stop] + iptables_service = lookup_or_create_service(svc) + [:disable, :stop].each do |a| + iptables_service.run_action(a) + new_resource.updated_by_last_action(true) if iptables_service.updated_by_last_action? end # must create empty file for service to start - file "create empty /etc/sysconfig/#{svc}" do - path "/etc/sysconfig/#{svc}" - content '# created by chef to allow service to start' - end + iptables_file = lookup_or_create_rulesfile(svc) + iptables_file.content '# created by chef to allow service to start' + iptables_file.run_action(:create) + new_resource.updated_by_last_action(true) if iptables_file.updated_by_last_action? end end - action :flush do - next if disabled?(new_resource) + def action_flush + return if disabled?(new_resource) iptables_flush!(new_resource) new_resource.updated_by_last_action(true) iptables_commands(new_resource).each do |svc| # must create empty file for service to start - file "create empty /etc/sysconfig/#{svc}" do - path "/etc/sysconfig/#{svc}" - content '# created by chef to allow service to start' + iptables_file = lookup_or_create_rulesfile(svc) + iptables_file.content '# created by chef to allow service to start' + iptables_file.run_action(:create) + new_resource.updated_by_last_action(true) if iptables_file.updated_by_last_action? + end + end + + def lookup_or_create_service(name) + begin + iptables_service = Chef.run_context.resource_collection.find(service: svc) + rescue + iptables_service = service name do + action :nothing end end + iptables_service + end + + def lookup_or_create_rulesfile(name) + begin + iptables_file = Chef.run_context.resource_collection.find(file: name) + rescue + iptables_file = file "/etc/sysconfig/#{name}" do + action :nothing + end + end + iptables_file end end end diff --git a/cookbooks/firewall/libraries/provider_firewall_iptables_ubuntu.rb b/cookbooks/firewall/libraries/provider_firewall_iptables_ubuntu.rb index 4491991..c89320d 100644 --- a/cookbooks/firewall/libraries/provider_firewall_iptables_ubuntu.rb +++ b/cookbooks/firewall/libraries/provider_firewall_iptables_ubuntu.rb @@ -30,37 +30,41 @@ class Chef false end - action :install do - next if disabled?(new_resource) + def action_install + return 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 + # Ensure the package is installed + pkg = package 'iptables-persistent' do + action :nothing + end + pkg.run_action(:install) + new_resource.updated_by_last_action(true) if pkg.updated_by_last_action? - 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 + rule_files = %w(rules.v4) + rule_files << 'rules.v6' if ipv6_enabled?(new_resource) + rule_files.each do |svc| + next unless ::File.exist?("/etc/iptables/#{svc}") - service 'netfilter-persistent' do - action [:enable, :start] - status_command 'true' # netfilter-persistent isn't a real service - end + # must create empty file for service to start + f = lookup_or_create_rulesfile(svc) + f.content '# created by chef to allow service to start' + f.run_action(:create) + + new_resource.updated_by_last_action(true) if f.updated_by_last_action? + end + + iptables_service = lookup_or_create_service('netfilter-persistent') + [:enable, :start].each do |act| + # iptables-persistent isn't a real service + iptables_service.status_command 'true' + + iptables_service.run_action(act) + new_resource.updated_by_last_action(true) if iptables_service.updated_by_last_action? end end - action :restart do - next if disabled?(new_resource) + def action_restart + return if disabled?(new_resource) # prints all the firewall rules log_iptables(new_resource) @@ -70,7 +74,7 @@ class Chef 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 = Chef.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) @@ -105,7 +109,7 @@ class Chef # ensure a file resource exists with the current iptables rules begin - iptables_file = run_context.resource_collection.find(file: iptables_filename) + iptables_file = Chef.run_context.resource_collection.find(file: iptables_filename) rescue iptables_file = file iptables_filename do action :nothing @@ -125,29 +129,31 @@ class Chef end end - action :disable do - next if disabled?(new_resource) + def action_disable + return if disabled?(new_resource) iptables_flush!(new_resource) iptables_default_allow!(new_resource) new_resource.updated_by_last_action(true) - service 'netfilter-persistent' do - action [:disable, :stop] + iptables_service = lookup_or_create_service('netfilter-persistent') + [:disable, :stop].each do |act| + iptables_service.run_action(act) + new_resource.updated_by_last_action(true) if iptables_service.updated_by_last_action? 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 + f = lookup_or_create_rulesfile(svc) + f.content '# created by chef to allow service to start' + f.run_action(:create) + + new_resource.updated_by_last_action(true) if f.updated_by_last_action? end end - action :flush do - next if disabled?(new_resource) + def action_flush + return if disabled?(new_resource) iptables_flush!(new_resource) new_resource.updated_by_last_action(true) @@ -156,11 +162,34 @@ class Chef 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' + f = lookup_or_create_rulesfile(svc) + f.content '# created by chef to allow service to start' + f.run_action(:create) + + new_resource.updated_by_last_action(true) if f.updated_by_last_action? + end + end + + def lookup_or_create_service(name) + begin + iptables_service = Chef.run_context.resource_collection.find(service: svc) + rescue + iptables_service = service name do + action :nothing end end + iptables_service + end + + def lookup_or_create_rulesfile(name) + begin + iptables_file = Chef.run_context.resource_collection.find(file: name) + rescue + iptables_file = file "/etc/iptables/#{name}" do + action :nothing + end + end + iptables_file end end end diff --git a/cookbooks/firewall/libraries/provider_firewall_iptables_ubuntu1404.rb b/cookbooks/firewall/libraries/provider_firewall_iptables_ubuntu1404.rb index b4c0200..8332be1 100644 --- a/cookbooks/firewall/libraries/provider_firewall_iptables_ubuntu1404.rb +++ b/cookbooks/firewall/libraries/provider_firewall_iptables_ubuntu1404.rb @@ -30,37 +30,41 @@ class Chef false end - action :install do - next if disabled?(new_resource) + def action_install + return 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 + # Ensure the package is installed + pkg = package 'iptables-persistent' do + action :nothing + end + pkg.run_action(:install) + new_resource.updated_by_last_action(true) if pkg.updated_by_last_action? - 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 + rule_files = %w(rules.v4) + rule_files << 'rules.v6' if ipv6_enabled?(new_resource) + rule_files.each do |svc| + next unless ::File.exist?("/etc/iptables/#{svc}") - service 'iptables-persistent' do - action [:enable, :start] - status_command 'true' # iptables-persistent isn't a real service - end + # must create empty file for service to start + f = lookup_or_create_rulesfile(svc) + f.content '# created by chef to allow service to start' + f.run_action(:create) + + new_resource.updated_by_last_action(true) if f.updated_by_last_action? + end + + iptables_service = lookup_or_create_service('iptables-persistent') + [:enable, :start].each do |act| + # iptables-persistent isn't a real service + iptables_service.status_command 'true' + + iptables_service.run_action(act) + new_resource.updated_by_last_action(true) if iptables_service.updated_by_last_action? end end - action :restart do - next if disabled?(new_resource) + def action_restart + return if disabled?(new_resource) # prints all the firewall rules log_iptables(new_resource) @@ -70,7 +74,7 @@ class Chef 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 = Chef.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) @@ -105,7 +109,7 @@ class Chef # ensure a file resource exists with the current iptables rules begin - iptables_file = run_context.resource_collection.find(file: iptables_filename) + iptables_file = Chef.run_context.resource_collection.find(file: iptables_filename) rescue iptables_file = file iptables_filename do action :nothing @@ -125,29 +129,31 @@ class Chef end end - action :disable do - next if disabled?(new_resource) + def action_disable + return 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] + iptables_service = lookup_or_create_service('iptables-persistent') + [:disable, :stop].each do |act| + iptables_service.run_action(act) + new_resource.updated_by_last_action(true) if iptables_service.updated_by_last_action? 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 + f = lookup_or_create_rulesfile(svc) + f.content '# created by chef to allow service to start' + f.run_action(:create) + + new_resource.updated_by_last_action(true) if f.updated_by_last_action? end end - action :flush do - next if disabled?(new_resource) + def action_flush + return if disabled?(new_resource) iptables_flush!(new_resource) new_resource.updated_by_last_action(true) @@ -156,11 +162,34 @@ class Chef 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' + f = lookup_or_create_rulesfile(svc) + f.content '# created by chef to allow service to start' + f.run_action(:create) + + new_resource.updated_by_last_action(true) if f.updated_by_last_action? + end + end + + def lookup_or_create_service(name) + begin + iptables_service = Chef.run_context.resource_collection.find(service: svc) + rescue + iptables_service = service name do + action :nothing end end + iptables_service + end + + def lookup_or_create_rulesfile(name) + begin + iptables_file = Chef.run_context.resource_collection.find(file: name) + rescue + iptables_file = file "/etc/iptables/#{name}" do + action :nothing + end + end + iptables_file end end end diff --git a/cookbooks/firewall/libraries/provider_firewall_rule.rb b/cookbooks/firewall/libraries/provider_firewall_rule.rb index f448610..85a27c5 100644 --- a/cookbooks/firewall/libraries/provider_firewall_rule.rb +++ b/cookbooks/firewall/libraries/provider_firewall_rule.rb @@ -21,14 +21,14 @@ class Chef class Provider::FirewallRuleGeneric < Chef::Provider::LWRPBase provides :firewall_rule - action :create do - 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 + def action_create + return unless new_resource.notify_firewall - new_resource.notifies(:restart, firewall_resource, :delayed) - new_resource.updated_by_last_action(true) - end + firewall_resource = Chef.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) end end end diff --git a/cookbooks/firewall/libraries/provider_firewall_ufw.rb b/cookbooks/firewall/libraries/provider_firewall_ufw.rb index 25e5a12..cc1aeb7 100644 --- a/cookbooks/firewall/libraries/provider_firewall_ufw.rb +++ b/cookbooks/firewall/libraries/provider_firewall_ufw.rb @@ -29,40 +29,44 @@ class Chef false end - action :install do - next if disabled?(new_resource) + def action_install + return if disabled?(new_resource) - converge_by('install ufw, create template for /etc/default') do - package 'ufw' do - action :install - end - - template '/etc/default/ufw' do - action [:create] - owner 'root' - group 'root' - mode '0644' - source 'ufw/default.erb' - cookbook 'firewall' - end - - file "create empty #{ufw_rules_filename}" do - path ufw_rules_filename - content '# created by chef to allow service to start' - not_if { ::File.exist?(ufw_rules_filename) } - end + pkg_ufw = package 'ufw' do + action :nothing end + pkg_ufw.run_action(:install) + new_resource.updated_by_last_action(true) if pkg_ufw.updated_by_last_action? + + defaults_ufw = template '/etc/default/ufw' do + action :nothing + owner 'root' + group 'root' + mode '0644' + source 'ufw/default.erb' + cookbook 'firewall' + end + defaults_ufw.run_action(:create) + new_resource.updated_by_last_action(true) if defaults_ufw.updated_by_last_action? + + return if ::File.exist?(ufw_rules_filename) + + ufw_file = lookup_or_create_rulesfile + ufw_file.content '# created by chef to allow service to start' + ufw_file.run_action(:create) + + new_resource.updated_by_last_action(true) if ufw_file.updated_by_last_action? end - action :restart do - next if disabled?(new_resource) + def action_restart + return if disabled?(new_resource) # ensure it's initialized new_resource.rules({}) unless new_resource.rules new_resource.rules['ufw'] = {} unless new_resource.rules['ufw'] # 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 = Chef.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) @@ -77,55 +81,58 @@ class Chef end # ensure a file resource exists with the current ufw rules + ufw_file = lookup_or_create_rulesfile + ufw_file.content build_rule_file(new_resource.rules['ufw']) + ufw_file.run_action(:create) + + # if the file was changed, restart iptables + return unless ufw_file.updated_by_last_action? + ufw_reset! + ufw_logging!(new_resource.log_level) if new_resource.log_level + + new_resource.rules['ufw'].sort_by { |_k, v| v }.map { |k, _v| k }.each do |cmd| + ufw_rule!(cmd) + end + + # ensure it's enabled _after_ rules are inputted, to catch malformed rules + ufw_enable! unless ufw_active? + new_resource.updated_by_last_action(true) + end + + def action_disable + return if disabled?(new_resource) + + ufw_file = lookup_or_create_rulesfile + ufw_file.content '# created by chef to allow service to start' + ufw_file.run_action(:create) + new_resource.updated_by_last_action(true) if ufw_file.updated_by_last_action? + + return unless ufw_active? + ufw_disable! + new_resource.updated_by_last_action(true) + end + + def action_flush + return if disabled?(new_resource) + + ufw_reset! + new_resource.updated_by_last_action(true) + + ufw_file = lookup_or_create_rulesfile + ufw_file.content '# created by chef to allow service to start' + ufw_file.run_action(:create) + new_resource.updated_by_last_action(true) if ufw_file.updated_by_last_action? + end + + def lookup_or_create_rulesfile begin - ufw_file = run_context.resource_collection.find(file: ufw_rules_filename) + ufw_file = Chef.run_context.resource_collection.find(file: ufw_rules_filename) rescue ufw_file = file ufw_rules_filename do action :nothing end end - ufw_file.content build_rule_file(new_resource.rules['ufw']) - ufw_file.run_action(:create) - - # if the file was changed, restart iptables - if ufw_file.updated_by_last_action? - ufw_reset! - ufw_logging!(new_resource.log_level) if new_resource.log_level - - new_resource.rules['ufw'].sort_by { |_k, v| v }.map { |k, _v| k }.each do |cmd| - ufw_rule!(cmd) - end - - # ensure it's enabled _after_ rules are inputted, to catch malformed rules - ufw_enable! unless ufw_active? - new_resource.updated_by_last_action(true) - end - end - - action :disable do - next if disabled?(new_resource) - - file "create empty #{ufw_rules_filename}" do - path ufw_rules_filename - content '# created by chef to allow service to start' - end - - if ufw_active? - ufw_disable! - new_resource.updated_by_last_action(true) - end - end - - action :flush do - next if disabled?(new_resource) - - ufw_reset! - new_resource.updated_by_last_action(true) - - file "create empty #{ufw_rules_filename}" do - path ufw_rules_filename - content '# created by chef to allow service to start' - end + ufw_file end end end diff --git a/cookbooks/firewall/libraries/provider_firewall_windows.rb b/cookbooks/firewall/libraries/provider_firewall_windows.rb index 0d242b2..d261f03 100644 --- a/cookbooks/firewall/libraries/provider_firewall_windows.rb +++ b/cookbooks/firewall/libraries/provider_firewall_windows.rb @@ -26,8 +26,8 @@ class Chef false end - action :install do - next if disabled?(new_resource) + def action_install + return if disabled?(new_resource) svc = service 'MpsSvc' do action :nothing @@ -39,14 +39,14 @@ class Chef end end - action :restart do - next if disabled?(new_resource) + def action_restart + return if disabled?(new_resource) # ensure it's initialized new_resource.rules({}) unless new_resource.rules new_resource.rules['windows'] = {} unless new_resource.rules['windows'] - firewall_rules = run_context.resource_collection.select { |item| item.is_a?(Chef::Resource::FirewallRule) } + firewall_rules = Chef.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) @@ -69,7 +69,7 @@ class Chef # ensure a file resource exists with the current rules begin - windows_file = run_context.resource_collection.find(file: windows_rules_filename) + windows_file = Chef.run_context.resource_collection.find(file: windows_rules_filename) rescue windows_file = file windows_rules_filename do action :nothing @@ -79,23 +79,23 @@ class Chef windows_file.run_action(:create) # if the file was changed, restart iptables - if windows_file.updated_by_last_action? - disable! if active? - delete_all_rules! # clear entirely - reset! # populate default rules + return unless windows_file.updated_by_last_action? - new_resource.rules['windows'].sort_by { |_k, v| v }.map { |k, _v| k }.each do |cmd| - add_rule!(cmd) - end - # ensure it's enabled _after_ rules are inputted, to catch malformed rules - enable! unless active? + disable! if active? + delete_all_rules! # clear entirely + reset! # populate default rules - new_resource.updated_by_last_action(true) + new_resource.rules['windows'].sort_by { |_k, v| v }.map { |k, _v| k }.each do |cmd| + add_rule!(cmd) end + # ensure it's enabled _after_ rules are inputted, to catch malformed rules + enable! unless active? + + new_resource.updated_by_last_action(true) end - action :disable do - next if disabled?(new_resource) + def action_disable + return if disabled?(new_resource) if active? disable! @@ -115,8 +115,8 @@ class Chef end end - action :flush do - next if disabled?(new_resource) + def action_flush + return if disabled?(new_resource) reset! Chef::Log.info("#{new_resource} reset.") diff --git a/cookbooks/firewall/metadata.json b/cookbooks/firewall/metadata.json index 6381404..1a05794 100644 --- a/cookbooks/firewall/metadata.json +++ b/cookbooks/firewall/metadata.json @@ -1 +1 @@ -{"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 +{"name":"firewall","version":"2.6.1","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.\n\n### disable_firewall\nUsed to disable platform specific firewall. Many clouds have their own firewall configured outside of the OS instance such as AWS Security Groups.\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* `default['firewall']['allow_loopback'] = false`, set to true to allow all traffic on the loopback interface\n* `default['firewall']['allow_icmp'] = false`, set true to allow icmp protocol on supported OSes (note: ufw and windows implementations don't support this)\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":{},"source_url":"https://github.com/chef-cookbooks/firewall","issues_url":"https://github.com/chef-cookbooks/firewall/issues","chef_version":[[">= 12.5"]],"ohai_version":[]} \ No newline at end of file diff --git a/cookbooks/firewall/recipes/default.rb b/cookbooks/firewall/recipes/default.rb index c85d5f5..9c2b10b 100644 --- a/cookbooks/firewall/recipes/default.rb +++ b/cookbooks/firewall/recipes/default.rb @@ -27,6 +27,21 @@ end # create a variable to use as a condition on some rules that follow iptables_firewall = rhel? || node['firewall']['ubuntu_iptables'] +firewall_rule 'allow loopback' do + interface 'lo' + protocol :none + command :allow + only_if { linux? && node['firewall']['allow_loopback'] } +end + +firewall_rule 'allow icmp' do + protocol :icmp + command :allow + # debian ufw doesn't allow 'icmp' protocol, but does open + # icmp by default, so we skip it in default recipe + only_if { (!debian? || iptables_firewall) && node['firewall']['allow_icmp'] } +end + firewall_rule 'allow world to ssh' do port 22 source '0.0.0.0/0' diff --git a/cookbooks/ufw/recipes/disable.rb b/cookbooks/firewall/recipes/disable_firewall.rb similarity index 78% rename from cookbooks/ufw/recipes/disable.rb rename to cookbooks/firewall/recipes/disable_firewall.rb index c0261fe..330953d 100644 --- a/cookbooks/ufw/recipes/disable.rb +++ b/cookbooks/firewall/recipes/disable_firewall.rb @@ -1,9 +1,8 @@ # -# Author:: Matt Ray -# Cookbook:: ufw -# Recipe:: disable +# Cookbook:: firewall +# Recipe:: disable_firewall # -# Copyright:: 2011-2017, 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. @@ -18,6 +17,7 @@ # limitations under the License. # -firewall 'ufw' do +# Disable platform default firewall +firewall 'default' do action :disable end diff --git a/cookbooks/ufw/.foodcritic b/cookbooks/ufw/.foodcritic deleted file mode 100644 index 698ef4c..0000000 --- a/cookbooks/ufw/.foodcritic +++ /dev/null @@ -1 +0,0 @@ -~FC003 diff --git a/cookbooks/ufw/CHANGELOG.md b/cookbooks/ufw/CHANGELOG.md deleted file mode 100644 index 03dceda..0000000 --- a/cookbooks/ufw/CHANGELOG.md +++ /dev/null @@ -1,47 +0,0 @@ -# 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. -- Updated testing, contributing, and maintainers docs -- Added source_url and issues_url metadata for supermarket -- Resolved all rubocop warnings and add the standard Chef rubocop file -- Added travis and supermarket version badges to the readme -- Added requirements section to the readme -- Added a chefignore file -- Added a Rakefile for simplified testing -- Added a basic converge chefspec - -## v0.7.4 -No change. Version bump for toolchain - -## v0.7.2 -Updating metadata to depend on firewall >= 0.9 - -## v0.7.0 -[COOK-3592] - allow source ports to be defined as a range in ufw - -## v0.6.4 -### Bug -- **[COOK-3316](https://tickets.chef.io/browse/COOK-3316)** - Fix README.md example - -## v0.6.2 -### Bug -- [COOK-2487]: when setting a node attribute you must specify the precedence -- [COOK-2982]: ufw cookbook has foodcritic failures diff --git a/cookbooks/ufw/CONTRIBUTING.md b/cookbooks/ufw/CONTRIBUTING.md deleted file mode 100644 index ef2f2b8..0000000 --- a/cookbooks/ufw/CONTRIBUTING.md +++ /dev/null @@ -1,2 +0,0 @@ -Please refer to -https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD diff --git a/cookbooks/ufw/MAINTAINERS.md b/cookbooks/ufw/MAINTAINERS.md deleted file mode 100644 index 645ed14..0000000 --- a/cookbooks/ufw/MAINTAINERS.md +++ /dev/null @@ -1,15 +0,0 @@ - - -# 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/ufw/README.md b/cookbooks/ufw/README.md deleted file mode 100644 index ac7aee7..0000000 --- a/cookbooks/ufw/README.md +++ /dev/null @@ -1,173 +0,0 @@ -# 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 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 explicitly added. - -## Requirements - -### Platforms - -- Ubuntu -- Debian - -### Chef - -- Chef 12.4+ - -### Cookbooks - -- firewall 2.0+ - -## Recipes - -### 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 - -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 - -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 apply the rules, so you may mix roles with databag items if you want (roles apply first, then data bag contents). - -### 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: - -#### attributes/default.rb for test cookbook - -```ruby -default['test']['firewall']['rules'] = [ - {"test"=> { - "port"=> "27901", - "protocol"=> "udp" - } - } -] -default['test::awesome']['firewall']['rules'] = [ - {"awesome"=> { - "port"=> "99427", - "protocol"=> "udp" - } - }, - {"awesome2"=> { - "port"=> "99428" - } - } -] -``` - -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 - -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( - "firewall" => { - "rules" => [ - {"tftp" => {}}, - {"http" => { - "port" => "80" - } - }, - {"block tomcat from 192.168.1.0/24" => { - "port" => "8080", - "source" => "192.168.1.0/24", - "action" => "deny" - } - }, - {"Allow access to udp 1.2.3.4 port 5469 from 1.2.3.5 port 5469" => { - "protocol" => "udp", - "port" => "5469", - "source" => "1.2.3.4", - "destination" => "1.2.3.5", - "dest_port" => "5469" - } - }, - {"allow to tcp ports 8000-8010 from 192.168.1.0/24" => { - "port_range" => "8000..8010", - "source" => "192.168.1.0/24", - "protocol" => "tcp" //protocol is mandatory when using port ranges - } - } - ] - } - ) -``` - -* 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 -``` - -### Example 'firewall' data bag item - -```javascript -{ - "id": "apache2", - "rules": [ - {"http": { - "port": "80" - }}, - {"block http from 192.168.1.0/24": { - "port": "80", - "source": "192.168.1.0/24", - "action": "deny" - }} - ] -} -``` - -## 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-2014, 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/ufw/attributes/default.rb b/cookbooks/ufw/attributes/default.rb deleted file mode 100644 index 44a9aea..0000000 --- a/cookbooks/ufw/attributes/default.rb +++ /dev/null @@ -1,3 +0,0 @@ -default['firewall']['rules'] = [] -default['firewall']['securitylevel'] = '' -default['firewall']['allow_ssh'] = true diff --git a/cookbooks/ufw/metadata.json b/cookbooks/ufw/metadata.json deleted file mode 100644 index 717bd6c..0000000 --- a/cookbooks/ufw/metadata.json +++ /dev/null @@ -1 +0,0 @@ -{"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 deleted file mode 100644 index fbebae1..0000000 --- a/cookbooks/ufw/recipes/databag.rb +++ /dev/null @@ -1,58 +0,0 @@ -# -# Author:: Matt Ray -# Cookbook:: ufw -# Recipe:: databag -# -# 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. -# 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. -# - -# flatten the run_list to just the names of the roles and recipes in order -def run_list_names(run_list) - names = [] - run_list.each do |entry| - Chef::Log.debug "ufw::databag:run_list_names+name: #{entry.name}" - if entry.name.index('::') # cookbook::recipe - names.push(entry.name.sub('::', '__')) - else - names.push(entry.name) - end - if entry.role? - rol = search(:role, "name:#{entry.name}")[0] - names.concat(run_list_names(rol.run_list)) - end - end - Chef::Log.debug "ufw::databag:run_list_names+names: #{names}" - names -end - -rlist = run_list_names(node.run_list) -rlist.uniq! -Chef::Log.debug "ufw::databag:rlist: #{rlist}" - -fw_db = data_bag('firewall') -Chef::Log.debug "ufw::databag:firewall:#{fw_db}" - -rlist.each do |entry| - Chef::Log.debug "ufw::databag: \"#{entry}\"" - next unless fw_db.member?(entry) - - # add the list of firewall rules to the current list - item = data_bag_item('firewall', entry) - rules = item['rules'] - node.normal['firewall']['rules'].concat(rules) unless rules.nil? -end - -# now go apply the rules -include_recipe 'ufw::default' diff --git a/cookbooks/ufw/recipes/default.rb b/cookbooks/ufw/recipes/default.rb deleted file mode 100644 index f67c889..0000000 --- a/cookbooks/ufw/recipes/default.rb +++ /dev/null @@ -1,71 +0,0 @@ -# -# Author:: Matt Ray -# Cookbook:: ufw -# Recipe:: default -# -# 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. -# 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. -# - -firewall 'default' do - action :install -end - -# leave this on by default -firewall_rule 'ssh' do - port 22 - action :create - only_if { node['firewall']['allow_ssh'] } -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' - 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/recipes.rb b/cookbooks/ufw/recipes/recipes.rb deleted file mode 100644 index 1cd634c..0000000 --- a/cookbooks/ufw/recipes/recipes.rb +++ /dev/null @@ -1,41 +0,0 @@ -# -# Author:: Matt Ray -# Cookbook:: ufw -# Recipe:: recipes -# -# 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. -# 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. -# - -# expand and parse the node's runlist for recipes and find attributes of the form node[]['firewall']['rules'] -# append them to the node['firewall']['rules'] array attribute -node.expand!.recipes.each do |recipe| - Chef::Log.debug "ufw::recipes: #{recipe}" - cookbook = recipe.split('::')[0] - # get the cookbook attributes if there are any - 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.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.normal['firewall']['rules'].concat(rules) unless rules.nil? -end - -# now go apply the rules -include_recipe 'ufw::default' diff --git a/cookbooks/ufw/recipes/securitylevel.rb b/cookbooks/ufw/recipes/securitylevel.rb deleted file mode 100644 index 524ac9b..0000000 --- a/cookbooks/ufw/recipes/securitylevel.rb +++ /dev/null @@ -1,41 +0,0 @@ -# -# Author:: Matt Ray -# Cookbook:: ufw -# Recipe:: securitylevel -# -# 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. -# 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. -# - -securitylevel = node['firewall']['securitylevel'] - -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 - 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 - -# now go apply the rules -include_recipe 'ufw::default' diff --git a/site-cookbooks/kosmos-base/metadata.rb b/site-cookbooks/kosmos-base/metadata.rb index 9ee04ac..88981e4 100644 --- a/site-cookbooks/kosmos-base/metadata.rb +++ b/site-cookbooks/kosmos-base/metadata.rb @@ -11,6 +11,6 @@ depends 'users' depends 'sudo' depends 'kosmos-postfix' depends 'hostname' -depends 'ufw' +depends 'firewall' depends 'omnibus_updater' depends 'timezone-ii' From 943b4ace1fe3f2a96983003594a18028e4b3520e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Tue, 2 May 2017 11:53:33 +0200 Subject: [PATCH 40/83] Replace omnibus_updater with chef_client_updater omnibus_updater is deprecated --- Batali | 4 +- batali.manifest | 13 +- cookbooks/chef_client_updater/.foodcritic | 1 + cookbooks/chef_client_updater/CHANGELOG.md | 16 ++ .../CONTRIBUTING.md | 0 .../MAINTAINERS.md | 0 cookbooks/chef_client_updater/README.md | 69 ++++++++ .../chef_client_updater/attributes/default.rb | 29 ++++ .../chef_client_updater/libraries/matchers.rb | 7 + cookbooks/chef_client_updater/metadata.json | 1 + .../recipes/default.rb} | 25 ++- .../chef_client_updater/resources/updater.rb | 136 ++++++++++++++++ cookbooks/omnibus_updater/CHANGELOG.md | 149 ------------------ cookbooks/omnibus_updater/README.md | 101 ------------ .../omnibus_updater/attributes/default.rb | 32 ---- .../omnibus_updater/libraries/omnitrucker.rb | 102 ------------ cookbooks/omnibus_updater/metadata.json | 1 - cookbooks/omnibus_updater/recipes/default.rb | 31 ---- .../omnibus_updater/recipes/downloader.rb | 77 --------- .../omnibus_updater/recipes/installer.rb | 124 --------------- .../recipes/old_package_cleaner.rb | 34 ---- site-cookbooks/kosmos-base/metadata.rb | 2 +- site-cookbooks/kosmos-base/recipes/default.rb | 8 +- 23 files changed, 285 insertions(+), 677 deletions(-) create mode 100644 cookbooks/chef_client_updater/.foodcritic create mode 100644 cookbooks/chef_client_updater/CHANGELOG.md rename cookbooks/{omnibus_updater => chef_client_updater}/CONTRIBUTING.md (100%) rename cookbooks/{omnibus_updater => chef_client_updater}/MAINTAINERS.md (100%) create mode 100644 cookbooks/chef_client_updater/README.md create mode 100644 cookbooks/chef_client_updater/attributes/default.rb create mode 100644 cookbooks/chef_client_updater/libraries/matchers.rb create mode 100644 cookbooks/chef_client_updater/metadata.json rename cookbooks/{omnibus_updater/libraries/omnibus_checker.rb => chef_client_updater/recipes/default.rb} (51%) create mode 100644 cookbooks/chef_client_updater/resources/updater.rb delete mode 100644 cookbooks/omnibus_updater/CHANGELOG.md delete mode 100644 cookbooks/omnibus_updater/README.md delete mode 100644 cookbooks/omnibus_updater/attributes/default.rb delete mode 100644 cookbooks/omnibus_updater/libraries/omnitrucker.rb delete mode 100644 cookbooks/omnibus_updater/metadata.json delete mode 100644 cookbooks/omnibus_updater/recipes/default.rb delete mode 100644 cookbooks/omnibus_updater/recipes/downloader.rb delete mode 100644 cookbooks/omnibus_updater/recipes/installer.rb delete mode 100644 cookbooks/omnibus_updater/recipes/old_package_cleaner.rb diff --git a/Batali b/Batali index e065c45..c96ff4e 100644 --- a/Batali +++ b/Batali @@ -26,13 +26,13 @@ Batali.define do git: 'https://github.com/phlipper/chef-redis.git', ref: 'v0.5.6' cookbook 'firewall', '~> 2.6.1' - cookbook 'chef_nginx' + cookbook 'chef_nginx', '~> 6.0.2' cookbook 'build-essential' cookbook 'mysql' cookbook 'postgresql', '~> 6.1' cookbook 'database' cookbook 'mysql2_chef_gem' - cookbook 'omnibus_updater' + cookbook 'chef_client_updater', '~> 1.0.2' cookbook 'timezone-ii' cookbook 'nodejs', '~> 3.0.0' cookbook 'ark' diff --git a/batali.manifest b/batali.manifest index 8f3c5f8..9a481f2 100644 --- a/batali.manifest +++ b/batali.manifest @@ -978,15 +978,18 @@ } }, { - "name": "omnibus_updater", + "name": "chef_client_updater", "dependencies": [ - + [ + "compat_resource", + ">= 12.16.3" + ] ], - "version": "3.0.2", + "version": "1.0.2", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/omnibus_updater/versions/3.0.2/download", - "version": "3.0.2" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/chef_client_updater/versions/1.0.2/download", + "version": "1.0.2" } }, { diff --git a/cookbooks/chef_client_updater/.foodcritic b/cookbooks/chef_client_updater/.foodcritic new file mode 100644 index 0000000..b9f8767 --- /dev/null +++ b/cookbooks/chef_client_updater/.foodcritic @@ -0,0 +1 @@ +~FC016 diff --git a/cookbooks/chef_client_updater/CHANGELOG.md b/cookbooks/chef_client_updater/CHANGELOG.md new file mode 100644 index 0000000..fbbad7f --- /dev/null +++ b/cookbooks/chef_client_updater/CHANGELOG.md @@ -0,0 +1,16 @@ +# chef_client_updater Cookbook CHANGELOG + +This file is used to list changes made in each version of the chef_client_updater cookbook. + +## 1.0.2 (2017-04-07) + +- Fix Chef 13 compatibility by using Kernel.exec not exec + +## 1.0.1 (2017-04-07) + +- point the URLs at the new project repo +- Add ChefSpec matcher + +## 1.0.0 + +- Initial release of chef_client_updater diff --git a/cookbooks/omnibus_updater/CONTRIBUTING.md b/cookbooks/chef_client_updater/CONTRIBUTING.md similarity index 100% rename from cookbooks/omnibus_updater/CONTRIBUTING.md rename to cookbooks/chef_client_updater/CONTRIBUTING.md diff --git a/cookbooks/omnibus_updater/MAINTAINERS.md b/cookbooks/chef_client_updater/MAINTAINERS.md similarity index 100% rename from cookbooks/omnibus_updater/MAINTAINERS.md rename to cookbooks/chef_client_updater/MAINTAINERS.md diff --git a/cookbooks/chef_client_updater/README.md b/cookbooks/chef_client_updater/README.md new file mode 100644 index 0000000..6ce141a --- /dev/null +++ b/cookbooks/chef_client_updater/README.md @@ -0,0 +1,69 @@ +# chef_client_updater + +[![Build Status](https://travis-ci.org/chef-cookbooks/chef_client_updater.svg?branch=master)](https://travis-ci.org/chef-cookbooks/chef_client_updater) [![Cookbook Version](https://img.shields.io/cookbook/v/chef_client_updater.svg)](https://supermarket.chef.io/cookbooks/chef_client_updater) + +This cookbook updates the chef-client + +## Requirements + +### Platforms + +- All platforms with a chef-client package on downloads.chef.io + +### Chef + +- Chef 12.1+ + +### Cookbooks + +- compat_resource + +### Usage + +This cookbook provides both a custom resource and a default recipe. The default recipe simply uses the custom resource with a set of attributes. You can add chef_client_updater::default to your run list or use the custom resource in a wrapper cookbook. + +### chef_client_updater + +Installs the mixlib-install/mixlib-install gems and upgrades the chef-client. + +#### properties + +- `channel` - The chef channel you fetch the chef client from. `stable` contains all officially released chef-client builds where as `current` contains unreleased builds. Default: `stable` +- `prevent_downgrade` - Don't allow this cookbook to downgrade the chef-client version. Default: true +- `version` - The version of the chef-client to install. Default :latest +- `post_install_action` - After installing the chef-client what should we do. `exec` to exec the new client or `kill` to kill the client and rely on the init system to start up the new version. Default: `exec` +- `exec_command` - The chef-client command. default: $PROGRAM_NAME.split(' ').first +- `exec_args` - An array of arguments to exec the chef-client with. default: ARGV + +#### examples + +```ruby +chef_client_updater 'Install latest' +``` + +```ruby +chef_client_updater 'Install 12.13.36 and kill' do + version '12.13.36' + post_install_action 'kill' +end +``` + +## License & Authors + +- Author: Tim Smith ([tsmith@chef.io](mailto:tsmith@chef.io)) + +```text +Copyright:: 2016-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. +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_client_updater/attributes/default.rb b/cookbooks/chef_client_updater/attributes/default.rb new file mode 100644 index 0000000..9ff102d --- /dev/null +++ b/cookbooks/chef_client_updater/attributes/default.rb @@ -0,0 +1,29 @@ +# +# Cookbook:: chef_client_updater +# Attributes:: default +# +# Copyright:: 2016-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. +# 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. + +# stable or current channel +default['chef_client_updater']['channel'] = 'stable' + +# prevent a newer client "updating" to an older client +default['chef_client_updater']['prevent_downgrade'] = true + +# the version to install (ex: '12.12.13') or 'latest' +default['chef_client_updater']['version'] = 'latest' + +# kill the client post install or exec the client post install for non-service based installs +default['chef_client_updater']['post_install_action'] = 'kill' diff --git a/cookbooks/chef_client_updater/libraries/matchers.rb b/cookbooks/chef_client_updater/libraries/matchers.rb new file mode 100644 index 0000000..c1f2766 --- /dev/null +++ b/cookbooks/chef_client_updater/libraries/matchers.rb @@ -0,0 +1,7 @@ +if defined?(ChefSpec) + ChefSpec.define_matcher(:chef_client_updater) + + def update_chef_client_updater(resource_name) + ChefSpec::Matchers::ResourceMatcher.new(:chef_client_updater, :update, resource_name) + end +end diff --git a/cookbooks/chef_client_updater/metadata.json b/cookbooks/chef_client_updater/metadata.json new file mode 100644 index 0000000..6237129 --- /dev/null +++ b/cookbooks/chef_client_updater/metadata.json @@ -0,0 +1 @@ +{"name":"chef_client_updater","version":"1.0.2","description":"Upgrades chef-client to specified releases","long_description":"Upgrades chef-client to specified releases","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","aix":">= 0.0.0"},"dependencies":{"compat_resource":">= 12.16.3"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{},"source_url":"https://github.com/chef-cookbooks/chef_client_updater","issues_url":"https://github.com/chef-cookbooks/chef_client_updater/issues","chef_version":[[">= 12.1"]],"ohai_version":[]} \ No newline at end of file diff --git a/cookbooks/omnibus_updater/libraries/omnibus_checker.rb b/cookbooks/chef_client_updater/recipes/default.rb similarity index 51% rename from cookbooks/omnibus_updater/libraries/omnibus_checker.rb rename to cookbooks/chef_client_updater/recipes/default.rb index 23cf860..c900dc7 100644 --- a/cookbooks/omnibus_updater/libraries/omnibus_checker.rb +++ b/cookbooks/chef_client_updater/recipes/default.rb @@ -1,30 +1,25 @@ # -# Cookbook:: omnibus_updater -# Library:: omnibuschecker +# Author:: Tim Smith () +# Cookbook:: chef_client_updater +# Recipe:: default # -# Copyright:: 2014-2017, Heavy Water Ops, LLC +# Copyright:: 2016-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. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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 OmnibusChecker - def is_omnibus? - Gem.bindir =~ %r{/opt/(opscode|chef)/} - end -end - -OmnibusChecker.send(:extend, OmnibusChecker) - -unless Chef::Recipe.instance_methods.include?(:is_omnibus?) - Chef::Recipe.send(:include, OmnibusChecker) +chef_client_updater 'update chef-client' do + channel node['chef_client_updater']['channel'] + version node['chef_client_updater']['version'] + prevent_downgrade node['chef_client_updater']['prevent_downgrade'] + post_install_action node['chef_client_updater']['post_install_action'] end diff --git a/cookbooks/chef_client_updater/resources/updater.rb b/cookbooks/chef_client_updater/resources/updater.rb new file mode 100644 index 0000000..c75bb24 --- /dev/null +++ b/cookbooks/chef_client_updater/resources/updater.rb @@ -0,0 +1,136 @@ +# +# Cookbook:: chef_client_updater +# Resource:: updater +# +# Copyright:: 2016-2017, Will Jordan +# Copyright:: 2016-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. +# 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 'chef_client_updater' + +property :channel, [String, Symbol], default: :stable +property :prevent_downgrade, [true, false], default: false +property :version, [String, Symbol], default: :latest +property :post_install_action, String, default: 'exec' +property :exec_command, String, default: $PROGRAM_NAME.split(' ').first +property :exec_args, Array, default: ARGV + +action :update do + if update_necessary? # ~FC023 + converge_by "Upgraded chef-client #{current_version} to #{desired_version}" do + upgrade_command = Mixlib::ShellOut.new(mixlib_install.install_command) + upgrade_command.run_command + run_post_install_action + end + end +end + +action_class.class_eval do + def load_mixlib_install + require 'mixlib/install' + rescue LoadError + Chef::Log.info('mixlib-install gem not found. Installing now') + chef_gem 'mixlib-install' do + compile_time true if respond_to?(:compile_time) + end + + require 'mixlib/install' + end + + def load_mixlib_versioning + require 'mixlib/versioning' + rescue LoadError + Chef::Log.info('mixlib-versioning gem not found. Installing now') + chef_gem 'mixlib-versioning' do + compile_time true if respond_to?(:compile_time) + end + + require 'mixlib/versioning' + end + + def mixlib_install + load_mixlib_install + options = { + product_name: 'chef', + platform_version_compatibility_mode: true, + channel: new_resource.channel.to_sym, + product_version: new_resource.version == 'latest' ? :latest : new_resource.version, + + } + Mixlib::Install.new(options) + end + + # why would we use this when mixlib-install has a current_version method? + # well mixlib-version parses the manifest JSON, which might not be there. + # ohai handles this better IMO + def current_version + node['chef_packages']['chef']['version'] + end + + def desired_version + new_resource.version == 'latest' ? mixlib_install.available_versions.last : new_resource.version + end + + # why wouldn't we use the built in update_available? method in mixlib-install? + # well that would use current_version from mixlib-install and it has no + # concept or preventing downgrades + def update_necessary? + load_mixlib_versioning + cur_version = Mixlib::Versioning.parse(current_version) + des_version = Mixlib::Versioning.parse(desired_version) + new_resource.prevent_downgrade ? (des_version > cur_version) : (des_version != cur_version) + end + + def eval_post_install_action + return unless new_resource.post_install_action == 'exec' + + if Chef::Config[:interval] + Chef::Log.warn 'post_install_action "exec" not supported for long-running client process -- changing to "kill".' + new_resource.post_install_action = 'kill' + end + + return if Process.respond_to?(:exec) + Chef::Log.warn 'post_install_action Process.exec not available -- changing to "kill".' + new_resource.post_install_action = 'kill' + end + + def run_post_install_action + # make sure the passed action will actually work + eval_post_install_action + + case new_resource.post_install_action + when 'exec' + if Chef::Config[:local_mode] + Chef::Log.info 'Shutting down local-mode server.' + if Chef::Application.respond_to?(:destroy_server_connectivity) + Chef::Application.destroy_server_connectivity + elsif defined?(Chef::LocalMode) && Chef::LocalMode.respond_to?(:destroy_server_connectivity) + Chef::LocalMode.destroy_server_connectivity + end + end + Chef::Log.warn 'Replacing ourselves with the new version of Chef to continue the run.' + Kernel.exec(new_resource.exec_command, *new_resource.exec_args) + when 'kill' + if Chef::Config[:client_fork] && Process.ppid != 1 + Chef::Log.warn 'Chef client is defined for forked runs. Sending TERM to parent process!' + Process.kill('TERM', Process.ppid) + end + Chef::Log.warn 'New chef-client installed. Forcing chef exit!' + exit(213) + else + raise "Unexpected post_install_action behavior: #{new_resource.post_install_action}" + end + end +end diff --git a/cookbooks/omnibus_updater/CHANGELOG.md b/cookbooks/omnibus_updater/CHANGELOG.md deleted file mode 100644 index c0d5196..0000000 --- a/cookbooks/omnibus_updater/CHANGELOG.md +++ /dev/null @@ -1,149 +0,0 @@ -# omnibus_updater Cookbook CHANGELOG - -This file is used to list changes made in each version of the omnibus_updater cookbook. - -## 3.0.2 (2017-03-07) - -- Fix version detection for macOS systems -- Test with Local Delivery instead of Rake - -## 3.0.1 (2017-01-05) - -- Remove the remaining system gem reference - -## 3.0.0 (2017-01-05) - -- 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 - -## 2.0.0 (2016-08-19) - -- Hard fail on unsupported platforms now -- Add suse support -- Add additional chefspec tests - -## 1.2.1 (2016-08-19) - -- 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 - -## 1.2.0 (2016-08-18) - -- 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 - -# v1.1.0 - -- 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. - -# 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/README.md b/cookbooks/omnibus_updater/README.md deleted file mode 100644 index 5c08a6d..0000000 --- a/cookbooks/omnibus_updater/README.md +++ /dev/null @@ -1,101 +0,0 @@ -# omnibus_updater cookbook - -[![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) - -This cookbook allows you to upgrade the omnibus based Chef install package via Chef. You can run either latest or pin to specific version. - -## Requirements - -### Platforms - -- 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.. - -```ruby -override_attributes( - :omnibus_updater => { - :version => '11.4.0' - } -) -``` - -## Features - -### 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 -``` - -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: - -## Restart chef-client Service - -Use the `restart_chef_service` attribute to restart chef-client if you have it running as a service. - -### Prerelease - -Prereleases can be installed via the auto-installation using `prerelease` attribute. - -### 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. - -### 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. - -## License & Authors - -- 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 deleted file mode 100644 index 2d1ebc4..0000000 --- a/cookbooks/omnibus_updater/attributes/default.rb +++ /dev/null @@ -1,32 +0,0 @@ -# -# Cookbook:: omnibus_updater -# Attributes:: default -# -# 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. -# 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. -# - -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/omnitrucker.rb b/cookbooks/omnibus_updater/libraries/omnitrucker.rb deleted file mode 100644 index e8d9247..0000000 --- a/cookbooks/omnibus_updater/libraries/omnitrucker.rb +++ /dev/null @@ -1,102 +0,0 @@ -# -# Cookbook:: omnibus_updater -# Library:: omnitrucker -# -# 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. -# 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/rest' -require 'chef/mash' -require 'net/http' - -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 - }.freeze unless defined?(URL_MAP) - - def build_url(*opts) - args = node = nil - opts.each do |o| - if o.is_a?(Hash) - args = o - elsif o.is_a?(Chef::Node) - node = o - else - raise ArgumentError.new "Provided argument is not allowed: #{o.class}" - end - end - args ||= {} - 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? - end.compact - "#{url}?#{u_args.join('&')}" - end - - def collect_attributes(node, args = {}) - set = Chef::Mash[ - %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: 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'] } - end - @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) - 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 - 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 - 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 deleted file mode 100644 index 2455d5e..0000000 --- a/cookbooks/omnibus_updater/metadata.json +++ /dev/null @@ -1 +0,0 @@ -{"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/recipes/default.rb b/cookbooks/omnibus_updater/recipes/default.rb deleted file mode 100644 index 96b13cd..0000000 --- a/cookbooks/omnibus_updater/recipes/default.rb +++ /dev/null @@ -1,31 +0,0 @@ -# -# Cookbook:: omnibus_updater -# Recipe:: default -# -# 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. -# 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. -# - -# 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' -else - include_recipe 'omnibus_updater::downloader' - include_recipe 'omnibus_updater::installer' -end diff --git a/cookbooks/omnibus_updater/recipes/downloader.rb b/cookbooks/omnibus_updater/recipes/downloader.rb deleted file mode 100644 index 8645dc8..0000000 --- a/cookbooks/omnibus_updater/recipes/downloader.rb +++ /dev/null @@ -1,77 +0,0 @@ -# -# Cookbook:: omnibus_updater -# Recipe:: downloader -# -# 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. -# 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 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'] -else - 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 - ) - raise 'Could not construct URL for chef-download' if remote_path.nil? -end - -if remote_path - node.normal['omnibus_updater']['full_url'] = remote_path - - 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)) - source remote_path - backup false - checksum node['omnibus_updater']['checksum'] if node['omnibus_updater']['checksum'] - action :create_if_missing - only_if do - 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'] - # 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') - Chef::Log.debug "Omnibus Updater remote path: #{remote_path}" - true - 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 - # default is to install if the versions don't match - Chef::VERSION != version.to_s.sub(/\-.+$/, '') - end - end - end -else - Chef::Log.warn 'Failed to retrieve omnibus download URL' -end - -include_recipe 'omnibus_updater::old_package_cleaner' diff --git a/cookbooks/omnibus_updater/recipes/installer.rb b/cookbooks/omnibus_updater/recipes/installer.rb deleted file mode 100644 index d509d91..0000000 --- a/cookbooks/omnibus_updater/recipes/installer.rb +++ /dev/null @@ -1,124 +0,0 @@ -# -# Cookbook:: omnibus_updater -# Recipe:: installer -# -# 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. -# 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. -# - -include_recipe 'omnibus_updater' -remote_path = node['omnibus_updater']['full_url'] - -service 'chef-client-omnibus' do - service_name 'chef-client' - supports status: true, restart: true - action :nothing -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 - - # clean up previous upgrades - directory 'c:/opscode/chef.upgrade' do - action :delete - recursive true - end - - 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 deleted file mode 100644 index 8c7ed04..0000000 --- a/cookbooks/omnibus_updater/recipes/old_package_cleaner.rb +++ /dev/null @@ -1,34 +0,0 @@ -# -# Cookbook:: omnibus_updater -# Recipe:: old_package_cleaner -# -# 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. -# 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. -# - -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|msi|dmg)$/).empty? - end - else - [] - end - -old_pkgs.each do |filename| - file filename do - action :delete - backup 1 - end -end diff --git a/site-cookbooks/kosmos-base/metadata.rb b/site-cookbooks/kosmos-base/metadata.rb index 88981e4..8e275f9 100644 --- a/site-cookbooks/kosmos-base/metadata.rb +++ b/site-cookbooks/kosmos-base/metadata.rb @@ -12,5 +12,5 @@ depends 'sudo' depends 'kosmos-postfix' depends 'hostname' depends 'firewall' -depends 'omnibus_updater' +depends 'chef_client_updater' depends 'timezone-ii' diff --git a/site-cookbooks/kosmos-base/recipes/default.rb b/site-cookbooks/kosmos-base/recipes/default.rb index b6d7484..168b85e 100644 --- a/site-cookbooks/kosmos-base/recipes/default.rb +++ b/site-cookbooks/kosmos-base/recipes/default.rb @@ -9,9 +9,11 @@ include_recipe 'timezone-ii' -node.override['omnibus_updater']['version'] = '12.19.36' -node.override['omnibus_updater']['kill_chef_on_upgrade'] = false -include_recipe 'omnibus_updater' +# Update chef to the chosen version +chef_version = '12.19.36' +chef_client_updater "Install #{chef_version}" do + version chef_version +end package 'mailutils' node.override['unattended-upgrades']['admin_email'] = 'ops@5apps.com' From 180b3f5df06f2c870cd7a2acf31826b76e53ca0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Tue, 2 May 2017 11:56:29 +0200 Subject: [PATCH 41/83] Update ark cookbook --- Batali | 2 +- batali.manifest | 26 +- cookbooks/ark/.foodcritic | 1 + cookbooks/ark/CHANGELOG.md | 5 + cookbooks/ark/README.md | 8 +- cookbooks/ark/attributes/default.rb | 2 +- cookbooks/ark/metadata.json | 2 +- cookbooks/ark/providers/default.rb | 503 ------------------------- cookbooks/ark/recipes/default.rb | 4 +- cookbooks/ark/resources/default.rb | 556 +++++++++++++++++++++++++--- 10 files changed, 535 insertions(+), 574 deletions(-) create mode 100644 cookbooks/ark/.foodcritic delete mode 100644 cookbooks/ark/providers/default.rb diff --git a/Batali b/Batali index c96ff4e..ab145b8 100644 --- a/Batali +++ b/Batali @@ -35,7 +35,7 @@ Batali.define do cookbook 'chef_client_updater', '~> 1.0.2' cookbook 'timezone-ii' cookbook 'nodejs', '~> 3.0.0' - cookbook 'ark' + cookbook 'ark', '~> 3.0.0' cookbook 'logrotate' cookbook 'openssl', '~> 7.0.1' end diff --git a/batali.manifest b/batali.manifest index 9a481f2..1f3226a 100644 --- a/batali.manifest +++ b/batali.manifest @@ -1035,6 +1035,18 @@ "version": "3.0.0" } }, + { + "name": "homebrew", + "dependencies": [ + + ], + "version": "3.0.0", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/homebrew/versions/3.0.0/download", + "version": "3.0.0" + } + }, { "name": "ark", "dependencies": [ @@ -1050,23 +1062,11 @@ "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": "homebrew", - "dependencies": [ - ], "version": "3.0.0", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/homebrew/versions/3.0.0/download", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/ark/versions/3.0.0/download", "version": "3.0.0" } }, diff --git a/cookbooks/ark/.foodcritic b/cookbooks/ark/.foodcritic new file mode 100644 index 0000000..b9f8767 --- /dev/null +++ b/cookbooks/ark/.foodcritic @@ -0,0 +1 @@ +~FC016 diff --git a/cookbooks/ark/CHANGELOG.md b/cookbooks/ark/CHANGELOG.md index 41b3e54..f10ff09 100644 --- a/cookbooks/ark/CHANGELOG.md +++ b/cookbooks/ark/CHANGELOG.md @@ -2,6 +2,11 @@ This file is used to list changes made in each version of the ark cookbook. +## 3.0.0 (2017-04-05) +- Rewrite of resource to custom resources. +- Remove EOL platforms from testing. +- Update zlib URL +- ## 2.2.1 (2016-12-16) - Use Ohai root_group attribute to avoid trying to set the group to root on BSD/macOS. - Add missing accessor for owner property diff --git a/cookbooks/ark/README.md b/cookbooks/ark/README.md index ac467c1..5b05216 100644 --- a/cookbooks/ark/README.md +++ b/cookbooks/ark/README.md @@ -16,7 +16,7 @@ ark 'pig' do end ``` -The provider will: +The `ark` resource will: - fetch it to to `/var/cache/chef/` - unpack it to the default path (`/usr/local/pig-0.8.0`) @@ -44,7 +44,7 @@ Should work on common Unix/Linux systems with typical userland utilities like ta ### Chef -- Chef 12.1+ +- Chef 12.5+ ### Cookbooks @@ -66,7 +66,7 @@ Customize the attributes to suit site specific conventions and defaults. ## Resources -- `ark` - does the extract/build/configure dance +- `ark` - does the extract/build/configure ### Actions @@ -281,7 +281,7 @@ You can also supply the file extension in case the file extension can not be det - Copyright: 2011, Philip (flip) Kromer - Infochimps, Inc - Copyright: 2012, Bryan W. Berry - Copyright: 2012, Denis Barishev -- Copyright: 2013-2016, Chef Software, Inc +- Copyright: 2013-2017, Chef Software, Inc - Copyright: 2014, Bloomberg L.P. ``` diff --git a/cookbooks/ark/attributes/default.rb b/cookbooks/ark/attributes/default.rb index 0f44dbd..0767723 100644 --- a/cookbooks/ark/attributes/default.rb +++ b/cookbooks/ark/attributes/default.rb @@ -1,5 +1,5 @@ # -# Cookbook Name:: ark +# Cookbook:: ark # Attributes:: default # # diff --git a/cookbooks/ark/metadata.json b/cookbooks/ark/metadata.json index d3ba1cf..7746bfc 100644 --- a/cookbooks/ark/metadata.json +++ b/cookbooks/ark/metadata.json @@ -1 +1 @@ -{"name":"ark","version":"2.2.1","description":"Provides a custom resource for installing runtime artifacts in a predictable fashion","long_description":"# ark cookbook\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/ark.svg?branch=master)](https://travis-ci.org/chef-cookbooks/ark) [![Cookbook Version](https://img.shields.io/cookbook/v/ark.svg)](https://supermarket.chef.io/cookbooks/ark)\n\n## Overview\n\nThis cookbook provides `ark`, a resource for managing software archives. It manages the fetch-unpack-configure-build-install process common to installing software from source, or from binary distributions that are not fully fledged OS packages.\n\nThis cookbook started its life as a modified version of Infochimp's install_from cookbook. It has since been heavily refactored and extended to meet different use cases.\n\nGiven a simple project archive available at a url:\n\n```ruby\nark 'pig' do\n url 'http://apache.org/pig/pig-0.8.0.tar.gz'\nend\n```\n\nThe provider will:\n\n- fetch it to to `/var/cache/chef/`\n- unpack it to the default path (`/usr/local/pig-0.8.0`)\n- create a symlink for `:home_dir` (`/usr/local/pig`) pointing to path\n- add specified binary commands to the environment `PATH` variable\n\nBy default, the ark will not run again if the `:path` is not empty. Ark provides many actions to accommodate different use cases, such as `:dump`, `:cherry_pick`, `:put`, and `:install_with_make`.\n\nAt this time ark only handles files available from URLs using the [remote_file](http://docs.chef.io/resource_remote_file.html) provider. It does handle local files using the `file://` protocol.\n\n## Requirements\n\n### Platforms\n\n- Debian/Ubuntu\n- RHEL/CentOS/Scientific/Oracle\n- Fedora\n- FreeBSD\n- SmartOS\n- Mac OS X\n- openSUSE / SUSE Linux Enterprises\n- Windows\n\nShould work on common Unix/Linux systems with typical userland utilities like tar, gzip, etc. May require the installation of build tools for compiling from source, but that installation is outside the scope of this cookbook.\n\n### Chef\n\n- Chef 12.1+\n\n### Cookbooks\n\n- build-essential\n- seven_zip\n- windows\n\n## Attributes\n\nCustomize the attributes to suit site specific conventions and defaults.\n\n- `node['ark']['apache_mirror']` - if the URL is an apache mirror, use the attribute as the default. default: `http://apache.mirrors.tds.net`\n- `node['ark']['prefix_root']` - default base location if the `prefix_root` is not passed into the resource. default: `/usr/local`\n- `node['ark']['prefix_bin']` - default binary location if the `prefix_bin` is not passed into the resource. default: `/usr/local/bin`\n- `node['ark']['prefix_home']` - default home location if the `prefix_home` is not passed into the resource. default: `/usr/local`\n- `node['ark']['package_dependencies']` - prerequisite system packages that need to be installed to support ark. default: varies based on platform\n- `node['ark']['tar']` - allows overriding the default path to the tar binary, which varies based on platform\n- `node['ark']['sevenzip_binary']` - allows overriding the default path to the 7zip binary, which is determined based on registry key value\n\n## Resources\n\n- `ark` - does the extract/build/configure dance\n\n### Actions\n\n- `:install`: extracts the file and creates a 'friendly' symbolic link to the extracted directory path\n- `:configure`: configure ahead of the install action\n- `:install_with_make`: extracts the archive to a path, runs `configure`, `make`, and `make install`.\n- `:dump`: strips all directories from the archive and dumps the contained files into a specified path\n- `:cherry_pick`: extract a specified file from an archive and places in specified path\n- `:put`: extract the archive to a specified path, does not create any symbolic links\n- `:remove`: removes the extracted directory and related symlink #TODO\n- `:setup_py`: runs the command \"python setup.py\" in the extracted directory\n- `:setup_py_build`: runs the command \"python setup.py build\" in the extracted directory\n- `:setup_py_install`: runs the command \"python setup.py install\" in the extracted directory\n\n### :cherry_pick\n\nExtract a specified file from an archive and places in specified path.\n\n#### Relevant Attribute Parameters for :cherry_pick\n\n- `path`: directory to place file in.\n- `creates`: specific file to cherry-pick.\n\n### :dump\n\nStrips all directories from the archive and dumps the contained files into a specified path.\n\nNOTE: This currently only works for zip archives\n\n#### Attribute Parameters for :dump\n\n- `path`: path to dump files to.\n- `mode`: file mode for `app_home`, as an integer.\n\n - Example: `0775`\n\n- `creates`: if you are appending files to a given directory, ark needs a condition to test whether the file has already been extracted. You can specify with creates, a file whose existence indicates the ark has previously been extracted and does not need to be extracted again.\n\n### :put\n\nExtract the archive to a specified path, does not create any symbolic links.\n\n#### Attribute Parameters for :put\n\n- `path`: path to extract to.\n\n - Default: `/usr/local`\n\n- `append_env_path`: boolean, if true, append the `./bin` directory of the extracted directory to the global `PATH` variable for all users.\n\n### Attribute Parameters\n\n- `name`: name of the package, defaults to the resource name.\n- `url`: url for tarball, `.tar.gz`, `.bin` (oracle-specific), `.war`, and `.zip` currently supported. Also supports special syntax\n- `:name:version:apache_mirror:` that will auto-magically construct download url from the apache mirrors site.\n- `version`: software version, defaults to `1`.\n- `mode`: file mode for `app_home`, is an integer.\n- `prefix_root`: default `prefix_root`, for use with `:install*` actions.\n- `prefix_home`: default directory prefix for a friendly symlink to the path.\n\n - Example: `/usr/local/maven` -> `/usr/local/maven-2.2.1`\n\n- `prefix_bin`: default directory to place a symlink to a binary command.\n\n - Example: `/opt/bin/mvn` -> `/opt/maven-2.2.1/bin/mvn`, where the `prefix_bin` is `/opt/bin`\n\n- `path`: path to extract the ark to. The `:install*` actions overwrite any user-provided values for `:path`.\n\n - Default: `/usr/local/-` for the `:install`, `:install_with_make` actions\n\n- `home_dir`: symbolic link to the path `:prefix_root/:name-:version`, does not apply to `:dump`, `:put`, or `:cherry_pick` actions.\n\n - Default: `:prefix_root/:name`\n\n- `has_binaries`: array of binary commands to symlink into `/usr/local/bin/`, you must specify the relative path.\n\n - Example: `[ 'bin/java', 'bin/javaws' ]`\n\n- `append_env_path`: boolean, similar to `has_binaries` but less granular. If true, append the `./bin` directory of the extracted directory to. the `PATH` environment variable for all users, by placing a file in `/etc/profile.d/`. The commands are symbolically linked into `/usr/bin/*`. This option provides more granularity than the boolean option.\n\n - Example: `mvn`, `java`, `javac`, etc.\n\n- `environment`: hash of environment variables to pass to invoked shell commands like `tar`, `unzip`, `configure`, and `make`.\n\n- `strip_components`: number of components in path to strip when extracting archive. With default value of `1`, ark strips the leading directory from an archive, which is the default for both `unzip` and `tar` commands.\n\n- `autoconf_opts`: an array of command line options for use with the GNU `autoconf` script.\n\n - Example: `[ '--include=/opt/local/include', '--force' ]`\n\n- `make_opts`: an array of command line options for use with `make`.\n\n - Example: `[ '--warn-undefined-variables', '--load-average=2' ]`\n\n- `owner`: owner of extracted directory.\n\n - Default: `root`\n\n- `group`: group of extracted directory.\n\n - Default: `root`\n\n- `backup`: The number of backups to be kept in /var/chef/backup (for UNIX- and Linux-based platforms) or C:/chef/backup (for the Microsoft Windows platform). Set to false to prevent backups from being kept.\n\n - Default: `5`\n\n#### Examples\n\nThis example copies `ivy.tar.gz` to `/var/cache/chef/ivy-2.2.0.tar.gz`, unpacks its contents to `/usr/local/ivy-2.2.0/` -- stripping the leading directory, and symlinks `/usr/local/ivy` to `/usr/local/ivy-2.2.0`\n\n```ruby\n # install Apache Ivy dependency resolution tool\n ark \"ivy\" do\n url 'http://someurl.example.com/ivy.tar.gz'\n version '2.2.0'\n checksum '89ba5fde0c596db388c3bbd265b63007a9cc3df3a8e6d79a46780c1a39408cb5'\n action :install\n end\n```\n\nThis example copies `jdk-7u2-linux-x64.tar.gz` to `/var/cache/chef/jdk-7.2.tar.gz`, unpacks its contents to `/usr/local/jvm/jdk-7.2/` -- stripping the leading directory, symlinks `/usr/local/jvm/default` to `/usr/local/jvm/jdk-7.2`, and adds `/usr/local/jvm/jdk-7.2/bin/` to the global `PATH` for all users. The user 'foobar' is the owner of the `/usr/local/jvm/jdk-7.2` directory:\n\n```ruby\n ark 'jdk' do\n url 'http://download.example.com/jdk-7u2-linux-x64.tar.gz'\n version '7.2'\n path \"/usr/local/jvm/\"\n home_dir \"/usr/local/jvm/default\"\n checksum '89ba5fde0c596db388c3bbd265b63007a9cc3df3a8e6d79a46780c1a39408cb5'\n append_env_path true\n owner 'foobar'\n end\n```\n\nInstall Apache Ivy dependency resolution tool in `/resource_name` in this case `/usr/local/ivy`, do not symlink, and strip any leading directory if one exists in the tarball:\n\n```ruby\n ark \"ivy\" do\n url 'http://someurl.example.com/ivy.tar.gz'\n checksum '89ba5fde0c596db388c3bbd265b63007a9cc3df3a8e6d79a46780c1a39408cb5'\n action :put\n end\n```\n\nInstall Apache Ivy dependency resolution tool in `/home/foobar/ivy`, strip any leading directory if one exists, don't keep backup copies of `ivy.tar.gz`:\n\n```ruby\n ark \"ivy\" do\n path \"/home/foobar\"\n url 'http://someurl.example.com/ivy.tar.gz'\n checksum '89ba5fde0c596db388c3bbd265b63007a9cc3df3a8e6d79a46780c1a39408cb5'\n action :put\n backup false\n end\n```\n\nStrip all directories and dump files into path specified by the path attribute. You must specify the `creates` attribute in order to keep the extraction from running every time. The directory path will be created if it doesn't already exist:\n\n```ruby\n ark \"my_jars\" do\n url \"http://example.com/bunch_of_jars.zip\"\n path \"/usr/local/tomcat/lib\"\n creates \"mysql.jar\"\n owner \"tomcat\"\n action :dump\n end\n```\n\nExtract specific files from a tarball (currently only handles one named file):\n\n```ruby\n ark 'mysql-connector-java' do\n url 'http://oracle.com/mysql-connector.zip'\n creates 'mysql-connector-java-5.0.8-bin.jar'\n path '/usr/local/tomcat/lib'\n action :cherry_pick\n end\n```\n\nBuild and install haproxy and use alternative values for `prefix_root`, `prefix_home`, and `prefix_bin`:\n\n```ruby\n ark \"haproxy\" do\n url \"http://haproxy.1wt.eu/download/1.5/src/snapshot/haproxy-ss-20120403.tar.gz\"\n version \"1.5\"\n checksum 'ba0424bf7d23b3a607ee24bbb855bb0ea347d7ffde0bec0cb12a89623cbaf911'\n make_opts [ 'TARGET=linux26' ]\n prefix_root '/opt'\n prefix_home '/opt'\n prefix_bin '/opt/bin'\n action :install_with_make\n end\n```\n\nYou can also supply the file extension in case the file extension can not be determined by the URL:\n\n```ruby\n ark \"test_autogen\" do\n url 'https://github.com/zeromq/libzmq/tarball/master'\n extension \"tar.gz\"\n action :install_with_make\n end\n```\n\n## License & Authors\n\n- Author: Philip (flip) Kromer - Infochimps, Inc([coders@infochimps.com](mailto:coders@infochimps.com))\n- Author: Bryan W. Berry ([bryan.berry@gmail.com](mailto:bryan.berry@gmail.com))\n- Author: Denis Barishev ([denis.barishev@gmail.com](mailto:denis.barishev@gmail.com))\n- Author: Sean OMeara ([someara@chef.io](mailto:someara@chef.io))\n- Author: John Bellone ([jbellone@bloomberg.net](mailto:jbellone@bloomberg.net))\n- Copyright: 2011, Philip (flip) Kromer - Infochimps, Inc\n- Copyright: 2012, Bryan W. Berry\n- Copyright: 2012, Denis Barishev\n- Copyright: 2013-2016, Chef Software, Inc\n- Copyright: 2014, Bloomberg L.P.\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","suse":">= 0.0.0","opensuse":">= 0.0.0","opensuseleap":">= 0.0.0","scientific":">= 0.0.0","oracle":">= 0.0.0","amazon":">= 0.0.0","windows":">= 0.0.0","mac_os_x":">= 0.0.0","smartos":">= 0.0.0","freebsd":">= 0.0.0"},"dependencies":{"build-essential":">= 0.0.0","windows":">= 0.0.0","seven_zip":">= 0.0.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{"ark::default":"Installs packages needed by the custom resource"}} \ No newline at end of file +{"name":"ark","version":"3.0.0","description":"Provides a custom resource for installing runtime artifacts in a predictable fashion","long_description":"# ark cookbook\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/ark.svg?branch=master)](https://travis-ci.org/chef-cookbooks/ark) [![Cookbook Version](https://img.shields.io/cookbook/v/ark.svg)](https://supermarket.chef.io/cookbooks/ark)\n\n## Overview\n\nThis cookbook provides `ark`, a resource for managing software archives. It manages the fetch-unpack-configure-build-install process common to installing software from source, or from binary distributions that are not fully fledged OS packages.\n\nThis cookbook started its life as a modified version of Infochimp's install_from cookbook. It has since been heavily refactored and extended to meet different use cases.\n\nGiven a simple project archive available at a url:\n\n```ruby\nark 'pig' do\n url 'http://apache.org/pig/pig-0.8.0.tar.gz'\nend\n```\n\nThe `ark` resource will:\n\n- fetch it to to `/var/cache/chef/`\n- unpack it to the default path (`/usr/local/pig-0.8.0`)\n- create a symlink for `:home_dir` (`/usr/local/pig`) pointing to path\n- add specified binary commands to the environment `PATH` variable\n\nBy default, the ark will not run again if the `:path` is not empty. Ark provides many actions to accommodate different use cases, such as `:dump`, `:cherry_pick`, `:put`, and `:install_with_make`.\n\nAt this time ark only handles files available from URLs using the [remote_file](http://docs.chef.io/resource_remote_file.html) provider. It does handle local files using the `file://` protocol.\n\n## Requirements\n\n### Platforms\n\n- Debian/Ubuntu\n- RHEL/CentOS/Scientific/Oracle\n- Fedora\n- FreeBSD\n- SmartOS\n- Mac OS X\n- openSUSE / SUSE Linux Enterprises\n- Windows\n\nShould work on common Unix/Linux systems with typical userland utilities like tar, gzip, etc. May require the installation of build tools for compiling from source, but that installation is outside the scope of this cookbook.\n\n### Chef\n\n- Chef 12.5+\n\n### Cookbooks\n\n- build-essential\n- seven_zip\n- windows\n\n## Attributes\n\nCustomize the attributes to suit site specific conventions and defaults.\n\n- `node['ark']['apache_mirror']` - if the URL is an apache mirror, use the attribute as the default. default: `http://apache.mirrors.tds.net`\n- `node['ark']['prefix_root']` - default base location if the `prefix_root` is not passed into the resource. default: `/usr/local`\n- `node['ark']['prefix_bin']` - default binary location if the `prefix_bin` is not passed into the resource. default: `/usr/local/bin`\n- `node['ark']['prefix_home']` - default home location if the `prefix_home` is not passed into the resource. default: `/usr/local`\n- `node['ark']['package_dependencies']` - prerequisite system packages that need to be installed to support ark. default: varies based on platform\n- `node['ark']['tar']` - allows overriding the default path to the tar binary, which varies based on platform\n- `node['ark']['sevenzip_binary']` - allows overriding the default path to the 7zip binary, which is determined based on registry key value\n\n## Resources\n\n- `ark` - does the extract/build/configure \n\n### Actions\n\n- `:install`: extracts the file and creates a 'friendly' symbolic link to the extracted directory path\n- `:configure`: configure ahead of the install action\n- `:install_with_make`: extracts the archive to a path, runs `configure`, `make`, and `make install`.\n- `:dump`: strips all directories from the archive and dumps the contained files into a specified path\n- `:cherry_pick`: extract a specified file from an archive and places in specified path\n- `:put`: extract the archive to a specified path, does not create any symbolic links\n- `:remove`: removes the extracted directory and related symlink #TODO\n- `:setup_py`: runs the command \"python setup.py\" in the extracted directory\n- `:setup_py_build`: runs the command \"python setup.py build\" in the extracted directory\n- `:setup_py_install`: runs the command \"python setup.py install\" in the extracted directory\n\n### :cherry_pick\n\nExtract a specified file from an archive and places in specified path.\n\n#### Relevant Attribute Parameters for :cherry_pick\n\n- `path`: directory to place file in.\n- `creates`: specific file to cherry-pick.\n\n### :dump\n\nStrips all directories from the archive and dumps the contained files into a specified path.\n\nNOTE: This currently only works for zip archives\n\n#### Attribute Parameters for :dump\n\n- `path`: path to dump files to.\n- `mode`: file mode for `app_home`, as an integer.\n\n - Example: `0775`\n\n- `creates`: if you are appending files to a given directory, ark needs a condition to test whether the file has already been extracted. You can specify with creates, a file whose existence indicates the ark has previously been extracted and does not need to be extracted again.\n\n### :put\n\nExtract the archive to a specified path, does not create any symbolic links.\n\n#### Attribute Parameters for :put\n\n- `path`: path to extract to.\n\n - Default: `/usr/local`\n\n- `append_env_path`: boolean, if true, append the `./bin` directory of the extracted directory to the global `PATH` variable for all users.\n\n### Attribute Parameters\n\n- `name`: name of the package, defaults to the resource name.\n- `url`: url for tarball, `.tar.gz`, `.bin` (oracle-specific), `.war`, and `.zip` currently supported. Also supports special syntax\n- `:name:version:apache_mirror:` that will auto-magically construct download url from the apache mirrors site.\n- `version`: software version, defaults to `1`.\n- `mode`: file mode for `app_home`, is an integer.\n- `prefix_root`: default `prefix_root`, for use with `:install*` actions.\n- `prefix_home`: default directory prefix for a friendly symlink to the path.\n\n - Example: `/usr/local/maven` -> `/usr/local/maven-2.2.1`\n\n- `prefix_bin`: default directory to place a symlink to a binary command.\n\n - Example: `/opt/bin/mvn` -> `/opt/maven-2.2.1/bin/mvn`, where the `prefix_bin` is `/opt/bin`\n\n- `path`: path to extract the ark to. The `:install*` actions overwrite any user-provided values for `:path`.\n\n - Default: `/usr/local/-` for the `:install`, `:install_with_make` actions\n\n- `home_dir`: symbolic link to the path `:prefix_root/:name-:version`, does not apply to `:dump`, `:put`, or `:cherry_pick` actions.\n\n - Default: `:prefix_root/:name`\n\n- `has_binaries`: array of binary commands to symlink into `/usr/local/bin/`, you must specify the relative path.\n\n - Example: `[ 'bin/java', 'bin/javaws' ]`\n\n- `append_env_path`: boolean, similar to `has_binaries` but less granular. If true, append the `./bin` directory of the extracted directory to. the `PATH` environment variable for all users, by placing a file in `/etc/profile.d/`. The commands are symbolically linked into `/usr/bin/*`. This option provides more granularity than the boolean option.\n\n - Example: `mvn`, `java`, `javac`, etc.\n\n- `environment`: hash of environment variables to pass to invoked shell commands like `tar`, `unzip`, `configure`, and `make`.\n\n- `strip_components`: number of components in path to strip when extracting archive. With default value of `1`, ark strips the leading directory from an archive, which is the default for both `unzip` and `tar` commands.\n\n- `autoconf_opts`: an array of command line options for use with the GNU `autoconf` script.\n\n - Example: `[ '--include=/opt/local/include', '--force' ]`\n\n- `make_opts`: an array of command line options for use with `make`.\n\n - Example: `[ '--warn-undefined-variables', '--load-average=2' ]`\n\n- `owner`: owner of extracted directory.\n\n - Default: `root`\n\n- `group`: group of extracted directory.\n\n - Default: `root`\n\n- `backup`: The number of backups to be kept in /var/chef/backup (for UNIX- and Linux-based platforms) or C:/chef/backup (for the Microsoft Windows platform). Set to false to prevent backups from being kept.\n\n - Default: `5`\n\n#### Examples\n\nThis example copies `ivy.tar.gz` to `/var/cache/chef/ivy-2.2.0.tar.gz`, unpacks its contents to `/usr/local/ivy-2.2.0/` -- stripping the leading directory, and symlinks `/usr/local/ivy` to `/usr/local/ivy-2.2.0`\n\n```ruby\n # install Apache Ivy dependency resolution tool\n ark \"ivy\" do\n url 'http://someurl.example.com/ivy.tar.gz'\n version '2.2.0'\n checksum '89ba5fde0c596db388c3bbd265b63007a9cc3df3a8e6d79a46780c1a39408cb5'\n action :install\n end\n```\n\nThis example copies `jdk-7u2-linux-x64.tar.gz` to `/var/cache/chef/jdk-7.2.tar.gz`, unpacks its contents to `/usr/local/jvm/jdk-7.2/` -- stripping the leading directory, symlinks `/usr/local/jvm/default` to `/usr/local/jvm/jdk-7.2`, and adds `/usr/local/jvm/jdk-7.2/bin/` to the global `PATH` for all users. The user 'foobar' is the owner of the `/usr/local/jvm/jdk-7.2` directory:\n\n```ruby\n ark 'jdk' do\n url 'http://download.example.com/jdk-7u2-linux-x64.tar.gz'\n version '7.2'\n path \"/usr/local/jvm/\"\n home_dir \"/usr/local/jvm/default\"\n checksum '89ba5fde0c596db388c3bbd265b63007a9cc3df3a8e6d79a46780c1a39408cb5'\n append_env_path true\n owner 'foobar'\n end\n```\n\nInstall Apache Ivy dependency resolution tool in `/resource_name` in this case `/usr/local/ivy`, do not symlink, and strip any leading directory if one exists in the tarball:\n\n```ruby\n ark \"ivy\" do\n url 'http://someurl.example.com/ivy.tar.gz'\n checksum '89ba5fde0c596db388c3bbd265b63007a9cc3df3a8e6d79a46780c1a39408cb5'\n action :put\n end\n```\n\nInstall Apache Ivy dependency resolution tool in `/home/foobar/ivy`, strip any leading directory if one exists, don't keep backup copies of `ivy.tar.gz`:\n\n```ruby\n ark \"ivy\" do\n path \"/home/foobar\"\n url 'http://someurl.example.com/ivy.tar.gz'\n checksum '89ba5fde0c596db388c3bbd265b63007a9cc3df3a8e6d79a46780c1a39408cb5'\n action :put\n backup false\n end\n```\n\nStrip all directories and dump files into path specified by the path attribute. You must specify the `creates` attribute in order to keep the extraction from running every time. The directory path will be created if it doesn't already exist:\n\n```ruby\n ark \"my_jars\" do\n url \"http://example.com/bunch_of_jars.zip\"\n path \"/usr/local/tomcat/lib\"\n creates \"mysql.jar\"\n owner \"tomcat\"\n action :dump\n end\n```\n\nExtract specific files from a tarball (currently only handles one named file):\n\n```ruby\n ark 'mysql-connector-java' do\n url 'http://oracle.com/mysql-connector.zip'\n creates 'mysql-connector-java-5.0.8-bin.jar'\n path '/usr/local/tomcat/lib'\n action :cherry_pick\n end\n```\n\nBuild and install haproxy and use alternative values for `prefix_root`, `prefix_home`, and `prefix_bin`:\n\n```ruby\n ark \"haproxy\" do\n url \"http://haproxy.1wt.eu/download/1.5/src/snapshot/haproxy-ss-20120403.tar.gz\"\n version \"1.5\"\n checksum 'ba0424bf7d23b3a607ee24bbb855bb0ea347d7ffde0bec0cb12a89623cbaf911'\n make_opts [ 'TARGET=linux26' ]\n prefix_root '/opt'\n prefix_home '/opt'\n prefix_bin '/opt/bin'\n action :install_with_make\n end\n```\n\nYou can also supply the file extension in case the file extension can not be determined by the URL:\n\n```ruby\n ark \"test_autogen\" do\n url 'https://github.com/zeromq/libzmq/tarball/master'\n extension \"tar.gz\"\n action :install_with_make\n end\n```\n\n## License & Authors\n\n- Author: Philip (flip) Kromer - Infochimps, Inc([coders@infochimps.com](mailto:coders@infochimps.com))\n- Author: Bryan W. Berry ([bryan.berry@gmail.com](mailto:bryan.berry@gmail.com))\n- Author: Denis Barishev ([denis.barishev@gmail.com](mailto:denis.barishev@gmail.com))\n- Author: Sean OMeara ([someara@chef.io](mailto:someara@chef.io))\n- Author: John Bellone ([jbellone@bloomberg.net](mailto:jbellone@bloomberg.net))\n- Copyright: 2011, Philip (flip) Kromer - Infochimps, Inc\n- Copyright: 2012, Bryan W. Berry\n- Copyright: 2012, Denis Barishev\n- Copyright: 2013-2017, Chef Software, Inc\n- Copyright: 2014, Bloomberg L.P.\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","suse":">= 0.0.0","opensuse":">= 0.0.0","opensuseleap":">= 0.0.0","scientific":">= 0.0.0","oracle":">= 0.0.0","amazon":">= 0.0.0","windows":">= 0.0.0","mac_os_x":">= 0.0.0","smartos":">= 0.0.0","freebsd":">= 0.0.0"},"dependencies":{"build-essential":">= 0.0.0","windows":">= 0.0.0","seven_zip":">= 0.0.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{"ark::default":"Installs packages needed by the custom resource"},"source_url":"https://github.com/chef-cookbooks/ark","issues_url":"https://github.com/chef-cookbooks/ark/issues","chef_version":">= 12.5","ohai_version":{}} \ No newline at end of file diff --git a/cookbooks/ark/providers/default.rb b/cookbooks/ark/providers/default.rb deleted file mode 100644 index 7f16a7f..0000000 --- a/cookbooks/ark/providers/default.rb +++ /dev/null @@ -1,503 +0,0 @@ -# -# Cookbook Name:: ark -# Provider:: Ark -# -# Author:: Bryan W. Berry -# Author:: Sean OMeara -# Copyright 2012, Bryan W. Berry -# Copyright 2013-2016, Chef Software, Inc. -# Copyright 2014, Bloomberg L.P. -# -# 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 -include ::Ark::ProviderHelpers - -################# -# action :install -################# -action :install do - show_deprecations - set_paths - - directory new_resource.path do - recursive true - action :create - notifies :run, "execute[unpack #{new_resource.release_file}]" - end - - remote_file new_resource.release_file do - Chef::Log.debug('DEBUG: new_resource.release_file') - source new_resource.url - checksum new_resource.checksum if new_resource.checksum - action :create - notifies :run, "execute[unpack #{new_resource.release_file}]" - backup new_resource.backup - end - - # unpack based on file extension - execute "unpack #{new_resource.release_file}" do - command unpack_command - cwd new_resource.path - environment new_resource.environment - notifies :run, "execute[set owner on #{new_resource.path}]" - action :nothing - end - - # set_owner - execute "set owner on #{new_resource.path}" do - command owner_command - action :nothing - end - - # usually on windows there is no central directory with executables where the applications are linked - unless node['platform_family'] == 'windows' - # symlink binaries - new_resource.has_binaries.each do |bin| - link ::File.join(new_resource.prefix_bin, ::File.basename(bin)) do - to ::File.join(new_resource.path, bin) - end - end - - # action_link_paths - link new_resource.home_dir do - to new_resource.path - end - - # Add to path for interactive bash sessions - template "/etc/profile.d/#{new_resource.name}.sh" do - cookbook 'ark' - source 'add_to_path.sh.erb' - owner 'root' - group node['root_group'] - mode '0755' - cookbook 'ark' - variables(directory: "#{new_resource.path}/bin") - only_if { new_resource.append_env_path } - end - end - - # Add to path for the current chef-client converge. - bin_path = ::File.join(new_resource.path, 'bin') - ruby_block "adding '#{bin_path}' to chef-client ENV['PATH']" do - block do - ENV['PATH'] = bin_path + ':' + ENV['PATH'] - end - only_if do - new_resource.append_env_path && ENV['PATH'].scan(bin_path).empty? - end - end -end - -############## -# action :put -############## -action :put do - show_deprecations - set_put_paths - - directory new_resource.path do - recursive true - action :create - notifies :run, "execute[unpack #{new_resource.release_file}]" - end - - # download - remote_file new_resource.release_file do - source new_resource.url - checksum new_resource.checksum if new_resource.checksum - action :create - notifies :run, "execute[unpack #{new_resource.release_file}]" - backup new_resource.backup - end - - # unpack based on file extension - execute "unpack #{new_resource.release_file}" do - command unpack_command - cwd new_resource.path - environment new_resource.environment - notifies :run, "execute[set owner on #{new_resource.path}]" - action :nothing - end - - # set_owner - execute "set owner on #{new_resource.path}" do - command owner_command - action :nothing - end -end - -########################### -# action :dump -########################### -action :dump do - show_deprecations - set_dump_paths - - directory new_resource.path do - recursive true - action :create - notifies :run, "execute[unpack #{new_resource.release_file}]" - end - - # download - remote_file new_resource.release_file do - Chef::Log.debug("DEBUG: new_resource.release_file #{new_resource.release_file}") - source new_resource.url - checksum new_resource.checksum if new_resource.checksum - action :create - notifies :run, "execute[unpack #{new_resource.release_file}]" - end - - # unpack based on file extension - execute "unpack #{new_resource.release_file}" do - command dump_command - cwd new_resource.path - environment new_resource.environment - notifies :run, "execute[set owner on #{new_resource.path}]" - action :nothing - end - - # set_owner - execute "set owner on #{new_resource.path}" do - command owner_command - action :nothing - end -end - -########################### -# action :unzip -########################### -action :unzip do - show_deprecations - set_dump_paths - - directory new_resource.path do - recursive true - action :create - notifies :run, "execute[unpack #{new_resource.release_file}]" - end - - # download - remote_file new_resource.release_file do - Chef::Log.debug("DEBUG: new_resource.release_file #{new_resource.release_file}") - source new_resource.url - checksum new_resource.checksum if new_resource.checksum - action :create - notifies :run, "execute[unpack #{new_resource.release_file}]" - end - - # unpack based on file extension - execute "unpack #{new_resource.release_file}" do - command unzip_command - cwd new_resource.path - environment new_resource.environment - notifies :run, "execute[set owner on #{new_resource.path}]" - action :nothing - end - - # set_owner - execute "set owner on #{new_resource.path}" do - command owner_command - action :nothing - end -end - -##################### -# action :cherry_pick -##################### -action :cherry_pick do - show_deprecations - set_dump_paths - Chef::Log.debug("DEBUG: new_resource.creates #{new_resource.creates}") - - directory new_resource.path do - recursive true - action :create - notifies :run, "execute[cherry_pick #{new_resource.creates} from #{new_resource.release_file}]" - end - - # download - remote_file new_resource.release_file do - source new_resource.url - checksum new_resource.checksum if new_resource.checksum - action :create - notifies :run, "execute[cherry_pick #{new_resource.creates} from #{new_resource.release_file}]" - end - - execute "cherry_pick #{new_resource.creates} from #{new_resource.release_file}" do - command cherry_pick_command - creates "#{new_resource.path}/#{new_resource.creates}" - notifies :run, "execute[set owner on #{new_resource.path}]" - action :nothing - end - - # set_owner - execute "set owner on #{new_resource.path}" do - command owner_command - action :nothing - end -end - -########################### -# action :install_with_make -########################### -action :install_with_make do - show_deprecations - set_paths - - directory new_resource.path do - recursive true - action :create - notifies :run, "execute[unpack #{new_resource.release_file}]" - end - - remote_file new_resource.release_file do - Chef::Log.debug('DEBUG: new_resource.release_file') - source new_resource.url - checksum new_resource.checksum if new_resource.checksum - action :create - notifies :run, "execute[unpack #{new_resource.release_file}]" - end - - # unpack based on file extension - execute "unpack #{new_resource.release_file}" do - command unpack_command - cwd new_resource.path - environment new_resource.environment - notifies :run, "execute[set owner on #{new_resource.path}]" - notifies :run, "execute[autogen #{new_resource.path}]" - notifies :run, "execute[configure #{new_resource.path}]" - notifies :run, "execute[make #{new_resource.path}]" - notifies :run, "execute[make install #{new_resource.path}]" - action :nothing - end - - # set_owner - execute "set owner on #{new_resource.path}" do - command owner_command - action :nothing - end - - execute "autogen #{new_resource.path}" do - command './autogen.sh' - only_if { ::File.exist? "#{new_resource.path}/autogen.sh" } - cwd new_resource.path - environment new_resource.environment - action :nothing - ignore_failure true - end - - execute "configure #{new_resource.path}" do - command "./configure #{new_resource.autoconf_opts.join(' ')}" - only_if { ::File.exist? "#{new_resource.path}/configure" } - cwd new_resource.path - environment new_resource.environment - action :nothing - end - - execute "make #{new_resource.path}" do - command "make #{new_resource.make_opts.join(' ')}" - cwd new_resource.path - environment new_resource.environment - action :nothing - end - - execute "make install #{new_resource.path}" do - command "make install #{new_resource.make_opts.join(' ')}" - cwd new_resource.path - environment new_resource.environment - action :nothing - end -end - -action :setup_py_build do - show_deprecations - set_paths - - directory new_resource.path do - recursive true - action :create - notifies :run, "execute[unpack #{new_resource.release_file}]" - end - - remote_file new_resource.release_file do - Chef::Log.debug('DEBUG: new_resource.release_file') - source new_resource.url - checksum new_resource.checksum if new_resource.checksum - action :create - notifies :run, "execute[unpack #{new_resource.release_file}]" - end - - # unpack based on file extension - execute "unpack #{new_resource.release_file}" do - command unpack_command - cwd new_resource.path - environment new_resource.environment - notifies :run, "execute[set owner on #{new_resource.path}]" - notifies :run, "execute[python setup.py build #{new_resource.path}]" - action :nothing - end - - # set_owner - execute "set owner on #{new_resource.path}" do - command owner_command - action :nothing - end - - execute "python setup.py build #{new_resource.path}" do - command "python setup.py build #{new_resource.make_opts.join(' ')}" - cwd new_resource.path - environment new_resource.environment - action :nothing - end -end - -action :setup_py_install do - show_deprecations - set_paths - - directory new_resource.path do - recursive true - action :create - notifies :run, "execute[unpack #{new_resource.release_file}]" - end - - remote_file new_resource.release_file do - Chef::Log.debug('DEBUG: new_resource.release_file') - source new_resource.url - checksum new_resource.checksum if new_resource.checksum - action :create - notifies :run, "execute[unpack #{new_resource.release_file}]" - end - - # unpack based on file extension - execute "unpack #{new_resource.release_file}" do - command unpack_command - cwd new_resource.path - environment new_resource.environment - notifies :run, "execute[set owner on #{new_resource.path}]" - notifies :run, "execute[python setup.py install #{new_resource.path}]" - action :nothing - end - - # set_owner - execute "set owner on #{new_resource.path}" do - command owner_command - action :nothing - end - - execute "python setup.py install #{new_resource.path}" do - command "python setup.py install #{new_resource.make_opts.join(' ')}" - cwd new_resource.path - environment new_resource.environment - action :nothing - end -end - -action :setup_py do - show_deprecations - set_paths - - directory new_resource.path do - recursive true - action :create - notifies :run, "execute[unpack #{new_resource.release_file}]" - end - - remote_file new_resource.release_file do - Chef::Log.debug('DEBUG: new_resource.release_file') - source new_resource.url - checksum new_resource.checksum if new_resource.checksum - action :create - notifies :run, "execute[unpack #{new_resource.release_file}]" - end - - # unpack based on file extension - execute "unpack #{new_resource.release_file}" do - command unpack_command - cwd new_resource.path - environment new_resource.environment - notifies :run, "execute[set owner on #{new_resource.path}]" - notifies :run, "execute[python setup.py #{new_resource.path}]" - action :nothing - end - - # set_owner - execute "set owner on #{new_resource.path}" do - command owner_command - action :nothing - end - - execute "python setup.py #{new_resource.path}" do - command "python setup.py #{new_resource.make_opts.join(' ')}" - cwd new_resource.path - environment new_resource.environment - action :nothing - end -end - -action :configure do - show_deprecations - set_paths - - directory new_resource.path do - recursive true - action :create - notifies :run, "execute[unpack #{new_resource.release_file}]" - end - - remote_file new_resource.release_file do - Chef::Log.debug('DEBUG: new_resource.release_file') - source new_resource.url - checksum new_resource.checksum if new_resource.checksum - action :create - notifies :run, "execute[unpack #{new_resource.release_file}]" - end - - # unpack based on file extension - execute "unpack #{new_resource.release_file}" do - command unpack_command - cwd new_resource.path - environment new_resource.environment - notifies :run, "execute[set owner on #{new_resource.path}]" - notifies :run, "execute[autogen #{new_resource.path}]" - notifies :run, "execute[configure #{new_resource.path}]" - action :nothing - end - - # set_owner - execute "set owner on #{new_resource.path}" do - command owner_command - action :nothing - end - - execute "autogen #{new_resource.path}" do - command './autogen.sh' - only_if { ::File.exist? "#{new_resource.path}/autogen.sh" } - cwd new_resource.path - environment new_resource.environment - action :nothing - ignore_failure true - end - - execute "configure #{new_resource.path}" do - command "./configure #{new_resource.autoconf_opts.join(' ')}" - only_if { ::File.exist? "#{new_resource.path}/configure" } - cwd new_resource.path - environment new_resource.environment - action :nothing - end -end diff --git a/cookbooks/ark/recipes/default.rb b/cookbooks/ark/recipes/default.rb index 8b5072c..9a482aa 100644 --- a/cookbooks/ark/recipes/default.rb +++ b/cookbooks/ark/recipes/default.rb @@ -1,9 +1,9 @@ # -# Cookbook Name:: ark +# Cookbook:: ark # Recipe:: default # # Author:: Bryan W. Berry -# Copyright 2012, Bryan W. Berry +# Copyright:: 2012-2017, 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. diff --git a/cookbooks/ark/resources/default.rb b/cookbooks/ark/resources/default.rb index 985d1e8..3ca2ea1 100644 --- a/cookbooks/ark/resources/default.rb +++ b/cookbooks/ark/resources/default.rb @@ -1,9 +1,10 @@ # -# Cookbook Name:: ark +# Cookbook:: ark # Resource:: Ark # # Author:: Bryan W. Berry -# Copyright 2012, Bryan W. Berry +# Copyright:: 2012-2017, Bryan W. Berry +# Copyright:: 2016-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,53 +19,510 @@ # limitations under the License. # -actions( - :cherry_pick, - :configure, - :dump, - :install, - :install_with_make, - :put, - :setup_py, - :setup_py_build, - :setup_py_install, - :unzip -) +property :owner, String +property :group, [String, Integer], default: 0 +property :url, String, required: true +property :path, String +property :full_path, String +property :append_env_path, [true, false], default: false +property :checksum, regex: /^[a-zA-Z0-9]{64}$/, default: nil +property :has_binaries, Array, default: [] +property :creates, String +property :release_file, String, default: '' +property :strip_leading_dir, [true, false, NilClass] +property :strip_components, Integer, default: 1 +property :mode, [Integer, String], default: 0755 +property :prefix_root, String +property :prefix_home, String +property :prefix_bin, String +property :version, String +property :home_dir, String +property :win_install_dir, String +property :environment, Hash, default: {} +property :autoconf_opts, Array, default: [] +property :make_opts, Array, default: [] +property :home_dir, String +property :autoconf_opts, Array, default: [] +property :extension, String +property :backup, [FalseClass, Integer], default: 5 -default_action :install +################# +# action :install +################# +action :install do + show_deprecations + set_paths -attr_accessor :extension, - :home_dir, - :owner, - :path, - :prefix_bin, - :prefix_root, - :release_file, - :version + directory new_resource.path do + recursive true + action :create + notifies :run, "execute[unpack #{new_resource.release_file}]" + end -attribute :owner, kind_of: String, default: nil -attribute :group, kind_of: [String, Integer], default: 0 -attribute :url, kind_of: String, required: true -attribute :path, kind_of: String, default: nil -attribute :full_path, kind_of: String, default: nil -attribute :append_env_path, kind_of: [TrueClass, FalseClass], default: false -attribute :checksum, regex: /^[a-zA-Z0-9]{64}$/, default: nil -attribute :has_binaries, kind_of: Array, default: [] -attribute :creates, kind_of: String, default: nil -attribute :release_file, kind_of: String, default: '' -attribute :strip_leading_dir, kind_of: [TrueClass, FalseClass, NilClass] -attribute :strip_components, kind_of: Integer, default: 1 -attribute :mode, kind_of: Integer, default: 0755 -attribute :prefix_root, kind_of: String, default: nil -attribute :prefix_home, kind_of: String, default: nil -attribute :prefix_bin, kind_of: String, default: nil -attribute :version, kind_of: String, default: nil -attribute :home_dir, kind_of: String, default: nil -attribute :win_install_dir, kind_of: String, default: nil -attribute :environment, kind_of: Hash, default: {} -attribute :autoconf_opts, kind_of: Array, default: [] -attribute :make_opts, kind_of: Array, default: [] -attribute :home_dir, kind_of: String, default: nil -attribute :autoconf_opts, kind_of: Array, default: [] -attribute :extension, kind_of: String -attribute :backup, kind_of: [FalseClass, Integer], default: 5 + remote_file new_resource.release_file do + Chef::Log.debug('DEBUG: new_resource.release_file') + source new_resource.url + checksum new_resource.checksum if new_resource.checksum + action :create + notifies :run, "execute[unpack #{new_resource.release_file}]" + backup new_resource.backup + end + + # unpack based on file extension + execute "unpack #{new_resource.release_file}" do + command unpack_command + cwd new_resource.path + environment new_resource.environment + notifies :run, "execute[set owner on #{new_resource.path}]" + action :nothing + end + + # set_owner + execute "set owner on #{new_resource.path}" do + command owner_command + action :nothing + end + + # usually on windows there is no central directory with executables where the applications are linked + unless node['platform_family'] == 'windows' + # symlink binaries + new_resource.has_binaries.each do |bin| + link ::File.join(new_resource.prefix_bin, ::File.basename(bin)) do + to ::File.join(new_resource.path, bin) + end + end + + # action_link_paths + link new_resource.home_dir do + to new_resource.path + end + + # Add to path for interactive bash sessions + template "/etc/profile.d/#{new_resource.name}.sh" do + cookbook 'ark' + source 'add_to_path.sh.erb' + owner 'root' + group node['root_group'] + mode '0755' + cookbook 'ark' + variables(directory: "#{new_resource.path}/bin") + only_if { new_resource.append_env_path } + end + end + + # Add to path for the current chef-client converge. + bin_path = ::File.join(new_resource.path, 'bin') + ruby_block "adding '#{bin_path}' to chef-client ENV['PATH']" do + block do + ENV['PATH'] = bin_path + ':' + ENV['PATH'] + end + only_if do + new_resource.append_env_path && ENV['PATH'].scan(bin_path).empty? + end + end +end + +############## +# action :put +############## +action :put do + show_deprecations + set_put_paths + + directory new_resource.path do + recursive true + action :create + notifies :run, "execute[unpack #{new_resource.release_file}]" + end + + # download + remote_file new_resource.release_file do + source new_resource.url + checksum new_resource.checksum if new_resource.checksum + action :create + notifies :run, "execute[unpack #{new_resource.release_file}]" + backup new_resource.backup + end + + # unpack based on file extension + execute "unpack #{new_resource.release_file}" do + command unpack_command + cwd new_resource.path + environment new_resource.environment + notifies :run, "execute[set owner on #{new_resource.path}]" + action :nothing + end + + # set_owner + execute "set owner on #{new_resource.path}" do + command owner_command + action :nothing + end +end + +########################### +# action :dump +########################### +action :dump do + show_deprecations + set_dump_paths + + directory new_resource.path do + recursive true + action :create + notifies :run, "execute[unpack #{new_resource.release_file}]" + end + + # download + remote_file new_resource.release_file do + Chef::Log.debug("DEBUG: new_resource.release_file #{new_resource.release_file}") + source new_resource.url + checksum new_resource.checksum if new_resource.checksum + action :create + notifies :run, "execute[unpack #{new_resource.release_file}]" + end + + # unpack based on file extension + execute "unpack #{new_resource.release_file}" do + command dump_command + cwd new_resource.path + environment new_resource.environment + notifies :run, "execute[set owner on #{new_resource.path}]" + action :nothing + end + + # set_owner + execute "set owner on #{new_resource.path}" do + command owner_command + action :nothing + end +end + +########################### +# action :unzip +########################### +action :unzip do + show_deprecations + set_dump_paths + + directory new_resource.path do + recursive true + action :create + notifies :run, "execute[unpack #{new_resource.release_file}]" + end + + # download + remote_file new_resource.release_file do + Chef::Log.debug("DEBUG: new_resource.release_file #{new_resource.release_file}") + source new_resource.url + checksum new_resource.checksum if new_resource.checksum + action :create + notifies :run, "execute[unpack #{new_resource.release_file}]" + end + + # unpack based on file extension + execute "unpack #{new_resource.release_file}" do + command unzip_command + cwd new_resource.path + environment new_resource.environment + notifies :run, "execute[set owner on #{new_resource.path}]" + action :nothing + end + + # set_owner + execute "set owner on #{new_resource.path}" do + command owner_command + action :nothing + end +end + +##################### +# action :cherry_pick +##################### +action :cherry_pick do + show_deprecations + set_dump_paths + Chef::Log.debug("DEBUG: new_resource.creates #{new_resource.creates}") + + directory new_resource.path do + recursive true + action :create + notifies :run, "execute[cherry_pick #{new_resource.creates} from #{new_resource.release_file}]" + end + + # download + remote_file new_resource.release_file do + source new_resource.url + checksum new_resource.checksum if new_resource.checksum + action :create + notifies :run, "execute[cherry_pick #{new_resource.creates} from #{new_resource.release_file}]" + end + + execute "cherry_pick #{new_resource.creates} from #{new_resource.release_file}" do + command cherry_pick_command + creates "#{new_resource.path}/#{new_resource.creates}" + notifies :run, "execute[set owner on #{new_resource.path}]" + action :nothing + end + + # set_owner + execute "set owner on #{new_resource.path}" do + command owner_command + action :nothing + end +end + +########################### +# action :install_with_make +########################### +action :install_with_make do + show_deprecations + set_paths + + directory new_resource.path do + recursive true + action :create + notifies :run, "execute[unpack #{new_resource.release_file}]" + end + + remote_file new_resource.release_file do + Chef::Log.debug('DEBUG: new_resource.release_file') + source new_resource.url + checksum new_resource.checksum if new_resource.checksum + action :create + notifies :run, "execute[unpack #{new_resource.release_file}]" + end + + # unpack based on file extension + execute "unpack #{new_resource.release_file}" do + command unpack_command + cwd new_resource.path + environment new_resource.environment + notifies :run, "execute[set owner on #{new_resource.path}]" + notifies :run, "execute[autogen #{new_resource.path}]" + notifies :run, "execute[configure #{new_resource.path}]" + notifies :run, "execute[make #{new_resource.path}]" + notifies :run, "execute[make install #{new_resource.path}]" + action :nothing + end + + # set_owner + execute "set owner on #{new_resource.path}" do + command owner_command + action :nothing + end + + execute "autogen #{new_resource.path}" do + command './autogen.sh' + only_if { ::File.exist? "#{new_resource.path}/autogen.sh" } + cwd new_resource.path + environment new_resource.environment + action :nothing + ignore_failure true + end + + execute "configure #{new_resource.path}" do + command "./configure #{new_resource.autoconf_opts.join(' ')}" + only_if { ::File.exist? "#{new_resource.path}/configure" } + cwd new_resource.path + environment new_resource.environment + action :nothing + end + + execute "make #{new_resource.path}" do + command "make #{new_resource.make_opts.join(' ')}" + cwd new_resource.path + environment new_resource.environment + action :nothing + end + + execute "make install #{new_resource.path}" do + command "make install #{new_resource.make_opts.join(' ')}" + cwd new_resource.path + environment new_resource.environment + action :nothing + end +end + +action :setup_py_build do + show_deprecations + set_paths + + directory new_resource.path do + recursive true + action :create + notifies :run, "execute[unpack #{new_resource.release_file}]" + end + + remote_file new_resource.release_file do + Chef::Log.debug('DEBUG: new_resource.release_file') + source new_resource.url + checksum new_resource.checksum if new_resource.checksum + action :create + notifies :run, "execute[unpack #{new_resource.release_file}]" + end + + # unpack based on file extension + execute "unpack #{new_resource.release_file}" do + command unpack_command + cwd new_resource.path + environment new_resource.environment + notifies :run, "execute[set owner on #{new_resource.path}]" + notifies :run, "execute[python setup.py build #{new_resource.path}]" + action :nothing + end + + # set_owner + execute "set owner on #{new_resource.path}" do + command owner_command + action :nothing + end + + execute "python setup.py build #{new_resource.path}" do + command "python setup.py build #{new_resource.make_opts.join(' ')}" + cwd new_resource.path + environment new_resource.environment + action :nothing + end +end + +action :setup_py_install do + show_deprecations + set_paths + + directory new_resource.path do + recursive true + action :create + notifies :run, "execute[unpack #{new_resource.release_file}]" + end + + remote_file new_resource.release_file do + Chef::Log.debug('DEBUG: new_resource.release_file') + source new_resource.url + checksum new_resource.checksum if new_resource.checksum + action :create + notifies :run, "execute[unpack #{new_resource.release_file}]" + end + + # unpack based on file extension + execute "unpack #{new_resource.release_file}" do + command unpack_command + cwd new_resource.path + environment new_resource.environment + notifies :run, "execute[set owner on #{new_resource.path}]" + notifies :run, "execute[python setup.py install #{new_resource.path}]" + action :nothing + end + + # set_owner + execute "set owner on #{new_resource.path}" do + command owner_command + action :nothing + end + + execute "python setup.py install #{new_resource.path}" do + command "python setup.py install #{new_resource.make_opts.join(' ')}" + cwd new_resource.path + environment new_resource.environment + action :nothing + end +end + +action :setup_py do + show_deprecations + set_paths + + directory new_resource.path do + recursive true + action :create + notifies :run, "execute[unpack #{new_resource.release_file}]" + end + + remote_file new_resource.release_file do + Chef::Log.debug('DEBUG: new_resource.release_file') + source new_resource.url + checksum new_resource.checksum if new_resource.checksum + action :create + notifies :run, "execute[unpack #{new_resource.release_file}]" + end + + # unpack based on file extension + execute "unpack #{new_resource.release_file}" do + command unpack_command + cwd new_resource.path + environment new_resource.environment + notifies :run, "execute[set owner on #{new_resource.path}]" + notifies :run, "execute[python setup.py #{new_resource.path}]" + action :nothing + end + + # set_owner + execute "set owner on #{new_resource.path}" do + command owner_command + action :nothing + end + + execute "python setup.py #{new_resource.path}" do + command "python setup.py #{new_resource.make_opts.join(' ')}" + cwd new_resource.path + environment new_resource.environment + action :nothing + end +end + +action :configure do + show_deprecations + set_paths + + directory new_resource.path do + recursive true + action :create + notifies :run, "execute[unpack #{new_resource.release_file}]" + end + + remote_file new_resource.release_file do + Chef::Log.debug('DEBUG: new_resource.release_file') + source new_resource.url + checksum new_resource.checksum if new_resource.checksum + action :create + notifies :run, "execute[unpack #{new_resource.release_file}]" + end + + # unpack based on file extension + execute "unpack #{new_resource.release_file}" do + command unpack_command + cwd new_resource.path + environment new_resource.environment + notifies :run, "execute[set owner on #{new_resource.path}]" + notifies :run, "execute[autogen #{new_resource.path}]" + notifies :run, "execute[configure #{new_resource.path}]" + action :nothing + end + + # set_owner + execute "set owner on #{new_resource.path}" do + command owner_command + action :nothing + end + + execute "autogen #{new_resource.path}" do + command './autogen.sh' + only_if { ::File.exist? "#{new_resource.path}/autogen.sh" } + cwd new_resource.path + environment new_resource.environment + action :nothing + ignore_failure true + end + + execute "configure #{new_resource.path}" do + command "./configure #{new_resource.autoconf_opts.join(' ')}" + only_if { ::File.exist? "#{new_resource.path}/configure" } + cwd new_resource.path + environment new_resource.environment + action :nothing + end +end + +action_class.class_eval do + include ::Ark::ProviderHelpers +end From ccbf11a4073025fb5f2728b8a771b3a67d3ceda1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Tue, 2 May 2017 11:58:32 +0200 Subject: [PATCH 42/83] Update logrotate cookbook --- Batali | 2 +- batali.manifest | 35 ++- cookbooks/logrotate/.kitchen.yml | 2 +- cookbooks/logrotate/.travis.yml | 12 +- cookbooks/logrotate/Berksfile | 7 + cookbooks/logrotate/CHANGELOG.md | 58 ++++ cookbooks/logrotate/CONTRIBUTING.md | 34 +- cookbooks/logrotate/Gemfile | 14 +- cookbooks/logrotate/Gemfile.lock | 295 +++++++++++++----- cookbooks/logrotate/LICENSE | 4 +- cookbooks/logrotate/Makefile | 13 + cookbooks/logrotate/README.md | 144 ++++++--- cookbooks/logrotate/TESTING.md | 49 --- cookbooks/logrotate/attributes/default.rb | 48 ++- .../logrotate/definitions/logrotate_app.rb | 77 ----- .../logrotate/libraries/logrotate_config.rb | 26 +- cookbooks/logrotate/libraries/matchers.rb | 153 +-------- cookbooks/logrotate/metadata.json | 18 +- cookbooks/logrotate/metadata.rb | 23 +- cookbooks/logrotate/recipes/default.rb | 31 +- cookbooks/logrotate/recipes/global.rb | 10 +- cookbooks/logrotate/resources/app.rb | 116 +++++++ .../logrotate/templates/default/logrotate.erb | 14 +- 23 files changed, 679 insertions(+), 506 deletions(-) create mode 100644 cookbooks/logrotate/Berksfile create mode 100644 cookbooks/logrotate/Makefile delete mode 100644 cookbooks/logrotate/TESTING.md delete mode 100644 cookbooks/logrotate/definitions/logrotate_app.rb create mode 100644 cookbooks/logrotate/resources/app.rb diff --git a/Batali b/Batali index ab145b8..9520bb3 100644 --- a/Batali +++ b/Batali @@ -36,6 +36,6 @@ Batali.define do cookbook 'timezone-ii' cookbook 'nodejs', '~> 3.0.0' cookbook 'ark', '~> 3.0.0' - cookbook 'logrotate' + cookbook 'logrotate', '~> 2.1.0' cookbook 'openssl', '~> 7.0.1' end diff --git a/batali.manifest b/batali.manifest index 1f3226a..613c42e 100644 --- a/batali.manifest +++ b/batali.manifest @@ -1035,18 +1035,6 @@ "version": "3.0.0" } }, - { - "name": "homebrew", - "dependencies": [ - - ], - "version": "3.0.0", - "source": { - "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/homebrew/versions/3.0.0/download", - "version": "3.0.0" - } - }, { "name": "ark", "dependencies": [ @@ -1071,15 +1059,30 @@ } }, { - "name": "logrotate", + "name": "homebrew", "dependencies": [ ], - "version": "1.9.2", + "version": "3.0.0", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/logrotate/versions/1.9.2/download", - "version": "1.9.2" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/homebrew/versions/3.0.0/download", + "version": "3.0.0" + } + }, + { + "name": "logrotate", + "dependencies": [ + [ + "compat_resource", + ">= 0.0.0" + ] + ], + "version": "2.1.0", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/logrotate/versions/2.1.0/download", + "version": "2.1.0" } } ] diff --git a/cookbooks/logrotate/.kitchen.yml b/cookbooks/logrotate/.kitchen.yml index 8ae0988..cd43292 100644 --- a/cookbooks/logrotate/.kitchen.yml +++ b/cookbooks/logrotate/.kitchen.yml @@ -6,7 +6,7 @@ platforms: - name: ubuntu-12.04 run_list: - recipe[fake::prep] - - name: centos-6.5 + - name: centos-6.7 suites: - name: default diff --git a/cookbooks/logrotate/.travis.yml b/cookbooks/logrotate/.travis.yml index 3b392bf..2d48aff 100644 --- a/cookbooks/logrotate/.travis.yml +++ b/cookbooks/logrotate/.travis.yml @@ -1,6 +1,10 @@ +sudo: false +branches: + only: + - master +language: ruby +cache: bundler rvm: - - 2.0.0 + - 2.2 script: - - bundle exec foodcritic -f any . --tags ~FC015 - - bundle exec rspec --color --format progress - - bundle exec rubocop -l + - make travis diff --git a/cookbooks/logrotate/Berksfile b/cookbooks/logrotate/Berksfile new file mode 100644 index 0000000..1e01c28 --- /dev/null +++ b/cookbooks/logrotate/Berksfile @@ -0,0 +1,7 @@ +source "https://supermarket.getchef.com" + +metadata + +group :development do + cookbook "fake", path: "test/fixtures/cookbooks/fake" +end diff --git a/cookbooks/logrotate/CHANGELOG.md b/cookbooks/logrotate/CHANGELOG.md index b3fe95b..034fc1e 100644 --- a/cookbooks/logrotate/CHANGELOG.md +++ b/cookbooks/logrotate/CHANGELOG.md @@ -3,6 +3,64 @@ logrotate Cookbook CHANGELOG This file is used to list changes made in each version of the logrotate cookbook. +v2.1.0 +------ + +# Bug Fixes + +- Restore `cookbook` parameter for `logrotate_app` resource due to + popular demand. + +- Add a `template_name` parameter to replace the 1.x `template` + parameter. The name `template` can't be used inside a resource + without conflicting with an attribute of the same name. + +- Fix exception when `options` specified as a string rather than an + array + +v2.0.0 +------ + +- Convert the logrotate_app definition to a resource +- Accept all options included in logrotate 3.9.2 + +# Known incompatibilities + +- The `cookbook` parameter to `logrotate_app` is no longer accepted. + + +v1.9.2 +------ + +## Bug Fixes + +- Fix deprecation warnings from ChefSpec + +v1.9.1 +------ + +## Bug Fixes + +- Fixes regression in the sharedscripts logrotate_app + parameter (Bug #69) + +v1.9.0 +------ + +### Improvements + +- All configuration options from the logrotate 3.8.8 manual page can +be used by the global configuration and the logrotate_app +definition. + +- Berkshelf is no longer a development dependency of the +logrotate cookbook. + +- Rubocop lint failures have been resolved. + + + + v1.8.0 ------ diff --git a/cookbooks/logrotate/CONTRIBUTING.md b/cookbooks/logrotate/CONTRIBUTING.md index 85e6c26..11f715d 100644 --- a/cookbooks/logrotate/CONTRIBUTING.md +++ b/cookbooks/logrotate/CONTRIBUTING.md @@ -11,6 +11,36 @@ - Please ensure all tests and lint checking pass before submitting pull requests. -## Testing +## Development -Please read TESTING.md for details on testing this cookbook. +### Requirements + +- Ruby 2.0+ +- Bundler (`gem install bundler`) +- [Vagrant](https://vagrantup.com) +- [VirtualBox](https://virtualbox.org) + +### Development Flow + +1. Clone the git repository from GitHub: + + $ git clone git@github.com:stevendanna/logrotate.git + +2. Install the dependencies using bundler: + + $ bundle install + +3. Create a branch for your changes: + + $ git checkout -b my_bug_fix + +4. Make any changes + +5. Write tests to support those changes. It is highly recommended you + write both unit and integration tests. + +6. Run the tests: + - `make travis` + - `kitchen test` + +7. Assuming the tests pass, open a Pull Request on GitHub diff --git a/cookbooks/logrotate/Gemfile b/cookbooks/logrotate/Gemfile index 5857ea6..c7a8252 100644 --- a/cookbooks/logrotate/Gemfile +++ b/cookbooks/logrotate/Gemfile @@ -1,9 +1,11 @@ -source 'https://rubygems.org' -gem 'chefspec', '~> 4.0' -gem 'foodcritic', '~> 4.0' -gem 'rubocop', '~> 0.12' +source "https://rubygems.org" + +gem "berkshelf", "~> 4.0" +gem "chefspec", "~> 4.0" +gem "foodcritic", "~> 6.0" +gem "chefstyle", github: "chef/chefstyle" group :integration do - gem 'test-kitchen', '~> 1.0' - gem 'kitchen-vagrant', '~> 0.11' + gem "test-kitchen", "~> 1.0" + gem "kitchen-vagrant", "~> 0.11" end diff --git a/cookbooks/logrotate/Gemfile.lock b/cookbooks/logrotate/Gemfile.lock index bdefc51..8d4c49c 100644 --- a/cookbooks/logrotate/Gemfile.lock +++ b/cookbooks/logrotate/Gemfile.lock @@ -1,141 +1,262 @@ +GIT + remote: git://github.com/chef/chefstyle.git + revision: cc37808b7849fdcf49f04011626143940f83fe92 + specs: + chefstyle (0.3.1) + rubocop (= 0.39.0) + GEM remote: https://rubygems.org/ specs: - ast (2.0.0) - astrolabe (1.3.0) - parser (>= 2.2.0.pre.3, < 3.0) - chef (12.0.3) - chef-zero (~> 3.2) + addressable (2.4.0) + artifactory (2.3.2) + ast (2.2.0) + berkshelf (4.3.2) + addressable (~> 2.3, >= 2.3.4) + berkshelf-api-client (~> 2.0, >= 2.0.2) + buff-config (~> 1.0) + buff-extensions (~> 1.0) + buff-shell_out (~> 0.1) + celluloid (= 0.16.0) + celluloid-io (~> 0.16.1) + cleanroom (~> 1.0) + faraday (~> 0.9) + httpclient (~> 2.7) + minitar (~> 0.5, >= 0.5.4) + octokit (~> 4.0) + retryable (~> 2.0) + ridley (~> 4.5) + solve (~> 2.0) + thor (~> 0.19) + berkshelf-api-client (2.0.2) + faraday (~> 0.9.1) + httpclient (~> 2.7.0) + ridley (~> 4.5) + buff-config (1.0.1) + buff-extensions (~> 1.0) + varia_model (~> 0.4) + buff-extensions (1.0.0) + buff-ignore (1.1.1) + buff-ruby_engine (0.1.0) + buff-shell_out (0.2.0) + buff-ruby_engine (~> 0.1.0) + builder (3.2.2) + celluloid (0.16.0) + timers (~> 4.0.0) + celluloid-io (0.16.2) + celluloid (>= 0.16.0) + nio4r (>= 1.1.0) + chef (12.9.38) + bundler (>= 1.10) + chef-config (= 12.9.38) + chef-zero (~> 4.5) diff-lcs (~> 1.2, >= 1.2.4) erubis (~> 2.7) - ffi-yajl (~> 1.2) + ffi-yajl (~> 2.2) highline (~> 1.6, >= 1.6.9) - mixlib-authentication (~> 1.3) + mixlib-authentication (~> 1.4) mixlib-cli (~> 1.4) - mixlib-config (~> 2.0) mixlib-log (~> 1.3) - mixlib-shellout (>= 2.0.0.rc.0, < 3.0) - net-ssh (~> 2.6) + mixlib-shellout (~> 2.0) + net-sftp (~> 2.1, >= 2.1.2) + net-ssh (>= 2.9, < 4.0) net-ssh-multi (~> 1.1) - ohai (~> 8.0) - plist (~> 3.1.0) - pry (~> 0.9) - chef-zero (3.2.1) - ffi-yajl (~> 1.1) - hashie (~> 2.0) + ohai (>= 8.6.0.alpha.1, < 9) + plist (~> 3.2) + proxifier (~> 1.0) + rspec-core (~> 3.4) + rspec-expectations (~> 3.4) + rspec-mocks (~> 3.4) + rspec_junit_formatter (~> 0.2.0) + serverspec (~> 2.7) + specinfra (~> 2.10) + syslog-logger (~> 1.6) + uuidtools (~> 2.1.5) + chef-config (12.9.38) + fuzzyurl (~> 0.8.0) + mixlib-config (~> 2.0) + mixlib-shellout (~> 2.0) + chef-zero (4.6.1) + ffi-yajl (~> 2.2) + hashie (>= 2.0, < 4.0) mixlib-log (~> 1.3) rack uuidtools (~> 2.1) - chefspec (4.2.0) + chefspec (4.6.1) chef (>= 11.14) - fauxhai (~> 2.0) + fauxhai (~> 3.2) rspec (~> 3.0) - coderay (1.1.0) + cleanroom (1.0.0) + cucumber-core (1.4.0) + gherkin (~> 3.2.0) diff-lcs (1.2.5) erubis (2.7.0) - fauxhai (2.3.0) + faraday (0.9.2) + multipart-post (>= 1.2, < 3) + fauxhai (3.3.0) net-ssh - ohai - ffi (1.9.6) - ffi-yajl (1.4.0) - ffi (~> 1.5) + ffi (1.9.10) + ffi-yajl (2.2.3) libyajl2 (~> 1.2) - foodcritic (4.0.0) + foodcritic (6.1.1) + cucumber-core (>= 1.3) erubis - gherkin (~> 2.11) - nokogiri (~> 1.5) + nokogiri (>= 1.5, < 2.0) rake rufus-lru (~> 1.0) treetop (~> 1.4) yajl-ruby (~> 1.1) - gherkin (2.12.2) - multi_json (~> 1.3) - hashie (2.1.2) - highline (1.7.1) - ipaddress (0.8.0) - kitchen-vagrant (0.15.0) - test-kitchen (~> 1.0) + fuzzyurl (0.8.0) + gherkin (3.2.0) + hashie (3.4.3) + highline (1.7.8) + hitimes (1.2.3) + httpclient (2.7.1) + ipaddress (0.8.3) + json (1.8.3) + kitchen-vagrant (0.20.0) + test-kitchen (~> 1.4) libyajl2 (1.2.0) - method_source (0.8.2) - mime-types (2.4.3) - mini_portile (0.6.2) - mixlib-authentication (1.3.0) + mini_portile2 (2.0.0) + minitar (0.5.4) + mixlib-authentication (1.4.0) mixlib-log + rspec-core (~> 3.2) + rspec-expectations (~> 3.2) + rspec-mocks (~> 3.2) mixlib-cli (1.5.0) - mixlib-config (2.1.0) + mixlib-config (2.2.1) + mixlib-install (1.0.7) + artifactory + mixlib-shellout + mixlib-versioning mixlib-log (1.6.0) - mixlib-shellout (2.0.1) - multi_json (1.10.1) - net-dhcp (1.3.2) + mixlib-shellout (2.2.6) + mixlib-versioning (1.1.0) + molinillo (0.4.4) + multi_json (1.11.2) + multipart-post (2.0.0) net-scp (1.2.1) net-ssh (>= 2.6.5) - net-ssh (2.9.2) + net-sftp (2.1.2) + net-ssh (>= 2.6.5) + net-ssh (3.1.1) net-ssh-gateway (1.2.0) net-ssh (>= 2.6.5) - net-ssh-multi (1.2.0) + net-ssh-multi (1.2.1) net-ssh (>= 2.6.5) net-ssh-gateway (>= 1.2.0) - nokogiri (1.6.6.2) - mini_portile (~> 0.6.0) - ohai (8.1.1) + net-telnet (0.1.1) + nio4r (1.2.1) + nokogiri (1.6.7.2) + mini_portile2 (~> 2.0.0.rc2) + octokit (4.3.0) + sawyer (~> 0.7.0, >= 0.5.3) + ohai (8.14.0) + chef-config (>= 12.5.0.alpha.1, < 13) ffi (~> 1.9) - ffi-yajl (~> 1.1) + ffi-yajl (~> 2.2) ipaddress - mime-types (~> 2.0) mixlib-cli mixlib-config (~> 2.0) mixlib-log mixlib-shellout (~> 2.0) - net-dhcp - rake (~> 10.1) + plist (~> 3.1) systemu (~> 2.6.4) wmi-lite (~> 1.0) - parser (2.2.0.3) - ast (>= 1.1, < 3.0) - plist (3.1.0) + parser (2.3.0.7) + ast (~> 2.2) + plist (3.2.0) polyglot (0.3.5) - powerpack (0.1.0) - pry (0.10.1) - coderay (~> 1.1.0) - method_source (~> 0.8.1) - slop (~> 3.4) - rack (1.6.0) - rainbow (2.0.0) - rake (10.4.2) - rspec (3.2.0) - rspec-core (~> 3.2.0) - rspec-expectations (~> 3.2.0) - rspec-mocks (~> 3.2.0) - rspec-core (3.2.0) - rspec-support (~> 3.2.0) - rspec-expectations (3.2.0) + powerpack (0.1.1) + proxifier (1.0.3) + rack (1.6.4) + rainbow (2.1.0) + rake (11.1.2) + retryable (2.0.3) + ridley (4.5.0) + addressable + buff-config (~> 1.0) + buff-extensions (~> 1.0) + buff-ignore (~> 1.1) + buff-shell_out (~> 0.1) + celluloid (~> 0.16.0) + celluloid-io (~> 0.16.1) + chef-config (>= 12.5.0) + erubis + faraday (~> 0.9.0) + hashie (>= 2.0.2, < 4.0.0) + httpclient (~> 2.7) + json (>= 1.7.7) + mixlib-authentication (>= 1.3.0) + retryable (~> 2.0) + semverse (~> 1.1) + varia_model (~> 0.4.0) + rspec (3.4.0) + rspec-core (~> 3.4.0) + rspec-expectations (~> 3.4.0) + rspec-mocks (~> 3.4.0) + rspec-core (3.4.4) + rspec-support (~> 3.4.0) + rspec-expectations (3.4.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.2.0) - rspec-mocks (3.2.0) + rspec-support (~> 3.4.0) + rspec-its (1.2.0) + rspec-core (>= 3.0.0) + rspec-expectations (>= 3.0.0) + rspec-mocks (3.4.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.2.0) - rspec-support (3.2.1) - rubocop (0.29.1) - astrolabe (~> 1.3) - parser (>= 2.2.0.1, < 3.0) + rspec-support (~> 3.4.0) + rspec-support (3.4.1) + rspec_junit_formatter (0.2.3) + builder (< 4) + rspec-core (>= 2, < 4, != 2.12.0) + rubocop (0.39.0) + parser (>= 2.3.0.7, < 3.0) powerpack (~> 0.1) rainbow (>= 1.99.1, < 3.0) - ruby-progressbar (~> 1.4) - ruby-progressbar (1.7.1) + ruby-progressbar (~> 1.7) + unicode-display_width (~> 1.0, >= 1.0.1) + ruby-progressbar (1.7.5) rufus-lru (1.0.5) safe_yaml (1.0.4) - slop (3.6.0) - systemu (2.6.4) - test-kitchen (1.3.1) + sawyer (0.7.0) + addressable (>= 2.3.5, < 2.5) + faraday (~> 0.8, < 0.10) + semverse (1.2.1) + serverspec (2.31.1) + multi_json + rspec (~> 3.0) + rspec-its + specinfra (~> 2.53) + sfl (2.2) + solve (2.0.3) + molinillo (~> 0.4.2) + semverse (~> 1.1) + specinfra (2.56.1) + net-scp + net-ssh (>= 2.7, < 4.0) + net-telnet + sfl + syslog-logger (1.6.8) + systemu (2.6.5) + test-kitchen (1.7.3) + mixlib-install (~> 1.0, >= 1.0.4) mixlib-shellout (>= 1.2, < 3.0) net-scp (~> 1.1) - net-ssh (~> 2.7) + net-ssh (>= 2.9, < 4.0) safe_yaml (~> 1.0) thor (~> 0.18) thor (0.19.1) - treetop (1.5.3) + timers (4.0.4) + hitimes + treetop (1.6.5) polyglot (~> 0.3) + unicode-display_width (1.0.3) uuidtools (2.1.5) + varia_model (0.4.1) + buff-extensions (~> 1.0) + hashie (>= 2.0.2, < 4.0.0) wmi-lite (1.0.0) yajl-ruby (1.2.1) @@ -143,8 +264,12 @@ PLATFORMS ruby DEPENDENCIES + berkshelf (~> 4.0) chefspec (~> 4.0) - foodcritic (~> 4.0) + chefstyle! + foodcritic (~> 6.0) kitchen-vagrant (~> 0.11) - rubocop (~> 0.12) test-kitchen (~> 1.0) + +BUNDLED WITH + 1.11.2 diff --git a/cookbooks/logrotate/LICENSE b/cookbooks/logrotate/LICENSE index 11069ed..911c489 100644 --- a/cookbooks/logrotate/LICENSE +++ b/cookbooks/logrotate/LICENSE @@ -186,7 +186,9 @@ APPENDIX: How to apply the Apache License to your work. same "printed page" as the copyright notice for easier identification within third-party archives. -Copyright [yyyy] [name of copyright owner] +Copyright 2009-2013, Chef Software, Inc. +Copyright 2015-2016, Steven Danna +Copyright 2016, Bloomberg Finance L.P. 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/logrotate/Makefile b/cookbooks/logrotate/Makefile new file mode 100644 index 0000000..315bc70 --- /dev/null +++ b/cookbooks/logrotate/Makefile @@ -0,0 +1,13 @@ +travis: bundle berks + bundle exec chefstyle -D + bundle exec foodcritic . + bundle exec rspec --color --format doc + +integration: bundle berks + bundle exec kitchen test + +bundle: + bundle install + +berks: + bundle exec berks install diff --git a/cookbooks/logrotate/README.md b/cookbooks/logrotate/README.md index 62e1d4f..09123e9 100644 --- a/cookbooks/logrotate/README.md +++ b/cookbooks/logrotate/README.md @@ -1,41 +1,53 @@ -logrotate Cookbook -================== +# logrotate Cookbook [![Build Status](https://secure.travis-ci.org/stevendanna/logrotate.png?branch=master)](http://travis-ci.org/stevendanna/logrotate) -Manages the logrotate package and provides a definition to manage application specific logrotate configuration. +Manages the logrotate package and provides a definition to manage +application specific logrotate configuration. -Requirements ------------- -Should work on any platform that includes a 'logrotate' package and writes logrotate configuration to /etc/logrotate.d. Tested on Ubuntu, Debian and Red Hat/CentOS. +## Requirements +Should work on any platform that includes a 'logrotate' package and +writes logrotate configuration to /etc/logrotate.d. Tested on Ubuntu +and Centos. -Recipes -------- +## Recipes + ### global -Generates and controls a global `/etc/logrotate.conf` file that will include additional files generated by the `logrotate_app` definition (see below). The contents of the configuration file is controlled through node attributes under `node['logrotate']['global']`. The default attributes are based on the configuration from the Ubuntu logrotate package. -To define a valueless directive (e.g. `compress`, `copy`) simply add an attribute named for the directive with a truthy value : +Generates and controls a global `/etc/logrotate.conf` file that will +include additional files generated by the `logrotate_app` definition +(see below). The contents of the configuration file is controlled +through node attributes under `node['logrotate']['global']`. The +default attributes are based on the configuration from the Ubuntu +logrotate package. + +To define a valueless directive (e.g. `compress`, `copy`) simply add +an attribute named for the directive with a truthy value: ```ruby node['logrotate']['global']['compress'] = 'any value here' ``` -Note that defining a valueless directive with a falsey value will not make it false, but will remove it: +Note that defining a valueless directive with a falsey value will not +make it false, but will remove it: ```ruby # Removes a defaulted 'compress' directive; does not add a 'nocompress' directive. node.override['logrotate']['global']['compress'] = false ``` -To fully override a booleanish directive like `compress`, you should probably remove the positive form and add the negative form: +To fully override a booleanish directive like `compress`, you should +probably remove the positive form and add the negative form: ```ruby node.override['logrotate']['global']['compress'] = false node.override['logrotate']['global']['nocompress'] = true ``` -The same is true of frequency directives; to be certain the frequency directive you want is included in the global configuration, you should override the ones you don't want as false: +The same is true of frequency directives; to be certain the frequency +directive you want is included in the global configuration, you should +override the ones you don't want as false: ```ruby %w[ daily weekly yearly ].each do |freq| @@ -44,13 +56,17 @@ end node.override['logrotate']['global']['monthly'] = true ``` -To define a parameter with a value (e.g. `create`, `mail`) add an attribute with the desired value: +To define a parameter with a value (e.g. `create`, `mail`) add an +attribute with the desired value: ```ruby node['logrotate']['global']['create'] = '0644 root adm' ``` -To define a path stanza in the global configuration (generally unneeded because of the `logrotate_app` definition) just add an attribute with the path as the name and a hash containing directives and parameters as described above: +To define a path stanza in the global configuration (generally +unneeded because of the `logrotate_app` definition) just add an +attribute with the path as the name and a hash containing directives +and parameters as described above: ```ruby node['logrotate']['global']['/var/log/wtmp'] = { @@ -61,7 +77,9 @@ node['logrotate']['global']['/var/log/wtmp'] = { } ``` -`firstaction`, `prerotate`, `postrotate`, and `lastaction` scripts can be defined either as arrays of the lines to put in the script or multiline strings: +`firstaction`, `prerotate`, `postrotate`, and `lastaction` scripts can +be defined either as arrays of the lines to put in the script or +multiline strings: ```ruby node['logrotate']['global']['/var/log/foo/*.log'] = { @@ -78,43 +96,76 @@ node['logrotate']['global']['/var/log/foo/*.log'] = { ``` -Definitions +Resources ----------- ### logrotate_app -This definition can be used to drop off customized logrotate config files on a per application basis. -The definition takes the following params: +This resource can be used to drop off customized logrotate config +files on a per application basis. -- `path`: specifies a single path (string) or multiple paths (array) that should have logrotation stanzas created in the config file. No default, this must be specified. -- `enable`: true/false, if true it will create the template in /etc/logrotate.d. -- `frequency`: sets the frequency for rotation. Default value is 'weekly'. Valid values are: daily, weekly, monthly, yearly, see the logrotate man page for more information. -- `dateformat`: specifies date extension with %Y, %m, %d, and %s. The default value is -%Y%m%d. -- `size`: Log files are rotated when they grow bigger than size bytes. -- `maxsize`: Log files are rotated when they grow bigger than size bytes even before the additionally specified time interval. -- `su`: Rotate log files set under this user and group instead of using default user/group. -- `template`: sets the template source, default is "logrotate.erb". -- `template_mode`: the mode to create the logrotate template with (default "0440") -- `template_owner`: the owner of the logrotate template (default "root") -- `template_group`: the group of the logrotate template (default "root") -- `cookbook`: select the template source from the specified cookbook. By default it will use the template from the logrotate cookbook. -- `create`: creation parameters for the logrotate "create" config, follows the form "mode owner group". This is an optional parameter, and is nil by default. -- `firstaction`: lines to be executed once before all log files that match the wildcarded pattern are rotated, before pre-rotate script is run and only if at least one log will actually be rotated -- `postrotate`: lines to be executed after the log file is rotated -- `prerotate`: lines to be executed before the log file is rotated -- `lastaction`: lines to be executed once after all log files that match the wildcarded pattern are rotated, after postrotate script is run and only if at least one log is rotated -- `rotate`: Log files are rotated this many times before being removed or mailed. -- `sharedscripts`: if true, the sharedscripts options is specified which makes sure prescript and postscript commands are run only once (even if multiple files match the path) +The resource takes the following properties: +- `path`: specifies a single path (string) or multiple paths (array) + that should have logrotation stanzas created in the config file. No + default, this must be specified. -Usage ------ -The default recipe will ensure logrotate is always up to date. +- `cookbook`: The cookbook that continues the template for + logrotate_app config definitions. By default this is `logrotate`. + Users can provide their own template by setting this attribute to + point at a different cookbook. -To create application specific logrotate configs, use the `logrotate_app` definition. For example, to rotate logs for a tomcat application named myapp that writes its log file to `/var/log/tomcat/myapp.log`: +- `template_name`: sets the template source, default is + "logrotate.erb". + +- `template_mode`: the mode to create the logrotate template with + (default: "0440") + +- `template_owner`: the owner of the logrotate template (default: + "root") + +- `template_group`: the group of the logrotate template (default: + "root") + +- `frequency`: sets the frequency for rotation. Default value is + 'weekly'. Valid values are: hourly, daily, weekly, monthly, yearly, + see the logrotate man page for more information. Note that usually + logrotate is configured to be run by cron daily. You have to change + this configuration and run logrotate hourly to be able to really + rotate logs hourly. Hourly rotation requires logrotate v3.8.5 or + higher. + +- `options`: Any logrotate configuration option that doesn't specify a + value. See the logrotate(8) manual page of v3.9.2 or earlier for + details. + +In addition to these properties, any logrotate option that takes a +parameter can be used as a logrotate_app property. For example, to set +the `rotate` option you can use a resource declaration such as: + +```ruby +logrotate_app 'tomcat-myapp' do + path '/var/log/tomcat/myapp.log' + frequency 'daily' + rotate 30 + create '644 root adm' +end +``` + +See the logrotate(8) manual page of v3.9.2 or earlier for the list of +available options. + + +## Usage + +The default recipe will ensure logrotate is always up to date. + +To create application specific logrotate configs, use the +`logrotate_app` definition. For example, to rotate logs for a tomcat +application named myapp that writes its log file to +`/var/log/tomcat/myapp.log`: ```ruby logrotate_app 'tomcat-myapp' do - cookbook 'logrotate' path '/var/log/tomcat/myapp.log' frequency 'daily' rotate 30 @@ -126,7 +177,6 @@ To rotate multiple logfile paths, specify the path as an array: ```ruby logrotate_app 'tomcat-myapp' do - cookbook 'logrotate' path ['/var/log/tomcat/myapp.log', '/opt/local/tomcat/catalina.out'] frequency 'daily' create '644 root adm' @@ -138,7 +188,6 @@ To specify which logrotate options, specify the options as an array: ```ruby logrotate_app 'tomcat-myapp' do - cookbook 'logrotate' path '/var/log/tomcat/myapp.log' options ['missingok', 'delaycompress', 'notifempty'] frequency 'daily' @@ -147,15 +196,16 @@ logrotate_app 'tomcat-myapp' do end ``` +## License & Authors -License & Authors ------------------ +- Author:: Steven Danna () - Author:: Scott M. Likens () - Author:: Joshua Timberman () ```text Copyright 2009, Scott M. Likens Copyright 2011-2012, Chef Software, Inc. +Copyright 2016, Steven Danna 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/logrotate/TESTING.md b/cookbooks/logrotate/TESTING.md deleted file mode 100644 index 0484b9f..0000000 --- a/cookbooks/logrotate/TESTING.md +++ /dev/null @@ -1,49 +0,0 @@ -This cookbook uses a variety of testing components: - -- Unit tests: [ChefSpec](https://github.com/acrmp/chefspec) -- Integration tests: [Test Kitchen](https://github.com/chef/test-kitchen) -- Chef Style lints: [Foodcritic](https://github.com/acrmp/foodcritic) -- Ruby Style lints: [Rubocop](https://github.com/bbatsov/rubocop) - - -Prerequisites -------------- -To develop on this cookbook, you must have a sane Ruby 1.9+ environment. Given the nature of this installation process (and it's variance across multiple operating systems), we will leave this installation process to the user. - -You must also have `bundler` installed: - - $ gem install bundler - -You must also have Vagrant and VirtualBox installed: - -- [Vagrant](https://vagrantup.com) -- [VirtualBox](https://virtualbox.org) - -Once installed, you must install the `vagrant-berkshelf` plugin: - - $ vagrant plugin install vagrant-berkshelf - - -Development ------------ -1. Clone the git repository from GitHub: - - $ git clone git@github.com:stevendanna/logrotate.git - -2. Install the dependencies using bundler: - - $ bundle install - -3. Create a branch for your changes: - - $ git checkout -b my_bug_fix - -4. Make any changes -5. Write tests to support those changes. It is highly recommended you write both unit and integration tests. -6. Run the tests: - - `bundle exec rspec` - - `bundle exec foodcritic .` - - `bundle exec rubocop -l ` - - `bundle exec kitchen test` - -7. Assuming the tests pass, open a Pull Request on GitHub diff --git a/cookbooks/logrotate/attributes/default.rb b/cookbooks/logrotate/attributes/default.rb index 70f86fd..4354527 100644 --- a/cookbooks/logrotate/attributes/default.rb +++ b/cookbooks/logrotate/attributes/default.rb @@ -2,7 +2,9 @@ # Cookbook Name:: logrotate # Attribute:: default # -# Copyright 2013, Chef +# Copyright 2013, Chef Software, Inc +# Copyright 2015-2016, Steven Danna +# Copyright 2016, Bloomberg Finance L.P. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,22 +19,36 @@ # limitations under the License. # -default['logrotate']['global'] = { - 'weekly' => true, - 'rotate' => 4, - 'create' => '', +default["logrotate"]["package"] = { + "name" => "logrotate", + "source" => nil, + "version" => nil, + "provider" => nil, +} - '/var/log/wtmp' => { - 'missingok' => true, - 'monthly' => true, - 'create' => '0664 root utmp', - 'rotate' => 1 +default["logrotate"]["directory"] = "/etc/logrotate.d" +default["logrotate"]["cron"]["install"] = platform?("solaris2") || platform?("aix") +default["logrotate"]["cron"]["name"] = "logrotate" +default["logrotate"]["cron"]["command"] = "/usr/sbin/logrotate /etc/logrotate.conf" +default["logrotate"]["cron"]["minute"] = 35 +default["logrotate"]["cron"]["hour"] = 2 + +default["logrotate"]["global"] = { + "weekly" => true, + "rotate" => 4, + "create" => "", + + "/var/log/wtmp" => { + "missingok" => true, + "monthly" => true, + "create" => "0664 root utmp", + "rotate" => 1, }, - '/var/log/btmp' => { - 'missingok' => true, - 'monthly' => true, - 'create' => '0660 root utmp', - 'rotate' => 1 - } + "/var/log/btmp" => { + "missingok" => true, + "monthly" => true, + "create" => "0660 root utmp", + "rotate" => 1, + }, } diff --git a/cookbooks/logrotate/definitions/logrotate_app.rb b/cookbooks/logrotate/definitions/logrotate_app.rb deleted file mode 100644 index 133a601..0000000 --- a/cookbooks/logrotate/definitions/logrotate_app.rb +++ /dev/null @@ -1,77 +0,0 @@ -# -# Cookbook Name:: logrotate -# Definition:: logrotate_instance -# -# Copyright 2009, Scott M. Likens -# -# 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. -# - -log_rotate_params = { - :enable => true, - :frequency => 'weekly', - :template => 'logrotate.erb', - :cookbook => 'logrotate', - :template_mode => '0440', - :template_owner => 'root', - :template_group => 'root', - :postrotate => nil, - :prerotate => nil, - :firstaction => nil, - :lastaction => nil, - :sharedscripts => false -} - -define(:logrotate_app, log_rotate_params) do - include_recipe 'logrotate::default' - - options_tmp = params[:options] ||= %w(missingok compress delaycompress copytruncate notifempty) - options = options_tmp.respond_to?(:each) ? options_tmp : options_tmp.split - options << 'sharedscripts' if params[:sharedscripts] - - if params[:enable] - invalid_options = options - CookbookLogrotate::DIRECTIVES - - unless invalid_options.empty? - Chef::Log.error("Invalid option(s) passed to logrotate: #{invalid_options.join(', ')}") - raise - end - - logrotate_config = { - :path => Array(params[:path]).map { |path| path.to_s.inspect }.join(' '), - :frequency => params[:frequency], - :options => options - } - CookbookLogrotate::VALUES.each do |opt_name| - logrotate_config[opt_name.to_sym] = params[opt_name.to_sym] - end - - CookbookLogrotate::SCRIPTS.each do |script_name| - logrotate_config[script_name.to_sym] = Array(params[script_name.to_sym]).join("\n") - end - - template "/etc/logrotate.d/#{params[:name]}" do - source params[:template] - cookbook params[:cookbook] - mode params[:template_mode] - owner params[:template_owner] - group params[:template_group] - backup false - variables logrotate_config - end - else - file "/etc/logrotate.d/#{params[:name]}" do - action :delete - end - end -end diff --git a/cookbooks/logrotate/libraries/logrotate_config.rb b/cookbooks/logrotate/libraries/logrotate_config.rb index 479a291..5ad750d 100644 --- a/cookbooks/logrotate/libraries/logrotate_config.rb +++ b/cookbooks/logrotate/libraries/logrotate_config.rb @@ -19,18 +19,18 @@ # Helper module for Logrotate configuration module CookbookLogrotate module CookbookLogrotate - DIRECTIVES = %w(compress copy copytruncate daily dateext + DIRECTIVES = %w{compress copy copytruncate daily dateext dateyesterday delaycompress hourly ifempty mailfirst maillast - missingok monthly nocompress nocopy nocopytruncate nocreate + missingok monthly nocompress nocopy nocopytruncate nocreate nocreateolddir nodelaycompress nodateext nomail nomissingok noolddir - nosharedscripts noshred notifempty sharedscripts shred weekly - yearly) unless const_defined?(:DIRECTIVES) + nosharedscripts noshred notifempty renamecopy sharedscripts shred weekly + yearly} unless const_defined?(:DIRECTIVES) - VALUES = %w(compresscmd uncompresscmd compressext compressoptions - create dateformat include mail extension maxage minsize maxsize - rotate size shredcycles start tabooext su olddir) unless const_defined?(:VALUES) + VALUES = %w{compresscmd uncompresscmd compressext compressoptions + create createolddir dateformat include mail extension maxage minsize maxsize + rotate size shredcycles start tabooext su olddir} unless const_defined?(:VALUES) - SCRIPTS = %w(firstaction prerotate postrotate lastaction preremove) unless const_defined?(:SCRIPTS) + SCRIPTS = %w{firstaction prerotate postrotate lastaction preremove} unless const_defined?(:SCRIPTS) DIRECTIVES_AND_VALUES = DIRECTIVES + VALUES unless const_defined?(:DIRECTIVES_AND_VALUES) @@ -52,11 +52,11 @@ module CookbookLogrotate end def paths_from(hash) - hash.select { |k| !(DIRECTIVES_AND_VALUES.include?(k)) }.reduce({}) do | accum_paths, (path, config) | + hash.select { |k| !(DIRECTIVES_AND_VALUES.include?(k)) }.reduce({}) do |accum_paths, (path, config)| accum_paths[path] = { - 'directives' => directives_from(config), - 'values' => values_from(config), - 'scripts' => scripts_from(config) + "directives" => directives_from(config), + "values" => values_from(config), + "scripts" => scripts_from(config), } accum_paths @@ -65,7 +65,7 @@ module CookbookLogrotate def scripts_from(hash) defined_scripts = hash.select { |k| SCRIPTS.include?(k) } - defined_scripts.reduce({}) do | accum_scripts, (script, lines) | + defined_scripts.reduce({}) do |accum_scripts, (script, lines)| if lines.respond_to?(:join) accum_scripts[script] = lines.join("\n") else diff --git a/cookbooks/logrotate/libraries/matchers.rb b/cookbooks/logrotate/libraries/matchers.rb index f74034a..11171a2 100644 --- a/cookbooks/logrotate/libraries/matchers.rb +++ b/cookbooks/logrotate/libraries/matchers.rb @@ -1,154 +1,9 @@ if defined?(ChefSpec) - def enable_logrotate_app(name) - LogrotateAppMatcher.new(name) + def enable_logrotate_app(resource) + ChefSpec::Matchers::ResourceMatcher.new(:logrotate_app, :enable, resource) end - class LogrotateAppMatcher - def initialize(name) - @name = name - end - - def with(parameters = {}) - params.merge!(parameters) - self - end - - def at_compile_time - raise ArgumentError, 'Cannot specify both .at_converge_time and .at_compile_time!' if @converge_time - @compile_time = true - self - end - - def at_converge_time - raise ArgumentError, 'Cannot specify both .at_compile_time and .at_converge_time!' if @compile_time - @converge_time = true - self - end - - # - # Allow users to specify fancy #with matchers. - # - def method_missing(m, *args, &block) - if m.to_s =~ /^with_(.+)$/ - with($1.to_sym => args.first) - self - else - super - end - end - - def description - %Q{"enable" #{@name} "logrotate_app"} - end - - def matches?(runner) - @runner = runner - - if resource - resource.performed_action?('create') && unmatched_parameters.empty? && correct_phase? - else - false - end - end - - def failure_message - if resource - if resource.performed_action?('create') - if unmatched_parameters.empty? - if @compile_time - %Q{expected "#{resource}" to be run at compile time} - else - %Q{expected "#{resource}" to be run at converge time} - end - else - %Q{expected "#{resource}" to have parameters:} \ - "\n\n" \ - " " + unmatched_parameters.collect { |parameter, h| - "#{parameter} #{h[:expected].inspect}, was #{h[:actual].inspect}" - }.join("\n ") - end - else - %Q{expected "#{resource}" actions #{resource.performed_actions.inspect}} \ - " to include : create" - end - else - %Q{expected "logrotate_app[#{@name}] with"} \ - " enable : true to be in Chef run. Other" \ - " #{@name} resources:" \ - "\n\n" \ - " " + similar_resources.map(&:to_s).join("\n ") + "\n " - end - end - - def failure_message_when_negated - if resource - message = %Q{expected "#{resource}" actions #{resource.performed_actions.inspect} to not exist} - else - message = %Q{expected "#{resource}" to not exist} - end - - message << " at compile time" if @compile_time - message << " at converge time" if @converge_time - message - end - - private - def unmatched_parameters - return @_unmatched_parameters if @_unmatched_parameters - - @_unmatched_parameters = {} - - params.each do |parameter, expected| - unless matches_parameter?(parameter, expected) - @_unmatched_parameters[parameter] = { - :expected => expected, - :actual => safe_send(parameter), - } - end - end - - @_unmatched_parameters - end - - def matches_parameter?(parameter, expected) - # Chef 11+ stores the source parameter internally as an Array - # - case parameter - when :cookbook - expected === safe_send(parameter) - when :path - Array(expected == safe_send('variables')[parameter]) - else - expected == safe_send('variables')[parameter] - end - end - - def correct_phase? - if @compile_time - resource.performed_action('create')[:compile_time] - elsif @converge_time - resource.performed_action('create')[:converge_time] - else - true - end - end - - def safe_send(parameter) - resource.send(parameter) - rescue NoMethodError - nil - end - - def similar_resources - @_similar_resources ||= @runner.find_resources('template') - end - - def resource - @_resource ||= @runner.find_resource('template', "/etc/logrotate.d/#{@name}") - end - - def params - @_params ||= {} - end + def disable_logrotate_app(resource) + ChefSpec::Matchers::ResourceMatcher.new(:logrotate_app, :disable, resource) end end diff --git a/cookbooks/logrotate/metadata.json b/cookbooks/logrotate/metadata.json index 3bf042e..6222e50 100644 --- a/cookbooks/logrotate/metadata.json +++ b/cookbooks/logrotate/metadata.json @@ -16,7 +16,7 @@ "ubuntu": ">= 0.0.0" }, "dependencies": { - + "compat_resource": ">= 0.0.0" }, "recommendations": { @@ -42,7 +42,17 @@ "recipes": { "logrotate": "Installs logrotate package" }, - "version": "1.9.2", - "source_url": "", - "issues_url": "" + "version": "2.1.0", + "source_url": "https://github.com/stevendanna/logrotate", + "issues_url": "https://github.com/stevendanna/logrotate/issues", + "privacy": false, + "chef_versions": [ + + ], + "ohai_versions": [ + + ], + "gems": [ + + ] } diff --git a/cookbooks/logrotate/metadata.rb b/cookbooks/logrotate/metadata.rb index dcdb9d5..9134e97 100644 --- a/cookbooks/logrotate/metadata.rb +++ b/cookbooks/logrotate/metadata.rb @@ -1,13 +1,18 @@ -name 'logrotate' -maintainer 'Steven Danna' -maintainer_email 'steve@chef.io' -license 'Apache 2.0' -description 'Installs logrotate package and provides a definition for logrotate configs' -long_description 'Installs the logrotate package, manages /etc/logrotate.conf, and provides a logrotate_app definition.' -version '1.9.2' +name "logrotate" +maintainer "Steven Danna" +maintainer_email "steve@chef.io" +license "Apache 2.0" +description "Installs logrotate package and provides a definition for logrotate configs" +long_description "Installs the logrotate package, manages /etc/logrotate.conf, and provides a logrotate_app definition." +version "2.1.0" -recipe 'logrotate', 'Installs logrotate package' -provides 'logrotate_app' +source_url "https://github.com/stevendanna/logrotate" if respond_to?(:source_url) +issues_url "https://github.com/stevendanna/logrotate/issues" if respond_to?(:issues_url) + +recipe "logrotate", "Installs logrotate package" +provides "logrotate_app" + +depends "compat_resource" %w{amazon centos debian fedora redhat scientific solaris2 ubuntu}.each do |platform| supports platform diff --git a/cookbooks/logrotate/recipes/default.rb b/cookbooks/logrotate/recipes/default.rb index 3486271..80fd168 100644 --- a/cookbooks/logrotate/recipes/default.rb +++ b/cookbooks/logrotate/recipes/default.rb @@ -3,6 +3,8 @@ # Recipe:: default # # Copyright 2009-2013, Chef Software, Inc. +# Copyright 2015-2016, Steven Danna +# Copyright 2016, Bloomberg Finance L.P. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -16,20 +18,25 @@ # See the License for the specific language governing permissions and # limitations under the License. # +return if platform?("windows") -package 'logrotate' - -directory "/etc/logrotate.d" do - owner "root" - group "root" - mode "0755" - action :create +package node["logrotate"]["package"]["name"] do + provider node["logrotate"]["package"]["provider"] if node["logrotate"]["package"]["provider"] + source node["logrotate"]["package"]["source"] if node["logrotate"]["package"]["source"] + version node["logrotate"]["package"]["version"] if node["logrotate"]["package"]["version"] + action :upgrade end -if platform? "solaris2" # ~FC023 style preference - cron "logrotate" do - minute "35" - hour "7" - command "/usr/sbin/logrotate /etc/logrotate.conf" +directory node["logrotate"]["directory"] do + owner "root" + group node["root_group"] + mode "0755" +end + +if node["logrotate"]["cron"]["install"] # ~FC023 + cron node["logrotate"]["cron"]["name"] do + minute node["logrotate"]["cron"]["minute"] + hour node["logrotate"]["cron"]["hour"] + command node["logrotate"]["cron"]["command"] end end diff --git a/cookbooks/logrotate/recipes/global.rb b/cookbooks/logrotate/recipes/global.rb index 2180c92..2808806 100644 --- a/cookbooks/logrotate/recipes/global.rb +++ b/cookbooks/logrotate/recipes/global.rb @@ -17,13 +17,13 @@ # limitations under the License. # -include_recipe 'logrotate::default' +include_recipe "logrotate::default" -parsed_configuration = CookbookLogrotate::LogrotateConfiguration.from_hash(node['logrotate']['global'].to_hash) +parsed_configuration = CookbookLogrotate::LogrotateConfiguration.from_hash(node["logrotate"]["global"].to_hash) -template '/etc/logrotate.conf' do - source 'logrotate-global.erb' - mode '0644' +template "/etc/logrotate.conf" do + source "logrotate-global.erb" + mode "0644" variables( :configuration => parsed_configuration ) diff --git a/cookbooks/logrotate/resources/app.rb b/cookbooks/logrotate/resources/app.rb new file mode 100644 index 0000000..8c5fb2b --- /dev/null +++ b/cookbooks/logrotate/resources/app.rb @@ -0,0 +1,116 @@ +# +# Copyright 2016, Steven Danna +# +# 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 :logrotate_app + +property :path, [String, Array], required: true +property :frequency, String, default: "weekly" +property :cookbook, default: "logrotate" +property :template_name, default: "logrotate.erb" +property :template_mode, default: "0644" +property :template_owner, default: "root" +property :template_group, default: "root" +property :base_dir, String, default: "/etc/logrotate.d" + +property :options, [Array, String], default: %w{missingok compress delaycompress copytruncate notifempty} + +default_action :enable + +CookbookLogrotate::SCRIPTS.each do |script_name| + property script_name.to_sym, coerce: Proc.new { |val| Array(val).join("\n") } +end + +CookbookLogrotate::VALUES.each do |configurable_name| + property configurable_name.to_sym +end + +# Deprecated options +property :sharedscripts, [TrueClass, FalseClass], default: false +property :enable, [TrueClass, FalseClass], default: true + +action :enable do + if !new_resource.enable + Chef::Log.deprecation "Use `action :disable` rather than `enable false` in the logrotate_app resource" + action_disable + return true + end + + logrotate_config = { + # The path should be a space separated list of quoted filesystem paths + path: Array(new_resource.path).map { |path| path.to_s.inspect }.join(" "), + frequency: new_resource.frequency, + directives: handle_options(new_resource), + scripts: handle_scripts(new_resource), + configurables: handle_configurables(new_resource), + } + + directory new_resource.base_dir do + owner "root" + group node["root_group"] + mode "0755" + action :create + end + + template "#{new_resource.base_dir}/#{new_resource.name}" do + source new_resource.template_name + cookbook new_resource.cookbook + mode new_resource.template_mode + owner new_resource.template_owner + group new_resource.template_group + backup false + variables logrotate_config + end +end + +action :disable do + file "#{new_resource.base_dir}/#{new_resource.name}" do + action :delete + end +end + +def handle_configurables(new_resource) + configurables = {} + CookbookLogrotate::VALUES.each do |opt_name| + if value = new_resource.send(opt_name.to_sym) + configurables[opt_name] = value + end + end + configurables +end + +def handle_scripts(new_resource) + scripts = {} + CookbookLogrotate::SCRIPTS.each do |script_name| + if script_body = new_resource.send(script_name.to_sym) + scripts[script_name] = script_body + end + end + scripts +end + +def handle_options(new_resource) + opts = if new_resource.options.is_a?(Array) + new_resource.options.dup + else + new_resource.options.split + end + + if new_resource.sharedscripts + Chef::Log.deprecation("The sharedscripts resource property is deprecated. Use the options property instead to set this value") + opts << "sharedscripts" + end + opts +end diff --git a/cookbooks/logrotate/templates/default/logrotate.erb b/cookbooks/logrotate/templates/default/logrotate.erb index f8e8d8d..3e838cd 100644 --- a/cookbooks/logrotate/templates/default/logrotate.erb +++ b/cookbooks/logrotate/templates/default/logrotate.erb @@ -5,19 +5,15 @@ <%- if @frequency %> <%= @frequency %> <%- end %> -<%- CookbookLogrotate::VALUES.each do |opt_name| %> - <% if instance_variable_get("@#{opt_name}") %> - <%= "#{opt_name} #{instance_variable_get("@#{opt_name}")}" %> - <%- end %> +<%- @configurables.each do |name, value| %> + <%= "#{name} #{value}" %> <%- end %> -<% @options.each do |o| -%> +<% @directives.each do |o| -%> <%= o %> <% end -%> -<%- CookbookLogrotate::SCRIPTS.each do |script_name| %> - <% unless instance_variable_get("@#{script_name}").empty? %> +<%- @scripts.each do |script_name, script| %> <%= script_name %> - <%= instance_variable_get("@#{script_name}") %> + <%= script %> endscript - <%- end %> <%- end %> } From 2f8de9100888bb074b2a2b03666d72ef9306eb42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Tue, 2 May 2017 17:43:02 +0200 Subject: [PATCH 43/83] Initial parity cookbook Supports installing multiple instances of Parity on the same machine, running on different ports Refs #15 --- site-cookbooks/kosmos-parity/CHANGELOG.md | 9 +++ site-cookbooks/kosmos-parity/README.md | 53 ++++++++++++++++++ .../kosmos-parity/attributes/default.rb | 1 + site-cookbooks/kosmos-parity/metadata.rb | 9 +++ .../kosmos-parity/recipes/default.rb | 56 +++++++++++++++++++ .../kosmos-parity/resources/node.rb | 50 +++++++++++++++++ .../templates/default/config.toml.erb | 13 +++++ .../default/parity.systemd.service.erb | 11 ++++ 8 files changed, 202 insertions(+) create mode 100644 site-cookbooks/kosmos-parity/CHANGELOG.md create mode 100644 site-cookbooks/kosmos-parity/README.md create mode 100644 site-cookbooks/kosmos-parity/attributes/default.rb create mode 100644 site-cookbooks/kosmos-parity/metadata.rb create mode 100644 site-cookbooks/kosmos-parity/recipes/default.rb create mode 100644 site-cookbooks/kosmos-parity/resources/node.rb create mode 100644 site-cookbooks/kosmos-parity/templates/default/config.toml.erb create mode 100644 site-cookbooks/kosmos-parity/templates/default/parity.systemd.service.erb diff --git a/site-cookbooks/kosmos-parity/CHANGELOG.md b/site-cookbooks/kosmos-parity/CHANGELOG.md new file mode 100644 index 0000000..fa0d873 --- /dev/null +++ b/site-cookbooks/kosmos-parity/CHANGELOG.md @@ -0,0 +1,9 @@ +# kosmos-parity CHANGELOG + +## 0.1.0 +- [Greg Karékinian] - Initial release of kosmos-parity + +- - - +Check the [Markdown Syntax Guide](http://daringfireball.net/projects/markdown/syntax) for help with Markdown. + +The [Github Flavored Markdown page](http://github.github.com/github-flavored-markdown/) describes the differences between markdown on github and standard markdown. diff --git a/site-cookbooks/kosmos-parity/README.md b/site-cookbooks/kosmos-parity/README.md new file mode 100644 index 0000000..7357580 --- /dev/null +++ b/site-cookbooks/kosmos-parity/README.md @@ -0,0 +1,53 @@ +# kosmos-parity Cookbook + +This cookbook installs [Parity](https://parity.io/) nodes + +## Requirements + +### Platforms + +- Ubuntu + +### Chef + +- Chef 12.1 or later + +## Attributes + +### kosmos-parity::default + + + + + + + + + + + + + + +
KeyTypeDescriptionDefault
['kosmos-parity']['home_path']StringThe parity user's home path/home/parity
+ +## Usage + +### kosmos-parity::default + +Just include `kosmos-parity` in your node's `run_list`: + +```json +{ + "name":"my_node", + "run_list": [ + "recipe[kosmos-parity]" + ] +} +``` + +## License and Authors + +Authors: + +* Greg Karékinian diff --git a/site-cookbooks/kosmos-parity/attributes/default.rb b/site-cookbooks/kosmos-parity/attributes/default.rb new file mode 100644 index 0000000..6910075 --- /dev/null +++ b/site-cookbooks/kosmos-parity/attributes/default.rb @@ -0,0 +1 @@ +node.default['kosmos-parity']['home_path'] = "/home/parity" diff --git a/site-cookbooks/kosmos-parity/metadata.rb b/site-cookbooks/kosmos-parity/metadata.rb new file mode 100644 index 0000000..a29b08d --- /dev/null +++ b/site-cookbooks/kosmos-parity/metadata.rb @@ -0,0 +1,9 @@ +name 'kosmos-parity' +maintainer 'Kosmos' +maintainer_email 'mail@kosmos.org' +license 'All rights reserved' +description 'Installs/Configures kosmos-parity' +long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) +version '0.1.0' + +depends 'ark' diff --git a/site-cookbooks/kosmos-parity/recipes/default.rb b/site-cookbooks/kosmos-parity/recipes/default.rb new file mode 100644 index 0000000..674eb18 --- /dev/null +++ b/site-cookbooks/kosmos-parity/recipes/default.rb @@ -0,0 +1,56 @@ +# +# Cookbook Name:: kosmos-parity +# Recipe:: default +# +# Copyright 2017, Kosmos +# +# All rights reserved - Do Not Redistribute +# + +group "parity" do + gid 72748 +end + +user "parity" do + system true + manage_home true + comment "parity user" + uid 72748 + gid 72748 +end + +parity_version = "1.6.6" +parity_package_path = "#{Chef::Config[:file_cache_path]}/parity_#{parity_version}_amd64.deb" +remote_file parity_package_path do + source "https://d1h4xl4cr1h0mo.cloudfront.net/v#{parity_version}/x86_64-unknown-linux-gnu/parity_#{parity_version}_amd64.deb" + mode 0750 + notifies :install, "dpkg_package[parity]", :immediately +end + +dpkg_package "parity" do + source parity_package_path +end + +parity_node "dev" do + config chain: "dev", + network_port: 30303, + json_rpc_port: 8545, + dapps_port: 8090, + ui_port: 8180 +end + +parity_node "testnet" do + config chain: "ropsten", + network_port: 30304, + json_rpc_port: 8546, + dapps_port: 8091, + ui_port: 8181 +end + +parity_node "mainnet" do + config chain: "homestead", + network_port: 30305, + json_rpc_port: 8547, + dapps_port: 8092, + ui_port: 8182 +end diff --git a/site-cookbooks/kosmos-parity/resources/node.rb b/site-cookbooks/kosmos-parity/resources/node.rb new file mode 100644 index 0000000..5301fc0 --- /dev/null +++ b/site-cookbooks/kosmos-parity/resources/node.rb @@ -0,0 +1,50 @@ +provides :parity_node + +property :name, String, name_property: true +property :config, Hash + +action :enable do + node_name = name + + base_path = "#{node['kosmos-parity']['home_path']}/.local/share/io.parity.ethereum/#{name}" + + directory base_path do + recursive true + owner "parity" + group "parity" + end + + %w(chains keys).each do |subfolder| + directory "#{base_path}/#{subfolder}" do + recursive true + owner "parity" + group "parity" + end + end + + config_file = "#{base_path}/config.toml" + + template config_file do + source "config.toml.erb" + owner "parity" + group "parity" + variables config.merge(base_path: base_path) + end + + execute "systemctl daemon-reload" do + command "systemctl daemon-reload" + action :nothing + end + + parity_service = "parity_#{node_name}" + template "/lib/systemd/system/#{parity_service}.service" do + source "parity.systemd.service.erb" + variables config_file: config_file + notifies :run, "execute[systemctl daemon-reload]", :delayed + notifies :restart, "service[#{parity_service}]", :delayed + end + + service parity_service do + action [:enable, :start] + end +end diff --git a/site-cookbooks/kosmos-parity/templates/default/config.toml.erb b/site-cookbooks/kosmos-parity/templates/default/config.toml.erb new file mode 100644 index 0000000..034c2e3 --- /dev/null +++ b/site-cookbooks/kosmos-parity/templates/default/config.toml.erb @@ -0,0 +1,13 @@ +[parity] +chain = "<%= @chain %>" +base_path = "<%= @base_path %>" +[network] +port = <%= @network_port %> +[rpc] +# JSON-RPC over HTTP +port = <%= @json_rpc_port %> +[dapps] +# Dapps Server +port = <%= @dapps_port %> +[ui] +port = <%= @ui_port %> diff --git a/site-cookbooks/kosmos-parity/templates/default/parity.systemd.service.erb b/site-cookbooks/kosmos-parity/templates/default/parity.systemd.service.erb new file mode 100644 index 0000000..073e82d --- /dev/null +++ b/site-cookbooks/kosmos-parity/templates/default/parity.systemd.service.erb @@ -0,0 +1,11 @@ +[Unit] +Description=Parity Daemon (<%= @environment %>) +After=network.target + +[Service] +ExecStart=/usr/bin/parity --config <%= @config_file %> $ARGS +User=parity +Group=parity + +[Install] +WantedBy=default.target From 462e7ff8587c11da3625cffd11371917022b9d04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Tue, 2 May 2017 18:07:46 +0200 Subject: [PATCH 44/83] Move version and checksum to attributes --- site-cookbooks/kosmos-parity/attributes/default.rb | 2 ++ site-cookbooks/kosmos-parity/recipes/default.rb | 7 ++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/site-cookbooks/kosmos-parity/attributes/default.rb b/site-cookbooks/kosmos-parity/attributes/default.rb index 6910075..4f8dca5 100644 --- a/site-cookbooks/kosmos-parity/attributes/default.rb +++ b/site-cookbooks/kosmos-parity/attributes/default.rb @@ -1 +1,3 @@ node.default['kosmos-parity']['home_path'] = "/home/parity" +node.default['kosmos-parity']['version'] = "1.6.6" +node.default['kosmos-parity']['checksum'] = '99ed4c0bf8cf7e0b143d8901f51c666d743844b0788ab03ccacb1f4538bfd085' diff --git a/site-cookbooks/kosmos-parity/recipes/default.rb b/site-cookbooks/kosmos-parity/recipes/default.rb index 674eb18..26d2487 100644 --- a/site-cookbooks/kosmos-parity/recipes/default.rb +++ b/site-cookbooks/kosmos-parity/recipes/default.rb @@ -19,11 +19,12 @@ user "parity" do gid 72748 end -parity_version = "1.6.6" +parity_version = node['kosmos-parity']['version'] parity_package_path = "#{Chef::Config[:file_cache_path]}/parity_#{parity_version}_amd64.deb" remote_file parity_package_path do - source "https://d1h4xl4cr1h0mo.cloudfront.net/v#{parity_version}/x86_64-unknown-linux-gnu/parity_#{parity_version}_amd64.deb" - mode 0750 + source "https://d1h4xl4cr1h0mo.cloudfront.net/v#{parity_version}/x86_64-unknown-linux-gnu/parity_#{parity_version}_amd64.deb" + checksum node['kosmos-parity']['checksum'] + mode 0750 notifies :install, "dpkg_package[parity]", :immediately end From e2b483eb3fb095830bc235e1dcc3d689811e9657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Wed, 3 May 2017 09:53:45 +0200 Subject: [PATCH 45/83] Generate the config files using a TOML parser Now we don't need to change both the template and the resources to add options --- site-cookbooks/kosmos-parity/metadata.rb | 2 + .../kosmos-parity/recipes/default.rb | 60 ++++++++++++++----- .../kosmos-parity/resources/node.rb | 8 ++- .../templates/default/config.toml.erb | 13 ---- 4 files changed, 52 insertions(+), 31 deletions(-) delete mode 100644 site-cookbooks/kosmos-parity/templates/default/config.toml.erb diff --git a/site-cookbooks/kosmos-parity/metadata.rb b/site-cookbooks/kosmos-parity/metadata.rb index a29b08d..db4e0f4 100644 --- a/site-cookbooks/kosmos-parity/metadata.rb +++ b/site-cookbooks/kosmos-parity/metadata.rb @@ -6,4 +6,6 @@ description 'Installs/Configures kosmos-parity' long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) version '0.1.0' +gem 'toml' + depends 'ark' diff --git a/site-cookbooks/kosmos-parity/recipes/default.rb b/site-cookbooks/kosmos-parity/recipes/default.rb index 26d2487..d70226f 100644 --- a/site-cookbooks/kosmos-parity/recipes/default.rb +++ b/site-cookbooks/kosmos-parity/recipes/default.rb @@ -33,25 +33,55 @@ dpkg_package "parity" do end parity_node "dev" do - config chain: "dev", - network_port: 30303, - json_rpc_port: 8545, - dapps_port: 8090, - ui_port: 8180 + config parity: { + chain: "dev", + }, + network: { + port: 30303, + }, + rpc: { + port: 8545, + }, + dapps: { + port: 8090, + }, + ui: { + port: 8180, + } end parity_node "testnet" do - config chain: "ropsten", - network_port: 30304, - json_rpc_port: 8546, - dapps_port: 8091, - ui_port: 8181 + config parity: { + chain: "ropsten", + }, + network: { + port: 30304, + }, + rpc: { + port: 8546, + }, + dapps: { + port: 8091, + }, + ui: { + port: 8181, + } end parity_node "mainnet" do - config chain: "homestead", - network_port: 30305, - json_rpc_port: 8547, - dapps_port: 8092, - ui_port: 8182 + config parity: { + chain: "homestead", + }, + network: { + port: 30305, + }, + rpc: { + port: 8547, + }, + dapps: { + port: 8092, + }, + ui: { + port: 8182, + } end diff --git a/site-cookbooks/kosmos-parity/resources/node.rb b/site-cookbooks/kosmos-parity/resources/node.rb index 5301fc0..8b6fb68 100644 --- a/site-cookbooks/kosmos-parity/resources/node.rb +++ b/site-cookbooks/kosmos-parity/resources/node.rb @@ -1,3 +1,5 @@ +require 'toml' + provides :parity_node property :name, String, name_property: true @@ -7,6 +9,7 @@ action :enable do node_name = name base_path = "#{node['kosmos-parity']['home_path']}/.local/share/io.parity.ethereum/#{name}" + config[:parity][:base_path] = base_path directory base_path do recursive true @@ -24,11 +27,10 @@ action :enable do config_file = "#{base_path}/config.toml" - template config_file do - source "config.toml.erb" + file config_file do + content TOML::Generator.new(config).body owner "parity" group "parity" - variables config.merge(base_path: base_path) end execute "systemctl daemon-reload" do diff --git a/site-cookbooks/kosmos-parity/templates/default/config.toml.erb b/site-cookbooks/kosmos-parity/templates/default/config.toml.erb deleted file mode 100644 index 034c2e3..0000000 --- a/site-cookbooks/kosmos-parity/templates/default/config.toml.erb +++ /dev/null @@ -1,13 +0,0 @@ -[parity] -chain = "<%= @chain %>" -base_path = "<%= @base_path %>" -[network] -port = <%= @network_port %> -[rpc] -# JSON-RPC over HTTP -port = <%= @json_rpc_port %> -[dapps] -# Dapps Server -port = <%= @dapps_port %> -[ui] -port = <%= @ui_port %> From 826b008fc0948f2c328413e0824b6504764a27a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Wed, 3 May 2017 18:24:57 +0200 Subject: [PATCH 46/83] Split node config into separate recipes, support account creation The account is automatically created and added to the list of accounts that are unlocked (can send without a password) --- .../kosmos-parity/recipes/default.rb | 54 ------------------ .../kosmos-parity/recipes/node_dev.rb | 34 +++++++++++ .../kosmos-parity/recipes/node_mainnet.rb | 26 +++++++++ .../kosmos-parity/recipes/node_testnet.rb | 27 +++++++++ .../kosmos-parity/resources/node.rb | 56 ++++++++++++++++--- 5 files changed, 135 insertions(+), 62 deletions(-) create mode 100644 site-cookbooks/kosmos-parity/recipes/node_dev.rb create mode 100644 site-cookbooks/kosmos-parity/recipes/node_mainnet.rb create mode 100644 site-cookbooks/kosmos-parity/recipes/node_testnet.rb diff --git a/site-cookbooks/kosmos-parity/recipes/default.rb b/site-cookbooks/kosmos-parity/recipes/default.rb index d70226f..865440e 100644 --- a/site-cookbooks/kosmos-parity/recipes/default.rb +++ b/site-cookbooks/kosmos-parity/recipes/default.rb @@ -31,57 +31,3 @@ end dpkg_package "parity" do source parity_package_path end - -parity_node "dev" do - config parity: { - chain: "dev", - }, - network: { - port: 30303, - }, - rpc: { - port: 8545, - }, - dapps: { - port: 8090, - }, - ui: { - port: 8180, - } -end - -parity_node "testnet" do - config parity: { - chain: "ropsten", - }, - network: { - port: 30304, - }, - rpc: { - port: 8546, - }, - dapps: { - port: 8091, - }, - ui: { - port: 8181, - } -end - -parity_node "mainnet" do - config parity: { - chain: "homestead", - }, - network: { - port: 30305, - }, - rpc: { - port: 8547, - }, - dapps: { - port: 8092, - }, - ui: { - port: 8182, - } -end diff --git a/site-cookbooks/kosmos-parity/recipes/node_dev.rb b/site-cookbooks/kosmos-parity/recipes/node_dev.rb new file mode 100644 index 0000000..d05ddd2 --- /dev/null +++ b/site-cookbooks/kosmos-parity/recipes/node_dev.rb @@ -0,0 +1,34 @@ +# +# Cookbook Name:: kosmos-parity +# Recipe:: node_dev +# +# Copyright 2017, Kosmos +# +# All rights reserved - Do Not Redistribute +# + +parity_node "dev" do + config parity: { + chain: "dev", + no_download: true, # Don't Download Updates + }, + network: { + port: 30303, + warp: true, + }, + rpc: { + port: 8545, + cors: "*", + }, + dapps: { + port: 8090, + }, + ui: { + port: 8180, + force: true, + }, + mining: { + reseal_min_period: 0, + } +end + diff --git a/site-cookbooks/kosmos-parity/recipes/node_mainnet.rb b/site-cookbooks/kosmos-parity/recipes/node_mainnet.rb new file mode 100644 index 0000000..1dbd33d --- /dev/null +++ b/site-cookbooks/kosmos-parity/recipes/node_mainnet.rb @@ -0,0 +1,26 @@ +# +# Cookbook Name:: kosmos-parity +# Recipe:: node_mainnet +# +# Copyright 2017, Kosmos +# +# All rights reserved - Do Not Redistribute +# + +parity_node "mainnet" do + config parity: { + chain: "homestead", + }, + network: { + port: 30305, + }, + rpc: { + port: 8547, + }, + dapps: { + port: 8092, + }, + ui: { + port: 8182, + } +end diff --git a/site-cookbooks/kosmos-parity/recipes/node_testnet.rb b/site-cookbooks/kosmos-parity/recipes/node_testnet.rb new file mode 100644 index 0000000..9fb08b0 --- /dev/null +++ b/site-cookbooks/kosmos-parity/recipes/node_testnet.rb @@ -0,0 +1,27 @@ +# +# Cookbook Name:: kosmos-parity +# Recipe:: node_testnet +# +# Copyright 2017, Kosmos +# +# All rights reserved - Do Not Redistribute +# + +parity_node "testnet" do + config parity: { + chain: "ropsten", + }, + network: { + port: 30304, + }, + rpc: { + port: 8546, + }, + dapps: { + port: 8091, + }, + ui: { + port: 8181, + } +end + diff --git a/site-cookbooks/kosmos-parity/resources/node.rb b/site-cookbooks/kosmos-parity/resources/node.rb index 8b6fb68..d7ac731 100644 --- a/site-cookbooks/kosmos-parity/resources/node.rb +++ b/site-cookbooks/kosmos-parity/resources/node.rb @@ -6,10 +6,16 @@ property :name, String, name_property: true property :config, Hash action :enable do - node_name = name + include_recipe "kosmos-parity::default" + node_name = name + parity_service = "parity_#{node_name}" base_path = "#{node['kosmos-parity']['home_path']}/.local/share/io.parity.ethereum/#{name}" + config_path = "#{base_path}/config.toml" + config[:parity][:base_path] = base_path + config[:account] = {} + config[:account][:password] = ["#{base_path}/password"] directory base_path do recursive true @@ -25,12 +31,47 @@ action :enable do end end - config_file = "#{base_path}/config.toml" + node_path = "#{node['kosmos-parity']['home_path']}/.local/share/io.parity.ethereum/dev" + password_path = "#{node_path}/password" - file config_file do - content TOML::Generator.new(config).body - owner "parity" - group "parity" + file password_path do + content "parityparity" + owner "parity" + group "parity" + mode 0640 + end + + ruby_block "generate config" do + block do + parity_account_list = Mixlib::ShellOut.new( + "parity account list --chain #{config[:parity][:chain]} --base-path #{base_path}", + user: "parity" + ) + parity_account_list.run_command + + parity_account = parity_account_list.stdout.strip.gsub(/[(\[|\])]/, '') + + if parity_account.empty? + parity_account_create = Mixlib::ShellOut.new( + "parity account new --chain #{config[:parity][:chain]} --base-path #{base_path} --password #{base_path}/password", + user: "parity" + ) + parity_account_create.run_command + + parity_account = parity_account_create.stdout.strip + end + + config[:account][:unlock] = [parity_account] + + file "config" do + path config_path + content TOML::Generator.new(config).body + owner "parity" + group "parity" + mode 0640 + notifies :restart, "service[#{parity_service}]", :delayed + end + end end execute "systemctl daemon-reload" do @@ -38,10 +79,9 @@ action :enable do action :nothing end - parity_service = "parity_#{node_name}" template "/lib/systemd/system/#{parity_service}.service" do source "parity.systemd.service.erb" - variables config_file: config_file + variables config_file: config_path notifies :run, "execute[systemctl daemon-reload]", :delayed notifies :restart, "service[#{parity_service}]", :delayed end From 37ab52902b2e90f68321308d5ecbd456e950f3d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Wed, 3 May 2017 19:05:43 +0200 Subject: [PATCH 47/83] Use a password attribute in the parity_node resource The mainnet and testnet nodes use data from an encrypted data bag Also fix a bug with the resource (hardcoded "dev" name instead of the name attribute) --- data_bags/credentials/parity.json | 15 +++++++++++++++ site-cookbooks/kosmos-parity/recipes/node_dev.rb | 1 + .../kosmos-parity/recipes/node_mainnet.rb | 3 +++ .../kosmos-parity/recipes/node_testnet.rb | 4 ++++ site-cookbooks/kosmos-parity/resources/node.rb | 9 +++++---- 5 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 data_bags/credentials/parity.json diff --git a/data_bags/credentials/parity.json b/data_bags/credentials/parity.json new file mode 100644 index 0000000..94ab413 --- /dev/null +++ b/data_bags/credentials/parity.json @@ -0,0 +1,15 @@ +{ + "id": "parity", + "testnet_password": { + "encrypted_data": "nPYzGCz9YkH7DyyYqEVzXMTK2Wim25jgP7NvO3epMR+J9Xu3vBG2kiQ6Wx0D\ngxM7\n", + "iv": "CuLNb2eNcBuoI1NuHf6j0g==\n", + "version": 1, + "cipher": "aes-256-cbc" + }, + "mainnet_password": { + "encrypted_data": "PqmxQnvGKVEs0/YuZB1M2VO45Zk3Hqg9bXsgrX5wvM9bFXPjg9/xv7AK215d\n3FrZEFiV9PNyqbfjTcCpPkkdbDEvuJ8n/+mnFshEH+7+T+I=\n", + "iv": "HjNL7eKlDwWE37ZTVa62rA==\n", + "version": 1, + "cipher": "aes-256-cbc" + } +} \ No newline at end of file diff --git a/site-cookbooks/kosmos-parity/recipes/node_dev.rb b/site-cookbooks/kosmos-parity/recipes/node_dev.rb index d05ddd2..0e67c59 100644 --- a/site-cookbooks/kosmos-parity/recipes/node_dev.rb +++ b/site-cookbooks/kosmos-parity/recipes/node_dev.rb @@ -8,6 +8,7 @@ # parity_node "dev" do + password "parityparity" config parity: { chain: "dev", no_download: true, # Don't Download Updates diff --git a/site-cookbooks/kosmos-parity/recipes/node_mainnet.rb b/site-cookbooks/kosmos-parity/recipes/node_mainnet.rb index 1dbd33d..9c5177a 100644 --- a/site-cookbooks/kosmos-parity/recipes/node_mainnet.rb +++ b/site-cookbooks/kosmos-parity/recipes/node_mainnet.rb @@ -7,7 +7,10 @@ # All rights reserved - Do Not Redistribute # +credentials = Chef::EncryptedDataBagItem.load('credentials', 'parity') + parity_node "mainnet" do + password credentials["mainnet_password"] config parity: { chain: "homestead", }, diff --git a/site-cookbooks/kosmos-parity/recipes/node_testnet.rb b/site-cookbooks/kosmos-parity/recipes/node_testnet.rb index 9fb08b0..f95c91e 100644 --- a/site-cookbooks/kosmos-parity/recipes/node_testnet.rb +++ b/site-cookbooks/kosmos-parity/recipes/node_testnet.rb @@ -7,7 +7,11 @@ # All rights reserved - Do Not Redistribute # +credentials = Chef::EncryptedDataBagItem.load('credentials', 'parity') +account_password = credentials["testnet_password"] + parity_node "testnet" do + password account_password config parity: { chain: "ropsten", }, diff --git a/site-cookbooks/kosmos-parity/resources/node.rb b/site-cookbooks/kosmos-parity/resources/node.rb index d7ac731..a2f180b 100644 --- a/site-cookbooks/kosmos-parity/resources/node.rb +++ b/site-cookbooks/kosmos-parity/resources/node.rb @@ -2,8 +2,9 @@ require 'toml' provides :parity_node -property :name, String, name_property: true -property :config, Hash +property :name, String, name_property: true, required: true +property :config, Hash, required: true +property :password, String, required: true action :enable do include_recipe "kosmos-parity::default" @@ -31,11 +32,11 @@ action :enable do end end - node_path = "#{node['kosmos-parity']['home_path']}/.local/share/io.parity.ethereum/dev" + node_path = "#{node['kosmos-parity']['home_path']}/.local/share/io.parity.ethereum/#{node_name}" password_path = "#{node_path}/password" file password_path do - content "parityparity" + content password owner "parity" group "parity" mode 0640 From fcf3b0b0dc7156780ca0972d00908005be58ebf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Wed, 3 May 2017 19:08:38 +0200 Subject: [PATCH 48/83] Remove unnecessary variable --- site-cookbooks/kosmos-parity/recipes/node_testnet.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/site-cookbooks/kosmos-parity/recipes/node_testnet.rb b/site-cookbooks/kosmos-parity/recipes/node_testnet.rb index f95c91e..b27cd8a 100644 --- a/site-cookbooks/kosmos-parity/recipes/node_testnet.rb +++ b/site-cookbooks/kosmos-parity/recipes/node_testnet.rb @@ -8,10 +8,9 @@ # credentials = Chef::EncryptedDataBagItem.load('credentials', 'parity') -account_password = credentials["testnet_password"] parity_node "testnet" do - password account_password + password credentials["testnet_password"] config parity: { chain: "ropsten", }, From 2624c09875f56a3acdf6c94adccd6feea1eccdcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 5 May 2017 19:47:30 +0200 Subject: [PATCH 49/83] Allow to create a package and install a package compiled from GitHub Also add nginx config for reverse proxying and set up Let's Encrypt automatically --- .../kosmos-parity/attributes/default.rb | 10 ++- site-cookbooks/kosmos-parity/metadata.rb | 3 + .../recipes/create_package_from_github.rb | 69 +++++++++++++++++++ .../kosmos-parity/recipes/default.rb | 12 +--- .../kosmos-parity/recipes/from_package.rb | 27 ++++++++ .../kosmos-parity/recipes/letsencrypt.rb | 40 +++++++++++ .../kosmos-parity/recipes/node_dev.rb | 26 +++++-- .../kosmos-parity/recipes/node_mainnet.rb | 1 + .../kosmos-parity/recipes/node_testnet.rb | 1 + site-cookbooks/kosmos-parity/recipes/user.rb | 20 ++++++ .../kosmos-parity/resources/node.rb | 30 +++++++- .../templates/default/nginx_conf_parity.erb | 34 +++++++++ .../default/nginx_conf_parity_letsencrypt.erb | 21 ++++++ 13 files changed, 274 insertions(+), 20 deletions(-) create mode 100644 site-cookbooks/kosmos-parity/recipes/create_package_from_github.rb create mode 100644 site-cookbooks/kosmos-parity/recipes/from_package.rb create mode 100644 site-cookbooks/kosmos-parity/recipes/letsencrypt.rb create mode 100644 site-cookbooks/kosmos-parity/recipes/user.rb create mode 100644 site-cookbooks/kosmos-parity/templates/default/nginx_conf_parity.erb create mode 100644 site-cookbooks/kosmos-parity/templates/default/nginx_conf_parity_letsencrypt.erb diff --git a/site-cookbooks/kosmos-parity/attributes/default.rb b/site-cookbooks/kosmos-parity/attributes/default.rb index 4f8dca5..1be87e1 100644 --- a/site-cookbooks/kosmos-parity/attributes/default.rb +++ b/site-cookbooks/kosmos-parity/attributes/default.rb @@ -1,3 +1,7 @@ -node.default['kosmos-parity']['home_path'] = "/home/parity" -node.default['kosmos-parity']['version'] = "1.6.6" -node.default['kosmos-parity']['checksum'] = '99ed4c0bf8cf7e0b143d8901f51c666d743844b0788ab03ccacb1f4538bfd085' +node.default['kosmos-parity']['home_path'] = "/home/parity" +node.default['kosmos-parity']['version'] = "1.6.6" +node.default['kosmos-parity']['package_checksum'] = '7fd51ded7a367774e62c965088ffd15ad0fa42251005d448eb700cbf5db8df24' +node.default['kosmos-parity']['package_version'] = '1.7.0' +node.default['kosmos-parity']['package_timestamp'] = '1493999009' +node.default['kosmos-parity']['debian_package_dir'] = Chef::Config[:file_cache_path] +node.default['kosmos-parity']['hostname'] = "parity.kosmos.org" diff --git a/site-cookbooks/kosmos-parity/metadata.rb b/site-cookbooks/kosmos-parity/metadata.rb index db4e0f4..1ddcb59 100644 --- a/site-cookbooks/kosmos-parity/metadata.rb +++ b/site-cookbooks/kosmos-parity/metadata.rb @@ -9,3 +9,6 @@ version '0.1.0' gem 'toml' depends 'ark' +depends 'build-essential' +depends 'kosmos-nginx' +depends 'firewall' diff --git a/site-cookbooks/kosmos-parity/recipes/create_package_from_github.rb b/site-cookbooks/kosmos-parity/recipes/create_package_from_github.rb new file mode 100644 index 0000000..a2bf041 --- /dev/null +++ b/site-cookbooks/kosmos-parity/recipes/create_package_from_github.rb @@ -0,0 +1,69 @@ +# +# Cookbook Name:: kosmos-parity +# Recipe:: create_package_from_github +# +# Copyright 2017, Kosmos +# +# All rights reserved - Do Not Redistribute +# + +include_recipe 'kosmos-parity::user' +include_recipe 'build-essential' +package %w(git libssl-dev pkg-config libudev-dev) +gem_package 'fpm' do + version '1.8.1' +end + +rust_version = '1.17.0' +architecture = node['kernel']['machine'] +rust_canonical_basename = "rust-#{rust_version}-#{architecture}-unknown-linux-gnu" +rust_path = "/usr/local/rust_#{rust_version}" + +url = "https://static.rust-lang.org/dist/#{rust_canonical_basename}.tar.gz" + +ark "rust_#{rust_version}" do + url url + path "/usr/local" + action :put + notifies :run, "execute[install rust]", :immediately +end + +execute "install rust" do + command "./install.sh" + cwd "#{rust_path}" + action :nothing +end + +parity_revision = "0d8920347a72fc50e82b540855eba94c8bbb2c0f" + +git "/home/parity/parity" do + repository "https://github.com/paritytech/parity.git" + revision parity_revision + user "parity" + group "parity" + notifies :run, "execute[build parity]", :immediately +end + +execute "build parity" do + cwd "/home/parity/parity" + environment "HOME" => "/home/parity" + command "cargo build --release" + action :nothing + user "parity" + group "parity" + notifies :run, "execute[copy parity]", :immediately +end + +execute "copy parity" do + command "cp /home/parity/parity/target/release/parity /usr/bin/" + action :run + notifies :run, "execute[create package]", :immediately +end + +timestamp = Time.now.strftime('%s') +parity_version = node['kosmos-parity']['package_version'] +execute "create package" do + cwd node['kosmos-parity']['debian_package_dir'] + command "fpm -s dir -t deb -n parity -v #{parity_version}-#{timestamp} -p parity_#{parity_version}-#{timestamp}.deb /usr/bin/parity" + action :nothing +end diff --git a/site-cookbooks/kosmos-parity/recipes/default.rb b/site-cookbooks/kosmos-parity/recipes/default.rb index 865440e..cd49c05 100644 --- a/site-cookbooks/kosmos-parity/recipes/default.rb +++ b/site-cookbooks/kosmos-parity/recipes/default.rb @@ -7,17 +7,7 @@ # All rights reserved - Do Not Redistribute # -group "parity" do - gid 72748 -end - -user "parity" do - system true - manage_home true - comment "parity user" - uid 72748 - gid 72748 -end +include_recipe 'kosmos-parity::user' parity_version = node['kosmos-parity']['version'] parity_package_path = "#{Chef::Config[:file_cache_path]}/parity_#{parity_version}_amd64.deb" diff --git a/site-cookbooks/kosmos-parity/recipes/from_package.rb b/site-cookbooks/kosmos-parity/recipes/from_package.rb new file mode 100644 index 0000000..f45678d --- /dev/null +++ b/site-cookbooks/kosmos-parity/recipes/from_package.rb @@ -0,0 +1,27 @@ +# +# Cookbook Name:: kosmos-parity +# Recipe:: default +# +# Copyright 2017, Kosmos +# +# All rights reserved - Do Not Redistribute +# + +include_recipe 'kosmos-parity::user' + +parity_version = node['kosmos-parity']['package_version'] +package_timestamp = node['kosmos-parity']['package_timestamp'] +parity_filename = "parity_#{parity_version}-#{package_timestamp}.deb" + +parity_package_path = "#{Chef::Config[:file_cache_path]}/#{parity_filename}" +remote_file parity_package_path do + source "https://dl.5apps.com/#{parity_filename}" + checksum node['kosmos-parity']['checksum'] + mode 0750 + notifies :install, "dpkg_package[parity]", :immediately +end + +dpkg_package "parity" do + source parity_package_path + version "#{parity_version}-#{package_timestamp}" +end diff --git a/site-cookbooks/kosmos-parity/recipes/letsencrypt.rb b/site-cookbooks/kosmos-parity/recipes/letsencrypt.rb new file mode 100644 index 0000000..fdb84a1 --- /dev/null +++ b/site-cookbooks/kosmos-parity/recipes/letsencrypt.rb @@ -0,0 +1,40 @@ +# +# Cookbook Name:: kosmos-parity +# Recipe:: letsencrypt +# +# Copyright 2017, Kosmos +# +# All rights reserved - Do Not Redistribute +# + +include_recipe "kosmos-base::letsencrypt" + +hostname = node['kosmos-parity']['hostname'] + +directory "/var/www/#{hostname}/.well-known/acme-challenge" do + owner node["nginx"]["user"] + group node["nginx"]["group"] + action :create + recursive true +end + +template "#{node['nginx']['dir']}/sites-available/#{hostname}" do + source 'nginx_conf_parity_letsencrypt.erb' + owner 'www-data' + mode 0640 + variables server_name: hostname, + ssl_cert: "/etc/letsencrypt/live/#{hostname}/fullchain.pem", + ssl_key: "/etc/letsencrypt/live/#{hostname}/privkey.pem" + notifies :reload, 'service[nginx]', :delayed +end + +nginx_site "#{hostname}" do + action :enable +end + +execute "letsencrypt cert for #{hostname}" do + command "./certbot-auto certonly --webroot --agree-tos --email ops@5apps.com --webroot-path /var/www/#{hostname} -d #{hostname} -n" + cwd "/usr/local/certbot" + not_if { File.exist? "/etc/letsencrypt/live/#{hostname}/fullchain.pem" } + notifies :reload, "service[nginx]", :delayed +end diff --git a/site-cookbooks/kosmos-parity/recipes/node_dev.rb b/site-cookbooks/kosmos-parity/recipes/node_dev.rb index 0e67c59..b15bea3 100644 --- a/site-cookbooks/kosmos-parity/recipes/node_dev.rb +++ b/site-cookbooks/kosmos-parity/recipes/node_dev.rb @@ -7,6 +7,9 @@ # All rights reserved - Do Not Redistribute # +rpc_proxy_port = 8545 +rpc_port = 18545 + parity_node "dev" do password "parityparity" config parity: { @@ -18,18 +21,33 @@ parity_node "dev" do warp: true, }, rpc: { - port: 8545, + port: rpc_port, cors: "*", + apis: ["safe"], + hosts: ["all"], }, dapps: { - port: 8090, + disable: true, }, ui: { - port: 8180, - force: true, + disable: true, + }, + websockets: { + disable: true, }, mining: { reseal_min_period: 0, } + rpc_proxy_port rpc_proxy_port end +# The firewall_rule doesn't appear to work inside a resource, that's why we're +# doing it here +unless node.chef_environment == "development" + include_recipe 'firewall' + firewall_rule "parity_dev" do + port rpc_proxy_port + protocol :tcp + command :allow + end +end diff --git a/site-cookbooks/kosmos-parity/recipes/node_mainnet.rb b/site-cookbooks/kosmos-parity/recipes/node_mainnet.rb index 9c5177a..c7ef644 100644 --- a/site-cookbooks/kosmos-parity/recipes/node_mainnet.rb +++ b/site-cookbooks/kosmos-parity/recipes/node_mainnet.rb @@ -13,6 +13,7 @@ parity_node "mainnet" do password credentials["mainnet_password"] config parity: { chain: "homestead", + no_download: true, # Don't Download Updates }, network: { port: 30305, diff --git a/site-cookbooks/kosmos-parity/recipes/node_testnet.rb b/site-cookbooks/kosmos-parity/recipes/node_testnet.rb index b27cd8a..18cebf7 100644 --- a/site-cookbooks/kosmos-parity/recipes/node_testnet.rb +++ b/site-cookbooks/kosmos-parity/recipes/node_testnet.rb @@ -13,6 +13,7 @@ parity_node "testnet" do password credentials["testnet_password"] config parity: { chain: "ropsten", + no_download: true, # Don't Download Updates }, network: { port: 30304, diff --git a/site-cookbooks/kosmos-parity/recipes/user.rb b/site-cookbooks/kosmos-parity/recipes/user.rb new file mode 100644 index 0000000..dd732ff --- /dev/null +++ b/site-cookbooks/kosmos-parity/recipes/user.rb @@ -0,0 +1,20 @@ +# +# Cookbook Name:: kosmos-parity +# Recipe:: user +# +# Copyright 2017, Kosmos +# +# All rights reserved - Do Not Redistribute +# + +group "parity" do + gid 72748 +end + +user "parity" do + system true + manage_home true + comment "parity user" + uid 72748 + gid 72748 +end diff --git a/site-cookbooks/kosmos-parity/resources/node.rb b/site-cookbooks/kosmos-parity/resources/node.rb index a2f180b..2001806 100644 --- a/site-cookbooks/kosmos-parity/resources/node.rb +++ b/site-cookbooks/kosmos-parity/resources/node.rb @@ -5,10 +5,9 @@ provides :parity_node property :name, String, name_property: true, required: true property :config, Hash, required: true property :password, String, required: true +property :rpc_proxy_port, Integer action :enable do - include_recipe "kosmos-parity::default" - node_name = name parity_service = "parity_#{node_name}" base_path = "#{node['kosmos-parity']['home_path']}/.local/share/io.parity.ethereum/#{name}" @@ -90,4 +89,31 @@ action :enable do service parity_service do action [:enable, :start] end + + if rpc_proxy_port + unless node.chef_environment == "development" + include_recipe "kosmos-parity::letsencrypt" + end + + include_recipe "kosmos-nginx" + + hostname = node['kosmos-parity']['hostname'] + + template "#{node['nginx']['dir']}/sites-available/#{parity_service}" do + source 'nginx_conf_parity.erb' + owner 'www-data' + mode 0640 + variables internal_port: config[:rpc][:port], + external_port: rpc_proxy_port, + parity_service: parity_service, + server_name: hostname, + ssl_cert: "/etc/letsencrypt/live/#{hostname}/fullchain.pem", + ssl_key: "/etc/letsencrypt/live/#{hostname}/privkey.pem" + notifies :reload, 'service[nginx]', :delayed + end + + nginx_site "#{parity_service}" do + action :enable + end + end end diff --git a/site-cookbooks/kosmos-parity/templates/default/nginx_conf_parity.erb b/site-cookbooks/kosmos-parity/templates/default/nginx_conf_parity.erb new file mode 100644 index 0000000..52fb6f3 --- /dev/null +++ b/site-cookbooks/kosmos-parity/templates/default/nginx_conf_parity.erb @@ -0,0 +1,34 @@ +# Generated by Chef +upstream _<%= @parity_service %> { + server localhost:<%= @internal_port %>; +} + +server { + <% if File.exist?(@ssl_cert) && File.exist?(@ssl_key) -%> + listen <%= @external_port %> ssl http2; + <% else -%> + listen <%= @external_port %>; + <% end -%> + + server_name <%= @server_name %>; + + access_log <%= node[:nginx][:log_dir] %>/<%= @parity_service %>.access.log json; + error_log <%= node[:nginx][:log_dir] %>/<%= @parity_service %>.error.log warn; + + location /.well-known { + root "/var/www/<%= @parity_service %>"; + } + + location / { + # Increase number of buffers. Default is 8 + proxy_buffers 1024 8k; + + proxy_pass http://_<%= @parity_service %>; + proxy_http_version 1.1; + } + + <% if File.exist?(@ssl_cert) && File.exist?(@ssl_key) -%> + ssl_certificate <%= @ssl_cert %>; + ssl_certificate_key <%= @ssl_key %>; + <% end -%> +} diff --git a/site-cookbooks/kosmos-parity/templates/default/nginx_conf_parity_letsencrypt.erb b/site-cookbooks/kosmos-parity/templates/default/nginx_conf_parity_letsencrypt.erb new file mode 100644 index 0000000..a4e8ad5 --- /dev/null +++ b/site-cookbooks/kosmos-parity/templates/default/nginx_conf_parity_letsencrypt.erb @@ -0,0 +1,21 @@ +# Generated by Chef +server { + listen 80; # For Let's Encrypt + <% if File.exist?(@ssl_cert) && File.exist?(@ssl_key) -%> + listen <%= @external_port %> ssl http2; + <% end -%> + + server_name <%= @server_name %>; + + access_log <%= node[:nginx][:log_dir] %>/<%= @server_name %>.access.log json; + error_log <%= node[:nginx][:log_dir] %>/<%= @server_name %>.error.log warn; + + location /.well-known { + root "/var/www/<%= @server_name %>"; + } + + <% if File.exist?(@ssl_cert) && File.exist?(@ssl_key) -%> + ssl_certificate <%= @ssl_cert %>; + ssl_certificate_key <%= @ssl_key %>; + <% end -%> +} From 3b6a1d0e4c9140abf0fab71d143b99024ae1afb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Sun, 7 May 2017 16:02:58 +0200 Subject: [PATCH 50/83] Set up config for testnet --- .../kosmos-parity/recipes/node_testnet.rb | 29 ++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/site-cookbooks/kosmos-parity/recipes/node_testnet.rb b/site-cookbooks/kosmos-parity/recipes/node_testnet.rb index 18cebf7..145ab53 100644 --- a/site-cookbooks/kosmos-parity/recipes/node_testnet.rb +++ b/site-cookbooks/kosmos-parity/recipes/node_testnet.rb @@ -7,25 +7,46 @@ # All rights reserved - Do Not Redistribute # +rpc_proxy_port = 8546 +rpc_port = 18546 + credentials = Chef::EncryptedDataBagItem.load('credentials', 'parity') parity_node "testnet" do password credentials["testnet_password"] config parity: { - chain: "ropsten", + chain: "testnet", no_download: true, # Don't Download Updates }, network: { port: 30304, + warp: true, }, rpc: { - port: 8546, + port: rpc_port, + cors: "*", + apis: ["safe"], + hosts: ["all"], }, dapps: { - port: 8091, + disable: true, }, ui: { - port: 8181, + disable: true, + }, + websockets: { + disable: true, } + rpc_proxy_port rpc_proxy_port end +# The firewall_rule doesn't appear to work inside a resource, that's why we're +# doing it here +unless node.chef_environment == "development" + include_recipe 'firewall' + firewall_rule "parity_testnet" do + port rpc_proxy_port + protocol :tcp + command :allow + end +end From 23a621270fea79d27c32c38997fb5c62a73f263b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Mon, 8 May 2017 12:07:03 +0200 Subject: [PATCH 51/83] Remove placeholder text from generated Chef cookbook --- site-cookbooks/kosmos-parity/CHANGELOG.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/site-cookbooks/kosmos-parity/CHANGELOG.md b/site-cookbooks/kosmos-parity/CHANGELOG.md index fa0d873..2d37a6a 100644 --- a/site-cookbooks/kosmos-parity/CHANGELOG.md +++ b/site-cookbooks/kosmos-parity/CHANGELOG.md @@ -2,8 +2,3 @@ ## 0.1.0 - [Greg Karékinian] - Initial release of kosmos-parity - -- - - -Check the [Markdown Syntax Guide](http://daringfireball.net/projects/markdown/syntax) for help with Markdown. - -The [Github Flavored Markdown page](http://github.github.com/github-flavored-markdown/) describes the differences between markdown on github and standard markdown. From eaaaacf97f08119098adfd42d9da40774f87fdf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Mon, 8 May 2017 12:07:32 +0200 Subject: [PATCH 52/83] Remove placeholder text from generated Chef cookbooks --- site-cookbooks/5apps-hubot/CHANGELOG.md | 9 +-------- site-cookbooks/5apps-xmpp_server/CHANGELOG.md | 2 -- site-cookbooks/ipfs/CHANGELOG.md | 2 -- site-cookbooks/kosmos-ipfs/CHANGELOG.md | 2 -- site-cookbooks/kosmos-mastodon/CHANGELOG.md | 9 +-------- site-cookbooks/kosmos-mediawiki/CHANGELOG.md | 9 +-------- site-cookbooks/kosmos-wordpress/CHANGELOG.md | 9 +-------- site-cookbooks/sockethub/CHANGELOG.md | 9 +-------- 8 files changed, 5 insertions(+), 46 deletions(-) diff --git a/site-cookbooks/5apps-hubot/CHANGELOG.md b/site-cookbooks/5apps-hubot/CHANGELOG.md index 2e739d7..0cc231e 100644 --- a/site-cookbooks/5apps-hubot/CHANGELOG.md +++ b/site-cookbooks/5apps-hubot/CHANGELOG.md @@ -1,11 +1,4 @@ # 5apps-hubot CHANGELOG -This file is used to list changes made in each version of the 5apps-hubot cookbook. - ## 0.1.0 -- [your_name] - Initial release of 5apps-hubot - -- - - -Check the [Markdown Syntax Guide](http://daringfireball.net/projects/markdown/syntax) for help with Markdown. - -The [Github Flavored Markdown page](http://github.github.com/github-flavored-markdown/) describes the differences between markdown on github and standard markdown. +- [Greg Karékinian] - Initial release of 5apps-hubot diff --git a/site-cookbooks/5apps-xmpp_server/CHANGELOG.md b/site-cookbooks/5apps-xmpp_server/CHANGELOG.md index 1790327..2668d1b 100644 --- a/site-cookbooks/5apps-xmpp_server/CHANGELOG.md +++ b/site-cookbooks/5apps-xmpp_server/CHANGELOG.md @@ -1,6 +1,4 @@ # 5apps-xmpp_server CHANGELOG -This file is used to list changes made in each version of the 5apps-xmpp_server cookbook. - ## 0.1.0 - [Greg Karékinian] - Initial release of 5apps-xmpp_server diff --git a/site-cookbooks/ipfs/CHANGELOG.md b/site-cookbooks/ipfs/CHANGELOG.md index 4b7a448..1523cdc 100644 --- a/site-cookbooks/ipfs/CHANGELOG.md +++ b/site-cookbooks/ipfs/CHANGELOG.md @@ -1,6 +1,4 @@ # ipfs CHANGELOG -This file is used to list changes made in each version of the ipfs cookbook. - ## 0.1.0 - [gregkare] - Initial release of ipfs diff --git a/site-cookbooks/kosmos-ipfs/CHANGELOG.md b/site-cookbooks/kosmos-ipfs/CHANGELOG.md index 6115db6..4ef121b 100644 --- a/site-cookbooks/kosmos-ipfs/CHANGELOG.md +++ b/site-cookbooks/kosmos-ipfs/CHANGELOG.md @@ -1,6 +1,4 @@ # kosmos-ipfs CHANGELOG -This file is used to list changes made in each version of the kosmos-ipfs cookbook. - ## 0.1.0 - [gregkare] - Initial release of kosmos-ipfs diff --git a/site-cookbooks/kosmos-mastodon/CHANGELOG.md b/site-cookbooks/kosmos-mastodon/CHANGELOG.md index 4e30fed..2c6362a 100644 --- a/site-cookbooks/kosmos-mastodon/CHANGELOG.md +++ b/site-cookbooks/kosmos-mastodon/CHANGELOG.md @@ -1,11 +1,4 @@ # kosmos-mastodon CHANGELOG -This file is used to list changes made in each version of the kosmos-mastodon cookbook. - ## 0.1.0 -- [your_name] - Initial release of kosmos-mastodon - -- - - -Check the [Markdown Syntax Guide](http://daringfireball.net/projects/markdown/syntax) for help with Markdown. - -The [Github Flavored Markdown page](http://github.github.com/github-flavored-markdown/) describes the differences between markdown on github and standard markdown. +- [Greg Karékinian] - Initial release of kosmos-mastodon diff --git a/site-cookbooks/kosmos-mediawiki/CHANGELOG.md b/site-cookbooks/kosmos-mediawiki/CHANGELOG.md index 7c7650b..0e86b43 100644 --- a/site-cookbooks/kosmos-mediawiki/CHANGELOG.md +++ b/site-cookbooks/kosmos-mediawiki/CHANGELOG.md @@ -1,13 +1,6 @@ kosmos-mediawiki CHANGELOG ========================== -This file is used to list changes made in each version of the kosmos-mediawiki cookbook. - 0.1.0 ----- -- [your_name] - Initial release of kosmos-mediawiki - -- - - -Check the [Markdown Syntax Guide](http://daringfireball.net/projects/markdown/syntax) for help with Markdown. - -The [Github Flavored Markdown page](http://github.github.com/github-flavored-markdown/) describes the differences between markdown on github and standard markdown. +- [Greg Karékinian] - Initial release of kosmos-mediawiki diff --git a/site-cookbooks/kosmos-wordpress/CHANGELOG.md b/site-cookbooks/kosmos-wordpress/CHANGELOG.md index 0bf2beb..a253528 100644 --- a/site-cookbooks/kosmos-wordpress/CHANGELOG.md +++ b/site-cookbooks/kosmos-wordpress/CHANGELOG.md @@ -1,13 +1,6 @@ kosmos-wordpress CHANGELOG ========================== -This file is used to list changes made in each version of the kosmos-wordpress cookbook. - 0.1.0 ----- -- [your_name] - Initial release of kosmos-wordpress - -- - - -Check the [Markdown Syntax Guide](http://daringfireball.net/projects/markdown/syntax) for help with Markdown. - -The [Github Flavored Markdown page](http://github.github.com/github-flavored-markdown/) describes the differences between markdown on github and standard markdown. +- [Greg Karékinian] - Initial release of kosmos-wordpress diff --git a/site-cookbooks/sockethub/CHANGELOG.md b/site-cookbooks/sockethub/CHANGELOG.md index c02f029..fdd6020 100644 --- a/site-cookbooks/sockethub/CHANGELOG.md +++ b/site-cookbooks/sockethub/CHANGELOG.md @@ -1,13 +1,6 @@ sockethub CHANGELOG =================== -This file is used to list changes made in each version of the sockethub cookbook. - 0.1.0 ----- -- [your_name] - Initial release of sockethub - -- - - -Check the [Markdown Syntax Guide](http://daringfireball.net/projects/markdown/syntax) for help with Markdown. - -The [Github Flavored Markdown page](http://github.github.com/github-flavored-markdown/) describes the differences between markdown on github and standard markdown. +- [Greg Karékinian] - Initial release of sockethub From 0f58a1c236522864d728d5db79c5b3ac294e20ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Mon, 8 May 2017 16:45:53 +0200 Subject: [PATCH 53/83] Add information about the parity nodes --- site-cookbooks/kosmos-parity/README.md | 17 ++++++++--------- .../kosmos-parity/recipes/node_dev.rb | 3 +++ .../kosmos-parity/recipes/node_testnet.rb | 3 +++ 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/site-cookbooks/kosmos-parity/README.md b/site-cookbooks/kosmos-parity/README.md index 7357580..a304316 100644 --- a/site-cookbooks/kosmos-parity/README.md +++ b/site-cookbooks/kosmos-parity/README.md @@ -35,16 +35,15 @@ This cookbook installs [Parity](https://parity.io/) nodes ### kosmos-parity::default -Just include `kosmos-parity` in your node's `run_list`: +### kosmos-parity::node_dev -```json -{ - "name":"my_node", - "run_list": [ - "recipe[kosmos-parity]" - ] -} -``` +Sets up a parity node running on the dev chain on port 8545 (behind nginx, with +HTTPS) + +### kosmos-parity::node_testnet + +Sets up a parity node running on the testnet chain on port 8546 (behind nginx, +with HTTPS) ## License and Authors diff --git a/site-cookbooks/kosmos-parity/recipes/node_dev.rb b/site-cookbooks/kosmos-parity/recipes/node_dev.rb index b15bea3..7c2bd51 100644 --- a/site-cookbooks/kosmos-parity/recipes/node_dev.rb +++ b/site-cookbooks/kosmos-parity/recipes/node_dev.rb @@ -7,6 +7,9 @@ # All rights reserved - Do Not Redistribute # +# Sets up a parity node running on the dev chain on port 8545 (behind nginx, +# with HTTPS) + rpc_proxy_port = 8545 rpc_port = 18545 diff --git a/site-cookbooks/kosmos-parity/recipes/node_testnet.rb b/site-cookbooks/kosmos-parity/recipes/node_testnet.rb index 145ab53..2bac0a8 100644 --- a/site-cookbooks/kosmos-parity/recipes/node_testnet.rb +++ b/site-cookbooks/kosmos-parity/recipes/node_testnet.rb @@ -7,6 +7,9 @@ # All rights reserved - Do Not Redistribute # +# Sets up a parity node running on the testnet chain on port 8546 (behind +# nginx, with HTTPS) + rpc_proxy_port = 8546 rpc_port = 18546 From 4fdf64dfbd4e4eb3a41c44e5803e359ae408a6a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Mon, 8 May 2017 16:47:58 +0200 Subject: [PATCH 54/83] Remove duplicate kosmos-nginx recipe directive --- site-cookbooks/sockethub/recipes/proxy.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/site-cookbooks/sockethub/recipes/proxy.rb b/site-cookbooks/sockethub/recipes/proxy.rb index c1fb46c..3961386 100644 --- a/site-cookbooks/sockethub/recipes/proxy.rb +++ b/site-cookbooks/sockethub/recipes/proxy.rb @@ -27,8 +27,6 @@ directory "/var/www/sockethub" do recursive true end -include_recipe 'kosmos-nginx' - template "#{node['nginx']['dir']}/sites-available/sockethub" do source 'nginx_conf_sockethub.erb' owner 'www-data' From fc346e85c9065af724199fb0d5dccd651bd48b49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Mon, 8 May 2017 16:51:50 +0200 Subject: [PATCH 55/83] Add initial parity role --- roles/parity.rb | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 roles/parity.rb diff --git a/roles/parity.rb b/roles/parity.rb new file mode 100644 index 0000000..69e1f1a --- /dev/null +++ b/roles/parity.rb @@ -0,0 +1,6 @@ +name 'parity' + +run_list %w( + recipe[kosmos-parity::from_package] + recipe[kosmos-parity::node_dev] +) From 18dba49d51a5af4de9a8d93ad4b5c209cd5cad4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Mon, 8 May 2017 16:52:08 +0200 Subject: [PATCH 56/83] Override the directory where the parity package is created in dev --- environments/development.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/environments/development.json b/environments/development.json index d8017c9..380715e 100644 --- a/environments/development.json +++ b/environments/development.json @@ -6,5 +6,8 @@ "default_attributes": { }, "override_attributes": { + "kosmos-parity": { + "debian_package_dir": "/vagrant" + } } } From 5285f86043edcc56a903737532fcca95d45453aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Mon, 8 May 2017 16:53:03 +0200 Subject: [PATCH 57/83] Use two CPUs for the VirtualBox Vagrant box --- Vagrantfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Vagrantfile b/Vagrantfile index d73b11d..a5221b6 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -18,6 +18,7 @@ Vagrant.configure(2) do |config| config.vm.provider :virtualbox do |vb| # Customize the amount of memory on the VM: vb.memory = "1024" + vb.cpus = 2 end config.vm.provider :docker do |d, override| From c334c05e6d2b56e7301682910cf0e8d153256936 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Mon, 8 May 2017 17:08:40 +0200 Subject: [PATCH 58/83] Add silverbucket user Fixes #14 --- data_bags/users/nkj.json | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 data_bags/users/nkj.json diff --git a/data_bags/users/nkj.json b/data_bags/users/nkj.json new file mode 100644 index 0000000..226871b --- /dev/null +++ b/data_bags/users/nkj.json @@ -0,0 +1,9 @@ +{ + "id": "nkj", + "ssh_keys": [ + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQChBWdyAG6uywiyNPjJzuoaf4/WfKb56c1uSbA2SggpWUdeblz78L8hWPiQ4Qd6ZyQmuKOqkWzY46wf80PrXK4393S0K7QGKuDL8Vd5dwmqqqtrEsz58JQMNRmJZ04Htw3cTQBXOjJMSuXdfBROKEY+hgqoJIHYtT/M+3OzLO6IJp6dIG5haDsjJ2hgZD91nXQrt5Vwvr3osaeiErQnkLPlOLmJSfQNFi1V0mZs4PTlaVXEHMssMxvH1upTYY5i9icBzejXHdhaWuHAZtIDXloaS6oEtH7Dcg3LYCnLuP12Ydfm3pKx+xonIYP2jiNgsQSpu/WLWlvKAwYMUMtTrC1f nkj@kosmos" + ], + "groups": ["sysadmin", "systemd-journal"], + "uid": 2005, + "shell": "\/bin\/bash" +} From e871095bb478eee6316fe5ef69a3f7a0b06a2b67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Mon, 8 May 2017 17:42:29 +0200 Subject: [PATCH 59/83] Backup the parity keys --- site-cookbooks/kosmos-parity/metadata.rb | 1 + site-cookbooks/kosmos-parity/recipes/default.rb | 2 ++ site-cookbooks/kosmos-parity/recipes/from_package.rb | 2 ++ site-cookbooks/kosmos-parity/resources/node.rb | 5 ++--- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/site-cookbooks/kosmos-parity/metadata.rb b/site-cookbooks/kosmos-parity/metadata.rb index 1ddcb59..01e7178 100644 --- a/site-cookbooks/kosmos-parity/metadata.rb +++ b/site-cookbooks/kosmos-parity/metadata.rb @@ -12,3 +12,4 @@ depends 'ark' depends 'build-essential' depends 'kosmos-nginx' depends 'firewall' +depends 'backup' diff --git a/site-cookbooks/kosmos-parity/recipes/default.rb b/site-cookbooks/kosmos-parity/recipes/default.rb index cd49c05..bdc657c 100644 --- a/site-cookbooks/kosmos-parity/recipes/default.rb +++ b/site-cookbooks/kosmos-parity/recipes/default.rb @@ -21,3 +21,5 @@ end dpkg_package "parity" do source parity_package_path end + +include_recipe "kosmos-parity::backup" diff --git a/site-cookbooks/kosmos-parity/recipes/from_package.rb b/site-cookbooks/kosmos-parity/recipes/from_package.rb index f45678d..3815a4d 100644 --- a/site-cookbooks/kosmos-parity/recipes/from_package.rb +++ b/site-cookbooks/kosmos-parity/recipes/from_package.rb @@ -25,3 +25,5 @@ dpkg_package "parity" do source parity_package_path version "#{parity_version}-#{package_timestamp}" end + +include_recipe "kosmos-parity::backup" diff --git a/site-cookbooks/kosmos-parity/resources/node.rb b/site-cookbooks/kosmos-parity/resources/node.rb index 2001806..c077928 100644 --- a/site-cookbooks/kosmos-parity/resources/node.rb +++ b/site-cookbooks/kosmos-parity/resources/node.rb @@ -10,7 +10,7 @@ property :rpc_proxy_port, Integer action :enable do node_name = name parity_service = "parity_#{node_name}" - base_path = "#{node['kosmos-parity']['home_path']}/.local/share/io.parity.ethereum/#{name}" + base_path = "#{node['kosmos-parity']['home_path']}/.local/share/io.parity.ethereum/#{node_name}" config_path = "#{base_path}/config.toml" config[:parity][:base_path] = base_path @@ -31,8 +31,7 @@ action :enable do end end - node_path = "#{node['kosmos-parity']['home_path']}/.local/share/io.parity.ethereum/#{node_name}" - password_path = "#{node_path}/password" + password_path = "#{base_path}/password" file password_path do content password From f1d48b9a68bbc1c6f269d9e54ae6f471b44afa74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Mon, 8 May 2017 18:24:51 +0200 Subject: [PATCH 60/83] Enable more networks (safe doesn't do what we want) --- site-cookbooks/kosmos-parity/recipes/node_dev.rb | 2 +- site-cookbooks/kosmos-parity/recipes/node_testnet.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/site-cookbooks/kosmos-parity/recipes/node_dev.rb b/site-cookbooks/kosmos-parity/recipes/node_dev.rb index 7c2bd51..fa2dc60 100644 --- a/site-cookbooks/kosmos-parity/recipes/node_dev.rb +++ b/site-cookbooks/kosmos-parity/recipes/node_dev.rb @@ -26,7 +26,7 @@ parity_node "dev" do rpc: { port: rpc_port, cors: "*", - apis: ["safe"], + apis: ["web3", "net", "traces", "rpc", "eth"], hosts: ["all"], }, dapps: { diff --git a/site-cookbooks/kosmos-parity/recipes/node_testnet.rb b/site-cookbooks/kosmos-parity/recipes/node_testnet.rb index 2bac0a8..3a3b684 100644 --- a/site-cookbooks/kosmos-parity/recipes/node_testnet.rb +++ b/site-cookbooks/kosmos-parity/recipes/node_testnet.rb @@ -28,7 +28,7 @@ parity_node "testnet" do rpc: { port: rpc_port, cors: "*", - apis: ["safe"], + apis: ["web3", "net", "traces", "rpc", "eth"], hosts: ["all"], }, dapps: { From 58c9ccc48c358b82230b73ee1ba0ae825273d207 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Mon, 8 May 2017 22:58:39 +0200 Subject: [PATCH 61/83] Fix the Let's Encrypt config for Parity The SSL port wasn't set in the variables --- .../templates/default/nginx_conf_parity_letsencrypt.erb | 8 -------- 1 file changed, 8 deletions(-) diff --git a/site-cookbooks/kosmos-parity/templates/default/nginx_conf_parity_letsencrypt.erb b/site-cookbooks/kosmos-parity/templates/default/nginx_conf_parity_letsencrypt.erb index a4e8ad5..e01b3f6 100644 --- a/site-cookbooks/kosmos-parity/templates/default/nginx_conf_parity_letsencrypt.erb +++ b/site-cookbooks/kosmos-parity/templates/default/nginx_conf_parity_letsencrypt.erb @@ -1,9 +1,6 @@ # Generated by Chef server { listen 80; # For Let's Encrypt - <% if File.exist?(@ssl_cert) && File.exist?(@ssl_key) -%> - listen <%= @external_port %> ssl http2; - <% end -%> server_name <%= @server_name %>; @@ -13,9 +10,4 @@ server { location /.well-known { root "/var/www/<%= @server_name %>"; } - - <% if File.exist?(@ssl_cert) && File.exist?(@ssl_key) -%> - ssl_certificate <%= @ssl_cert %>; - ssl_certificate_key <%= @ssl_key %>; - <% end -%> } From 82386b44ba09d080190651f2e7d253c7043763cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Mon, 8 May 2017 22:59:40 +0200 Subject: [PATCH 62/83] Add missing backup recipe --- site-cookbooks/kosmos-parity/recipes/backup.rb | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 site-cookbooks/kosmos-parity/recipes/backup.rb diff --git a/site-cookbooks/kosmos-parity/recipes/backup.rb b/site-cookbooks/kosmos-parity/recipes/backup.rb new file mode 100644 index 0000000..77782b1 --- /dev/null +++ b/site-cookbooks/kosmos-parity/recipes/backup.rb @@ -0,0 +1,6 @@ + +return if node.chef_environment == "development" + +# Backup the local directory +node.override["backup"]["archives"]["parity"] = ["#{node['kosmos-parity']['home_path']}/.local/share/io.parity.ethereum/**/keys"] +include_recipe "backup" From 5b49d727a6ad4e463d54ac3bc5b2cf60b6528997 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Mon, 8 May 2017 22:59:57 +0200 Subject: [PATCH 63/83] Enable Dapps It's required after all, but doesn't need to have its port open --- site-cookbooks/kosmos-parity/recipes/node_dev.rb | 3 ++- site-cookbooks/kosmos-parity/recipes/node_testnet.rb | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/site-cookbooks/kosmos-parity/recipes/node_dev.rb b/site-cookbooks/kosmos-parity/recipes/node_dev.rb index fa2dc60..52256b3 100644 --- a/site-cookbooks/kosmos-parity/recipes/node_dev.rb +++ b/site-cookbooks/kosmos-parity/recipes/node_dev.rb @@ -12,6 +12,7 @@ rpc_proxy_port = 8545 rpc_port = 18545 +dapps_port = 8180 parity_node "dev" do password "parityparity" @@ -30,7 +31,7 @@ parity_node "dev" do hosts: ["all"], }, dapps: { - disable: true, + port: dapps_port, }, ui: { disable: true, diff --git a/site-cookbooks/kosmos-parity/recipes/node_testnet.rb b/site-cookbooks/kosmos-parity/recipes/node_testnet.rb index 3a3b684..fcd6c6d 100644 --- a/site-cookbooks/kosmos-parity/recipes/node_testnet.rb +++ b/site-cookbooks/kosmos-parity/recipes/node_testnet.rb @@ -12,6 +12,7 @@ rpc_proxy_port = 8546 rpc_port = 18546 +dapps_port = 8181 credentials = Chef::EncryptedDataBagItem.load('credentials', 'parity') @@ -32,7 +33,7 @@ parity_node "testnet" do hosts: ["all"], }, dapps: { - disable: true, + port: dapps_port, }, ui: { disable: true, From 383d3adaae58756f88924378bb09e9f5e923aba2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Tue, 9 May 2017 00:02:07 +0200 Subject: [PATCH 64/83] Add parity testnet --- roles/parity.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/roles/parity.rb b/roles/parity.rb index 69e1f1a..06b232e 100644 --- a/roles/parity.rb +++ b/roles/parity.rb @@ -3,4 +3,5 @@ name 'parity' run_list %w( recipe[kosmos-parity::from_package] recipe[kosmos-parity::node_dev] + recipe[kosmos-parity::node_testnet] ) From 541599434deaf56b8118c12d3e4d7ea032a0f82c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Tue, 9 May 2017 00:04:39 +0200 Subject: [PATCH 65/83] Update the mainnet recipe --- .../kosmos-parity/recipes/node_mainnet.rb | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/site-cookbooks/kosmos-parity/recipes/node_mainnet.rb b/site-cookbooks/kosmos-parity/recipes/node_mainnet.rb index c7ef644..924c1ab 100644 --- a/site-cookbooks/kosmos-parity/recipes/node_mainnet.rb +++ b/site-cookbooks/kosmos-parity/recipes/node_mainnet.rb @@ -7,6 +7,13 @@ # All rights reserved - Do Not Redistribute # +# Sets up a parity node running on the mainnet chain on port 8547 (behind +# nginx, with HTTPS) + +rpc_proxy_port = 8547 +rpc_port = 18547 +dapps_port = 8182 + credentials = Chef::EncryptedDataBagItem.load('credentials', 'parity') parity_node "mainnet" do @@ -17,14 +24,33 @@ parity_node "mainnet" do }, network: { port: 30305, + warp: true, }, rpc: { - port: 8547, + port: rpc_port, + cors: "*", + apis: ["web3", "net", "traces", "rpc", "eth"], + hosts: ["all"], }, dapps: { - port: 8092, + port: dapps_port, }, ui: { - port: 8182, + disable: true, + }, + websockets: { + disable: true, } + rpc_proxy_port rpc_proxy_port +end + +# The firewall_rule doesn't appear to work inside a resource, that's why we're +# doing it here +unless node.chef_environment == "development" + include_recipe 'firewall' + firewall_rule "parity_mainnet" do + port rpc_proxy_port + protocol :tcp + command :allow + end end From 78c377e07fe6271d9cd5122e10dc5dde136c0492 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Tue, 9 May 2017 00:05:20 +0200 Subject: [PATCH 66/83] Add parity role to the dev server --- nodes/dev.kosmos.org.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nodes/dev.kosmos.org.json b/nodes/dev.kosmos.org.json index 4824f75..8db48c3 100644 --- a/nodes/dev.kosmos.org.json +++ b/nodes/dev.kosmos.org.json @@ -12,7 +12,8 @@ "5apps-hubot::xmpp_botka", "kosmos-ipfs", "kosmos-mastodon", - "kosmos-mastodon::nginx" + "kosmos-mastodon::nginx", + "role[parity]" ], "normal": { "postgresql": { From 81e87bc9efc09e9520e144fa510dfee3a01929d4 Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Fri, 12 May 2017 00:02:58 +0200 Subject: [PATCH 67/83] Parity: open network port, use Ropsten --- site-cookbooks/kosmos-parity/recipes/node_testnet.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/site-cookbooks/kosmos-parity/recipes/node_testnet.rb b/site-cookbooks/kosmos-parity/recipes/node_testnet.rb index fcd6c6d..8becabb 100644 --- a/site-cookbooks/kosmos-parity/recipes/node_testnet.rb +++ b/site-cookbooks/kosmos-parity/recipes/node_testnet.rb @@ -13,17 +13,18 @@ rpc_proxy_port = 8546 rpc_port = 18546 dapps_port = 8181 +network_port = 30304 credentials = Chef::EncryptedDataBagItem.load('credentials', 'parity') parity_node "testnet" do password credentials["testnet_password"] config parity: { - chain: "testnet", + chain: "ropsten", no_download: true, # Don't Download Updates }, network: { - port: 30304, + port: network_port, warp: true, }, rpc: { @@ -49,7 +50,7 @@ end unless node.chef_environment == "development" include_recipe 'firewall' firewall_rule "parity_testnet" do - port rpc_proxy_port + port [ rpc_proxy_port, network_port ] protocol :tcp command :allow end From 75b2df5c73291e689812cc59f3f513eee9077f73 Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Fri, 12 May 2017 00:03:45 +0200 Subject: [PATCH 68/83] Set up Hubot for Kredits --- data_bags/credentials/hal8000_freenode.json | 24 +++++++--- .../kosmos-hubot/attributes/default.rb | 4 ++ .../kosmos-hubot/files/default/wallet.json | 1 + .../kosmos-hubot/recipes/default.rb | 48 ++++++++++--------- 4 files changed, 49 insertions(+), 28 deletions(-) create mode 100644 site-cookbooks/kosmos-hubot/attributes/default.rb create mode 100644 site-cookbooks/kosmos-hubot/files/default/wallet.json diff --git a/data_bags/credentials/hal8000_freenode.json b/data_bags/credentials/hal8000_freenode.json index edc0b9d..0945753 100644 --- a/data_bags/credentials/hal8000_freenode.json +++ b/data_bags/credentials/hal8000_freenode.json @@ -1,20 +1,32 @@ { "id": "hal8000_freenode", "nickserv_password": { - "encrypted_data": "3ttriIAvS6ay6jvgJIaIp1fDDWc+kNedBEYMRGKL/vOViAsEKs7cHncsPYh0\nIk3Kyo/6iIp2bTbffJ7a+tv8UabecIZKiBMwOXm/yKIbjWo=\n", - "iv": "LVM4d6lk5OEOM5BoEZ3/nQ==\n", + "encrypted_data": "VaHF6vdJekpJFf/D1Ss9Kut4txn3x+pn5rCXqv8WCf8yxigEHGHW7lh0ufeL\nObi9g3H8Co6RdmlC0OBXZhC8bTh4R9kg9Dk8hB5qwdIMlfs=\n", + "iv": "IpQpztTEDi0tE+hin3LrPQ==\n", "version": 1, "cipher": "aes-256-cbc" }, "rs_logger_token": { - "encrypted_data": "JV3agXQC/aPdjkGOXswD8vopqXqpUKvy5i6eveqmB3n8//DcqhW42Tvy4Hxv\ncACSQ52/XRu3G0cCGkufR1IR1A==\n", - "iv": "su0/3+3sb/iHzHR00BvadQ==\n", + "encrypted_data": "/p/KOwVAh5SJ90RsCxSB5mhU5eWB2AsXdEJSTJvPiL/ZfGMVUhRKuXQRfH54\nLmDl4vdNlBZPcBXYvnKRFhOB0g==\n", + "iv": "evYwOynZfms/MyqdO0eDiw==\n", "version": 1, "cipher": "aes-256-cbc" }, "webhook_token": { - "encrypted_data": "lD/XfSO3dH9iWu1Wa+wjDg8uHrb4SZrBZbvtlw2qA7r/4j79R4KTNluDgsUG\nPfZZ\n", - "iv": "KhQjR/DH4gQaIfMnUMF3wA==\n", + "encrypted_data": "ijgaUo7WLIh1qiHARke0ZBrKNacI57Mzqp/TJSV1Td+XKArq7ZG9uw/xP0zE\nYIKv\n", + "iv": "LPdJ81jHrdgtMX72UGRCNA==\n", + "version": 1, + "cipher": "aes-256-cbc" + }, + "kredits_webhook_token": { + "encrypted_data": "7JASF00/9iZ+r+gDW3bAQQdzLgFQGz0pe1oTD2nI+anQqXAjD2ptzlvxRsDi\nSEM0\n", + "iv": "nkdJAj5DamG3psuAWR5r9w==\n", + "version": 1, + "cipher": "aes-256-cbc" + }, + "kredits_wallet_password": { + "encrypted_data": "e3aRrVHp64UHpa2ajw3GJIAb6BDHPEeXDeDE6srBCLb/Ruh3wq4IQr1Oejc7\n71by\n", + "iv": "ugYzQLlhsnIh0kso2+AnCA==\n", "version": 1, "cipher": "aes-256-cbc" } diff --git a/site-cookbooks/kosmos-hubot/attributes/default.rb b/site-cookbooks/kosmos-hubot/attributes/default.rb new file mode 100644 index 0000000..967712a --- /dev/null +++ b/site-cookbooks/kosmos-hubot/attributes/default.rb @@ -0,0 +1,4 @@ +node.default['hal8000']['kredits']['provider_url'] = 'https://parity.kosmos.org:8546' +node.default['hal8000']['kredits']['room'] = '#kosmos' +node.default['hal8000']['kredits']['wallet_path'] = 'wallet.json' +node.default['hal8000']['kredits']['contract_address'] = '0x206a58891a17ec3b594489c77d931920b33a2a81' diff --git a/site-cookbooks/kosmos-hubot/files/default/wallet.json b/site-cookbooks/kosmos-hubot/files/default/wallet.json new file mode 100644 index 0000000..5d338e9 --- /dev/null +++ b/site-cookbooks/kosmos-hubot/files/default/wallet.json @@ -0,0 +1 @@ +{"version":3,"id":"7096b0d1-9426-4130-8f38-c7dfa2a225a3","address":"c80d2513277fa04b10403e2d1d7daa86f931f4d1","crypto":{"ciphertext":"b3e50e533ebbe3ac05b52d8689e87df86a651138fe65f55a1fa9ec08f479a0d0","cipherparams":{"iv":"9b514daf0f202b111bee9ad131e433df"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"10490a40bf9b1d8efc146bf2c974e4a7fb750a24a7e08a9fc599024e5a7aaabc","n":262144,"r":8,"p":1},"mac":"b3f584afe25b973a8f1eceb344201cec6de24dc14d99ea37576ce7f9f9e936ce"}} \ No newline at end of file diff --git a/site-cookbooks/kosmos-hubot/recipes/default.rb b/site-cookbooks/kosmos-hubot/recipes/default.rb index 594625b..8b001e0 100644 --- a/site-cookbooks/kosmos-hubot/recipes/default.rb +++ b/site-cookbooks/kosmos-hubot/recipes/default.rb @@ -60,6 +60,7 @@ application hal8000_path do "hubot-rss-reader", "hubot-incoming-webhook", "hubot-auth", + "hubot-kredits", ].to_json end @@ -82,33 +83,36 @@ application hal8000_path do group: "hubot", app_dir: hal8000_path, entry: "#{hal8000_path}/bin/hubot -a irc", - environment: { "HUBOT_IRC_SERVER" => "irc.freenode.net", - "HUBOT_IRC_ROOMS" => "#5apps,#kosmos,#kosmos-dev,#remotestorage,#hackerbeach,#unhosted,#sockethub", - "HUBOT_IRC_NICK" => "hal8000", - "HUBOT_IRC_NICKSERV_USERNAME" => "hal8000", - "HUBOT_IRC_NICKSERV_PASSWORD" => hal8000_freenode_data_bag_item['nickserv_password'], - "HUBOT_IRC_UNFLOOD" => "100", - "HUBOT_RSS_PRINTSUMMARY" => "false", - "HUBOT_RSS_IRCCOLORS" => "true", - # "HUBOT_LOG_LEVEL" => "error", - "EXPRESS_PORT" => "8080", - "HUBOT_RSS_HEADER" => "Update:", - "HUBOT_AUTH_ADMIN" => "bkero,derbumi,galfert,gregkare,jaaan,slvrbckt,raucao", - "OA_ASSET_FROM_ADDRESS" => "akRWZJMETdM2U5UGKadKhv1PAj2npoGja1m", - "OA_DEFAULT_QUANTITY" => "100", - "OA_ASSET_ID" => "AbDn6L2AUGnDreUuNkGFEqcxnsoUP4HCjm", - "OA_SERVER_URL" => "http://localhost:4562", - "OA_SERVER_USERNAME" => "kosmos", - "OA_SERVER_PASSWORD" => "asEjdak1yqw", - "OA_MAX_QUANTITY" => "5000", - "OA_BOT_KEYWORD" => "kredits", - "OA_PLUSPLUS_ROOMS" => "#kosmos", - "WEBHOOK_TOKEN" => hal8000_freenode_data_bag_item['webhook_token'] } + environment: { + # "HUBOT_LOG_LEVEL" => "error", + "HUBOT_IRC_SERVER" => "irc.freenode.net", + "HUBOT_IRC_ROOMS" => "#5apps,#kosmos,#kosmos-dev,#remotestorage,#hackerbeach,#unhosted,#sockethub", + "HUBOT_IRC_NICK" => "hal8000", + "HUBOT_IRC_NICKSERV_USERNAME" => "hal8000", + "HUBOT_IRC_NICKSERV_PASSWORD" => hal8000_freenode_data_bag_item['nickserv_password'], + "HUBOT_IRC_UNFLOOD" => "100", + "HUBOT_RSS_PRINTSUMMARY" => "false", + "HUBOT_RSS_IRCCOLORS" => "true", + "EXPRESS_PORT" => "8080", + "HUBOT_RSS_HEADER" => "Update:", + "HUBOT_AUTH_ADMIN" => "bkero,derbumi,galfert,gregkare,slvrbckt,raucao", + "WEBHOOK_TOKEN" => hal8000_freenode_data_bag_item['webhook_token'], + "KREDITS_WEBHOOK_TOKEN" => hal8000_freenode_data_bag_item['kredits_webhook_token'], + "KREDITS_PROVIDER_URL" => node['hal8000']['kredits']['provider_url'], + "KREDITS_ROOM" => node['hal8000']['kredits']['room'], + "KREDITS_WALLET_PATH" => node['hal8000']['kredits']['wallet_path'], + "KREDITS_WALLET_PASSWORD" => hal8000_freenode_data_bag_item['kredits_wallet_password'], + "KREDITS_CONTRACT_ADDRESS" => node['hal8000']['kredits']['contract_address'] + } ) notifies :run, "execute[systemctl daemon-reload]", :delayed notifies :restart, "service[hal8000_nodejs]", :delayed end + cookbook_file "#{name}/wallet.json" do + source "wallet.json" + end + service "hal8000_nodejs" do action [:enable, :start] end From 025eb7744137507b56281c3d4744409ad9147bcc Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Fri, 12 May 2017 13:46:06 +0200 Subject: [PATCH 69/83] Update some kredits data --- data_bags/credentials/hal8000_freenode.json | 20 +++++++++---------- .../kosmos-hubot/attributes/default.rb | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/data_bags/credentials/hal8000_freenode.json b/data_bags/credentials/hal8000_freenode.json index 0945753..f6a531f 100644 --- a/data_bags/credentials/hal8000_freenode.json +++ b/data_bags/credentials/hal8000_freenode.json @@ -1,32 +1,32 @@ { "id": "hal8000_freenode", "nickserv_password": { - "encrypted_data": "VaHF6vdJekpJFf/D1Ss9Kut4txn3x+pn5rCXqv8WCf8yxigEHGHW7lh0ufeL\nObi9g3H8Co6RdmlC0OBXZhC8bTh4R9kg9Dk8hB5qwdIMlfs=\n", - "iv": "IpQpztTEDi0tE+hin3LrPQ==\n", + "encrypted_data": "wVOuYDPJAjWN/Un+cB/bpKD7gJ4FOOfY6xSTwpOutMD+KmhgjEX4Z99G9rwv\nmeFoBiO3Z9O+C1BeIf3YGAgWnfBgNS5eRnGAxhkzsVyvpyo=\n", + "iv": "26SarumevOdpdim4omgXng==\n", "version": 1, "cipher": "aes-256-cbc" }, "rs_logger_token": { - "encrypted_data": "/p/KOwVAh5SJ90RsCxSB5mhU5eWB2AsXdEJSTJvPiL/ZfGMVUhRKuXQRfH54\nLmDl4vdNlBZPcBXYvnKRFhOB0g==\n", - "iv": "evYwOynZfms/MyqdO0eDiw==\n", + "encrypted_data": "A3z2klmsLGwmJmB4eMVKJu5yC2mjaQii7SAuYBSl/hVtrrWDqlqR5N6vqHSv\nMWoXhptuF+RBOL7wgg0DN08B8A==\n", + "iv": "hpQA2RgJhHytnvoxgsuAhw==\n", "version": 1, "cipher": "aes-256-cbc" }, "webhook_token": { - "encrypted_data": "ijgaUo7WLIh1qiHARke0ZBrKNacI57Mzqp/TJSV1Td+XKArq7ZG9uw/xP0zE\nYIKv\n", - "iv": "LPdJ81jHrdgtMX72UGRCNA==\n", + "encrypted_data": "w/cC18Wte2w2j1mU9SkeepRxOm4zBgZKd7djU6N1t3i7YgjEhHMPeQmD4m8f\nxhes\n", + "iv": "dqFAa3sXHLePuH26YrJUxw==\n", "version": 1, "cipher": "aes-256-cbc" }, "kredits_webhook_token": { - "encrypted_data": "7JASF00/9iZ+r+gDW3bAQQdzLgFQGz0pe1oTD2nI+anQqXAjD2ptzlvxRsDi\nSEM0\n", - "iv": "nkdJAj5DamG3psuAWR5r9w==\n", + "encrypted_data": "mBESEC0w2Q2wf8LRtHUtKAPDkqqt/xTjtoKCXVbu92xJedCccS51qZNcHp69\nw64Y\n", + "iv": "iZX6EzyyFkTHvJ6nnUWT6Q==\n", "version": 1, "cipher": "aes-256-cbc" }, "kredits_wallet_password": { - "encrypted_data": "e3aRrVHp64UHpa2ajw3GJIAb6BDHPEeXDeDE6srBCLb/Ruh3wq4IQr1Oejc7\n71by\n", - "iv": "ugYzQLlhsnIh0kso2+AnCA==\n", + "encrypted_data": "6Lq61jWP1oRSLiI0JucQtCdGnPFeJOYpSMZ9nw6oIkWEFbdMXnrEnKNxYJax\n0abI\n", + "iv": "XMDv5T30HTK/BhsR1lH79g==\n", "version": 1, "cipher": "aes-256-cbc" } diff --git a/site-cookbooks/kosmos-hubot/attributes/default.rb b/site-cookbooks/kosmos-hubot/attributes/default.rb index 967712a..8c7adbd 100644 --- a/site-cookbooks/kosmos-hubot/attributes/default.rb +++ b/site-cookbooks/kosmos-hubot/attributes/default.rb @@ -1,4 +1,4 @@ -node.default['hal8000']['kredits']['provider_url'] = 'https://parity.kosmos.org:8546' +node.default['hal8000']['kredits']['provider_url'] = 'https://parity.kosmos.org:8545' node.default['hal8000']['kredits']['room'] = '#kosmos' node.default['hal8000']['kredits']['wallet_path'] = 'wallet.json' -node.default['hal8000']['kredits']['contract_address'] = '0x206a58891a17ec3b594489c77d931920b33a2a81' +node.default['hal8000']['kredits']['contract_address'] = '0xcec0941dce22f2ecba48dc594dac72b66da651a0' From 892d02bf2d9c1d61e301da164c42ed13bc879cae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Wed, 17 May 2017 12:13:43 +0200 Subject: [PATCH 70/83] Deploy XMPP schlupp's master branch again --- site-cookbooks/5apps-hubot/recipes/xmpp_schlupp.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site-cookbooks/5apps-hubot/recipes/xmpp_schlupp.rb b/site-cookbooks/5apps-hubot/recipes/xmpp_schlupp.rb index 32a2749..8550165 100644 --- a/site-cookbooks/5apps-hubot/recipes/xmpp_schlupp.rb +++ b/site-cookbooks/5apps-hubot/recipes/xmpp_schlupp.rb @@ -42,7 +42,7 @@ application schlupp_xmpp_path do user "hubot" group "hubot" repository "git@gitlab.com:5apps/schlupp.git" - revision "feature/add_staging_label" + revision "master" deploy_key schlupp_xmpp_data_bag_item['deploy_key'] end From 2cec659eb793693582782f4ca319b39cb3f29ae6 Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Wed, 17 May 2017 12:38:08 +0200 Subject: [PATCH 71/83] Use new contract address --- site-cookbooks/kosmos-hubot/attributes/default.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site-cookbooks/kosmos-hubot/attributes/default.rb b/site-cookbooks/kosmos-hubot/attributes/default.rb index 8c7adbd..301b4a1 100644 --- a/site-cookbooks/kosmos-hubot/attributes/default.rb +++ b/site-cookbooks/kosmos-hubot/attributes/default.rb @@ -1,4 +1,4 @@ node.default['hal8000']['kredits']['provider_url'] = 'https://parity.kosmos.org:8545' node.default['hal8000']['kredits']['room'] = '#kosmos' node.default['hal8000']['kredits']['wallet_path'] = 'wallet.json' -node.default['hal8000']['kredits']['contract_address'] = '0xcec0941dce22f2ecba48dc594dac72b66da651a0' +node.default['hal8000']['kredits']['contract_address'] = '0x7dfab325c6ec203597c419b4b3172c6b219b9315' From 41e47f42c1673f7c652df39ca32b253e2a3097e7 Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Wed, 17 May 2017 12:38:46 +0200 Subject: [PATCH 72/83] Don't run testnet node for now --- roles/parity.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/roles/parity.rb b/roles/parity.rb index 06b232e..69e1f1a 100644 --- a/roles/parity.rb +++ b/roles/parity.rb @@ -3,5 +3,4 @@ name 'parity' run_list %w( recipe[kosmos-parity::from_package] recipe[kosmos-parity::node_dev] - recipe[kosmos-parity::node_testnet] ) From 6621127c411e8be421693046f12d9d0f227aaa2a Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Wed, 17 May 2017 12:39:23 +0200 Subject: [PATCH 73/83] Don't connect to local IPs --- site-cookbooks/kosmos-parity/recipes/node_dev.rb | 3 ++- site-cookbooks/kosmos-parity/recipes/node_mainnet.rb | 1 + site-cookbooks/kosmos-parity/recipes/node_testnet.rb | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/site-cookbooks/kosmos-parity/recipes/node_dev.rb b/site-cookbooks/kosmos-parity/recipes/node_dev.rb index 52256b3..72e9fa4 100644 --- a/site-cookbooks/kosmos-parity/recipes/node_dev.rb +++ b/site-cookbooks/kosmos-parity/recipes/node_dev.rb @@ -18,11 +18,12 @@ parity_node "dev" do password "parityparity" config parity: { chain: "dev", - no_download: true, # Don't Download Updates + no_download: true, # Don't download updates }, network: { port: 30303, warp: true, + allow_ips: "public" # Don't connect to local IPs }, rpc: { port: rpc_port, diff --git a/site-cookbooks/kosmos-parity/recipes/node_mainnet.rb b/site-cookbooks/kosmos-parity/recipes/node_mainnet.rb index 924c1ab..a6667c3 100644 --- a/site-cookbooks/kosmos-parity/recipes/node_mainnet.rb +++ b/site-cookbooks/kosmos-parity/recipes/node_mainnet.rb @@ -25,6 +25,7 @@ parity_node "mainnet" do network: { port: 30305, warp: true, + allow_ips: "public" # Don't connect to local IPs }, rpc: { port: rpc_port, diff --git a/site-cookbooks/kosmos-parity/recipes/node_testnet.rb b/site-cookbooks/kosmos-parity/recipes/node_testnet.rb index 8becabb..3896e91 100644 --- a/site-cookbooks/kosmos-parity/recipes/node_testnet.rb +++ b/site-cookbooks/kosmos-parity/recipes/node_testnet.rb @@ -21,11 +21,12 @@ parity_node "testnet" do password credentials["testnet_password"] config parity: { chain: "ropsten", - no_download: true, # Don't Download Updates + no_download: true, # Don't download updates }, network: { port: network_port, warp: true, + allow_ips: "public" # Don't connect to local IPs }, rpc: { port: rpc_port, From 1ce7c21c868186d723e3a338d32637415470e6fd Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Wed, 17 May 2017 12:39:53 +0200 Subject: [PATCH 74/83] Use custom chain config --- .../kosmos-parity/resources/node.rb | 22 ++++++++++-- .../templates/default/chain-config.json.erb | 34 +++++++++++++++++++ .../default/parity.systemd.service.erb | 2 +- 3 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 site-cookbooks/kosmos-parity/templates/default/chain-config.json.erb diff --git a/site-cookbooks/kosmos-parity/resources/node.rb b/site-cookbooks/kosmos-parity/resources/node.rb index c077928..4555a07 100644 --- a/site-cookbooks/kosmos-parity/resources/node.rb +++ b/site-cookbooks/kosmos-parity/resources/node.rb @@ -17,6 +17,10 @@ action :enable do config[:account] = {} config[:account][:password] = ["#{base_path}/password"] + if config[:parity][:chain] == "dev" + config[:parity][:chain] = "#{base_path}/chain-config.json" + end + directory base_path do recursive true owner "parity" @@ -42,8 +46,10 @@ action :enable do ruby_block "generate config" do block do + parity_args = "--chain #{config[:parity][:chain]} --base-path #{base_path}" + parity_account_list = Mixlib::ShellOut.new( - "parity account list --chain #{config[:parity][:chain]} --base-path #{base_path}", + "parity account list #{parity_args}", user: "parity" ) parity_account_list.run_command @@ -52,7 +58,7 @@ action :enable do if parity_account.empty? parity_account_create = Mixlib::ShellOut.new( - "parity account new --chain #{config[:parity][:chain]} --base-path #{base_path} --password #{base_path}/password", + "parity account new #{parity_args} --password #{base_path}/password", user: "parity" ) parity_account_create.run_command @@ -62,6 +68,18 @@ action :enable do config[:account][:unlock] = [parity_account] + # Using our own chain config (i.e. dev) + if config[:parity][:chain].include?(".json") + template "#{base_path}/chain-config.json" do + source 'chain-config.json.erb' + variables parity_account: parity_account + owner "parity" + group "parity" + mode 0640 + notifies :restart, "service[#{parity_service}]", :delayed + end + end + file "config" do path config_path content TOML::Generator.new(config).body diff --git a/site-cookbooks/kosmos-parity/templates/default/chain-config.json.erb b/site-cookbooks/kosmos-parity/templates/default/chain-config.json.erb new file mode 100644 index 0000000..9075929 --- /dev/null +++ b/site-cookbooks/kosmos-parity/templates/default/chain-config.json.erb @@ -0,0 +1,34 @@ +{ + "name": "KreditsChain", + "engine": { + "instantSeal": { "params": {} } + }, + "params": { + "accountStartNonce": "0x00", + "maximumExtraDataSize": "0x20", + "minGasLimit": "0x1388", + "networkID" : "0x11" + }, + "genesis": { + "seal": { + "ethereum": { + "nonce": "0x00006d6f7264656e", + "mixHash": "0x00000000000000000000000000000000000000647572616c65787365646c6578" + } + }, + "difficulty": "0x20000", + "author": "0x0000000000000000000000000000000000000000", + "timestamp": "0x00", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData": "0x", + "gasLimit": "0x5B8D80" + }, + "accounts": { + "0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, + "0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, + "0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, + "0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, + "<%= @parity_account %>":{"balance": "1606938044258990275541962092341162602522" } + } +} + diff --git a/site-cookbooks/kosmos-parity/templates/default/parity.systemd.service.erb b/site-cookbooks/kosmos-parity/templates/default/parity.systemd.service.erb index 073e82d..0700f45 100644 --- a/site-cookbooks/kosmos-parity/templates/default/parity.systemd.service.erb +++ b/site-cookbooks/kosmos-parity/templates/default/parity.systemd.service.erb @@ -3,7 +3,7 @@ Description=Parity Daemon (<%= @environment %>) After=network.target [Service] -ExecStart=/usr/bin/parity --config <%= @config_file %> $ARGS +ExecStart=/usr/bin/parity --config <%= @config_file %> --no-discovery $ARGS User=parity Group=parity From b7e395f1229be3a273c5f105cae1ceeff4b203a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 2 Jun 2017 18:30:48 +0200 Subject: [PATCH 75/83] Update application_ruby cookbook --- Batali | 2 +- batali.manifest | 14 +-- cookbooks/application_ruby/CHANGELOG.md | 6 ++ cookbooks/application_ruby/README.md | 38 +++++++- .../halite_gem/poise_application_ruby.rb | 2 +- .../poise_application_ruby/app_mixin.rb | 2 +- .../poise_application_ruby/cheftie.rb | 2 +- .../poise_application_ruby/error.rb | 2 +- .../poise_application_ruby/resources.rb | 3 +- .../resources/bundle_install.rb | 2 +- .../poise_application_ruby/resources/puma.rb | 86 +++++++++++++++++++ .../resources/rackup.rb | 2 +- .../poise_application_ruby/resources/rails.rb | 48 +++++++++-- .../poise_application_ruby/resources/ruby.rb | 2 +- .../resources/ruby_execute.rb | 2 +- .../resources/ruby_gem.rb | 2 +- .../poise_application_ruby/resources/thin.rb | 2 +- .../resources/unicorn.rb | 2 +- .../poise_application_ruby/service_mixin.rb | 12 ++- .../poise_application_ruby/version.rb | 4 +- .../application_ruby/libraries/default.rb | 2 +- cookbooks/application_ruby/metadata.json | 2 +- .../templates/secret_token.rb.erb | 3 + .../templates/secrets.yml.erb | 2 +- 24 files changed, 205 insertions(+), 39 deletions(-) create mode 100644 cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/puma.rb create mode 100644 cookbooks/application_ruby/templates/secret_token.rb.erb diff --git a/Batali b/Batali index 9520bb3..8d351ad 100644 --- a/Batali +++ b/Batali @@ -17,7 +17,7 @@ Batali.define do cookbook 'poise-ruby-build', '~> 1.1.0' cookbook 'application', '~> 5.2.0' cookbook 'application_javascript' - cookbook 'application_ruby' + cookbook 'application_ruby', '~> 4.1.0' cookbook 'application_git', '~> 1.1.0' # 1.2.0 doesn't work with knife-solo cookbook 'users', '~> 5.0.0' cookbook 'sudo', '~> 3.4.0' diff --git a/batali.manifest b/batali.manifest index 613c42e..06a7dd9 100644 --- a/batali.manifest +++ b/batali.manifest @@ -813,10 +813,6 @@ { "name": "application_ruby", "dependencies": [ - [ - "poise-service", - "~> 1.0" - ], [ "poise", "~> 2.0" @@ -828,13 +824,17 @@ [ "poise-ruby", "~> 2.1" + ], + [ + "poise-service", + "~> 1.0" ] ], - "version": "4.0.1", + "version": "4.1.0", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/application_ruby/versions/4.0.1/download", - "version": "4.0.1" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/application_ruby/versions/4.1.0/download", + "version": "4.1.0" } }, { diff --git a/cookbooks/application_ruby/CHANGELOG.md b/cookbooks/application_ruby/CHANGELOG.md index 5200030..e8818bd 100644 --- a/cookbooks/application_ruby/CHANGELOG.md +++ b/cookbooks/application_ruby/CHANGELOG.md @@ -1,5 +1,11 @@ # Application_Ruby Changelog +## v4.1.0 + +* Add an `application_puma` resource to run a Puma application server. +* Add support for `:initializer` style secrets for the `application_rails` resource. +* Chef 13 support. + ## v4.0.1 * Correct `gem_binary` results for `application_ruby`. diff --git a/cookbooks/application_ruby/README.md b/cookbooks/application_ruby/README.md index 98ea3e3..288f5e2 100644 --- a/cookbooks/application_ruby/README.md +++ b/cookbooks/application_ruby/README.md @@ -33,7 +33,7 @@ end ## Requirements -Chef 12 or newer is required. +Chef 12.1 or newer is required. ## Resources @@ -53,6 +53,34 @@ end All actions and properties are the same as the [`bundle_install` resource](https://github.com/poise/poise-ruby#bundle_install). +### `application_puma` + +The `application_puma` resource creates a service for `puma`. + +```ruby +application '/srv/myapp' do + puma do + port 8000 + end +end +``` + +#### Actions + +* `:enable` – Create, enable and start the service. *(default)* +* `:disable` – Stop, disable, and destroy the service. +* `:start` – Start the service. +* `:stop` – Stop the service. +* `:restart` – Stop and then start the service. +* `:reload` – Send the configured reload signal to the service. + +#### Properties + +* `path` – Base path for the application. *(name attribute)* +* `port` – Port to listen on. *(default: 80)* +* `service_name` – Name of the service to create. *(default: auto-detect)* +* `user` – User to run the service as. *(default: application owner)* + ### `application_rackup` The `application_rackup` resource creates a service for `rackup`. @@ -102,6 +130,8 @@ end #### Properties * `path` – Base path for the application. *(name attribute)* +* `app_module` – Top-level application module. Only needed for the :initializer + style of secret token configuration. *(default: auto-detect)* * `database` – Database settings for Rails. See [the database section below](#database-parameters) for more information. *(option collector)* * `migrate` – Run database migrations. *(default: false)* @@ -218,7 +248,7 @@ end * `config_path` – Path to a Thin configuration file. * `port` – Port to listen on. *(default: 80)* * `service_name` – Name of the service to create. *(default: auto-detect)* -# `user` – User to run the service as. *(default: application owner)* +* `user` – User to run the service as. *(default: application owner)* ### `application_unicorn` @@ -246,7 +276,7 @@ end * `path` – Base path for the application. *(name attribute)* * `port` – Port to listen on. *(default: 80)* * `service_name` – Name of the service to create. *(default: auto-detect)* -# `user` – User to run the service as. *(default: application owner)* +* `user` – User to run the service as. *(default: application owner)* ## Sponsors @@ -256,7 +286,7 @@ The Poise test server infrastructure is sponsored by [Rackspace](https://rackspa ## License -Copyright 2015, Noah Kantrowitz +Copyright 2015-2017, Noah Kantrowitz 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/application_ruby/files/halite_gem/poise_application_ruby.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby.rb index 7d480bf..a8da458 100644 --- a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby.rb +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2017, Noah Kantrowitz # # 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/application_ruby/files/halite_gem/poise_application_ruby/app_mixin.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/app_mixin.rb index d377f7a..2f0bb45 100644 --- a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/app_mixin.rb +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/app_mixin.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2017, Noah Kantrowitz # # 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/application_ruby/files/halite_gem/poise_application_ruby/cheftie.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/cheftie.rb index ca8eb03..4f3781e 100644 --- a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/cheftie.rb +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/cheftie.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2017, Noah Kantrowitz # # 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/application_ruby/files/halite_gem/poise_application_ruby/error.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/error.rb index ae21fa0..ab04a50 100644 --- a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/error.rb +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/error.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2017, Noah Kantrowitz # # 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/application_ruby/files/halite_gem/poise_application_ruby/resources.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources.rb index 4b58b49..5343ccb 100644 --- a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources.rb +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2017, Noah Kantrowitz # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,7 @@ # require 'poise_application_ruby/resources/bundle_install' +require 'poise_application_ruby/resources/puma' require 'poise_application_ruby/resources/rackup' require 'poise_application_ruby/resources/rails' require 'poise_application_ruby/resources/ruby' diff --git a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/bundle_install.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/bundle_install.rb index d6ccd82..ce40017 100644 --- a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/bundle_install.rb +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/bundle_install.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2017, Noah Kantrowitz # # 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/application_ruby/files/halite_gem/poise_application_ruby/resources/puma.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/puma.rb new file mode 100644 index 0000000..3f574c3 --- /dev/null +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/puma.rb @@ -0,0 +1,86 @@ +# +# Copyright 2015-2017, Noah Kantrowitz +# +# 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/provider' +require 'chef/resource' + +require 'poise_application_ruby/service_mixin' + +module PoiseApplicationRuby + module Resources + # (see Puma::Resource) + # @since 4.1.0 + module Puma + # An `application_puma` resource to manage a puma web application + # server. + # + # @since 4.1.0 + # @provides application_puma + # @action enable + # @action disable + # @action start + # @action stop + # @action restart + # @action reload + # @example + # application '/srv/myapp' do + # git '...' + # bundle_install + # puma do + # port 8080 + # end + # end + class Resource < Chef::Resource + include PoiseApplicationRuby::ServiceMixin + provides(:application_puma) + + # @!attribute port + # Port to bind to. + attribute(:port, kind_of: [String, Integer], default: 80) + end + + # Provider for `application_puma`. + # + # @since 4.1.0 + # @see Resource + # @provides application_puma + class Provider < Chef::Provider + include PoiseApplicationRuby::ServiceMixin + provides(:application_puma) + + private + + # Find the path to the config.ru. If the resource path was to a + # directory, apparent /config.ru. + # + # @return [String] + def configru_path + @configru_path ||= if ::File.directory?(new_resource.path) + ::File.join(new_resource.path, 'config.ru') + else + new_resource.path + end + end + + # Set service resource options. + def service_options(resource) + super + resource.ruby_command("puma --port #{new_resource.port} #{configru_path}") + end + end + end + end +end diff --git a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/rackup.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/rackup.rb index 8b29730..869ea6b 100644 --- a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/rackup.rb +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/rackup.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2017, Noah Kantrowitz # # 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/application_ruby/files/halite_gem/poise_application_ruby/resources/rails.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/rails.rb index 3ac56f9..6a06532 100644 --- a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/rails.rb +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/rails.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2017, Noah Kantrowitz # # 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,7 @@ require 'chef/provider' require 'chef/resource' require 'poise_application_ruby/app_mixin' +require 'poise_application_ruby/error' module PoiseApplicationRuby @@ -47,6 +48,11 @@ module PoiseApplicationRuby provides(:application_rails) actions(:deploy) + # @!attribute app_module + # Top-level application module. Only needed for the :initializer style + # of secret token configuration, and generally auto-detected. + # @return [String, false, nil] + attribute(:app_module, kind_of: [String, FalseClass, NilClass], default: lazy { default_app_module }) # @!attribute database # Option collector attribute for Rails database configuration. # @return [Hash] @@ -84,14 +90,20 @@ module PoiseApplicationRuby # Secret token for Rails session verification and other purposes. On # Rails 4.2 this will be used for secret_key_base. If not set, no # secrets configuration is written. - # @return [String] - attribute(:secret_token, kind_of: [String, FalseClass]) + # @return [String, false, nil] + attribute(:secret_token, kind_of: [String, FalseClass, NilClass]) # @!attribute secrets_config # Template content attribute for the contents of secrets.yml. Only # used when secrets_mode is :yaml. # @todo Redo this doc to cover the actual attributes created. # @return [Poise::Helpers::TemplateContent] attribute(:secrets_config, template: true, default_source: 'secrets.yml.erb', default_options: lazy { default_secrets_options }) + # @!attribute secrets_initializer + # Template content attribute for the contents of secret_token.rb. Only + # used when secrets_mode is :initializer. + # @todo Redo this doc to cover the actual attributes created. + # @return [Poise::Helpers::TemplateContent] + attribute(:secrets_initializer, template: true, default_source: 'secret_token.rb.erb', default_options: lazy { default_secrets_options }) # @!attribute secrets_mode # Secrets configuration mode. Set to `:yaml` to generate a Rails 4.2 # secrets.yml. Set to `:initializer` to update @@ -140,21 +152,33 @@ module PoiseApplicationRuby # # @return [Symbol] def default_secrets_mode - ::File.exists?(::File.join(path, 'config', 'initializers', 'secret_token.rb')) ? :initialize : :yaml + ::File.exists?(::File.join(path, 'config', 'initializers', 'secret_token.rb')) ? :initializer : :yaml end - # Default template variables for the secrets.yml. + # Default template variables for the secrets.yml and secret_token.rb. # # @return [Hash] def default_secrets_options { - config: { + yaml_config: { rails_env => { 'secret_key_base' => secret_token, } }, + secret_token: secret_token, + app_module: if secrets_mode == :initializer + raise Error.new("Unable to extract app module for #{self}, please set app_module property") if !app_module || app_module.empty? + app_module + end } end + + # Default application module name. + # + # @return [String] + def default_app_module + IO.read(::File.join(path, 'config', 'initializers', 'secret_token.rb'))[/(\w+)::Application\.config\.secret_token/, 1] + end end # Provider for `application_rails`. @@ -205,6 +229,8 @@ module PoiseApplicationRuby write_secrets_yml when :initializer write_secrets_initializer + else + raise Error.new("Unknown secrets mode #{new_resource.secrets_mode.inspect}") end end @@ -215,13 +241,19 @@ module PoiseApplicationRuby group new_resource.parent.group mode '640' content new_resource.secrets_config_content + sensitive true end end # In-place update a config/initializers/secret_token.rb file. def write_secrets_initializer - # @todo Implement initalizer-style secret support. - raise NotImplementedError.new('Sorry, intializer-style secrets loading is not yet supported.') + file ::File.join(new_resource.path, 'config', 'initializers', 'secret_token.rb') do + user new_resource.parent.owner + group new_resource.parent.group + mode '640' + content new_resource.secrets_initializer_content + sensitive true + end end # Precompile assets using the rake task. diff --git a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/ruby.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/ruby.rb index 2519699..7523e4d 100644 --- a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/ruby.rb +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/ruby.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2017, Noah Kantrowitz # # 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/application_ruby/files/halite_gem/poise_application_ruby/resources/ruby_execute.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/ruby_execute.rb index 8ca2b19..3d145b1 100644 --- a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/ruby_execute.rb +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/ruby_execute.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2017, Noah Kantrowitz # # 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/application_ruby/files/halite_gem/poise_application_ruby/resources/ruby_gem.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/ruby_gem.rb index 6a637e2..e62ae45 100644 --- a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/ruby_gem.rb +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/ruby_gem.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2017, Noah Kantrowitz # # 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/application_ruby/files/halite_gem/poise_application_ruby/resources/thin.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/thin.rb index a106137..1124790 100644 --- a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/thin.rb +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/thin.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2017, Noah Kantrowitz # # 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/application_ruby/files/halite_gem/poise_application_ruby/resources/unicorn.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/unicorn.rb index 3053d3e..0728b51 100644 --- a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/unicorn.rb +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/resources/unicorn.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2017, Noah Kantrowitz # # 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/application_ruby/files/halite_gem/poise_application_ruby/service_mixin.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/service_mixin.rb index 08ff095..c733ba8 100644 --- a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/service_mixin.rb +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/service_mixin.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2017, Noah Kantrowitz # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -39,6 +39,7 @@ module PoiseApplicationRuby module Provider include PoiseApplication::ServiceMixin::Provider include PoiseApplicationRuby::AppMixin::Provider + include PoiseRuby::RubyCommandMixin::Provider include PoiseRuby::BundlerMixin # Set up the service for running Ruby stuff. @@ -48,10 +49,17 @@ module PoiseApplicationRuby self_ = self # Create a new singleton method that fills in Python for you. resource.define_singleton_method(:ruby_command) do |val| - path = self_.new_resource.app_state_environment_ruby['PATH'] + path = self_.new_resource.app_state_environment_ruby['PATH'] || ENV['PATH'] cmd = if self_.new_resource.parent_bundle bundle_exec_command(val, path: path) else + # Insert the gem executable directory at the front of the path. + gem_environment = self_.send(:ruby_shell_out!, self_.new_resource.gem_binary, 'environment') + matches = gem_environment.stdout.scan(/EXECUTABLE DIRECTORY: (.*)$/).first + if matches + Chef::Log.debug("[#{new_resource}] Prepending gem executable directory #{matches.first} to existing $PATH (#{path})") + path = "#{matches.first}:#{path}" + end "#{self_.new_resource.ruby} #{PoiseLanguages::Utils.absolute_command(val, path: path)}" end resource.command(cmd) diff --git a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/version.rb b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/version.rb index 48f7d53..2dfdd80 100644 --- a/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/version.rb +++ b/cookbooks/application_ruby/files/halite_gem/poise_application_ruby/version.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2017, Noah Kantrowitz # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,5 +15,5 @@ # module PoiseApplicationRuby - VERSION = '4.0.1' + VERSION = '4.1.0' end diff --git a/cookbooks/application_ruby/libraries/default.rb b/cookbooks/application_ruby/libraries/default.rb index 673a63b..9b5b405 100644 --- a/cookbooks/application_ruby/libraries/default.rb +++ b/cookbooks/application_ruby/libraries/default.rb @@ -1,5 +1,5 @@ # -# Copyright 2015, Noah Kantrowitz +# Copyright 2015-2017, Noah Kantrowitz # # 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/application_ruby/metadata.json b/cookbooks/application_ruby/metadata.json index 3707047..544b213 100644 --- a/cookbooks/application_ruby/metadata.json +++ b/cookbooks/application_ruby/metadata.json @@ -1 +1 @@ -{"name":"application_ruby","version":"4.0.1","description":"A Chef cookbook for deploying application code.","long_description":"# Application_Ruby Cookbook\n\n[![Build Status](https://img.shields.io/travis/poise/application_ruby.svg)](https://travis-ci.org/poise/application_ruby)\n[![Gem Version](https://img.shields.io/gem/v/poise-application-ruby.svg)](https://rubygems.org/gems/poise-application-ruby)\n[![Cookbook Version](https://img.shields.io/cookbook/v/application_ruby.svg)](https://supermarket.chef.io/cookbooks/application_ruby)\n[![Coverage](https://img.shields.io/codecov/c/github/poise/application_ruby.svg)](https://codecov.io/github/poise/application_ruby)\n[![Gemnasium](https://img.shields.io/gemnasium/poise/application_ruby.svg)](https://gemnasium.com/poise/application_ruby)\n[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)\n\nA [Chef](https://www.chef.io/) cookbook to deploy Ruby applications.\n\n## Quick Start\n\nTo deploy a Rails application from git:\n\n```ruby\napplication '/srv/myapp' do\n git 'https://github.com/example/myapp.git'\n bundle_install do\n deployment true\n without %w{development test}\n end\n rails do\n database 'sqlite3:///db.sqlite3'\n secret_token 'd78fe08df56c9'\n migrate true\n end\n unicorn do\n port 8000\n end\nend\n```\n\n## Requirements\n\nChef 12 or newer is required.\n\n## Resources\n\n### `application_bundle_install`\n\nThe `application_bundle_install` resource installs gems using Bundler for a\ndeployment.\n\n```ruby\napplication '/srv/myapp' do\n bundle_install do\n deployment true\n without %w{development test}\n end\nend\n```\n\nAll actions and properties are the same as the [`bundle_install` resource](https://github.com/poise/poise-ruby#bundle_install).\n\n### `application_rackup`\n\nThe `application_rackup` resource creates a service for `rackup`.\n\n```ruby\napplication '/srv/myapp' do\n rackup do\n port 8000\n end\nend\n```\n\n#### Actions\n\n* `:enable` – Create, enable and start the service. *(default)*\n* `:disable` – Stop, disable, and destroy the service.\n* `:start` – Start the service.\n* `:stop` – Stop the service.\n* `:restart` – Stop and then start the service.\n* `:reload` – Send the configured reload signal to the service.\n\n#### Properties\n\n* `path` – Base path for the application. *(name attribute)*\n* `port` – Port to listen on. *(default: 80)*\n* `service_name` – Name of the service to create. *(default: auto-detect)*\n# `user` – User to run the service as. *(default: application owner)*\n\n### `application_rails`\n\nThe `application_rails` resource\n\n```ruby\napplication '/srv/myapp' do\n rails do\n database 'sqlite3:///db.sqlite3'\n secret_token 'd78fe08df56c9'\n migrate true\n end\nend\n```\n\n#### Actions\n\n* `:deploy` – Create config files and run required deployments steps. *(default)*\n\n#### Properties\n\n* `path` – Base path for the application. *(name attribute)*\n* `database` – Database settings for Rails. See [the database section\n below](#database-parameters) for more information. *(option collector)*\n* `migrate` – Run database migrations. *(default: false)*\n* `precompile_assets` – Run `rake assets:precompile`. *(default: auto-detect)()\n* `rails_env` – Rails environment name. *(default: node.chef_environment)*\n* `secret_token` – Secret token for Rails session verification et al.\n* `secrets_mode` – Secrets configuration mode. Set to `:yaml` to generate a\n Rails 4.2 secrets.yml. Set to `:initializer` to update\n `config/initializers/secret_token.rb`. *(default: auto-detect)*\n\n**NOTE:** At this time `secrets_mode :initializer` is not implemented.\n\n#### Database Parameters\n\nThe database parameters can be set in three ways: URL, hash, and block.\n\nIf you have a single URL for the parameters, you can pass it directly to\n`database`:\n\n```ruby\nrails do\n database 'mysql2://myuser@dbhost/myapp'\nend\n```\n\nPassing a single URL will also set the `$DATABASE_URL` environment variable\nautomatically for compatibility with Heroku-based applications.\n\nAs with other option collector resources, you can pass individual settings as\neither a hash or block:\n\n```ruby\nrails do\n database do\n adapter 'mysql2'\n username 'myuser'\n host 'dbhost'\n database 'myapp'\n end\nend\n\nrails do\n database({\n adapter: 'mysql2',\n username: 'myuser',\n host: 'dbhost',\n database: 'myapp',\n })\nend\n```\n\n### `application_ruby`\n\nThe `application_ruby` resource installs a Ruby runtime for the deployment.\n\n```ruby\napplication '/srv/myapp' do\n ruby '2.2'\nend\n```\n\nAll actions and properties are the same as the [`ruby_runtime` resource](https://github.com/poise/poise-ruby#ruby_runtime).\n\n### `application_ruby_gem`\n\nThe `application_ruby_gem` resource installs Ruby gems for the deployment.\n\n```ruby\napplication '/srv/myapp' do\n ruby_gem 'rake'\nend\n```\n\nAll actions and properties are the same as the [`ruby_gem` resource](https://github.com/poise/poise-ruby#ruby_gem).\n\n### `application_ruby_execute`\n\nThe `application_ruby_execute` resource runs Ruby commands for the deployment.\n\n```ruby\napplication '/srv/myapp' do\n ruby_execute 'rake'\nend\n```\n\nAll actions and properties are the same as the [`ruby_execute` resource](https://github.com/poise/poise-ruby#ruby_execute),\nexcept that the `cwd`, `environment`, `group`, and `user` properties default to\nthe application-level data if not specified.\n\n### `application_thin`\n\nThe `application_thin` resource creates a service for `thin`.\n\n```ruby\napplication '/srv/myapp' do\n thin do\n port 8000\n end\nend\n```\n\n#### Actions\n\n* `:enable` – Create, enable and start the service. *(default)*\n* `:disable` – Stop, disable, and destroy the service.\n* `:start` – Start the service.\n* `:stop` – Stop the service.\n* `:restart` – Stop and then start the service.\n* `:reload` – Send the configured reload signal to the service.\n\n#### Properties\n\n* `path` – Base path for the application. *(name attribute)*\n* `config_path` – Path to a Thin configuration file.\n* `port` – Port to listen on. *(default: 80)*\n* `service_name` – Name of the service to create. *(default: auto-detect)*\n# `user` – User to run the service as. *(default: application owner)*\n\n### `application_unicorn`\n\nThe `application_unicorn` resource creates a service for `unicorn`.\n\n```ruby\napplication '/srv/myapp' do\n unicorn do\n port 8000\n end\nend\n```\n\n#### Actions\n\n* `:enable` – Create, enable and start the service. *(default)*\n* `:disable` – Stop, disable, and destroy the service.\n* `:start` – Start the service.\n* `:stop` – Stop the service.\n* `:restart` – Stop and then start the service.\n* `:reload` – Send the configured reload signal to the service.\n\n#### Properties\n\n* `path` – Base path for the application. *(name attribute)*\n* `port` – Port to listen on. *(default: 80)*\n* `service_name` – Name of the service to create. *(default: auto-detect)*\n# `user` – User to run the service as. *(default: application owner)*\n\n## Sponsors\n\nDevelopment sponsored by [Chef Software](https://www.chef.io/), [Symonds & Son](http://symondsandson.com/), and [Orion](https://www.orionlabs.co/).\n\nThe Poise test server infrastructure is sponsored by [Rackspace](https://rackspace.com/).\n\n## License\n\nCopyright 2015, Noah Kantrowitz\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","maintainer":"YOUR_COMPANY_NAME","maintainer_email":"YOUR_EMAIL","license":"none","platforms":{},"dependencies":{"poise":"~> 2.0","application":"~> 5.0","poise-ruby":"~> 2.1","poise-service":"~> 1.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{}} \ No newline at end of file +{"name":"application_ruby","version":"4.1.0","description":"A Chef cookbook for deploying application code.","long_description":"# Application_Ruby Cookbook\n\n[![Build Status](https://img.shields.io/travis/poise/application_ruby.svg)](https://travis-ci.org/poise/application_ruby)\n[![Gem Version](https://img.shields.io/gem/v/poise-application-ruby.svg)](https://rubygems.org/gems/poise-application-ruby)\n[![Cookbook Version](https://img.shields.io/cookbook/v/application_ruby.svg)](https://supermarket.chef.io/cookbooks/application_ruby)\n[![Coverage](https://img.shields.io/codecov/c/github/poise/application_ruby.svg)](https://codecov.io/github/poise/application_ruby)\n[![Gemnasium](https://img.shields.io/gemnasium/poise/application_ruby.svg)](https://gemnasium.com/poise/application_ruby)\n[![License](https://img.shields.io/badge/license-Apache_2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)\n\nA [Chef](https://www.chef.io/) cookbook to deploy Ruby applications.\n\n## Quick Start\n\nTo deploy a Rails application from git:\n\n```ruby\napplication '/srv/myapp' do\n git 'https://github.com/example/myapp.git'\n bundle_install do\n deployment true\n without %w{development test}\n end\n rails do\n database 'sqlite3:///db.sqlite3'\n secret_token 'd78fe08df56c9'\n migrate true\n end\n unicorn do\n port 8000\n end\nend\n```\n\n## Requirements\n\nChef 12.1 or newer is required.\n\n## Resources\n\n### `application_bundle_install`\n\nThe `application_bundle_install` resource installs gems using Bundler for a\ndeployment.\n\n```ruby\napplication '/srv/myapp' do\n bundle_install do\n deployment true\n without %w{development test}\n end\nend\n```\n\nAll actions and properties are the same as the [`bundle_install` resource](https://github.com/poise/poise-ruby#bundle_install).\n\n### `application_puma`\n\nThe `application_puma` resource creates a service for `puma`.\n\n```ruby\napplication '/srv/myapp' do\n puma do\n port 8000\n end\nend\n```\n\n#### Actions\n\n* `:enable` – Create, enable and start the service. *(default)*\n* `:disable` – Stop, disable, and destroy the service.\n* `:start` – Start the service.\n* `:stop` – Stop the service.\n* `:restart` – Stop and then start the service.\n* `:reload` – Send the configured reload signal to the service.\n\n#### Properties\n\n* `path` – Base path for the application. *(name attribute)*\n* `port` – Port to listen on. *(default: 80)*\n* `service_name` – Name of the service to create. *(default: auto-detect)*\n* `user` – User to run the service as. *(default: application owner)*\n\n### `application_rackup`\n\nThe `application_rackup` resource creates a service for `rackup`.\n\n```ruby\napplication '/srv/myapp' do\n rackup do\n port 8000\n end\nend\n```\n\n#### Actions\n\n* `:enable` – Create, enable and start the service. *(default)*\n* `:disable` – Stop, disable, and destroy the service.\n* `:start` – Start the service.\n* `:stop` – Stop the service.\n* `:restart` – Stop and then start the service.\n* `:reload` – Send the configured reload signal to the service.\n\n#### Properties\n\n* `path` – Base path for the application. *(name attribute)*\n* `port` – Port to listen on. *(default: 80)*\n* `service_name` – Name of the service to create. *(default: auto-detect)*\n# `user` – User to run the service as. *(default: application owner)*\n\n### `application_rails`\n\nThe `application_rails` resource\n\n```ruby\napplication '/srv/myapp' do\n rails do\n database 'sqlite3:///db.sqlite3'\n secret_token 'd78fe08df56c9'\n migrate true\n end\nend\n```\n\n#### Actions\n\n* `:deploy` – Create config files and run required deployments steps. *(default)*\n\n#### Properties\n\n* `path` – Base path for the application. *(name attribute)*\n* `app_module` – Top-level application module. Only needed for the :initializer\n style of secret token configuration. *(default: auto-detect)*\n* `database` – Database settings for Rails. See [the database section\n below](#database-parameters) for more information. *(option collector)*\n* `migrate` – Run database migrations. *(default: false)*\n* `precompile_assets` – Run `rake assets:precompile`. *(default: auto-detect)()\n* `rails_env` – Rails environment name. *(default: node.chef_environment)*\n* `secret_token` – Secret token for Rails session verification et al.\n* `secrets_mode` – Secrets configuration mode. Set to `:yaml` to generate a\n Rails 4.2 secrets.yml. Set to `:initializer` to update\n `config/initializers/secret_token.rb`. *(default: auto-detect)*\n\n**NOTE:** At this time `secrets_mode :initializer` is not implemented.\n\n#### Database Parameters\n\nThe database parameters can be set in three ways: URL, hash, and block.\n\nIf you have a single URL for the parameters, you can pass it directly to\n`database`:\n\n```ruby\nrails do\n database 'mysql2://myuser@dbhost/myapp'\nend\n```\n\nPassing a single URL will also set the `$DATABASE_URL` environment variable\nautomatically for compatibility with Heroku-based applications.\n\nAs with other option collector resources, you can pass individual settings as\neither a hash or block:\n\n```ruby\nrails do\n database do\n adapter 'mysql2'\n username 'myuser'\n host 'dbhost'\n database 'myapp'\n end\nend\n\nrails do\n database({\n adapter: 'mysql2',\n username: 'myuser',\n host: 'dbhost',\n database: 'myapp',\n })\nend\n```\n\n### `application_ruby`\n\nThe `application_ruby` resource installs a Ruby runtime for the deployment.\n\n```ruby\napplication '/srv/myapp' do\n ruby '2.2'\nend\n```\n\nAll actions and properties are the same as the [`ruby_runtime` resource](https://github.com/poise/poise-ruby#ruby_runtime).\n\n### `application_ruby_gem`\n\nThe `application_ruby_gem` resource installs Ruby gems for the deployment.\n\n```ruby\napplication '/srv/myapp' do\n ruby_gem 'rake'\nend\n```\n\nAll actions and properties are the same as the [`ruby_gem` resource](https://github.com/poise/poise-ruby#ruby_gem).\n\n### `application_ruby_execute`\n\nThe `application_ruby_execute` resource runs Ruby commands for the deployment.\n\n```ruby\napplication '/srv/myapp' do\n ruby_execute 'rake'\nend\n```\n\nAll actions and properties are the same as the [`ruby_execute` resource](https://github.com/poise/poise-ruby#ruby_execute),\nexcept that the `cwd`, `environment`, `group`, and `user` properties default to\nthe application-level data if not specified.\n\n### `application_thin`\n\nThe `application_thin` resource creates a service for `thin`.\n\n```ruby\napplication '/srv/myapp' do\n thin do\n port 8000\n end\nend\n```\n\n#### Actions\n\n* `:enable` – Create, enable and start the service. *(default)*\n* `:disable` – Stop, disable, and destroy the service.\n* `:start` – Start the service.\n* `:stop` – Stop the service.\n* `:restart` – Stop and then start the service.\n* `:reload` – Send the configured reload signal to the service.\n\n#### Properties\n\n* `path` – Base path for the application. *(name attribute)*\n* `config_path` – Path to a Thin configuration file.\n* `port` – Port to listen on. *(default: 80)*\n* `service_name` – Name of the service to create. *(default: auto-detect)*\n* `user` – User to run the service as. *(default: application owner)*\n\n### `application_unicorn`\n\nThe `application_unicorn` resource creates a service for `unicorn`.\n\n```ruby\napplication '/srv/myapp' do\n unicorn do\n port 8000\n end\nend\n```\n\n#### Actions\n\n* `:enable` – Create, enable and start the service. *(default)*\n* `:disable` – Stop, disable, and destroy the service.\n* `:start` – Start the service.\n* `:stop` – Stop the service.\n* `:restart` – Stop and then start the service.\n* `:reload` – Send the configured reload signal to the service.\n\n#### Properties\n\n* `path` – Base path for the application. *(name attribute)*\n* `port` – Port to listen on. *(default: 80)*\n* `service_name` – Name of the service to create. *(default: auto-detect)*\n* `user` – User to run the service as. *(default: application owner)*\n\n## Sponsors\n\nDevelopment sponsored by [Chef Software](https://www.chef.io/), [Symonds & Son](http://symondsandson.com/), and [Orion](https://www.orionlabs.co/).\n\nThe Poise test server infrastructure is sponsored by [Rackspace](https://rackspace.com/).\n\n## License\n\nCopyright 2015-2017, Noah Kantrowitz\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","maintainer":"Noah Kantrowitz","maintainer_email":"noah@coderanger.net","license":"Apache 2.0","platforms":{},"dependencies":{"poise":"~> 2.0","application":"~> 5.0","poise-ruby":"~> 2.1","poise-service":"~> 1.0"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{},"source_url":"https://github.com/poise/application_ruby","issues_url":"https://github.com/poise/application_ruby/issues","chef_version":[["< 14",">= 12.1"]],"ohai_version":[]} \ No newline at end of file diff --git a/cookbooks/application_ruby/templates/secret_token.rb.erb b/cookbooks/application_ruby/templates/secret_token.rb.erb new file mode 100644 index 0000000..d7acf98 --- /dev/null +++ b/cookbooks/application_ruby/templates/secret_token.rb.erb @@ -0,0 +1,3 @@ +# Generated by Chef for <%= @new_resource.to_s %> + +<%= @app_module %>::Application.config.secret_token = <%= @secret_token.inspect %> diff --git a/cookbooks/application_ruby/templates/secrets.yml.erb b/cookbooks/application_ruby/templates/secrets.yml.erb index a1bdc6e..c8c0fec 100644 --- a/cookbooks/application_ruby/templates/secrets.yml.erb +++ b/cookbooks/application_ruby/templates/secrets.yml.erb @@ -1,3 +1,3 @@ # Generated by Chef for <%= @new_resource.to_s %> -<%= @config.to_yaml %> +<%= @yaml_config.to_yaml %> From 9065db8476e810e97e33963220e75934ce9c942a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 2 Jun 2017 18:30:57 +0200 Subject: [PATCH 76/83] Update mastodon cookbook for 1.4.1 There is a strange issue with assets precompilation. I have found a workaround but it looks like a bug in application_ruby (in production I fixed it manually) --- .../kosmos-mastodon/recipes/default.rb | 44 ++++++++++++------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/site-cookbooks/kosmos-mastodon/recipes/default.rb b/site-cookbooks/kosmos-mastodon/recipes/default.rb index bb62af4..818fe31 100644 --- a/site-cookbooks/kosmos-mastodon/recipes/default.rb +++ b/site-cookbooks/kosmos-mastodon/recipes/default.rb @@ -41,13 +41,22 @@ user "mastodon" do home mastodon_path end -package %w(imagemagick ffmpeg libxml2-dev libxslt1-dev file git curl) -node_package %w(yarn) +package %w(imagemagick ffmpeg libxml2-dev libxslt1-dev file git curl pkg-config libprotobuf-dev protobuf-compiler) +node_package %w(yarn) # Used by Rails' assets pipeline + +ruby_version = "2.4.1" application mastodon_path do owner "mastodon" group "mastodon" + environment "HOME" => mastodon_path + + ruby_runtime ruby_version do + provider :ruby_build + version ruby_version + end + git do user "mastodon" group "mastodon" @@ -83,24 +92,27 @@ application mastodon_path do recursive true end - ruby_runtime do - provider :ruby_build - version '2.4.1' - end - bundle_install do user "mastodon" deployment true without %w(development test) end - npm_install do - user "mastodon" - end - rails do migrate true rails_env "production" + precompile_assets false # buggy, done manually below + end + + # This is the only way I could find that makes compiling the assets + # successfully for now. application_ruby's precompile_assets crashes because + # it cannot find the bundled gems + execute 'rake assets:precompile' do + environment "RAILS_ENV" => "production", "HOME" => mastodon_path + user "mastodon" + group "mastodon" + cwd mastodon_path + command "PATH=\"/opt/ruby_build/builds/#{ruby_version}/bin:$PATH\" /opt/ruby_build/builds/#{ruby_version}/bin/bundle exec rake assets:precompile" end execute "systemctl daemon-reload" do @@ -115,9 +127,9 @@ application mastodon_path do variables user: user, app_dir: mastodon_path, port: node["kosmos-mastodon"]["puma_port"], - bundle_path: '/opt/ruby_build/builds/opt/mastodon/bin/bundle' + bundle_path: "/opt/ruby_build/builds/#{ruby_version}/bin/bundle" notifies :run, "execute[systemctl daemon-reload]", :delayed - # notifies :restart, "service[mastodon-web]", :delayed + notifies :restart, "service[mastodon-web]", :delayed end service "mastodon-web" do @@ -130,9 +142,9 @@ application mastodon_path do source "mastodon-sidekiq.systemd.service.erb" variables user: user, app_dir: mastodon_path, - bundle_path: '/opt/ruby_build/builds/opt/mastodon/bin/bundle' + bundle_path: "/opt/ruby_build/builds/#{ruby_version}/bin/bundle" notifies :run, "execute[systemctl daemon-reload]", :delayed - # notifies :restart, "service[mastodon-sidekiq]", :delayed + notifies :restart, "service[mastodon-sidekiq]", :delayed end service "mastodon-sidekiq" do @@ -147,7 +159,7 @@ application mastodon_path do app_dir: mastodon_path, port: node["kosmos-mastodon"]["streaming_port"] notifies :run, "execute[systemctl daemon-reload]", :delayed - # notifies :restart, "service[mastodon-streaming]", :delayed + notifies :restart, "service[mastodon-streaming]", :delayed end service "mastodon-streaming" do From a715756e7f35605cbdd5f0d87f3a6b99f606f7b2 Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Thu, 8 Jun 2017 23:59:14 +0200 Subject: [PATCH 77/83] Add IPFS config for hubot-kredits --- site-cookbooks/kosmos-hubot/attributes/default.rb | 3 +++ site-cookbooks/kosmos-hubot/recipes/default.rb | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/site-cookbooks/kosmos-hubot/attributes/default.rb b/site-cookbooks/kosmos-hubot/attributes/default.rb index 301b4a1..541e2a5 100644 --- a/site-cookbooks/kosmos-hubot/attributes/default.rb +++ b/site-cookbooks/kosmos-hubot/attributes/default.rb @@ -2,3 +2,6 @@ node.default['hal8000']['kredits']['provider_url'] = 'https://parity.kosmos. node.default['hal8000']['kredits']['room'] = '#kosmos' node.default['hal8000']['kredits']['wallet_path'] = 'wallet.json' node.default['hal8000']['kredits']['contract_address'] = '0x7dfab325c6ec203597c419b4b3172c6b219b9315' +node.default['hal8000']['kredits']['ipfs_host'] = 'ipfs.kosmos.org' +node.default['hal8000']['kredits']['ipfs_port'] = '5444' +node.default['hal8000']['kredits']['ipfs_protocol'] = 'https' diff --git a/site-cookbooks/kosmos-hubot/recipes/default.rb b/site-cookbooks/kosmos-hubot/recipes/default.rb index 8b001e0..66890d4 100644 --- a/site-cookbooks/kosmos-hubot/recipes/default.rb +++ b/site-cookbooks/kosmos-hubot/recipes/default.rb @@ -102,7 +102,10 @@ application hal8000_path do "KREDITS_ROOM" => node['hal8000']['kredits']['room'], "KREDITS_WALLET_PATH" => node['hal8000']['kredits']['wallet_path'], "KREDITS_WALLET_PASSWORD" => hal8000_freenode_data_bag_item['kredits_wallet_password'], - "KREDITS_CONTRACT_ADDRESS" => node['hal8000']['kredits']['contract_address'] + "KREDITS_CONTRACT_ADDRESS" => node['hal8000']['kredits']['contract_address'], + "IPFS_API_HOST" => node['hal8000']['kredits']['ipfs_host'], + "IPFS_API_PORT" => node['hal8000']['kredits']['ipfs_port'], + "IPFS_API_PROTOCOL" => node['hal8000']['kredits']['ipfs_protocol'] } ) notifies :run, "execute[systemctl daemon-reload]", :delayed From 25c4a038d3d7fa1da8b5a3b4ba5258d2767ebd20 Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Fri, 9 Jun 2017 13:01:26 +0200 Subject: [PATCH 78/83] Use local IPFS API in hal8000 --- site-cookbooks/kosmos-hubot/recipes/default.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/site-cookbooks/kosmos-hubot/recipes/default.rb b/site-cookbooks/kosmos-hubot/recipes/default.rb index 66890d4..88c8367 100644 --- a/site-cookbooks/kosmos-hubot/recipes/default.rb +++ b/site-cookbooks/kosmos-hubot/recipes/default.rb @@ -102,10 +102,10 @@ application hal8000_path do "KREDITS_ROOM" => node['hal8000']['kredits']['room'], "KREDITS_WALLET_PATH" => node['hal8000']['kredits']['wallet_path'], "KREDITS_WALLET_PASSWORD" => hal8000_freenode_data_bag_item['kredits_wallet_password'], - "KREDITS_CONTRACT_ADDRESS" => node['hal8000']['kredits']['contract_address'], - "IPFS_API_HOST" => node['hal8000']['kredits']['ipfs_host'], - "IPFS_API_PORT" => node['hal8000']['kredits']['ipfs_port'], - "IPFS_API_PROTOCOL" => node['hal8000']['kredits']['ipfs_protocol'] + "KREDITS_CONTRACT_ADDRESS" => node['hal8000']['kredits']['contract_address'] + # "IPFS_API_HOST" => node['hal8000']['kredits']['ipfs_host'], + # "IPFS_API_PORT" => node['hal8000']['kredits']['ipfs_port'], + # "IPFS_API_PROTOCOL" => node['hal8000']['kredits']['ipfs_protocol'] } ) notifies :run, "execute[systemctl daemon-reload]", :delayed From e5f3121ee301274b27552d101796de79a4fbe770 Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Fri, 9 Jun 2017 13:01:38 +0200 Subject: [PATCH 79/83] Improve CORS headers for IPFS proxy --- .../templates/default/nginx_conf_ipfs.kosmos.org.erb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/site-cookbooks/kosmos-ipfs/templates/default/nginx_conf_ipfs.kosmos.org.erb b/site-cookbooks/kosmos-ipfs/templates/default/nginx_conf_ipfs.kosmos.org.erb index 6fdb500..abba8e5 100644 --- a/site-cookbooks/kosmos-ipfs/templates/default/nginx_conf_ipfs.kosmos.org.erb +++ b/site-cookbooks/kosmos-ipfs/templates/default/nginx_conf_ipfs.kosmos.org.erb @@ -32,7 +32,9 @@ server { proxy_buffers 1024 8k; proxy_http_version 1.1; # CORS headers for Kredits - add_header 'Access-Control-Allow-Origin' 'https://kredits.kosmos.org'; + add_header 'Access-Control-Allow-Origin' '*'; + add_header 'Access-Control-Allow-Methods' 'GET,POST,PUT'; + add_header 'Access-Control-Allow-Credentials' 'true'; location /api/v0/cat { proxy_pass http://_ipfs/api/v0/cat; From f96444d6f4087cb07cfc7754d2db07b976568649 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 9 Jun 2017 13:34:44 +0200 Subject: [PATCH 80/83] Move CORS headers from nginx to ipfs --- site-cookbooks/kosmos-ipfs/recipes/default.rb | 11 +++++++++++ .../templates/default/nginx_conf_ipfs.kosmos.org.erb | 4 ---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/site-cookbooks/kosmos-ipfs/recipes/default.rb b/site-cookbooks/kosmos-ipfs/recipes/default.rb index 9ea808d..a8f095f 100644 --- a/site-cookbooks/kosmos-ipfs/recipes/default.rb +++ b/site-cookbooks/kosmos-ipfs/recipes/default.rb @@ -21,4 +21,15 @@ ipfs_config "Gateway.Writable" do value true end +# Set up CORS headers +ipfs_config "API.HTTPHeaders.Access-Control-Allow-Credentials" do + value '["true"]' +end +ipfs_config "API.HTTPHeaders.Access-Control-Allow-Methods" do + value '["PUT", "GET", "POST"]' +end +ipfs_config "API.HTTPHeaders.Access-Control-Allow-Origin" do + value '["*"]' +end + include_recipe "kosmos-ipfs::letsencrypt" diff --git a/site-cookbooks/kosmos-ipfs/templates/default/nginx_conf_ipfs.kosmos.org.erb b/site-cookbooks/kosmos-ipfs/templates/default/nginx_conf_ipfs.kosmos.org.erb index abba8e5..62fbee9 100644 --- a/site-cookbooks/kosmos-ipfs/templates/default/nginx_conf_ipfs.kosmos.org.erb +++ b/site-cookbooks/kosmos-ipfs/templates/default/nginx_conf_ipfs.kosmos.org.erb @@ -31,10 +31,6 @@ server { # Increase number of buffers. Default is 8 proxy_buffers 1024 8k; proxy_http_version 1.1; - # CORS headers for Kredits - add_header 'Access-Control-Allow-Origin' '*'; - add_header 'Access-Control-Allow-Methods' 'GET,POST,PUT'; - add_header 'Access-Control-Allow-Credentials' 'true'; location /api/v0/cat { proxy_pass http://_ipfs/api/v0/cat; From cf48006a0acf541c8ef9aa344c884fa4eb64daf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 9 Jun 2017 13:37:33 +0200 Subject: [PATCH 81/83] Add get endpoint to ipfs proxied API --- .../templates/default/nginx_conf_ipfs.kosmos.org.erb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/site-cookbooks/kosmos-ipfs/templates/default/nginx_conf_ipfs.kosmos.org.erb b/site-cookbooks/kosmos-ipfs/templates/default/nginx_conf_ipfs.kosmos.org.erb index 62fbee9..e399f6c 100644 --- a/site-cookbooks/kosmos-ipfs/templates/default/nginx_conf_ipfs.kosmos.org.erb +++ b/site-cookbooks/kosmos-ipfs/templates/default/nginx_conf_ipfs.kosmos.org.erb @@ -40,6 +40,10 @@ server { proxy_pass http://_ipfs/api/v0/add; } + location /api/v0/get { + proxy_pass http://_ipfs/api/v0/get; + } + <% if File.exist?(@ssl_cert) && File.exist?(@ssl_key) -%> ssl_certificate <%= @ssl_cert %>; ssl_certificate_key <%= @ssl_key %>; From 0acc4e65e920ba2531eb49deea93a275a6c964e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 9 Jun 2017 15:35:16 +0200 Subject: [PATCH 82/83] Fix the IPFS API URL for the get command --- .../templates/default/nginx_conf_ipfs.kosmos.org.erb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/site-cookbooks/kosmos-ipfs/templates/default/nginx_conf_ipfs.kosmos.org.erb b/site-cookbooks/kosmos-ipfs/templates/default/nginx_conf_ipfs.kosmos.org.erb index e399f6c..9afd2ea 100644 --- a/site-cookbooks/kosmos-ipfs/templates/default/nginx_conf_ipfs.kosmos.org.erb +++ b/site-cookbooks/kosmos-ipfs/templates/default/nginx_conf_ipfs.kosmos.org.erb @@ -40,8 +40,8 @@ server { proxy_pass http://_ipfs/api/v0/add; } - location /api/v0/get { - proxy_pass http://_ipfs/api/v0/get; + location /api/v0/object/get { + proxy_pass http://_ipfs/api/v0/object/get; } <% if File.exist?(@ssl_cert) && File.exist?(@ssl_key) -%> From afc07c3192d90088a51e62a42ef7931e1c71181b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Kar=C3=A9kinian?= Date: Fri, 9 Jun 2017 16:08:36 +0200 Subject: [PATCH 83/83] Add more secure sudo configuration Also update the sudo cookbook --- Batali | 2 +- batali.manifest | 6 +++--- cookbooks/sudo/CHANGELOG.md | 4 ++++ cookbooks/sudo/metadata.json | 2 +- cookbooks/sudo/providers/default.rb | 4 ++++ site-cookbooks/kosmos-base/recipes/default.rb | 8 ++++++++ 6 files changed, 21 insertions(+), 5 deletions(-) diff --git a/Batali b/Batali index 8d351ad..1e3e6b1 100644 --- a/Batali +++ b/Batali @@ -20,7 +20,7 @@ Batali.define do cookbook 'application_ruby', '~> 4.1.0' cookbook 'application_git', '~> 1.1.0' # 1.2.0 doesn't work with knife-solo cookbook 'users', '~> 5.0.0' - cookbook 'sudo', '~> 3.4.0' + cookbook 'sudo', '~> 3.5.0' cookbook 'hostname' cookbook 'redis', git: 'https://github.com/phlipper/chef-redis.git', diff --git a/batali.manifest b/batali.manifest index 06a7dd9..1e5e03f 100644 --- a/batali.manifest +++ b/batali.manifest @@ -912,11 +912,11 @@ "dependencies": [ ], - "version": "3.4.0", + "version": "3.5.0", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/sudo/versions/3.4.0/download", - "version": "3.4.0" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/sudo/versions/3.5.0/download", + "version": "3.5.0" } }, { diff --git a/cookbooks/sudo/CHANGELOG.md b/cookbooks/sudo/CHANGELOG.md index 7ae8ead..691c8a8 100644 --- a/cookbooks/sudo/CHANGELOG.md +++ b/cookbooks/sudo/CHANGELOG.md @@ -2,6 +2,10 @@ This file is used to list changes made in each version of the sudo cookbook. +## 3.5.0 (2017-05-16) + +- Add sudo package management to resource + ## 3.4.0 (2017-04-26) - Add lwrp support for only env_keep add/subtract diff --git a/cookbooks/sudo/metadata.json b/cookbooks/sudo/metadata.json index f96d2e8..3f2a4e7 100644 --- a/cookbooks/sudo/metadata.json +++ b/cookbooks/sudo/metadata.json @@ -1 +1 @@ -{"name":"sudo","version":"3.4.0","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 default recipe installs the `sudo` package and configures the `/etc/sudoers` file. The cookbook also includes a sudo resource to adding and removing individual sudo entries.\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\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\n### Attributes\n\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\n\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 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### Sudo Resource\n\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#### Resource Properties\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 \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## License & Authors\n\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"},"source_url":"https://github.com/chef-cookbooks/sudo","issues_url":"https://github.com/chef-cookbooks/sudo/issues","chef_version":[[">= 12.1"]],"ohai_version":[]} \ No newline at end of file +{"name":"sudo","version":"3.5.0","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 default recipe installs the `sudo` package and configures the `/etc/sudoers` file. The cookbook also includes a sudo resource to adding and removing individual sudo entries.\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\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\n### Attributes\n\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\n\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 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### Sudo Resource\n\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#### Resource Properties\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 \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## License & Authors\n\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"},"source_url":"https://github.com/chef-cookbooks/sudo","issues_url":"https://github.com/chef-cookbooks/sudo/issues","chef_version":[[">= 12.1"]],"ohai_version":[]} \ No newline at end of file diff --git a/cookbooks/sudo/providers/default.rb b/cookbooks/sudo/providers/default.rb index 4b6a16f..03e0a2b 100644 --- a/cookbooks/sudo/providers/default.rb +++ b/cookbooks/sudo/providers/default.rb @@ -113,6 +113,10 @@ end action :install do target = "#{node['authorization']['sudo']['prefix']}/sudoers.d/" + package 'sudo' do + not_if 'which sudo' + end + unless ::File.exist?(target) sudoers_dir = directory target sudoers_dir.run_action(:create) diff --git a/site-cookbooks/kosmos-base/recipes/default.rb b/site-cookbooks/kosmos-base/recipes/default.rb index 168b85e..2d88fa2 100644 --- a/site-cookbooks/kosmos-base/recipes/default.rb +++ b/site-cookbooks/kosmos-base/recipes/default.rb @@ -28,6 +28,14 @@ users_manage 'sysadmin' do action [:remove, :create] end +node.override['authorization']['sudo']['sudoers_defaults'] = [ + # not default on Ubuntu, explicitely enable. Uses a minimal white list of + # environment variables + 'env_reset', + # Send emails on unauthorized attempts + 'mail_badpass', + 'secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"', +] node.override['authorization']['sudo']['passwordless'] = true include_recipe 'sudo'