├── .delivery └── project.toml ├── .editorconfig ├── .gitattributes ├── .github ├── CODEOWNERS └── workflows │ ├── branchcleanup.yml │ ├── delivery.yml │ └── kitchen.yml ├── .gitignore ├── .travis.yml ├── .vscode └── extensions.json ├── Berksfile ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Gemfile ├── LICENSE ├── README.md ├── TESTING.md ├── attributes └── default.rb ├── chefignore ├── kitchen.dokken.yml ├── kitchen.yml ├── libraries └── helpers.rb ├── metadata.rb ├── recipes ├── bsd_service.rb ├── config.rb ├── cron.rb ├── default.rb ├── delete_validation.rb ├── init_service.rb ├── launchd_service.rb ├── runit_service.rb ├── service.rb ├── smf_service.rb ├── src_service.rb ├── systemd_service.rb ├── task.rb ├── upstart_service.rb └── windows_service.rb ├── resources ├── cron.rb ├── launchd.rb ├── scheduled_task.rb ├── systemd_timer.rb └── trusted_certificate.rb ├── spec ├── spec_helper.rb └── unit │ ├── config_spec.rb │ ├── cron_spec.rb │ ├── init_service_spec.rb │ ├── launchd_service_spec.rb │ ├── scheduled_task_spec.rb │ └── service_spec.rb ├── templates └── default │ ├── clearlinux │ └── chef │ │ └── chef-client.erb │ ├── client.rb.erb │ ├── com.chef.chef-client.plist.erb │ ├── debian │ ├── default │ │ └── chef-client.erb │ └── init.d │ │ └── chef-client.erb │ ├── fedora │ └── sysconfig │ │ └── chef-client.erb │ ├── freebsd │ ├── chef-client.erb │ └── chef.erb │ ├── redhat │ ├── init.d │ │ └── chef-client.erb │ └── sysconfig │ │ └── chef-client.erb │ ├── solaris │ ├── chef-client.erb │ ├── manifest-5.11.xml.erb │ └── manifest.xml.erb │ ├── suse │ ├── init.d │ │ └── chef-client.erb │ └── sysconfig │ │ └── chef-client.erb │ └── windows │ └── client.service.rb.erb └── test ├── cookbooks └── test │ ├── metadata.rb │ └── recipes │ ├── config.rb │ ├── cron.rb │ ├── cron_resource.rb │ ├── license.rb │ ├── service.rb │ ├── systemd_timer_resource.rb │ └── task.rb └── integration ├── config └── client_rb_spec.rb ├── cron └── cron_spec.rb ├── cron_resource └── cron_spec.rb ├── license └── client_rb_spec.rb ├── service_bsd └── service_bsd_spec.rb ├── service_init └── service_init_spec.rb ├── service_systemd └── service_init_spec.rb ├── task └── task_spec.rb └── timer_systemd └── timer_systemd_spec.rb /.delivery/project.toml: -------------------------------------------------------------------------------- 1 | [local_phases] 2 | unit = "rspec spec/" 3 | lint = 'cookstyle --display-cop-names --extra-details' 4 | syntax = "echo skipping" 5 | provision = "echo skipping" 6 | deploy = "echo skipping" 7 | smoke = "echo skipping" 8 | functional = "echo skipping" 9 | cleanup = "echo skipping" 10 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root=true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | insert_final_newline = true 10 | 11 | # 2 space indentation 12 | indent_style = space 13 | indent_size = 2 14 | 15 | # Avoid issues parsing cookbook files later 16 | charset = utf-8 17 | 18 | # Avoid cookstyle warnings 19 | trim_trailing_whitespace = true 20 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @chef-cookbooks/cookbook_engineering_team 2 | -------------------------------------------------------------------------------- /.github/workflows/branchcleanup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Branch Cleanup 3 | # This workflow is triggered on all closed pull requests. 4 | # However the script does not do anything if a merge was not performed. 5 | "on": 6 | pull_request: 7 | types: [closed] 8 | 9 | env: 10 | NO_BRANCH_DELETED_EXIT_CODE: 0 11 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 12 | 13 | jobs: 14 | build: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: jessfraz/branch-cleanup-action@master 18 | -------------------------------------------------------------------------------- /.github/workflows/delivery.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: delivery 3 | 4 | on: [push, pull_request] 5 | 6 | jobs: 7 | delivery: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Check out code 11 | uses: actions/checkout@master 12 | - name: Run Chef Delivery 13 | uses: actionshub/chef-delivery@main 14 | env: 15 | CHEF_LICENSE: accept-no-persist 16 | -------------------------------------------------------------------------------- /.github/workflows/kitchen.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: kitchen 3 | 4 | on: 5 | pull_request: 6 | push: 7 | branches: 8 | - master 9 | 10 | jobs: 11 | dokken: 12 | runs-on: ubuntu-latest 13 | strategy: 14 | matrix: 15 | os: 16 | - 'amazonlinux-2' 17 | - 'centos-7' 18 | - 'centos-8' 19 | - 'debian-10' 20 | - 'debian-9' 21 | - 'fedora-latest' 22 | - 'opensuse-leap-15' 23 | - 'ubuntu-1604' 24 | - 'ubuntu-1804' 25 | - 'ubuntu-2004' 26 | suite: 27 | - 'cron' 28 | - 'cron-resource' 29 | - 'config' 30 | - 'timer-systemd' 31 | - 'systemd-timer-resource' 32 | - 'service-systemd' 33 | fail-fast: false 34 | 35 | steps: 36 | - name: Check out cookbook code 37 | uses: actions/checkout@master 38 | - name: Install Chef Infra Client 39 | uses: actionshub/chef-install@master 40 | - name: Dokken 41 | uses: actionshub/kitchen-dokken@master 42 | env: 43 | CHEF_LICENSE: accept-no-persist 44 | KITCHEN_LOCAL_YAML: kitchen.dokken.yml 45 | with: 46 | suite: ${{ matrix.suite }} 47 | os: ${{ matrix.os }} 48 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.rbc 2 | .config 3 | InstalledFiles 4 | lib/bundler/man 5 | pkg 6 | test/tmp 7 | test/version_tmp 8 | tmp 9 | _Store 10 | *~ 11 | *# 12 | .#* 13 | \#*# 14 | *.un~ 15 | *.tmp 16 | *.bk 17 | *.bkup 18 | 19 | # editor temp files 20 | .idea 21 | .*.sw[a-z] 22 | 23 | # ruby/bundler files 24 | .ruby-version 25 | .ruby-gemset 26 | .rvmrc 27 | Gemfile.lock 28 | .bundle 29 | *.gem 30 | coverage 31 | spec/reports 32 | 33 | # YARD / rdoc artifacts 34 | .yardoc 35 | _yardoc 36 | doc/ 37 | rdoc 38 | 39 | # chef infra stuff 40 | Berksfile.lock 41 | .kitchen 42 | kitchen.local.yml 43 | vendor/ 44 | .coverage/ 45 | .zero-knife.rb 46 | Policyfile.lock.json 47 | 48 | # vagrant stuff 49 | .vagrant/ 50 | .vagrant.d/ 51 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | addons: 2 | apt: 3 | sources: 4 | - chef-current-xenial 5 | packages: 6 | - chef-workstation 7 | 8 | install: echo "skip bundle install" 9 | 10 | env: 11 | - CHEF_LICENSE=accept 12 | 13 | branches: 14 | only: 15 | - master 16 | 17 | services: docker 18 | 19 | env: 20 | matrix: 21 | - CHEF_VERSION=15 INSTANCE=cron-ubuntu-1604 22 | - CHEF_VERSION=15 INSTANCE=cron-ubuntu-1804 23 | - CHEF_VERSION=15 INSTANCE=cron-centos-6 24 | - CHEF_VERSION=15 INSTANCE=cron-centos-7 25 | - CHEF_VERSION=15 INSTANCE=cron-centos-8 26 | - CHEF_VERSION=15 INSTANCE=cron-opensuse-leap-15 27 | - CHEF_VERSION=15 INSTANCE=delete-validation-ubuntu-1804 28 | - CHEF_VERSION=15 INSTANCE=service-systemd-amazonlinux-2 29 | - CHEF_VERSION=15 INSTANCE=service-systemd-centos-7 30 | - CHEF_VERSION=15 INSTANCE=service-systemd-centos-8 31 | - CHEF_VERSION=15 INSTANCE=service-systemd-debian-9 32 | - CHEF_VERSION=15 INSTANCE=service-systemd-debian-10 33 | - CHEF_VERSION=15 INSTANCE=service-systemd-fedora-latest 34 | - CHEF_VERSION=15 INSTANCE=service-systemd-opensuse-leap-15 35 | - CHEF_VERSION=15 INSTANCE=service-systemd-ubuntu-1604 36 | - CHEF_VERSION=15 INSTANCE=service-systemd-ubuntu-1804 37 | - CHEF_VERSION=15 INSTANCE=timer-systemd-amazonlinux-2 38 | - CHEF_VERSION=15 INSTANCE=timer-systemd-centos-7 39 | - CHEF_VERSION=15 INSTANCE=timer-systemd-centos-8 40 | - CHEF_VERSION=15 INSTANCE=timer-systemd-debian-9 41 | - CHEF_VERSION=15 INSTANCE=timer-systemd-debian-10 42 | - CHEF_VERSION=15 INSTANCE=timer-systemd-fedora-latest 43 | - CHEF_VERSION=15 INSTANCE=timer-systemd-opensuse-leap-15 44 | - CHEF_VERSION=15 INSTANCE=timer-systemd-ubuntu-1604 45 | - CHEF_VERSION=15 INSTANCE=timer-systemd-ubuntu-1804 46 | - CHEF_VERSION=14 INSTANCE=cron-ubuntu-1604 47 | - CHEF_VERSION=14 INSTANCE=cron-ubuntu-1804 48 | - CHEF_VERSION=14 INSTANCE=cron-centos-6 49 | - CHEF_VERSION=14 INSTANCE=cron-centos-7 50 | - CHEF_VERSION=14 INSTANCE=cron-opensuse-leap-15 51 | - CHEF_VERSION=14 INSTANCE=delete-validation-ubuntu-1804 52 | - CHEF_VERSION=14 INSTANCE=service-systemd-amazonlinux-2 53 | - CHEF_VERSION=14 INSTANCE=service-systemd-centos-7 54 | - CHEF_VERSION=14 INSTANCE=service-systemd-debian-9 55 | - CHEF_VERSION=14 INSTANCE=service-systemd-debian-10 56 | - CHEF_VERSION=14 INSTANCE=service-systemd-fedora-latest 57 | - CHEF_VERSION=14 INSTANCE=service-systemd-opensuse-leap-15 58 | - CHEF_VERSION=14 INSTANCE=service-systemd-ubuntu-1604 59 | - CHEF_VERSION=14 INSTANCE=service-systemd-ubuntu-1804 60 | - CHEF_VERSION=14 INSTANCE=timer-systemd-amazonlinux-2 61 | - CHEF_VERSION=14 INSTANCE=timer-systemd-centos-7 62 | - CHEF_VERSION=14 INSTANCE=timer-systemd-debian-9 63 | - CHEF_VERSION=14 INSTANCE=timer-systemd-debian-10 64 | - CHEF_VERSION=14 INSTANCE=timer-systemd-fedora-latest 65 | - CHEF_VERSION=14 INSTANCE=timer-systemd-opensuse-leap-15 66 | - CHEF_VERSION=14 INSTANCE=timer-systemd-ubuntu-1604 67 | - CHEF_VERSION=14 INSTANCE=timer-systemd-ubuntu-1804 68 | - CHEF_VERSION=13 INSTANCE=cron-ubuntu-1604 69 | - CHEF_VERSION=13 INSTANCE=cron-ubuntu-1804 70 | - CHEF_VERSION=13 INSTANCE=cron-centos-6 71 | - CHEF_VERSION=13 INSTANCE=cron-centos-7 72 | - CHEF_VERSION=13 INSTANCE=delete-validation-ubuntu-1804 73 | - CHEF_VERSION=13 INSTANCE=service-systemd-amazonlinux-2 74 | - CHEF_VERSION=13 INSTANCE=service-systemd-centos-7 75 | - CHEF_VERSION=13 INSTANCE=service-systemd-debian-9 76 | - CHEF_VERSION=13 INSTANCE=service-systemd-debian-10 77 | - CHEF_VERSION=13 INSTANCE=service-systemd-fedora-latest 78 | - CHEF_VERSION=13 INSTANCE=service-systemd-ubuntu-1604 79 | - CHEF_VERSION=13 INSTANCE=service-systemd-ubuntu-1804 80 | - CHEF_VERSION=13 INSTANCE=timer-systemd-amazonlinux-2 81 | - CHEF_VERSION=13 INSTANCE=timer-systemd-centos-7 82 | - CHEF_VERSION=13 INSTANCE=timer-systemd-debian-9 83 | - CHEF_VERSION=13 INSTANCE=timer-systemd-debian-10 84 | - CHEF_VERSION=13 INSTANCE=timer-systemd-fedora-latest 85 | - CHEF_VERSION=13 INSTANCE=timer-systemd-ubuntu-1604 86 | - CHEF_VERSION=13 INSTANCE=timer-systemd-ubuntu-1804 87 | 88 | before_script: 89 | - sudo iptables -L DOCKER || ( echo "DOCKER iptables chain missing" ; sudo iptables -N DOCKER ) 90 | - eval "$(chef shell-init bash)" 91 | - chef --version 92 | 93 | script: KITCHEN_LOCAL_YAML=kitchen.dokken.yml CHEF_VERSION=${CHEF_VERSION} kitchen verify ${INSTANCE} 94 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "chef-software.chef", 4 | "rebornix.ruby", 5 | "editorconfig.editorconfig" 6 | ] 7 | } -------------------------------------------------------------------------------- /Berksfile: -------------------------------------------------------------------------------- 1 | source 'https://supermarket.chef.io' 2 | 3 | metadata 4 | 5 | group :integration do 6 | cookbook 'test', path: 'test/cookbooks/test' 7 | end 8 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | Please refer to the Chef Community Code of Conduct at 2 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Please refer to 2 | https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD 3 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # This gemfile provides additional gems for testing and releasing this cookbook 2 | # It is meant to be installed on top of ChefDK / Chef Workstation which provide the majority 3 | # of the necessary gems for testing this cookbook 4 | # 5 | # Run 'chef exec bundle install' to install these dependencies 6 | 7 | source 'https://rubygems.org' 8 | 9 | gem 'community_cookbook_releaser' 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Chef Client Cookbook 2 | 3 | [![Build Status](https://travis-ci.org/chef-cookbooks/chef-client.svg?branch=master)](https://travis-ci.org/chef-cookbooks/chef-client) [![Cookbook Version](https://img.shields.io/cookbook/v/chef-client.svg)](https://supermarket.chef.io/cookbooks/chef-client) 4 | 5 | This cookbook is used to configure a system to run the Chef Infra Client. 6 | 7 | ## Deprecation 8 | 9 | This cookbook is no longer under active maintenance. The functionality previously provided here is now built into Chef Infra Client itself making it easier to configure Chef Infra Client without the need for external dependencies. 10 | 11 | See these built-in resources for managing client.rb configuration and setting up Chef Infra Client to run on a schedule: 12 | 13 | - [chef_client_config](https://docs.chef.io/resources/chef_client_config/) 14 | - [chef_handler](https://docs.chef.io/resources/chef_handler/) 15 | - [chef_client_trusted_certificate](https://docs.chef.io/resources/chef_client_trusted_certificate/) 16 | - [chef_client_cron](https://docs.chef.io/resources/chef_client_cron/) 17 | - [chef_client_systemd_timer](https://docs.chef.io/resources/chef_client_systemd_timer/) 18 | - [chef_client_scheduled_task](https://docs.chef.io/resources/chef_client_scheduled_task/) 19 | - [chef_client_launchd](https://docs.chef.io/resources/chef_client_launchd/) 20 | 21 | ### What about older Chef Infra Client Releases 22 | 23 | If you're using an Infra Client release before the above resources shipped, you can keep using this cookbook without issue. Just keep in mind that at some point in the future changes to Chef Infra Client may cause this cookbook to stop working. We believe the built-in resoures offer a more powerful configuration options for users. The approach offered by these resources also align with our own best practices and we'd highly suggest moving towards those resources for configuring your Chef Infra Client. 24 | 25 | ### The new resources are missing x, y, or z 26 | 27 | If there's af feature missing from the new resources please do let us know at https://github.com/chef/chef/issues. We will not be replicating all functionality of this cookbook, but we are interested in hearing what the community needs to manage their systems. 28 | 29 | ## Requirements 30 | 31 | ### Platforms 32 | 33 | - AIX 6+ 34 | - Clear Linux 35 | - Debian 36 | - Fedora 37 | - FreeBSD 38 | - macOS 39 | - openSUSE 40 | - SLES 12+ 41 | - RHEL 42 | - Solaris 10+ 43 | - Ubuntu 44 | - Windows 45 | 46 | ### Chef 47 | 48 | - Chef 13.0+ 49 | 50 | ### Cookbooks 51 | 52 | - cron 2.0+ 53 | - logrotate 1.9.0+ 54 | 55 | See [USAGE](#usage). 56 | 57 | 58 | ## Resources 59 | 60 | The chef-client cookbook provides several resources for setting up Chef Infra Client to run on a schedule. When possible these resources should be used instead of the legacy attributes / recipes as these same resources will be included in Chef Infra Client 16+ out of the box. 61 | 62 | ### chef_client_scheduled_task 63 | 64 | The chef_client_scheduled_task resource setups up Chef Infra Client to run as a scheduled task on Windows. You can use this resource directly in any of your own recipes. Using this resource to configure Chef Infra Client running as a scheduled task allows you to control where you store the user credentials instead of storing them as node attributes. This is useful if you want to store these credentials in an encrypted databag or other secrets store. 65 | 66 | ### Actions 67 | 68 | - `:add` 69 | - `:remove` 70 | 71 | ### Properties 72 | 73 | - `user` - The username to run the task as. default: 'System' 74 | - `password` The password of the user to run the task as if not using the System user 75 | - `frequency` - Frequency with which to run the task (e.g., 'hourly', 'daily', etc.) Default is 'minute' 76 | - `frequency_modifier` Numeric value to go with the scheduled task frequency - default: '30' 77 | - `start_time` The start time for the task in HH:mm format (ex: 14:00). If the `frequency` is `minute` default start time will be `Time.now` plus the `frequency_modifier` number of minutes. 78 | - `start_date` - The start date for the task in `m:d:Y` format (ex: 12/17/2017). nil by default and isn't necessary if you're running a regular interval. 79 | - `splay` - A random number of seconds between 0 and X to add to interval. default: '300' 80 | - `config_directory` - The path to the Chef config directory. default: 'C:/chef' 81 | - `log_file_name` - The name of the log file. default: 'client.log' 82 | - `log_directory` - The path to the Chef log directory. default: 'CONFIG_DIRECTORY/log' 83 | - `chef_binary_path` - The path to the chef-client binary. default: 'C:/opscode/chef/bin/chef-client' 84 | - `daemon_options` - An optional array of extra options to pass to the chef-client 85 | - `task_name` - The name of the scheduled task. This allows for multiple chef_client_scheduled_task resources when it is used directly like in a wrapper cookbook. default: 'chef-client' 86 | 87 | ### chef_client_cron 88 | 89 | The chef_client_cron resource sets up Chef Infra Client to run as a cron job using a cron.d configuration file on Linux hosts or a job in /etc/crontab for other Unix operating systems. You can use this resource directly in any of your own recipes. 90 | 91 | ### Actions 92 | 93 | - `:add` 94 | - `:remove` 95 | 96 | ### Properties 97 | 98 | - `user` - The username to run the task as. default: 'root' 99 | - `minute` - The minute that Chef Infra Client will run as a cron task. default: '0,30' (every 30 minutes) 100 | - `hour` - The hour that Chef Infra Client will run as a cron task. default: '*' 101 | - `day` - The day that Chef Infra Client will run as a cron task. default: '*' 102 | - `month` - The month that Chef Infra Client will run as a cron task. default: '*' 103 | - `weekday` - The weekday that Chef Infra Client will run as a cron task. default: '*' 104 | - `comment` - A comment to add to the cron file. 105 | - `mailto` - The e-mail address to e-mail any cron task failures to. 106 | - `job_name` - The name of the cron task to create. This allows you to have schedules with different options if necessary. default: 'chef-client' 107 | - `splay` - A random number of seconds between 0 and X to add to interval. default: '300' 108 | - `environment` - A hash of environment variables to pass to chef-client's execution (e.g. `SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt chef-client`) 109 | - `config_directory` - The path to the Chef config directory. default: '/etc/chef/' 110 | - `log_file_name` - The name of the log file. default: 'client.log' 111 | - `log_directory` - The path to the Chef log directory. default: '/var/log/chef' on *nix or '/Library/Logs/Chef' on macOS 112 | - `append_log_file` - Whether to append to the log. Default: `true` chef-client output. 113 | - `chef_binary_path` - The path to the chef-client binary. default: '/opt/chef/bin/chef-client' 114 | - `daemon_options` - An optional array of extra command line options to pass to the chef-client 115 | 116 | ### chef_client_trusted_certificate 117 | 118 | The chef_client_trusted_certificate allows you to add a certificate to Chef Infra Client's set of trusted certificates. This is helpful when adding internal certificates for systems that the Chef Infra Client will later need to communicate with using SSL. You can use this resource directly in any of your own recipes. 119 | 120 | ### Actions 121 | 122 | - `:add` 123 | - `:remove` 124 | 125 | ### Properties 126 | 127 | - `cert_name` - The name on disk for the cert file. If not specified the resource name will be used (and .pem appended if necessary) 128 | - `certificate` - The text content of the certificate file 129 | 130 | ### Examples 131 | 132 | ```ruby 133 | chef_client_trusted_certificate 'self-signed.badssl.com' do 134 | certificate <<~CERT 135 | -----BEGIN CERTIFICATE----- 136 | MIIDeTCCAmGgAwIBAgIJAPziuikCTox4MA0GCSqGSIb3DQEBCwUAMGIxCzAJBgNV 137 | BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNp 138 | c2NvMQ8wDQYDVQQKDAZCYWRTU0wxFTATBgNVBAMMDCouYmFkc3NsLmNvbTAeFw0x 139 | OTEwMDkyMzQxNTJaFw0yMTEwMDgyMzQxNTJaMGIxCzAJBgNVBAYTAlVTMRMwEQYD 140 | VQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMQ8wDQYDVQQK 141 | DAZCYWRTU0wxFTATBgNVBAMMDCouYmFkc3NsLmNvbTCCASIwDQYJKoZIhvcNAQEB 142 | BQADggEPADCCAQoCggEBAMIE7PiM7gTCs9hQ1XBYzJMY61yoaEmwIrX5lZ6xKyx2 143 | PmzAS2BMTOqytMAPgLaw+XLJhgL5XEFdEyt/ccRLvOmULlA3pmccYYz2QULFRtMW 144 | hyefdOsKnRFSJiFzbIRMeVXk0WvoBj1IFVKtsyjbqv9u/2CVSndrOfEk0TG23U3A 145 | xPxTuW1CrbV8/q71FdIzSOciccfCFHpsKOo3St/qbLVytH5aohbcabFXRNsKEqve 146 | ww9HdFxBIuGa+RuT5q0iBikusbpJHAwnnqP7i/dAcgCskgjZjFeEU4EFy+b+a1SY 147 | QCeFxxC7c3DvaRhBB0VVfPlkPz0sw6l865MaTIbRyoUCAwEAAaMyMDAwCQYDVR0T 148 | BAIwADAjBgNVHREEHDAaggwqLmJhZHNzbC5jb22CCmJhZHNzbC5jb20wDQYJKoZI 149 | hvcNAQELBQADggEBAGlwCdbPxflZfYOaukZGCaxYK6gpincX4Lla4Ui2WdeQxE95 150 | w7fChXvP3YkE3UYUE7mupZ0eg4ZILr/A0e7JQDsgIu/SRTUE0domCKgPZ8v99k3A 151 | vka4LpLK51jHJJK7EFgo3ca2nldd97GM0MU41xHFk8qaK1tWJkfrrfcGwDJ4GQPI 152 | iLlm6i0yHq1Qg1RypAXJy5dTlRXlCLd8ufWhhiwW0W75Va5AEnJuqpQrKwl3KQVe 153 | wGj67WWRgLfSr+4QG1mNvCZb2CkjZWmxkGPuoP40/y7Yu5OFqxP5tAjj4YixCYTW 154 | EVA0pmzIzgBg+JIe3PdRy27T0asgQW/F4TY61Yk= 155 | -----END CERTIFICATE----- 156 | CERT 157 | end 158 | ``` 159 | 160 | ## Attributes 161 | 162 | The following attributes affect the behavior of the chef-client program when running as a service through one of the service recipes, or in cron with the cron recipe, or are used in the recipes for various settings that require flexibility. 163 | 164 | - `node['chef_client']['interval']` - Sets `Chef::Config[:interval]` via command-line option for number of seconds between chef-client daemon runs. Default 1800. 165 | - `node['chef_client']['splay']` - Sets `Chef::Config[:splay]` via command-line option for a random amount of seconds to add to interval. On windows, this value is used for the scheduled task's random delay. Default 300. 166 | - `node['chef_client']['log_file']` - Sets the file name used to store chef-client logs. Default "client.log". 167 | - `node['chef_client']['log_dir']` - Sets directory used to store chef-client logs. Default "/var/log/chef". 168 | - `node['chef_client']['log_rotation']['options']` - Set options to logrotation of chef-client log file. Default `['compress']`. 169 | - `node['chef_client']['log_rotation']['prerotate']` - Set prerotate action for chef-client logrotation. Default to `nil`. 170 | - `node['chef_client']['log_rotation']['postrotate']` - Set postrotate action for chef-client logrotation. Default to chef-client service reload depending on init system. It should be empty to skip reloading chef-client service in case if `node['chef_client']['systemd']['timer']` is true. 171 | - `node['chef_client']['conf_dir']` - Sets directory used via command-line option to a location where chef-client search for the client config file . Default "/etc/chef". 172 | - `node['chef_client']['bin']` - Sets the full path to the `chef-client` binary. Mainly used to set a specific path if multiple versions of chef-client exist on a system or the bin has been installed in a non-sane path. Default "/opt/chef/bin/chef-client". 173 | - `node['chef_client']['ca_cert_path']` - Sets the full path to the PEM-encoded certificate trust store used by `chef-client` when daemonized. If not set, [default values](https://docs.chef.io/chef_client_security.html#ssl-cert-file) are used. 174 | - `node['chef_client']['cron']['minute']` - The minute that chef-client will run as a cron task. See [cron recipe](#cron) 175 | - `node['chef_client']['cron']['hour']` - The hour that chef-client will run as a cron task. See [cron recipe](#cron) 176 | - `node['chef_client']['cron']['weekday']` - The weekday that chef-client will run as a cron task. See [cron recipe](#cron) 177 | - `node['chef_client']['cron']['environment_variables']` - Environment variables to pass to chef-client's execution (e.g. `SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt` chef-client) 178 | - `node['chef_client']['cron']['log_file']` - Location to capture the log output of chef-client during the chef run. 179 | - `node['chef_client']['cron']['append_log']` - Whether to append to the log. Default: `false` chef-client output. 180 | - `node['chef_client']['cron']['use_cron_d']` - If true, use the [`cron_d` resource](https://github.com/chef-cookbooks/cron). If false (default), use the cron resource built-in to Chef. 181 | - `node['chef_client']['cron']['mailto']` - If set, `MAILTO` env variable is set for cron definition 182 | - `node['chef_client']['cron']['priority']` - If set, defines the scheduling priority for the `chef-client` process. MUST be a value between -20 and 19\. ONLY applies to \*nix-style operating systems. 183 | - `node['chef_client']['reload_config']` - If true, reload Chef config of current Chef run when `client.rb` template changes (defaults to true) 184 | - `node['chef_client']['daemon_options']` - An array of additional options to pass to the chef-client service, empty by default, and must be an array if specified. 185 | - `node['chef_client']['systemd']['timer']` - If true, uses systemd timer to run chef frequently instead of chef-client daemon mode (defaults to false). This only works on platforms where systemd is installed and used. 186 | - `node['chef_client']['systemd']['timeout']` - If configured, sets the systemd timeout. This might be useful to avoid stalled chef runs in the systemd timer setup. 187 | - `node['chef_client']['systemd']['restart']` - The string to use for systemd `Restart=` value when not running as a timer. Defaults to `always`. Other possible options: `no, on-success, on-failure, on-abnormal, on-watchdog, on-abort`. 188 | - `node['chef_client']['systemd']['killmode']` - If configured, the string to use for the systemd `KillMode=` value. This determines how PIDs spawned by the chef-client process are handled when chef-client PID stops. Options: `control-group, process, mixed, none`. Systemd defaults to `control-group` when this is not specified. More information can be found on the [systemd.kill man page](https://www.freedesktop.org/software/systemd/man/systemd.kill.html). 189 | - `node['chef_client']['task']['frequency']` - Frequency with which to run the `chef-client` scheduled task (e.g., `'hourly'`, `'daily'`, etc.) Default is `'minute'`. 190 | - `node['chef_client']['task']['frequency_modifier']` - Numeric value to go with the scheduled task frequency. Default is `node['chef_client']['interval'].to_i / 60` 191 | - `node['chef_client']['task']['start_time']` - The start time for the task in `HH:mm` format (ex: 14:00). If the `frequency` is `minute` default start time will be `Time.now` plus the `frequency_modifier` number of minutes. 192 | - `node['chef_client']['task']['start_date']` - The start date for the task in `m:d:Y` format (ex: 12/17/2017). nil by default and isn't necessary if you're running a regular interval. 193 | - `node['chef_client']['task']['user']` - The user the scheduled task will run as, defaults to `'SYSTEM'`. 194 | - `node['chef_client']['task']['password']` - The password for the user the scheduled task will run as, defaults to `nil` because the default user, `'SYSTEM'`, does not need a password. 195 | - `node['chef_client']['task']['name']` - The name of the scheduled task, defaults to `chef-client`. 196 | 197 | The following attributes are set on a per-platform basis, see the `attributes/default.rb` file for default values. 198 | 199 | - `node['chef_client']['init_style']` - Sets up the client service based on the style of init system to use. Default is based on platform and falls back to `'none'`. See [service recipes](#service-recipes). 200 | - `node['chef_client']['run_path']` - Directory location where chef-client should write the PID file. Default based on platform, falls back to "/var/run". 201 | - `node['chef_client']['file_cache_path']` - Directory location for `Chef::Config[:file_cache_path]` where chef-client will cache various files. Default is unset as it causes problems on first chef runs. The default location is typically "/var/cache/cache" but could be different based on the platform. Use this attribute at your own risk. 202 | - `node['chef_client']['file_backup_path']` - Directory location for `Chef::Config[:file_backup_path]` where chef-client will backup templates and cookbook files. Default is based on platform, falls back to "/var/chef/backup". 203 | - `node['chef_client']['file_staging_uses_destdir']` - How file staging (via temporary files) is done. When true, temporary files are created in the directory in which files will reside. When false, temporary files are created under ENV['TMP']. When set to `:auto` it creates them in the destination directory, and falls back to the ENV['TMP'] directory when that is not possible. default value: chef-client default. 204 | This cookbook makes use of attribute-driven configuration with this attribute. See [USAGE](#usage) for examples. 205 | - `node['chef_client']['launchd_mode']` - (only for macOS) If set to `'daemon'`, runs chef-client with `-d` and `-s` options; defaults to `'interval'`. 206 | - `node['chef_client']['launchd_working_dir']` - (only for macOS) Sets the working directory for the launchd user (generally `root`); defaults to `/var/root`. 207 | - `node['chef_client']['launchd_self-update']` - (only for macOS) Determines whether chef-client should attempt to `:restart` itself when changes are made to the launchd plist during converge. Note that the [current implementation](https://github.com/chef/chef/blob/129a6f3982218e5eadcd33b272ba738b317bbcae/lib/chef/provider/service/macosx.rb#L128) of `macosx_service` `:restart` unloads the daemon, which stops the current chef-client run and requires an external process to resume the service. Defaults to `false`. 208 | - When `chef_client['log_file']` is set and running on a [logrotate](https://supermarket.chef.io/cookbooks/logrotate) supported platform (debian, rhel, fedora family), use the following attributes to tune log rotation. 209 | - `node['chef_client']['logrotate']['rotate']` - Number of rotated logs to keep on disk, default 12. 210 | - `node['chef_client']['logrotate']['frequency']` - How often to rotate chef client logs, default weekly. 211 | 212 | - `node['chef_client']['config']` - A hash of Chef::Config keys and their values, rendered dynamically in `/etc/chef/client.rb`. 213 | - `node['chef_client']['load_gems']` - Hash of gems to load into chef via the client.rb file 214 | - `node['ohai']['disabled_plugins']` - An array of ohai plugins to disable, empty by default, and must be an array if specified. Ohai 6 plugins should be specified as a string (ie. "dmi"). Ohai 7+ plugins should be specified as a symbol within quotation marks (ie. ":Passwd"). 215 | - `node['ohai']['optional_plugins']` - An array of optional ohai plugins to enable, empty by default, and must be an array if specified. Ohai 6 plugins should be specified as a string (ie. "dmi"). Ohai 7+ plugins should be specified as a symbol within quotation marks (ie. ":Passwd"). 216 | - `node['ohai']['plugin_path']` - An additional path to load Ohai plugins from. Necessary if you use the ohai_plugin resource in the Ohai cookbook to install your own ohai plugins. 217 | 218 | ### Chef Client Config 219 | 220 | [For the most current information about Chef Client configuration, read the documentation.](https://docs.chef.io/config_rb_client.html). 221 | 222 | - `node['chef_client']['chef_license']` - Set to 'accept' or 'accept-no-persist' to accept the [license](https://docs.chef.io/chef_license.html) before upgrading to Chef 15. 223 | - `node['chef_client']['config']['chef_server_url']` - The URL for the Chef server. 224 | - `node['chef_client']['config']['validation_client_name']` - The name of the chef-validator key that is used by the chef-client to access the Chef server during the initial chef-client run. 225 | - `node['chef_client']['config']['verbose_logging']` - Set the log level. Options: true, nil, and false. When this is set to false, notifications about individual resources being processed are suppressed (and are output at the :info logging level). Setting this to false can be useful when a chef-client is run as a daemon. Default value: nil. 226 | - `node['chef_client']['config']['rubygems_url']` - The location to source rubygems. It can be set to a string or array of strings for URIs to set as rubygems sources. This allows individuals to setup an internal mirror of rubygems for "airgapped" environments. Default value: `https://www.rubygems.org`. 227 | 228 | - See [USAGE](#usage) for how to set handlers with the `config` attribute. 229 | 230 | ## Recipes 231 | 232 | This section describes the recipes in the cookbook and how to use them in your environment. 233 | 234 | ### config 235 | 236 | Sets up the `/etc/chef/client.rb` config file from a template and reloads the configuration for the current chef-client run. 237 | 238 | See [USAGE](#usage) for more information on how the configuration is rendered with attributes. 239 | 240 | ### service recipes 241 | 242 | The `chef-client::service` recipe includes one of the `chef-client::INIT_STYLE_service` recipes based on the attribute, `node['chef_client']['init_style']`. The individual service recipes can be included directly, too. For example, to use the init scripts, on a node or role's run list: 243 | 244 | ``` 245 | recipe[chef-client::init_service] 246 | ``` 247 | 248 | Use this recipe on systems that should have a `chef-client` daemon running, such as when Knife bootstrap was used to install Chef on a new system. 249 | 250 | - `init` - uses the init script included in this cookbook, supported on debian and redhat family distributions. 251 | - `launchd` - sets up the service under launchd, supported on macOS 252 | - `bsd` - prints a message about how to update BSD systems to enable the chef-client service. 253 | - `systemd` - sets up the service under systemd. Supported on systemd based distros. 254 | 255 | ### default 256 | 257 | Includes the `chef-client::service` recipe by default on \*nix platforms and the task recipe for Windows hosts. 258 | 259 | ### delete_validation 260 | 261 | Use this recipe to delete the validation certificate (default `/etc/chef/validation.pem`) when using a `chef-client` after the client has been validated and authorized to connect to the server. 262 | 263 | ### cron 264 | 265 | Use this recipe to run chef-client as a cron job rather than as a service. The cron job runs after random delay that is between 0 and 90 seconds to ensure that the chef-clients don't attempt to connect to the chef-server at the exact same time. You should set `node['chef_client']['init_style'] = 'none'` when you use this mode but it is not required. 266 | 267 | ### task 268 | 269 | Use this recipe to run chef-client on Windows nodes as a scheduled task. Without modifying attributes the scheduled task will run 30 minutes after the recipe runs, with each chef run rescheduling the run 30 minutes in the future. By default the job runs as the system user. The time period between runs can be modified with the `default['chef_client']['task']['frequency_modifier']` attribute and the user can be changed with the `default['chef_client']['task']['user']` and `default['chef_client']['task']['password']` attributes. 270 | 271 | ## Usage 272 | 273 | Use the recipes as described above to configure your systems to run Chef as a service via cron / scheduled task or one of the service management systems supported by the recipes. 274 | 275 | The `chef-client::config` recipe is only _required_ with init style `init` (default setting for the attribute on debian/redhat family platforms, because the init script doesn't include the `pid_file` option which is set in the config. 276 | 277 | If you wish to accept the [Chef license](https://docs.chef.io/chef_license.html) before upgrading to Chef 15 you must use the `chef-client::config` recipe or set the `chef_license` value in your config manually. See [Accepting the Chef license](https://docs.chef.io/chef_license_accept.html) for more details or other ways to accept the license. 278 | 279 | The config recipe is used to dynamically generate the `/etc/chef/client.rb` config file. The template walks all attributes in `node['chef_client']['config']` and writes them out as key:value pairs. The key should be the configuration directive. For example, the following attributes (in a role): 280 | 281 | ```ruby 282 | default_attributes( 283 | "chef_client" => { 284 | "config" => { 285 | "ssl_verify_mode" => ":verify_peer", 286 | "client_fork" => true 287 | } 288 | } 289 | ) 290 | ``` 291 | 292 | will render the following configuration (`/etc/chef/client.rb`): 293 | 294 | ```ruby 295 | chef_server_url "https://api.chef.io/organizations/MYORG" 296 | validation_client_name "MYORG-validator" 297 | ssl_verify_mode :verify_peer 298 | node_name "config-ubuntu-1204" 299 | client_fork true 300 | ``` 301 | 302 | The `chef_server_url`, `node_name` and `validation_client_name` are set by default in the attributes file from `Chef::Config`. They are presumed to come from the `knife bootstrap` command when setting up a new node for Chef. To set the node name to the default value (the `node['fqdn']` attribute), it can be set false. Be careful when setting this or the Server URL, as those values may already exist. 303 | 304 | As another example, to set HTTP proxy configuration settings. By default Chef will not use a proxy. 305 | 306 | ```ruby 307 | default_attributes( 308 | "chef_client" => { 309 | "config" => { 310 | "http_proxy" => "http://proxy.mycorp.com:3128", 311 | "https_proxy" => "http://proxy.mycorp.com:3128", 312 | "http_proxy_user" => "my_username", 313 | "http_proxy_pass" => "Awe_some_Pass_Word!", 314 | "no_proxy" => "*.vmware.com,10.*" 315 | } 316 | } 317 | ) 318 | ``` 319 | 320 | ### Special Behavior 321 | 322 | Because attributes are strings and the `/etc/chef/client.rb` can use settings that are not string, such as symbols, some configuration attributes have resulting lines with special behavior: 323 | 324 | * the `audit_mode`, `log_level`, and `ssl_verify_mode` attributes are converted to symbols. The attribute need not include an initial colon. For example: 325 | 326 | ```ruby 327 | default_attributes( 328 | "chef_client" => { 329 | "config" => { 330 | "ssl_verify_mode" => ":verify_peer", 331 | "log_level" => "debug" 332 | } 333 | } 334 | ) 335 | ``` 336 | 337 | will render the following configuration (`/etc/chef/client.rb`): 338 | 339 | ```ruby 340 | ssl_verify_mode :verify_peer 341 | log_level :debug 342 | ``` 343 | 344 | * the `log_level` setting can be either a string representing a file path or one of the symbols `STDOUT`, `STDERR`, `:syslog`, and `:win_evt`. If the `log_level` attribute is a string suggestive of one of these symbols, the resulting configuration line will use the symbol. For example, 345 | 346 | ```ruby 347 | default_attributes( 348 | "chef_client" => { 349 | "config" => { 350 | "log_location" => "STDOUT" 351 | } 352 | } 353 | ) 354 | ``` 355 | 356 | will render the following configuration (`/etc/chef/client.rb`): 357 | 358 | ```ruby 359 | log_location STDOUT 360 | ``` 361 | 362 | and 363 | 364 | ```ruby 365 | default_attributes( 366 | "chef_client" => { 367 | "config" => { 368 | "log_location" => ":syslog" 369 | } 370 | } 371 | ) 372 | ``` 373 | 374 | will render the following configuration (`/etc/chef/client.rb`): 375 | 376 | ```ruby 377 | log_location :syslog 378 | ``` 379 | 380 | The strings "syslog" and "win_evt" will become the symbols `:syslog` and `:win_evt` regardless of whether they have an initial colon. 381 | 382 | ### Configuration Includes 383 | 384 | The `/etc/chef/client.rb` file will include all the configuration files in `/etc/chef/client.d/*.rb`. To create custom configuration, simply render a file resource with `file` (and the `content` parameter), `template`, `remote_file`, or `cookbook_file`. For example, in your own cookbook that requires custom Chef client configuration, create the following `cookbook_file` resource: 385 | 386 | ```ruby 387 | chef_gem 'syslog-logger' 388 | 389 | cookbook_file "/etc/chef/client.d/myconfig.rb" do 390 | source "myconfig.rb" 391 | mode '0644' 392 | notifies :create, "ruby_block[reload_client_config]" 393 | end 394 | 395 | include_recipe 'chef-client::config' 396 | ``` 397 | 398 | Then create `files/default/myconfig.rb` with the configuration content you want. For example, if you wish to create a configuration to log to syslog: 399 | 400 | ```ruby 401 | require 'syslog-logger' 402 | require 'syslog' 403 | 404 | Logger::Syslog.class_eval do 405 | attr_accessor :sync, :formatter 406 | end 407 | 408 | log_location Chef::Log::Syslog.new('chef-client', ::Syslog::LOG_DAEMON) 409 | ``` 410 | 411 | On Windows: 412 | 413 | ```ruby 414 | log_location Chef::Log::WinEvt.new 415 | ``` 416 | 417 | ### Requiring Gems 418 | 419 | Use the `load_gems` attribute to install gems that need to be required in the client.rb. This attribute should be a hash. The gem will also be installed with `chef_gem`. For example, suppose we want to use a Chef Handler Gem, `chef-handler-updated-resources`, which is used in the next heading. Set the attributes, e.g., in a role: 420 | 421 | ```ruby 422 | default_attributes( 423 | "chef_client" => { 424 | "load_gems" => { 425 | "chef-handler-updated-resources" => { 426 | "require_name" => "chef/handler/updated_resources", 427 | "version" => "0.1" 428 | } 429 | } 430 | } 431 | ) 432 | ``` 433 | 434 | Each key in `load_gems` is the name of a gem. Each gem hash can have two keys, the `require_name` which is the string that will be `require`'d in `/etc/chef/client.rb`, and `version` which is the version of the gem to install. If the version is not specified, the latest version will be installed. 435 | 436 | The above example will render the following in `/etc/chef/client.rb`: 437 | 438 | ```ruby 439 | ["chef/handler/updated_resources"].each do |lib| 440 | begin 441 | require lib 442 | rescue LoadError 443 | Chef::Log.warn "Failed to load #{lib}. This should be resolved after a chef run." 444 | end 445 | end 446 | ``` 447 | 448 | ### Start, Report, Exception Handlers 449 | 450 | To dynamically render configuration for Start, Report, or Exception handlers, set the following attributes in the `config` attributes: 451 | 452 | - `start_handlers` 453 | - `report_handlers` 454 | - `exception_handlers` 455 | 456 | This is an alternative to using the [`chef_handler` cookbook](https://supermarket.chef.io/cookbooks/chef_handler). 457 | 458 | Each of these attributes must be an array of hashes. The hash has two keys, `class` (a string), and `arguments` (an array). For example, to use the report handler in the [Requiring Gems](#requiring-gems) section: 459 | 460 | ```ruby 461 | default_attributes( 462 | "chef_client" => { 463 | "config" => { 464 | "report_handlers" => [ 465 | {"class" => "SimpleReport::UpdatedResources", "arguments" => []} 466 | ] 467 | } 468 | } 469 | ) 470 | ``` 471 | 472 | If the handler you're using has an initialize method that takes arguments, then pass each one as a member of the array. Otherwise, leave it blank as above. 473 | 474 | This will render the following in `/etc/chef/client.rb`. 475 | 476 | ```ruby 477 | report_handlers << SimpleReport::UpdatedResources.new() 478 | ``` 479 | 480 | #### Launchd 481 | 482 | On macOS and macOS Server, the default service implementation is "launchd". 483 | 484 | Since launchd can run a service in interval mode, by default chef-client is not started in daemon mode like on Debian or Ubuntu. Keep this in mind when you look at your process list and check for a running chef process! If you wish to run chef-client in daemon mode, set attribute `chef_client.launchd_mode` to "daemon". 485 | 486 | ## Installing and updating chef-client 487 | 488 | This cookbook does not handle updating the chef-client, as that's out of the cookbook's current scope. To sensibly manage updates of the chef-client's install, we refer you to: 489 | 490 | - [chef_client_updater](https://github.com/chef-cookbooks/chef_client_updater) - Cookbook for keeping your install up-to-date 491 | 492 | ## License 493 | 494 | **Copyright:** 2010-2020, Chef Software, Inc. 495 | 496 | ``` 497 | Licensed under the Apache License, Version 2.0 (the "License"); 498 | you may not use this file except in compliance with the License. 499 | You may obtain a copy of the License at 500 | 501 | http://www.apache.org/licenses/LICENSE-2.0 502 | 503 | Unless required by applicable law or agreed to in writing, software 504 | distributed under the License is distributed on an "AS IS" BASIS, 505 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 506 | See the License for the specific language governing permissions and 507 | limitations under the License. 508 | ``` 509 | -------------------------------------------------------------------------------- /TESTING.md: -------------------------------------------------------------------------------- 1 | Please refer to 2 | 3 | -------------------------------------------------------------------------------- /attributes/default.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Joshua Timberman () 3 | # Author:: Seth Chisamore () 4 | # Cookbook:: chef-client 5 | # Attributes:: default 6 | # 7 | # Copyright:: Copyright (c) Chef Software Inc. 8 | # 9 | # Licensed under the Apache License, Version 2.0 (the 'License'); 10 | # you may not use this file except in compliance with the License. 11 | # You may obtain a copy of the License at 12 | # 13 | # http://www.apache.org/licenses/LICENSE-2.0 14 | # 15 | # Unless required by applicable law or agreed to in writing, software 16 | # distributed under the License is distributed on an 'AS IS' BASIS, 17 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | # See the License for the specific language governing permissions and 19 | # limitations under the License. 20 | 21 | # We only set these by default because this is what comes from `knife 22 | # bootstrap` (the best way to install Chef Client on managed nodes). 23 | # 24 | # Users can add other configuration options through attributes in 25 | # their favorite way (role, 'site' cookbooks, etc). 26 | default['chef_client']['config'] = { 27 | 'chef_server_url' => Chef::Config[:chef_server_url], 28 | 'validation_client_name' => Chef::Config[:validation_client_name], 29 | 'node_name' => Chef::Config[:node_name], 30 | 'verify_api_cert' => true, 31 | } 32 | 33 | # Accept the chef license when running the chef service 34 | default['chef_client']['chef_license'] = nil 35 | 36 | default['chef_client']['log_file'] = 'client.log' 37 | default['chef_client']['interval'] = '1800' 38 | default['chef_client']['splay'] = '300' 39 | default['chef_client']['conf_dir'] = '/etc/chef' 40 | default['chef_client']['bin'] = '/opt/chef/bin/chef-client' 41 | 42 | # Set a sane default log directory location, overriden by specific 43 | # platforms below. 44 | default['chef_client']['log_dir'] = '/var/log/chef' 45 | 46 | # If log file is used, default permissions so everyone can read 47 | default['chef_client']['log_perm'] = '640' 48 | 49 | # Configuration for chef-client::cron recipe. 50 | default['chef_client']['cron'] = { 51 | 'minute' => '0,30', 52 | 'hour' => '*', 53 | 'weekday' => '*', 54 | 'path' => nil, 55 | 'environment_variables' => nil, 56 | 'log_directory' => nil, 57 | 'log_file' => '/dev/null', 58 | 'append_log' => false, 59 | 'use_cron_d' => false, 60 | 'mailto' => nil, 61 | 'nice_path' => '/bin/nice', 62 | } 63 | 64 | # on linux we should use cron_d instead of crontab 65 | default['chef_client']['cron']['use_cron_d'] = true if node['os'] == 'linux' 66 | 67 | # Configuration for chef-client::systemd_service recipe 68 | default['chef_client']['systemd']['timer'] = false 69 | # Systemd timeout. Might be useful for timer setups to avoid stalled chef runs 70 | default['chef_client']['systemd']['timeout'] = false 71 | # Restart mode when not running as a timer 72 | default['chef_client']['systemd']['restart'] = 'always' 73 | 74 | # Configuration for Windows scheduled task 75 | default['chef_client']['task']['frequency'] = 'minute' 76 | default['chef_client']['task']['frequency_modifier'] = node['chef_client']['interval'].to_i / 60 77 | default['chef_client']['task']['user'] = 'SYSTEM' 78 | default['chef_client']['task']['password'] = nil # Password is only required for non-system users 79 | default['chef_client']['task']['start_time'] = nil 80 | default['chef_client']['task']['start_date'] = nil 81 | default['chef_client']['task']['name'] = 'chef-client' 82 | 83 | default['chef_client']['load_gems'] = {} 84 | 85 | default['chef_client']['config']['start_handlers'] = [] 86 | default['chef_client']['config']['report_handlers'] = [] 87 | default['chef_client']['config']['exception_handlers'] = [] 88 | 89 | # If set to false, changes in the `client.rb` template won't trigger a reload 90 | # of those configs in the current Chef run. 91 | default['chef_client']['reload_config'] = true 92 | 93 | # Any additional daemon options can be set as an array. This will be 94 | # join'ed in the relevant service configuration. 95 | default['chef_client']['daemon_options'] = [] 96 | 97 | # Ohai plugins to be disabled are configured in /etc/chef/client.rb, 98 | # so they can be set as an array in this attribute. 99 | default['ohai']['disabled_plugins'] = [] 100 | 101 | # Ohai plugins to be enabled are configured in /etc/chef/client.rb, 102 | # so they can be set as an array in this attribute. 103 | default['ohai']['optional_plugins'] = [] 104 | 105 | # An additional path to load Ohai plugins from. 106 | default['ohai']['plugin_path'] = nil 107 | 108 | # Use logrotate_app definition on supported platforms via config recipe 109 | # when chef_client['log_file'] is set. 110 | # Default rotate: 12; frequency: weekly 111 | default['chef_client']['logrotate']['rotate'] = 12 112 | default['chef_client']['logrotate']['frequency'] = 'weekly' 113 | 114 | case node['platform_family'] 115 | when 'aix' 116 | default['chef_client']['init_style'] = 'src' 117 | default['chef_client']['svc_name'] = 'chef' 118 | default['chef_client']['run_path'] = '/var/run/chef' 119 | default['chef_client']['file_backup_path'] = '/var/lib/chef' 120 | default['chef_client']['log_dir'] = '/var/adm/chef' 121 | when 'amazon', 'rhel', 'fedora', 'debian', 'suse', 'clearlinux' 122 | default['chef_client']['init_style'] = node['init_package'] 123 | default['chef_client']['run_path'] = '/var/run/chef' 124 | default['chef_client']['file_backup_path'] = '/var/lib/chef' 125 | default['chef_client']['chkconfig']['start_order'] = 98 126 | default['chef_client']['chkconfig']['stop_order'] = 02 127 | when 'freebsd' 128 | default['chef_client']['init_style'] = 'bsd' 129 | default['chef_client']['run_path'] = '/var/run' 130 | default['chef_client']['file_backup_path'] = '/var/chef/backup' 131 | # don't use bsd paths per COOK-1379 132 | when 'mac_os_x' 133 | default['chef_client']['init_style'] = 'launchd' 134 | default['chef_client']['log_dir'] = '/Library/Logs/Chef' 135 | # Launchd doesn't use pid files 136 | default['chef_client']['run_path'] = '/var/run/chef' 137 | default['chef_client']['file_backup_path'] = '/Library/Caches/Chef/Backup' 138 | # Set to 'daemon' if you want chef-client to run 139 | # continuously with the -d and -s options, or leave 140 | # as 'interval' if you want chef-client to be run 141 | # periodically by launchd 142 | default['chef_client']['launchd_mode'] = 'interval' 143 | default['chef_client']['launchd_working_dir'] = '/var/root' 144 | default['chef_client']['launchd_self-update'] = false 145 | when 'openindiana', 'opensolaris', 'nexentacore', 'solaris2', 'omnios' 146 | default['chef_client']['init_style'] = 'smf' 147 | default['chef_client']['run_path'] = '/var/run/chef' 148 | default['chef_client']['file_backup_path'] = '/var/chef/backup' 149 | default['chef_client']['method_dir'] = '/lib/svc/method' 150 | default['chef_client']['bin_dir'] = '/usr/bin' 151 | default['chef_client']['locale'] = 'en_US.UTF-8' 152 | default['chef_client']['env_path'] = '/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin' 153 | when 'smartos' 154 | default['chef_client']['init_style'] = 'smf' 155 | default['chef_client']['run_path'] = '/var/run/chef' 156 | default['chef_client']['file_backup_path'] = '/var/chef/backup' 157 | default['chef_client']['method_dir'] = '/opt/local/lib/svc/method' 158 | default['chef_client']['bin_dir'] = '/opt/local/bin' 159 | default['chef_client']['locale'] = 'en_US.UTF-8' 160 | default['chef_client']['env_path'] = '/usr/local/sbin:/usr/local/bin:/opt/local/sbin:/opt/local/bin:/usr/sbin:/usr/bin:/sbin' 161 | when 'windows' 162 | default['chef_client']['init_style'] = 'windows' 163 | default['chef_client']['conf_dir'] = 'C:/chef' 164 | default['chef_client']['run_path'] = "#{node['chef_client']['conf_dir']}/run" 165 | default['chef_client']['file_backup_path'] = "#{node['chef_client']['conf_dir']}/backup" 166 | default['chef_client']['log_dir'] = "#{node['chef_client']['conf_dir']}/log" 167 | default['chef_client']['bin'] = 'C:/opscode/chef/bin/chef-client' 168 | else 169 | default['chef_client']['init_style'] = 'none' 170 | default['chef_client']['run_path'] = '/var/run' 171 | default['chef_client']['file_backup_path'] = '/var/chef/backup' 172 | end 173 | 174 | # Must appear after init_style to take effect correctly 175 | default['chef_client']['log_rotation']['options'] = ['compress'] 176 | default['chef_client']['log_rotation']['prerotate'] = nil 177 | default['chef_client']['log_rotation']['postrotate'] = case node['chef_client']['init_style'] 178 | when 'systemd' 179 | node['chef_client']['systemd']['timer'] ? '' : 'systemctl reload chef-client.service >/dev/null || :' 180 | else 181 | '/etc/init.d/chef-client reload >/dev/null || :' 182 | end 183 | -------------------------------------------------------------------------------- /chefignore: -------------------------------------------------------------------------------- 1 | # Put files/directories that should be ignored in this file when uploading 2 | # to a Chef Infra Server or Supermarket. 3 | # Lines that start with '# ' are comments. 4 | 5 | # OS generated files # 6 | ###################### 7 | .DS_Store 8 | ehthumbs.db 9 | Icon? 10 | nohup.out 11 | Thumbs.db 12 | .envrc 13 | 14 | # EDITORS # 15 | ########### 16 | .#* 17 | .project 18 | .settings 19 | *_flymake 20 | *_flymake.* 21 | *.bak 22 | *.sw[a-z] 23 | *.tmproj 24 | *~ 25 | \#* 26 | REVISION 27 | TAGS* 28 | tmtags 29 | .vscode 30 | .editorconfig 31 | 32 | ## COMPILED ## 33 | ############## 34 | *.class 35 | *.com 36 | *.dll 37 | *.exe 38 | *.o 39 | *.pyc 40 | *.so 41 | */rdoc/ 42 | a.out 43 | mkmf.log 44 | 45 | # Testing # 46 | ########### 47 | .circleci/* 48 | .codeclimate.yml 49 | .delivery/* 50 | .foodcritic 51 | .kitchen* 52 | .mdlrc 53 | .overcommit.yml 54 | .rspec 55 | .rubocop.yml 56 | .travis.yml 57 | .watchr 58 | .yamllint 59 | azure-pipelines.yml 60 | Dangerfile 61 | examples/* 62 | features/* 63 | Guardfile 64 | kitchen.yml* 65 | mlc_config.json 66 | Procfile 67 | Rakefile 68 | spec/* 69 | test/* 70 | 71 | # SCM # 72 | ####### 73 | .git 74 | .gitattributes 75 | .gitconfig 76 | .github/* 77 | .gitignore 78 | .gitkeep 79 | .gitmodules 80 | .svn 81 | */.bzr/* 82 | */.git 83 | */.hg/* 84 | */.svn/* 85 | 86 | # Berkshelf # 87 | ############# 88 | Berksfile 89 | Berksfile.lock 90 | cookbooks/* 91 | tmp 92 | 93 | # Bundler # 94 | ########### 95 | vendor/* 96 | Gemfile 97 | Gemfile.lock 98 | 99 | # Policyfile # 100 | ############## 101 | Policyfile.rb 102 | Policyfile.lock.json 103 | 104 | # Documentation # 105 | ############# 106 | CODE_OF_CONDUCT* 107 | CONTRIBUTING* 108 | documentation/* 109 | TESTING* 110 | UPGRADING* 111 | 112 | # Vagrant # 113 | ########### 114 | .vagrant 115 | Vagrantfile 116 | -------------------------------------------------------------------------------- /kitchen.dokken.yml: -------------------------------------------------------------------------------- 1 | --- 2 | driver: 3 | name: dokken 4 | privileged: true # because Docker and SystemD 5 | chef_version: <%= ENV['CHEF_VERSION'] || 'current' %> 6 | chef_license: accept-no-persist 7 | 8 | transport: 9 | name: dokken 10 | 11 | provisioner: 12 | name: dokken 13 | deprecations_as_errors: true 14 | chef_license: accept-no-persist 15 | 16 | verifier: 17 | name: inspec 18 | 19 | platforms: 20 | - name: amazonlinux 21 | driver: 22 | image: dokken/amazonlinux 23 | pid_one_command: /sbin/init 24 | 25 | - name: amazonlinux-2 26 | driver: 27 | image: dokken/amazonlinux-2 28 | pid_one_command: /usr/lib/systemd/systemd 29 | 30 | - name: debian-9 31 | driver: 32 | image: dokken/debian-9 33 | pid_one_command: /bin/systemd 34 | intermediate_instructions: 35 | - RUN /usr/bin/apt-get update 36 | 37 | - name: debian-10 38 | driver: 39 | image: dokken/debian-10 40 | pid_one_command: /bin/systemd 41 | intermediate_instructions: 42 | - RUN /usr/bin/apt-get update 43 | 44 | - name: centos-6 45 | driver: 46 | image: dokken/centos-6 47 | pid_one_command: /sbin/init 48 | 49 | - name: centos-7 50 | driver: 51 | image: dokken/centos-7 52 | pid_one_command: /usr/lib/systemd/systemd 53 | 54 | - name: centos-8 55 | driver: 56 | image: dokken/centos-8 57 | pid_one_command: /usr/lib/systemd/systemd 58 | 59 | - name: oraclelinux-6 60 | driver: 61 | image: dokken/oraclelinux-6 62 | pid_one_command: /sbin/init 63 | 64 | - name: oraclelinux-7 65 | driver: 66 | image: dokken/oraclelinux-7 67 | pid_one_command: /usr/lib/systemd/systemd 68 | 69 | - name: oraclelinux-8 70 | driver: 71 | image: dokken/oraclelinux-8 72 | pid_one_command: /usr/lib/systemd/systemd 73 | 74 | - name: fedora-latest 75 | driver: 76 | image: dokken/fedora-latest 77 | pid_one_command: /usr/lib/systemd/systemd 78 | 79 | - name: ubuntu-16.04 80 | driver: 81 | image: dokken/ubuntu-16.04 82 | pid_one_command: /bin/systemd 83 | intermediate_instructions: 84 | - RUN /usr/bin/apt-get update 85 | 86 | - name: ubuntu-18.04 87 | driver: 88 | image: dokken/ubuntu-18.04 89 | pid_one_command: /bin/systemd 90 | intermediate_instructions: 91 | - RUN /usr/bin/apt-get update 92 | 93 | - name: ubuntu-20.04 94 | driver: 95 | image: dokken/ubuntu-20.04 96 | pid_one_command: /bin/systemd 97 | intermediate_instructions: 98 | - RUN /usr/bin/apt-get update 99 | 100 | - name: opensuse-leap-15 101 | driver: 102 | image: dokken/opensuse-leap-15 103 | pid_one_command: /bin/systemd 104 | 105 | suites: 106 | - name: service-init 107 | run_list: 108 | - recipe[test::service] 109 | includes: ["oraclelinux-6", "amazonlinux", "centos-6"] 110 | 111 | - name: service-systemd 112 | run_list: 113 | - recipe[test::service] 114 | excludes: ["oraclelinux-6", "amazonlinux", "centos-6"] 115 | 116 | - name: systemd-timer-resource 117 | run_list: 118 | - recipe[test::systemd_timer_resource] 119 | excludes: ["oraclelinux-6", "amazonlinux", "centos-6"] 120 | 121 | - name: timer-systemd 122 | run_list: 123 | - recipe[chef-client::systemd_service] 124 | attributes: 125 | chef_client: 126 | systemd: 127 | timer: true 128 | excludes: ["oraclelinux-6", "amazonlinux", "centos-6"] 129 | 130 | - name: cron 131 | run_list: 132 | - recipe[test::cron] 133 | 134 | - name: cron-resource 135 | run_list: 136 | - recipe[test::cron_resource] 137 | 138 | - name: config 139 | run_list: 140 | - recipe[test::config] 141 | 142 | - name: delete_validation 143 | run_list: 144 | - recipe[chef-client::delete_validation] 145 | -------------------------------------------------------------------------------- /kitchen.yml: -------------------------------------------------------------------------------- 1 | --- 2 | driver: 3 | name: vagrant 4 | 5 | provisioner: 6 | name: chef_zero 7 | deprecations_as_errors: true 8 | chef_license: accept-no-persist 9 | # log_level: :debug 10 | 11 | verifier: 12 | name: inspec 13 | 14 | platforms: 15 | - name: amazonlinux-2 16 | - name: centos-6 17 | - name: centos-7 18 | - name: centos-8 19 | - name: debian-9 20 | - name: debian-10 21 | - name: fedora-latest 22 | - name: freebsd-12 23 | - name: opensuse-leap-15 24 | - name: ubuntu-16.04 25 | - name: ubuntu-18.04 26 | - name: ubuntu-20.04 27 | - name: macos-10.15 28 | driver: 29 | box: tas50/macos_10.15 30 | - name: windows-2019 31 | transport: 32 | name: winrm 33 | elevated: true 34 | driver: 35 | box: tas50/windows_2019 36 | gui: false 37 | customize: 38 | memory: 2048 39 | - name: windows-2016 40 | transport: 41 | name: winrm 42 | elevated: true 43 | driver: 44 | box: tas50/windows_2016 45 | gui: false 46 | customize: 47 | memory: 2048 48 | - name: windows-2012r2-13 49 | provisioner: 50 | product_name: chef 51 | product_version: 13 52 | driver: 53 | box: tas50/windows_2012r2 54 | transport: 55 | name: winrm 56 | elevated: true 57 | - name: windows-2012r2-14 58 | provisioner: 59 | product_name: chef 60 | product_version: 14 61 | driver: 62 | box: tas50/windows_2012r2 63 | transport: 64 | name: winrm 65 | elevated: true 66 | 67 | suites: 68 | - name: service-bsd 69 | run_list: 70 | - recipe[test::service] 71 | includes: ["freebsd-12"] 72 | 73 | - name: service-init 74 | run_list: 75 | - recipe[test::service] 76 | includes: ["centos-6", "amazon-linux"] 77 | 78 | - name: service-systemd 79 | run_list: 80 | - recipe[test::service] 81 | excludes: ["windows-2012r2-13", "windows-2012r2-14", "windows-2016", "windows-2019", "macos-10.15", "freebsd-12"] 82 | 83 | - name: systemd-timer-resource 84 | run_list: 85 | - recipe[test::systemd_timer_resource] 86 | excludes: ["windows-2012r2-13", "windows-2012r2-14", "windows-2016", "windows-2019", "macos-10.15", "freebsd-12"] 87 | 88 | - name: service-launchd 89 | run_list: 90 | - recipe[test::service] 91 | includes: ["macos-10.15"] 92 | 93 | - name: cron 94 | run_list: 95 | - recipe[test::cron] 96 | excludes: ["windows-2012r2-13", "windows-2012r2-14", "windows-2016", "windows-2019", "macos-10.15"] 97 | 98 | - name: cron-resource 99 | run_list: 100 | - recipe[test::cron_resource] 101 | excludes: ["windows-2012r2-13", "windows-2012r2-14", "windows-2016", "windows-2019", "macos-10.15"] 102 | 103 | - name: timer-systemd 104 | run_list: 105 | - recipe[chef-client::systemd_service] 106 | attributes: 107 | chef_client: 108 | systemd: 109 | timer: true 110 | excludes: ["windows-2012r2-13", "windows-2012r2-14", "windows-2016", "windows-2019", "macos-10.15", "freebsd-12"] 111 | 112 | - name: config 113 | run_list: 114 | - recipe[test::config] 115 | excludes: ["windows-2012r2-13", "windows-2012r2-14", "windows-2016", "windows-2019", "macos-10.15"] 116 | 117 | - name: task 118 | run_list: 119 | - recipe[test::task] 120 | includes: ["windows-2012r2-13", "windows-2012r2-14", "windows-2016", "windows-2019"] 121 | -------------------------------------------------------------------------------- /libraries/helpers.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: John Dewey () 3 | # Cookbook:: chef-client 4 | # Library:: helpers 5 | # 6 | # Copyright:: 2012-2017, John Dewey 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | 20 | module Opscode 21 | module ChefClient 22 | # helper methods for use in chef-client recipe code 23 | module Helpers 24 | include Chef::Mixin::Which 25 | require 'digest/md5' 26 | 27 | def wmi_property_from_query(wmi_property, wmi_query) 28 | @wmi = ::WIN32OLE.connect('winmgmts://') 29 | result = @wmi.ExecQuery(wmi_query) 30 | return unless result.each.count > 0 31 | result.each.next.send(wmi_property) 32 | end 33 | 34 | # Generate a uniformly distributed unique number to sleep. 35 | def splay_sleep_time(splay) 36 | seed = node['shard_seed'] || Digest::MD5.hexdigest(node.name).to_s.hex 37 | random = Random.new(seed.to_i) 38 | random.rand(splay) 39 | end 40 | 41 | def root_owner 42 | if platform?('windows') 43 | wmi_property_from_query(:name, "select * from Win32_UserAccount where sid like 'S-1-5-21-%-500' and LocalAccount=True") 44 | else 45 | 'root' 46 | end 47 | end 48 | 49 | def create_chef_directories 50 | # root_owner is not in scope in the block below. 51 | d_owner = root_owner 52 | %w(run_path file_cache_path file_backup_path log_dir conf_dir).each do |dir| 53 | next if node['chef_client'][dir].nil? 54 | # Do not redefine the resource if it exist 55 | find_resource(:directory, node['chef_client'][dir]) do 56 | recursive true 57 | mode '0755' if dir == 'log_dir' 58 | owner d_owner 59 | group node['root_group'] 60 | end 61 | end 62 | end 63 | 64 | def find_chef_client 65 | # executable on windows really means it ends in .exec/.bat 66 | existence_check = platform?('windows') ? :exist? : :executable? 67 | 68 | if ::File.send(existence_check, node['chef_client']['bin']) 69 | Chef::Log.debug 'Using chef-client bin from node attributes' 70 | node['chef_client']['bin'] 71 | else 72 | Chef::Log.debug "Searching path for chef-client bin as node['chef_client']['bin'] does not exist" 73 | which('chef-client') || raise("Could not locate the chef-client bin in any known path. Please set the proper path by overriding the node['chef_client']['bin'] attribute.") 74 | end 75 | end 76 | 77 | # Return true/false if node['chef_client']['cron']['environment_variables'] 78 | # is defined. 79 | def env_vars? 80 | !!node['chef_client']['cron']['environment_variables'] 81 | end 82 | 83 | # Return node['chef_client']['cron']['environment_variables'] 84 | def env_vars 85 | node['chef_client']['cron']['environment_variables'] 86 | end 87 | 88 | # Return true/false if node['chef_client']['cron']['priority'] is defined. 89 | def prioritized? 90 | !!node['chef_client']['cron']['priority'] 91 | end 92 | 93 | # Determine the process priority for chef-client. 94 | # Guard against unwanted values, returning nil. 95 | # Returns the desired priority to use with /bin/nice. 96 | def process_priority 97 | return unless prioritized? 98 | if platform?('windows') 99 | Chef::Log.warn 'Cannot prioritize the chef-client process on Windows hosts.' 100 | return 101 | end 102 | 103 | priority = node['chef_client']['cron']['priority'] 104 | # Convert strings to integers. If we see anything that doesn't match an 105 | # integer, bail. 106 | if priority.is_a?(String) 107 | unless /^-?\d+$/ =~ priority 108 | Chef::Log.warn "Process priority (#{priority}) is invalid. It must be an integer in the range -20 to 19, inclusize." 109 | return 110 | end 111 | priority = priority.to_i 112 | end 113 | 114 | if priority < -20 || priority > 19 115 | Chef::Log.warn "Process priority (#{priority}) is invalid. It must be an integer in the range -20 to 19, inclusize." 116 | return 117 | end 118 | priority 119 | end 120 | end 121 | end 122 | end 123 | 124 | Chef::DSL::Recipe.include Opscode::ChefClient::Helpers 125 | Chef::Resource.include Opscode::ChefClient::Helpers 126 | -------------------------------------------------------------------------------- /metadata.rb: -------------------------------------------------------------------------------- 1 | name 'chef-client' 2 | maintainer 'Chef Software, Inc.' 3 | maintainer_email 'cookbooks@chef.io' 4 | license 'Apache-2.0' 5 | description 'Manages client.rb configuration and chef-client service' 6 | version '12.3.4' 7 | 8 | %w( aix amazon centos fedora freebsd debian oracle mac_os_x redhat suse opensuseleap ubuntu windows zlinux ).each do |os| 9 | supports os 10 | end 11 | 12 | depends 'cron', '>= 4.2.0' 13 | depends 'logrotate', '>= 1.9.0' 14 | 15 | source_url 'https://github.com/chef-cookbooks/chef-client' 16 | issues_url 'https://github.com/chef-cookbooks/chef-client/issues' 17 | chef_version '>= 13.0' 18 | -------------------------------------------------------------------------------- /recipes/bsd_service.rb: -------------------------------------------------------------------------------- 1 | # Used by chef-client.erb template to find command interpreter 2 | require 'rbconfig' 3 | 4 | # include helper meth 5 | class ::Chef::Recipe 6 | include ::Opscode::ChefClient::Helpers 7 | end 8 | 9 | # libraries/helpers.rb method to DRY directory creation resources 10 | client_bin = find_chef_client 11 | Chef::Log.debug("Using chef-client binary at #{client_bin}") 12 | node.default['chef_client']['bin'] = client_bin 13 | create_chef_directories 14 | 15 | if platform_family?('freebsd') 16 | directory '/etc/rc.conf.d' do 17 | owner 'root' 18 | group 'wheel' 19 | mode '0644' 20 | action :create 21 | end 22 | 23 | template '/usr/local/etc/rc.d/chef-client' do 24 | source 'freebsd/chef-client.erb' 25 | owner 'root' 26 | group 'wheel' 27 | variables client_bin: client_bin 28 | mode '0755' 29 | end 30 | 31 | # Remove wrong rc.d script created by an older version of cookbook 32 | file '/etc/rc.d/chef-client' do 33 | action :delete 34 | end 35 | 36 | template '/etc/rc.conf.d/chef' do 37 | source 'freebsd/chef.erb' 38 | mode '0644' 39 | notifies :start, 'service[chef-client]', :delayed 40 | end 41 | 42 | service 'chef-client' do 43 | supports status: true, restart: true 44 | action [:start] 45 | end 46 | 47 | else 48 | log "You specified service style 'bsd'. You will need to set up your rc.local file. Hint: chef-client -i #{node['chef_client']['client_interval']} -s #{node['chef_client']['client_splay']}" 49 | end 50 | -------------------------------------------------------------------------------- /recipes/config.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Joshua Timberman () 3 | # Author:: Joshua Sierles () 4 | # Author:: Seth Chisamore () 5 | # Cookbook:: chef-client 6 | # Recipe:: config 7 | # 8 | # Copyright:: 2008-2019, Chef Software, Inc. 9 | # Copyright:: 2009-2017, 37signals 10 | # 11 | # Licensed under the Apache License, Version 2.0 (the "License"); 12 | # you may not use this file except in compliance with the License. 13 | # You may obtain a copy of the License at 14 | # 15 | # http://www.apache.org/licenses/LICENSE-2.0 16 | # 17 | # Unless required by applicable law or agreed to in writing, software 18 | # distributed under the License is distributed on an "AS IS" BASIS, 19 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | # See the License for the specific language governing permissions and 21 | # limitations under the License. 22 | 23 | # include helper methods 24 | class ::Chef::Recipe 25 | include ::Opscode::ChefClient::Helpers 26 | end 27 | 28 | # chef_node_name = Chef::Config[:node_name] == node['fqdn'] ? false : Chef::Config[:node_name] 29 | 30 | if node['chef_client']['log_file'].is_a?(String) 31 | log_path = ::File.join(node['chef_client']['log_dir'], node['chef_client']['log_file']) 32 | node.default['chef_client']['config']['log_location'] = log_path 33 | 34 | if node['os'] == 'linux' 35 | logrotate_app 'chef-client' do 36 | path [log_path] 37 | rotate node['chef_client']['logrotate']['rotate'] 38 | frequency node['chef_client']['logrotate']['frequency'] 39 | options node['chef_client']['log_rotation']['options'] 40 | prerotate node['chef_client']['log_rotation']['prerotate'] 41 | postrotate node['chef_client']['log_rotation']['postrotate'] 42 | template_mode '0644' 43 | end 44 | end 45 | else 46 | log_path = 'STDOUT' 47 | end 48 | 49 | # libraries/helpers.rb method to DRY directory creation resources 50 | create_chef_directories 51 | 52 | # We need to set these local variables because the methods aren't 53 | # available in the Chef::Resource scope 54 | d_owner = root_owner 55 | 56 | if log_path != 'STDOUT' 57 | file log_path do 58 | owner d_owner 59 | group node['root_group'] 60 | mode node['chef_client']['log_perm'] 61 | end 62 | end 63 | 64 | chef_requires = [] 65 | node['chef_client']['load_gems'].each do |gem_name, gem_info_hash| 66 | gem_info_hash ||= {} 67 | chef_gem gem_name do 68 | compile_time true 69 | action gem_info_hash[:action] || :install 70 | source gem_info_hash[:source] if gem_info_hash[:source] 71 | version gem_info_hash[:version] if gem_info_hash[:version] 72 | options gem_info_hash[:options] if gem_info_hash[:options] 73 | retries gem_info_hash[:retries] if gem_info_hash[:retries] 74 | retry_delay gem_info_hash[:retry_delay] if gem_info_hash[:retry_delay] 75 | timeout gem_info_hash[:timeout] if gem_info_hash[:timeout] 76 | end 77 | chef_requires.push(gem_info_hash[:require_name] || gem_name) 78 | end 79 | 80 | template "#{node['chef_client']['conf_dir']}/client.rb" do 81 | source 'client.rb.erb' 82 | owner d_owner 83 | mode '0644' 84 | variables( 85 | chef_config: node['chef_client']['config'], 86 | chef_requires: chef_requires, 87 | ohai_disabled_plugins: node['ohai']['disabled_plugins'], 88 | ohai_optional_plugins: node['ohai']['optional_plugins'], 89 | start_handlers: node['chef_client']['config']['start_handlers'], 90 | report_handlers: node['chef_client']['config']['report_handlers'], 91 | exception_handlers: node['chef_client']['config']['exception_handlers'], 92 | chef_license: node['chef_client']['chef_license'] 93 | ) 94 | 95 | if node['chef_client']['reload_config'] || ENV['TEST_KITCHEN'] 96 | notifies :run, 'ruby_block[reload_client_config]', :immediately 97 | end 98 | end 99 | 100 | directory ::File.join(node['chef_client']['conf_dir'], 'client.d') do 101 | recursive true 102 | owner d_owner 103 | group node['root_group'] 104 | mode '0755' 105 | end 106 | 107 | ruby_block 'reload_client_config' do 108 | block do 109 | Chef::Config.from_file("#{node['chef_client']['conf_dir']}/client.rb") 110 | end 111 | action :nothing 112 | end 113 | -------------------------------------------------------------------------------- /recipes/cron.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Joshua Timberman () 3 | # Author:: Seth Chisamore () 4 | # Author:: Bryan Berry () 5 | # Cookbook:: chef-client 6 | # Recipe:: cron 7 | # 8 | # Copyright:: 2009-2019, Chef Software Inc. 9 | # 10 | # Licensed under the Apache License, Version 2.0 (the "License"); 11 | # you may not use this file except in compliance with the License. 12 | # You may obtain a copy of the License at 13 | # 14 | # http://www.apache.org/licenses/LICENSE-2.0 15 | # 16 | # Unless required by applicable law or agreed to in writing, software 17 | # distributed under the License is distributed on an "AS IS" BASIS, 18 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | # See the License for the specific language governing permissions and 20 | # limitations under the License. 21 | # 22 | 23 | # include helper methods 24 | class ::Chef::Recipe 25 | include ::Opscode::ChefClient::Helpers 26 | end 27 | 28 | # libraries/helpers.rb method to DRY directory creation resources 29 | create_chef_directories 30 | 31 | # Stop any running chef-client services 32 | if node['os'] == 'linux' 33 | service 'chef-client' do 34 | supports status: true, restart: true 35 | action [:disable, :stop] 36 | ignore_failure true 37 | end 38 | 39 | file '/etc/init.d/chef-client' do 40 | action :delete 41 | end 42 | end 43 | 44 | case node['platform_family'] 45 | when 'openindiana', 'opensolaris', 'nexentacore', 'solaris2', 'smartos', 'omnios' 46 | service 'chef-client' do 47 | supports status: true, restart: true 48 | action [:disable, :stop] 49 | ignore_failure true 50 | end 51 | 52 | when 'freebsd' 53 | template '/etc/rc.d/chef-client' do 54 | source 'freebsd/chef-client.erb' 55 | owner 'root' 56 | group 'wheel' 57 | variables client_bin: node['chef_client']['bin'] 58 | mode '0755' 59 | end 60 | 61 | file '/etc/rc.conf.d/chef' do 62 | action :delete 63 | end 64 | 65 | service 'chef-client' do 66 | supports status: true, restart: true 67 | action [:stop] 68 | end 69 | end 70 | 71 | # If "use_cron_d" is set to true, delete the cron entry that uses the cron 72 | # resource built in to Chef and instead use the cron_d LWRP. 73 | if node['chef_client']['cron']['use_cron_d'] 74 | cron 'chef-client' do 75 | action :delete 76 | end 77 | 78 | chef_client_cron 'chef-client cron.d job' do 79 | minute node['chef_client']['cron']['minute'] 80 | hour node['chef_client']['cron']['hour'] 81 | weekday node['chef_client']['cron']['weekday'] 82 | chef_binary_path node['chef_client']['bin'] if node['chef_client']['bin'] 83 | mailto node['chef_client']['cron']['mailto'] if node['chef_client']['cron']['mailto'] 84 | splay node['chef_client']['splay'] 85 | log_directory node['chef_client']['cron']['log_directory'] 86 | log_file_name node['chef_client']['cron']['log_file'] 87 | append_log_file node['chef_client']['cron']['append_log'] 88 | daemon_options node['chef_client']['daemon_options'] 89 | environment node['chef_client']['cron']['environment_variables'] if node['chef_client']['cron']['environment_variables'] 90 | end 91 | else 92 | # Non-linux platforms don't support cron.d so we won't try to remove a cron_d resource. 93 | # https://github.com/chef-cookbooks/cron/blob/master/resources/d.rb#L55 94 | if node['os'] == 'linux' 95 | cron_d 'chef-client' do 96 | action :delete 97 | end 98 | end 99 | 100 | sleep_time = splay_sleep_time(node['chef_client']['splay'].to_i) 101 | log_file = node['chef_client']['cron']['log_file'] 102 | append_log = node['chef_client']['cron']['append_log'] ? '>>' : '>' 103 | daemon_options = " #{node['chef_client']['daemon_options'].join(' ')} " if node['chef_client']['daemon_options'].any? 104 | 105 | cron 'chef-client' do 106 | minute node['chef_client']['cron']['minute'] 107 | hour node['chef_client']['cron']['hour'] 108 | weekday node['chef_client']['cron']['weekday'] 109 | path node['chef_client']['cron']['path'] if node['chef_client']['cron']['path'] 110 | mailto node['chef_client']['cron']['mailto'] if node['chef_client']['cron']['mailto'] 111 | user 'root' 112 | cmd = '' 113 | cmd << "/bin/sleep #{sleep_time}; " if sleep_time 114 | cmd << "#{env_vars} " if env_vars? 115 | cmd << "#{node['chef_client']['cron']['nice_path']} -n #{process_priority} " if process_priority 116 | cmd << "#{node['chef_client']['bin']} #{daemon_options}#{append_log} #{log_file} 2>&1" 117 | cmd << ' || echo "Chef client execution failed"' if node['chef_client']['cron']['mailto'] 118 | command cmd 119 | end 120 | end 121 | -------------------------------------------------------------------------------- /recipes/default.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: chef-client 3 | # Recipe:: default 4 | # 5 | # Copyright:: 2010-2019, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | if platform?('windows') 21 | include_recipe 'chef-client::task' 22 | else 23 | include_recipe 'chef-client::service' 24 | end 25 | -------------------------------------------------------------------------------- /recipes/delete_validation.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Joshua Timberman 3 | # Cookbook:: chef 4 | # Recipe:: delete_validation 5 | # 6 | # Copyright:: 2010-2019, Chef Software, Inc. 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | 20 | class ::Chef::Recipe 21 | include ::Opscode::ChefClient::Helpers 22 | end 23 | 24 | # Don't do anything run running as solo. This can happen when using ChefSpec or 25 | # Test Kitchen. 26 | if Chef::Config[:solo] 27 | if !ENV['TEST_KITCHEN'] && !defined?(ChefSpec) 28 | Chef::Log.info('[chef-client::delete_validation] Skipping validation ' \ 29 | 'delete because we are running under chef-solo') 30 | end 31 | return 32 | end 33 | 34 | unless Chef::Config[:validation_key].nil? 35 | file Chef::Config[:validation_key] do 36 | action :delete 37 | backup false 38 | only_if { ::File.exist?(Chef::Config[:client_key]) } 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /recipes/init_service.rb: -------------------------------------------------------------------------------- 1 | raise 'The chef_client::init_service recipe only supports RHEL / Amazon platform families. All other platforms should run chef-client as a service using systemd or a scheduled job using cron / systemd timers.' unless platform_family?('rhel', 'amazon') 2 | 3 | # include helper methods 4 | class ::Chef::Recipe 5 | include ::Opscode::ChefClient::Helpers 6 | end 7 | 8 | # libraries/helpers.rb method to DRY directory creation resources 9 | client_bin = find_chef_client 10 | Chef::Log.debug("Using chef-client binary at #{client_bin}") 11 | node.default['chef_client']['bin'] = client_bin 12 | create_chef_directories 13 | 14 | template '/etc/init.d/chef-client' do 15 | source 'redhat/init.d/chef-client.erb' 16 | mode '0755' 17 | variables(client_bin: client_bin, 18 | chkconfig_start_order: node['chef_client']['chkconfig']['start_order'], 19 | chkconfig_stop_order: node['chef_client']['chkconfig']['stop_order']) 20 | notifies :restart, 'service[chef-client]', :delayed 21 | end 22 | 23 | template '/etc/sysconfig/chef-client' do 24 | source 'redhat/sysconfig/chef-client.erb' 25 | mode '0644' 26 | notifies :restart, 'service[chef-client]', :delayed 27 | end 28 | 29 | service 'chef-client' do 30 | supports status: true, restart: true 31 | action [:enable, :start] 32 | end 33 | -------------------------------------------------------------------------------- /recipes/launchd_service.rb: -------------------------------------------------------------------------------- 1 | # include helper methods 2 | class ::Chef::Recipe 3 | include ::Opscode::ChefClient::Helpers 4 | end 5 | 6 | create_chef_directories 7 | 8 | template '/Library/LaunchDaemons/com.chef.chef-client.plist' do 9 | source 'com.chef.chef-client.plist.erb' 10 | mode '0644' 11 | variables( 12 | client_bin: node['chef_client']['bin'] || '/opt/chef/bin/chef-client', 13 | daemon_options: node['chef_client']['daemon_options'], 14 | interval: node['chef_client']['interval'], 15 | launchd_mode: node['chef_client']['launchd_mode'], 16 | log_dir: node['chef_client']['log_dir'], 17 | log_file: node['chef_client']['log_file'], 18 | splay: node['chef_client']['splay'], 19 | working_dir: node['chef_client']['launchd_working_dir'] 20 | ) 21 | notifies :restart, 'launchd[com.chef.chef-client]' if node['chef_client']['launchd_self-update'] 22 | end 23 | 24 | launchd 'com.chef.chef-client' do 25 | path '/Library/LaunchDaemons/com.chef.chef-client.plist' 26 | action [:create, :enable] 27 | end 28 | -------------------------------------------------------------------------------- /recipes/runit_service.rb: -------------------------------------------------------------------------------- 1 | raise 'Runit support in the chef-client cookbook has been removed. You may downgrade to the 8.1.X release of the cookbook for Runit suppor however we highly recommend you use a native init system instead.' 2 | -------------------------------------------------------------------------------- /recipes/service.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: chef-client 3 | # Recipe:: service 4 | # 5 | # Author:: Joshua Timberman () 6 | # Author:: Seth Chisamore () 7 | # Author:: Paul Mooring () 8 | # 9 | # Copyright:: 2009-2019, Chef Software, Inc. 10 | # 11 | # Licensed under the Apache License, Version 2.0 (the "License"); 12 | # you may not use this file except in compliance with the License. 13 | # You may obtain a copy of the License at 14 | # 15 | # http://www.apache.org/licenses/LICENSE-2.0 16 | # 17 | # Unless required by applicable law or agreed to in writing, software 18 | # distributed under the License is distributed on an "AS IS" BASIS, 19 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | # See the License for the specific language governing permissions and 21 | # limitations under the License. 22 | # 23 | 24 | supported_init_styles = %w( 25 | bsd 26 | init 27 | launchd 28 | smf 29 | src 30 | systemd 31 | windows 32 | ) 33 | 34 | init_style = node['chef_client']['init_style'] 35 | 36 | raise "The init style specified at node['chef_client']['init_style'] is not supported by the chef-client cookbook. Supported values are: #{supported_init_styles.join(',')}." unless supported_init_styles.include?(init_style) 37 | 38 | include_recipe "chef-client::#{init_style}_service" 39 | -------------------------------------------------------------------------------- /recipes/smf_service.rb: -------------------------------------------------------------------------------- 1 | # include helper methods 2 | class ::Chef::Recipe 3 | include ::Opscode::ChefClient::Helpers 4 | end 5 | 6 | # libraries/helpers.rb method to DRY directory creation resources 7 | client_bin = find_chef_client 8 | Chef::Log.debug("Using chef-client binary at #{client_bin}") 9 | node.default['chef_client']['bin'] = client_bin 10 | create_chef_directories 11 | 12 | directory node['chef_client']['method_dir'] do 13 | action :create 14 | owner 'root' 15 | group 'bin' 16 | mode '0755' 17 | recursive true 18 | end 19 | 20 | local_path = ::File.join(Chef::Config[:file_cache_path], '/') 21 | template "#{node['chef_client']['method_dir']}/chef-client" do 22 | source 'solaris/chef-client.erb' 23 | owner 'root' 24 | group 'root' 25 | mode '0555' 26 | notifies :restart, 'service[chef-client]' 27 | end 28 | 29 | template(local_path + 'chef-client.xml') do 30 | if node['platform_version'].to_f >= 5.11 && !platform?('smartos') 31 | source 'solaris/manifest-5.11.xml.erb' 32 | else 33 | source 'solaris/manifest.xml.erb' 34 | end 35 | owner 'root' 36 | group 'root' 37 | mode '0644' 38 | end 39 | 40 | execute 'load chef-client manifest' do 41 | action :nothing 42 | command "/usr/sbin/svccfg import #{local_path}chef-client.xml" 43 | notifies :restart, 'service[chef-client]' 44 | end 45 | 46 | service 'chef-client' do 47 | action [:enable, :start] 48 | provider Chef::Provider::Service::Solaris 49 | notifies :run, 'execute[load chef-client manifest]', :before 50 | end 51 | -------------------------------------------------------------------------------- /recipes/src_service.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: chef-client 3 | # Recipe:: src_service 4 | # 5 | # Author:: Julian C. Dunn () 6 | # 7 | # Copyright:: 2014-2019, Chef Software, Inc. 8 | # 9 | # Licensed under the Apache License, Version 2.0 (the "License"); 10 | # you may not use this file except in compliance with the License. 11 | # You may obtain a copy of the License at 12 | # 13 | # http://www.apache.org/licenses/LICENSE-2.0 14 | # 15 | # Unless required by applicable law or agreed to in writing, software 16 | # distributed under the License is distributed on an "AS IS" BASIS, 17 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | # See the License for the specific language governing permissions and 19 | # limitations under the License. 20 | # 21 | 22 | # include helper methods 23 | class ::Chef::Recipe 24 | include ::Opscode::ChefClient::Helpers 25 | end 26 | 27 | # libraries/helpers.rb method to DRY directory creation resources 28 | client_bin = find_chef_client 29 | Chef::Log.debug("Using chef-client binary at #{client_bin}") 30 | node.default['chef_client']['bin'] = client_bin 31 | create_chef_directories 32 | 33 | execute "install #{node['chef_client']['svc_name']} in SRC" do 34 | command "mkssys -s #{node['chef_client']['svc_name']} -p #{node['chef_client']['bin']} -u root -S -n 15 -f 9 -o #{node['chef_client']['log_dir']}/#{node['chef_client']['log_file']} -e #{node['chef_client']['log_dir']}/#{node['chef_client']['log_file']} -a '-i #{node['chef_client']['interval']} -s #{node['chef_client']['splay']}'" 35 | not_if "lssrc -s #{node['chef_client']['svc_name']}" 36 | action :run 37 | end 38 | 39 | execute "enable #{node['chef_client']['svc_name']}" do 40 | if node['chef_client']['ca_cert_path'] 41 | command "mkitab '#{node['chef_client']['svc_name']}:2:once:/usr/bin/startsrc -e \"SSL_CERT_FILE=#{node['chef_client']['ca_cert_path']}\" -s #{node['chef_client']['svc_name']} > /dev/console 2>&1'" 42 | else 43 | command "mkitab '#{node['chef_client']['svc_name']}:2:once:/usr/bin/startsrc -s #{node['chef_client']['svc_name']} > /dev/console 2>&1'" 44 | end 45 | not_if "lsitab #{node['chef_client']['svc_name']}" 46 | end 47 | 48 | service node['chef_client']['svc_name'] do 49 | action :start 50 | end 51 | -------------------------------------------------------------------------------- /recipes/systemd_service.rb: -------------------------------------------------------------------------------- 1 | class ::Chef::Recipe 2 | include ::Opscode::ChefClient::Helpers 3 | end 4 | 5 | # libraries/helpers.rb method to DRY directory creation resources 6 | client_bin = find_chef_client 7 | Chef::Log.debug("Using chef-client binary at #{client_bin}") 8 | node.default['chef_client']['bin'] = client_bin 9 | create_chef_directories 10 | 11 | dist_dir, conf_dir, env_file = value_for_platform_family( 12 | ['amazon'] => %w(redhat sysconfig chef-client), 13 | ['fedora'] => %w(fedora sysconfig chef-client), 14 | ['rhel'] => %w(redhat sysconfig chef-client), 15 | ['suse'] => %w(redhat sysconfig chef-client), 16 | ['debian'] => %w(debian default chef-client), 17 | ['clearlinux'] => %w(clearlinux chef chef-client) 18 | ) 19 | 20 | timer = node['chef_client']['systemd']['timer'] 21 | 22 | exec_options = if timer 23 | '-c $CONFIG $OPTIONS' 24 | else 25 | '-c $CONFIG -i $INTERVAL -s $SPLAY $OPTIONS' 26 | end 27 | 28 | env_file = template "/etc/#{conf_dir}/#{env_file}" do 29 | source "default/#{dist_dir}/#{conf_dir}/chef-client.erb" 30 | mode '0644' 31 | notifies :restart, 'service[chef-client]', :delayed unless timer 32 | end 33 | 34 | directory '/etc/systemd/system' do 35 | owner 'root' 36 | group 'root' 37 | mode '0755' 38 | recursive true 39 | action :create 40 | end 41 | 42 | service_unit_content = { 43 | 'Unit' => { 44 | 'Description' => 'Chef Infra Client', 45 | 'After' => 'network.target auditd.service', 46 | }, 47 | 'Service' => { 48 | 'Type' => timer ? 'oneshot' : 'simple', 49 | 'EnvironmentFile' => env_file.path, 50 | 'ExecStart' => "#{client_bin} #{exec_options}", 51 | 'ExecReload' => '/bin/kill -HUP $MAINPID', 52 | 'SuccessExitStatus' => 3, 53 | 'Restart' => node['chef_client']['systemd']['restart'], 54 | }, 55 | 'Install' => { 'WantedBy' => 'multi-user.target' }, 56 | } 57 | 58 | # add "daemon to the description when we're creating a timer unit 59 | service_unit_content['Unit']['Description'] << ' daemon' unless timer 60 | 61 | service_unit_content['Service'].delete('Restart') if timer 62 | 63 | if node['chef_client']['systemd']['timeout'] 64 | service_unit_content['Service']['TimeoutSec'] = 65 | node['chef_client']['systemd']['timeout'] 66 | end 67 | 68 | if node['chef_client']['systemd']['killmode'] 69 | service_unit_content['Service']['KillMode'] = 70 | node['chef_client']['systemd']['killmode'] 71 | end 72 | 73 | systemd_unit 'chef-client.service' do 74 | content service_unit_content 75 | action :create 76 | notifies(:restart, 'service[chef-client]', :delayed) unless timer 77 | end 78 | 79 | systemd_unit 'chef-client.timer' do 80 | content( 81 | 'Unit' => { 'Description' => 'chef-client periodic run' }, 82 | 'Install' => { 'WantedBy' => 'timers.target' }, 83 | 'Timer' => { 84 | 'OnBootSec' => '1min', 85 | 'OnUnitInactiveSec' => "#{node['chef_client']['interval']}sec", 86 | 'RandomizedDelaySec' => "#{node['chef_client']['splay']}sec", 87 | } 88 | ) 89 | action(timer ? [:create, :enable, :start] : [:stop, :disable, :delete]) 90 | notifies :restart, to_s, :delayed unless timer 91 | end 92 | 93 | service 'chef-client' do 94 | supports status: true, restart: true 95 | action(timer ? [:disable, :stop] : [:enable, :start]) 96 | end 97 | -------------------------------------------------------------------------------- /recipes/task.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Paul Mooring () 3 | # Cookbook:: chef-client 4 | # Recipe:: task 5 | # 6 | # Copyright:: 2011-2020, Chef Software, Inc. 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | 21 | # include helper methods 22 | class ::Chef::Recipe 23 | include ::Opscode::ChefClient::Helpers 24 | end 25 | 26 | # libraries/helpers.rb method to DRY directory creation resources 27 | client_bin = find_chef_client 28 | Chef::Log.info("Using chef-client binary at #{client_bin}") 29 | node.default['chef_client']['bin'] = client_bin 30 | 31 | chef_client_scheduled_task 'Chef Client' do 32 | user node['chef_client']['task']['user'] 33 | password node['chef_client']['task']['password'] 34 | frequency node['chef_client']['task']['frequency'] 35 | frequency_modifier lazy { node['chef_client']['task']['frequency_modifier'] } 36 | start_time node['chef_client']['task']['start_time'] 37 | start_date node['chef_client']['task']['start_date'] 38 | splay node['chef_client']['splay'] 39 | config_directory node['chef_client']['conf_dir'] 40 | log_directory node['chef_client']['log_dir'] 41 | chef_binary_path node['chef_client']['bin'] 42 | daemon_options node['chef_client']['daemon_options'] 43 | task_name node['chef_client']['task']['name'] 44 | end 45 | 46 | windows_service 'chef-client' do 47 | startup_type :disabled 48 | action [:configure_startup, :stop] 49 | ignore_failure true 50 | only_if { ::Win32::Service.exists?('chef-client') } 51 | end 52 | -------------------------------------------------------------------------------- /recipes/upstart_service.rb: -------------------------------------------------------------------------------- 1 | raise 'Support for running the chef-client using the Upstart init system has been removed from the chef-client cookbook as Ubuntu 14.04 is now EOL. Please upgrade your system or downgrade to the chef-client cookbook version < 11.0.' 2 | -------------------------------------------------------------------------------- /recipes/windows_service.rb: -------------------------------------------------------------------------------- 1 | raise 'Support for running the chef-client as a service on Windows has been replaced with support for running the chef-client as a scheduled task. We highly recommend not running chef-client as a service, but if you require this support please downgrade to the 8.1.X release of the chef-client cookbook..' 2 | -------------------------------------------------------------------------------- /resources/cron.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: chef-client 3 | # resource:: chef_client_cron 4 | # 5 | # Copyright:: 2020, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | chef_version_for_provides '< 16.0' if respond_to?(:chef_version_for_provides) 21 | 22 | provides :chef_client_cron 23 | resource_name :chef_client_cron 24 | 25 | property :job_name, String, default: 'chef-client' 26 | property :comment, String 27 | 28 | property :user, String, default: 'root' 29 | 30 | property :minute, [Integer, String], default: '0,30' 31 | property :hour, [Integer, String], default: '*' 32 | property :day, [Integer, String], default: '*' 33 | property :month, [Integer, String], default: '*' 34 | property :weekday, [Integer, String], default: '*' 35 | property :splay, [Integer, String], default: 300, 36 | coerce: proc { |x| Integer(x) }, 37 | callbacks: { 'should be a positive number' => proc { |v| v > 0 } } 38 | property :mailto, String 39 | property :accept_chef_license, [true, false], default: false 40 | 41 | property :config_directory, String, default: '/etc/chef' 42 | property :log_directory, String, default: lazy { platform?('mac_os_x') ? '/Library/Logs/Chef' : '/var/log/chef' } 43 | property :log_file_name, String, default: 'client.log' 44 | property :append_log_file, [true, false], default: true 45 | property :chef_binary_path, String, default: '/opt/chef/bin/chef-client' 46 | property :daemon_options, Array, default: [] 47 | property :environment, Hash, default: lazy { {} } 48 | 49 | property :nice, [Integer, String], 50 | coerce: proc { |x| Integer(x) }, 51 | callbacks: { 'should be an Integer between -20 and 19' => proc { |v| v >= -20 && v <= 19 } } 52 | 53 | action :add do 54 | unless new_resource.log_directory.nil? || ::Dir.exist?(new_resource.log_directory) 55 | directory new_resource.log_directory do 56 | owner new_resource.user 57 | mode '0750' 58 | recursive true 59 | end 60 | end 61 | 62 | declare_resource(cron_resource_type, new_resource.job_name) do 63 | minute new_resource.minute 64 | hour new_resource.hour 65 | day new_resource.day 66 | weekday new_resource.weekday 67 | month new_resource.month 68 | environment new_resource.environment 69 | mailto new_resource.mailto if new_resource.mailto 70 | user new_resource.user 71 | comment new_resource.comment if new_resource.comment 72 | command cron_command 73 | end 74 | end 75 | 76 | action :remove do 77 | declare_resource(cron_resource_type, new_resource.job_name) do 78 | action :delete 79 | end 80 | end 81 | 82 | action_class do 83 | # 84 | # The complete cron command to run 85 | # 86 | # @return [String] 87 | # 88 | def cron_command 89 | cmd = '' 90 | cmd << "/bin/sleep #{splay_sleep_time(new_resource.splay)}; " 91 | cmd << "#{which('nice')} -n #{new_resource.nice} " if new_resource.nice 92 | cmd << "#{new_resource.chef_binary_path} " 93 | cmd << "#{new_resource.daemon_options.join(' ')} " unless new_resource.daemon_options.empty? 94 | cmd << "-c #{::File.join(new_resource.config_directory, 'client.rb')} " 95 | cmd << '--chef-license accept ' if new_resource.accept_chef_license && Gem::Requirement.new('>= 14.12.9').satisfied_by?(Gem::Version.new(Chef::VERSION)) 96 | cmd << log_command 97 | cmd << " || echo \"#{Chef::Dist::PRODUCT} execution failed\"" if new_resource.mailto 98 | cmd 99 | end 100 | 101 | # 102 | # The portion of the overall cron job that handles logging based on the append_log_file property 103 | # 104 | # @return [String] 105 | # 106 | def log_command 107 | if new_resource.append_log_file 108 | # Chef 15 and lower still sends output to stdout when -L is used 109 | if Gem::Requirement.new('< 16.0.0').satisfied_by?(Gem::Version.new(Chef::VERSION)) 110 | ">> #{log_path} 2>&1" 111 | else 112 | "-L #{log_path}" 113 | end 114 | else 115 | "> #{log_path} 2>&1" 116 | end 117 | end 118 | 119 | # 120 | # The absolute log path location 121 | # 122 | # @return [String] 123 | # 124 | def log_path 125 | return new_resource.log_file_name if new_resource.log_directory.nil? 126 | ::File.join(new_resource.log_directory, new_resource.log_file_name) 127 | end 128 | 129 | # 130 | # The type of cron resource to run. Linux systems all support the /etc/cron.d directory 131 | # and can use the cron_d resource, but Solaris / AIX / FreeBSD need to use the crontab 132 | # via the legacy cron resource. 133 | # 134 | # @return [Symbol] 135 | # 136 | def cron_resource_type 137 | node['os'] == 'linux' ? :cron_d : :cron 138 | end 139 | end 140 | -------------------------------------------------------------------------------- /resources/launchd.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: chef-client 3 | # Resource:: chef_client_launchd 4 | # 5 | # Copyright:: Chef Software, Inc. 6 | # 7 | 8 | chef_version_for_provides '< 16.5' if respond_to?(:chef_version_for_provides) 9 | 10 | resource_name :chef_client_launchd 11 | provides :chef_client_launchd 12 | 13 | unified_mode true if respond_to?(:unified_mode) 14 | 15 | property :user, String, 16 | default: 'root' 17 | 18 | property :working_directory, String, 19 | default: '/var/root' 20 | 21 | property :interval, [Integer, String], 22 | coerce: proc { |x| Integer(x) }, 23 | callbacks: { 'should be a positive number' => proc { |v| v > 0 } }, 24 | default: 30 25 | 26 | property :splay, [Integer, String], 27 | default: 300, 28 | coerce: proc { |x| Integer(x) }, 29 | callbacks: { 'should be a positive number' => proc { |v| v > 0 } } 30 | property :accept_chef_license, [true, false], 31 | default: false 32 | 33 | property :config_directory, String, 34 | default: '/etc/chef' 35 | 36 | property :log_directory, String, 37 | default: '/Library/Logs/Chef' 38 | 39 | property :log_file_name, String, 40 | default: 'client.log' 41 | 42 | property :chef_binary_path, String, 43 | default: '/opt/chef/bin/chef-client' 44 | 45 | property :daemon_options, Array, 46 | default: lazy { [] } 47 | 48 | property :environment, Hash, 49 | default: lazy { {} } 50 | 51 | property :nice, [Integer, String], 52 | coerce: proc { |x| Integer(x) }, 53 | callbacks: { 'should be an Integer between -20 and 19' => proc { |v| v >= -20 && v <= 19 } } 54 | 55 | property :low_priority_io, [true, false], 56 | default: true 57 | 58 | action :enable do 59 | unless ::Dir.exist?(new_resource.log_directory) 60 | directory new_resource.log_directory do 61 | owner new_resource.user 62 | mode '0750' 63 | recursive true 64 | end 65 | end 66 | 67 | launchd 'com.chef.chef-client' do 68 | username new_resource.user 69 | working_directory new_resource.working_directory 70 | start_interval new_resource.interval * 60 71 | program_arguments ['/bin/bash', '-c', client_command] 72 | environment_variables new_resource.environment unless new_resource.environment.empty? 73 | nice new_resource.nice 74 | low_priority_io true 75 | action :enable 76 | end 77 | end 78 | 79 | action :disable do 80 | service 'chef-client' do 81 | service_name 'com.chef.chef-client' 82 | action :disable 83 | end 84 | end 85 | 86 | action_class do 87 | # 88 | # Generate a uniformly distributed unique number to sleep from 0 to the splay time 89 | # 90 | # @param [Integer] splay The number of seconds to splay 91 | # 92 | # @return [Integer] 93 | # 94 | def splay_sleep_time(splay) 95 | seed = node['shard_seed'] || Digest::MD5.hexdigest(node.name).to_s.hex 96 | random = Random.new(seed.to_i) 97 | random.rand(splay) 98 | end 99 | 100 | # 101 | # random sleep time + chef-client + daemon option properties + license acceptance 102 | # 103 | # @return [String] 104 | # 105 | def client_command 106 | cmd = '' 107 | cmd << "/bin/sleep #{splay_sleep_time(new_resource.splay)};" 108 | cmd << " #{new_resource.chef_binary_path}" 109 | cmd << " #{new_resource.daemon_options.join(' ')}" unless new_resource.daemon_options.empty? 110 | cmd << " -c #{::File.join(new_resource.config_directory, 'client.rb')}" 111 | cmd << " -L #{::File.join(new_resource.log_directory, new_resource.log_file_name)}" 112 | cmd << ' --chef-license accept' if new_resource.accept_chef_license 113 | cmd 114 | end 115 | end 116 | -------------------------------------------------------------------------------- /resources/scheduled_task.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: chef-client 3 | # resource:: chef_client_scheduled_task 4 | # 5 | # Copyright:: 2017-2020, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | chef_version_for_provides '< 16.0' if respond_to?(:chef_version_for_provides) 21 | 22 | provides :chef_client_scheduled_task 23 | resource_name :chef_client_scheduled_task 24 | 25 | property :task_name, String, 26 | default: 'chef-client' 27 | 28 | property :user, String, 29 | default: 'System', sensitive: true 30 | 31 | property :password, String, 32 | sensitive: true 33 | 34 | property :frequency, String, 35 | default: 'minute', 36 | equal_to: %w(minute hourly daily monthly once on_logon onstart on_idle) 37 | 38 | property :frequency_modifier, [Integer, String], 39 | coerce: proc { |x| Integer(x) }, 40 | callbacks: { 'should be a positive number' => proc { |v| v > 0 } }, 41 | default: lazy { frequency == 'minute' ? 30 : 1 } 42 | 43 | property :accept_chef_license, [true, false], 44 | default: false 45 | 46 | property :start_date, String, 47 | regex: [%r{^[0-1][0-9]\/[0-3][0-9]\/\d{4}$}] 48 | 49 | property :start_time, String, 50 | regex: [/^\d{2}:\d{2}$/] 51 | 52 | property :splay, [Integer, String], 53 | coerce: proc { |x| Integer(x) }, 54 | callbacks: { 'should be a positive number' => proc { |v| v > 0 } }, 55 | default: 300 56 | 57 | property :run_on_battery, [true, false], 58 | default: true 59 | 60 | property :config_directory, String, 61 | default: 'C:/chef' 62 | 63 | property :log_directory, String, 64 | default: lazy { |r| "#{r.config_directory}/log" } 65 | 66 | property :log_file_name, String, 67 | default: 'client.log' 68 | 69 | property :chef_binary_path, String, 70 | default: 'C:/opscode/chef/bin/chef-client' 71 | 72 | property :daemon_options, Array, 73 | default: lazy { [] } 74 | 75 | action :add do 76 | # create a directory in case the log directory does not exist 77 | unless Dir.exist?(new_resource.log_directory) 78 | directory new_resource.log_directory do 79 | inherits true 80 | recursive true 81 | action :create 82 | end 83 | end 84 | 85 | # According to https://docs.microsoft.com/en-us/windows/desktop/taskschd/schtasks, 86 | # the :once, :onstart, :onlogon, and :onidle schedules don't accept schedule modifiers 87 | windows_task new_resource.task_name do 88 | run_level :highest 89 | command full_command 90 | user new_resource.user 91 | password new_resource.password 92 | frequency new_resource.frequency.to_sym 93 | frequency_modifier new_resource.frequency_modifier if frequency_supports_frequency_modifier? 94 | start_time start_time_value 95 | start_day new_resource.start_date unless new_resource.start_date.nil? 96 | random_delay new_resource.splay if frequency_supports_random_delay? 97 | disallow_start_if_on_batteries new_resource.splay unless new_resource.run_on_battery || Gem::Requirement.new('< 14.4').satisfied_by?(Gem::Version.new(Chef::VERSION)) 98 | action [ :create, :enable ] 99 | end 100 | end 101 | 102 | action :remove do 103 | windows_task new_resource.task_name do 104 | action :delete 105 | end 106 | end 107 | 108 | action_class do 109 | # 110 | # The full command to run in the scheduled task 111 | # 112 | # @return [String] 113 | # 114 | def full_command 115 | # Fetch path of cmd.exe through environment variable comspec 116 | cmd_path = ENV['COMSPEC'] 117 | 118 | "#{cmd_path} /c \"#{client_cmd}\"" 119 | end 120 | 121 | # 122 | # Build command line to pass to cmd.exe 123 | # 124 | # @return [String] 125 | # 126 | def client_cmd 127 | cmd = new_resource.chef_binary_path.dup 128 | cmd << " -L #{::File.join(new_resource.log_directory, new_resource.log_file_name)}" 129 | cmd << " -c #{::File.join(new_resource.config_directory, 'client.rb')}" 130 | 131 | # Add custom options 132 | cmd << " #{new_resource.daemon_options.join(' ')}" if new_resource.daemon_options.any? 133 | cmd << ' --chef-license accept' if new_resource.accept_chef_license && Gem::Requirement.new('>= 14.12.9').satisfied_by?(Gem::Version.new(Chef::VERSION)) 134 | cmd 135 | end 136 | 137 | # 138 | # not all frequencies in the windows_task resource support random_delay 139 | # 140 | # @return [boolean] 141 | # 142 | def frequency_supports_random_delay? 143 | %w(once minute hourly daily weekly monthly).include?(new_resource.frequency) 144 | end 145 | 146 | # 147 | # not all frequencies in the windows_task resource support frequency_modifier 148 | # 149 | # @return [boolean] 150 | # 151 | def frequency_supports_frequency_modifier? 152 | # these are the only ones that don't 153 | !%w(once on_logon onstart on_idle).include?(new_resource.frequency) 154 | end 155 | 156 | # @todo this can all get removed when we don't support Chef 13.6 anymore 157 | def start_time_value 158 | if new_resource.start_time 159 | new_resource.start_time 160 | elsif Gem::Requirement.new('< 13.7.0').satisfied_by?(Gem::Version.new(Chef::VERSION)) 161 | new_resource.frequency == 'minute' ? (Time.now + 60 * new_resource.frequency_modifier.to_f).strftime('%H:%M') : nil 162 | end 163 | end 164 | end 165 | -------------------------------------------------------------------------------- /resources/systemd_timer.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: chef-client 3 | # resource:: chef_client_systemd_timer 4 | # 5 | # Copyright:: 2020, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | chef_version_for_provides '< 16.0' if respond_to?(:chef_version_for_provides) 21 | 22 | provides :chef_client_systemd_timer 23 | resource_name :chef_client_systemd_timer 24 | 25 | property :job_name, String, default: 'chef-client' 26 | property :description, String, default: 'Chef Infra Client periodic execution' 27 | 28 | property :user, String, default: 'root' 29 | 30 | property :delay_after_boot, String, default: '1min' 31 | property :interval, String, default: '30min' 32 | property :splay, [Integer, String], default: 300, 33 | coerce: proc { |x| Integer(x) }, 34 | callbacks: { 'should be a positive number' => proc { |v| v > 0 } } 35 | 36 | property :accept_chef_license, [true, false], default: false 37 | 38 | property :run_on_battery, [true, false], default: true 39 | 40 | property :config_directory, String, default: '/etc/chef' 41 | property :chef_binary_path, String, default: '/opt/chef/bin/chef-client' 42 | property :daemon_options, Array, default: [] 43 | property :environment, Hash, default: lazy { {} } 44 | 45 | action :add do 46 | systemd_unit "#{new_resource.job_name}.service" do 47 | content service_content 48 | action :create 49 | end 50 | 51 | systemd_unit "#{new_resource.job_name}.timer" do 52 | content timer_content 53 | action [:create, :enable, :start] 54 | end 55 | end 56 | 57 | action :remove do 58 | systemd_unit "#{new_resource.job_name}.service" do 59 | action :delete 60 | end 61 | 62 | systemd_unit "#{new_resource.job_name}.timer" do 63 | action :delete 64 | end 65 | end 66 | 67 | action_class do 68 | # 69 | # The chef-client command to run in the systemd unit. 70 | # 71 | # @return [String] 72 | # 73 | def chef_client_cmd 74 | cmd = "#{new_resource.chef_binary_path} " 75 | cmd << "#{new_resource.daemon_options.join(' ')} " unless new_resource.daemon_options.empty? 76 | cmd << '--chef-license accept ' if new_resource.accept_chef_license && Gem::Requirement.new('>= 14.12.9').satisfied_by?(Gem::Version.new(Chef::VERSION)) 77 | cmd << "-c #{::File.join(new_resource.config_directory, 'client.rb')} " 78 | cmd 79 | end 80 | 81 | # 82 | # The timer content to pass to the systemd_unit 83 | # 84 | # @return [Hash] 85 | # 86 | def timer_content 87 | { 88 | 'Unit' => { 'Description' => new_resource.description }, 89 | 'Timer' => { 90 | 'OnBootSec' => new_resource.delay_after_boot, 91 | 'OnUnitActiveSec' => new_resource.interval, 92 | 'RandomizedDelaySec' => new_resource.splay, 93 | }, 94 | 'Install' => { 'WantedBy' => 'timers.target' }, 95 | } 96 | end 97 | 98 | # 99 | # The service content to pass to the systemd_unit 100 | # 101 | # @return [Hash] 102 | # 103 | def service_content 104 | unit = { 105 | 'Unit' => { 106 | 'Description' => new_resource.description, 107 | 'After' => 'network.target auditd.service', 108 | }, 109 | 'Service' => { 110 | 'Type' => 'oneshot', 111 | 'ExecStart' => chef_client_cmd, 112 | 'SuccessExitStatus' => [3, 213, 35, 37, 41], 113 | }, 114 | 'Install' => { 'WantedBy' => 'multi-user.target' }, 115 | } 116 | 117 | unit['Service']['ConditionACPower'] = 'true' unless new_resource.run_on_battery 118 | unit['Service']['Environment'] = new_resource.environment.collect { |k, v| "\"#{k}=#{v}\"" } unless new_resource.environment.empty? 119 | unit 120 | end 121 | end 122 | -------------------------------------------------------------------------------- /resources/trusted_certificate.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: chef-client 3 | # resource:: chef_client_trusted_certificate 4 | # 5 | # Copyright:: 2020, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | chef_version_for_provides '< 16.5' if respond_to?(:chef_version_for_provides) 21 | 22 | provides :chef_client_trusted_certificate 23 | resource_name :chef_client_trusted_certificate 24 | 25 | unified_mode true if respond_to?(:unified_mode) 26 | 27 | property :cert_name, String, name_property: true 28 | 29 | # this version check can go away once this is ported into chef itself 30 | property :certificate, String, required: Chef::VERSION.to_i >= 16 ? [:add] : true 31 | 32 | action :add do 33 | unless ::Dir.exist?(Chef::Config[:trusted_certs_dir]) 34 | directory Chef::Config[:trusted_certs_dir] do 35 | mode '0640' 36 | recursive true 37 | end 38 | end 39 | 40 | file cert_path do 41 | content new_resource.certificate 42 | mode '0640' 43 | end 44 | end 45 | 46 | action :remove do 47 | file cert_path do 48 | action :delete 49 | end 50 | end 51 | 52 | action_class do 53 | # 54 | # The path to the string on disk 55 | # 56 | # @return [String] 57 | # 58 | def cert_path 59 | path = ::File.join(Chef::Config[:trusted_certs_dir], new_resource.cert_name) 60 | path << '.pem' unless path.end_with?('.pem') 61 | path 62 | end 63 | end 64 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'chefspec' 2 | require 'chefspec/berkshelf' 3 | 4 | RSpec.configure do |config| 5 | config.color = true # Use color in STDOUT 6 | config.formatter = :documentation # Use the specified formatter 7 | config.log_level = :error # Avoid deprecation notice SPAM 8 | end 9 | -------------------------------------------------------------------------------- /spec/unit/config_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'chef-client::config' do 4 | cached(:chef_run) do 5 | ChefSpec::ServerRunner.new(platform: 'ubuntu', version: '18.04').converge(described_recipe) 6 | end 7 | 8 | it 'does not accept the chef license by default' do 9 | expect(chef_run).to render_file('/etc/chef/client.rb') \ 10 | .with_content { |content| expect(content).to_not match(/chef_license/) } 11 | end 12 | 13 | it 'contains the default chef_server_url setting' do 14 | expect(chef_run).to render_file('/etc/chef/client.rb') \ 15 | .with_content(/chef_server_url/) 16 | end 17 | 18 | it 'contains the default validation_client_name setting' do 19 | expect(chef_run).to render_file('/etc/chef/client.rb') \ 20 | .with_content(/validation_client_name/) 21 | end 22 | 23 | [ 24 | '/var/run/chef', 25 | # '/var/cache/chef', 26 | '/var/lib/chef', 27 | '/var/log/chef', 28 | '/etc/chef', 29 | '/etc/chef/client.d', 30 | ].each do |dir| 31 | it "contains #{dir} directory" do 32 | expect(chef_run).to create_directory(dir) 33 | end 34 | end 35 | 36 | let(:template) { chef_run.template('/etc/chef/client.rb') } 37 | 38 | it 'notifies the client to reload' do 39 | expect(template).to notify('ruby_block[reload_client_config]') 40 | end 41 | 42 | it 'reloads the client config' do 43 | expect(chef_run).to_not run_ruby_block('reload_client_config') 44 | end 45 | 46 | context 'Custom Attributes' do 47 | cached(:chef_run) do 48 | ChefSpec::ServerRunner.new(platform: 'ubuntu', version: '18.04') do |node| 49 | node.normal['chef_client']['chef_license'] = 'accept-no-persist' 50 | node.normal['ohai']['disabled_plugins'] = [:passwd, 'dmi'] 51 | node.normal['ohai']['optional_plugins'] = [:mdadm] 52 | node.normal['ohai']['plugin_path'] = '/etc/chef/ohai_plugins' 53 | node.normal['chef_client']['config']['log_level'] = ':debug' 54 | node.normal['chef_client']['config']['log_location'] = '/dev/null' 55 | node.normal['chef_client']['config']['ssl_verify_mode'] = ':verify_none' 56 | node.normal['chef_client']['config']['exception_handlers'] = [{ class: 'SimpleReport::UpdatedResources', arguments: [] }] 57 | node.normal['chef_client']['config']['report_handlers'] = [{ class: 'SimpleReport::UpdatedResources', arguments: [] }] 58 | node.normal['chef_client']['config']['start_handlers'] = [{ class: 'SimpleReport::UpdatedResources', arguments: [] }] 59 | node.normal['chef_client']['config']['http_proxy'] = 'http://proxy.vmware.com:3128' 60 | node.normal['chef_client']['config']['https_proxy'] = 'http://proxy.vmware.com:3128' 61 | node.normal['chef_client']['config']['no_proxy'] = '*.vmware.com,10.*' 62 | node.normal['chef_client']['load_gems']['chef-handler-updated-resources']['require_name'] = 'chef/handler/updated_resources' 63 | node.normal['chef_client']['reload_config'] = false 64 | end.converge(described_recipe) 65 | end 66 | 67 | it 'accepts the chef license' do 68 | expect(chef_run).to render_file('/etc/chef/client.rb') \ 69 | .with_content(/chef_license "accept-no-persist"/) 70 | end 71 | 72 | it 'disables ohai 6 & 7 plugins' do 73 | expect(chef_run).to render_file('/etc/chef/client.rb') \ 74 | .with_content(/ohai.disabled_plugins =\s+\[:passwd,"dmi"\]/) 75 | end 76 | 77 | it 'enables ohai 6 & 7 plugins' do 78 | expect(chef_run).to render_file('/etc/chef/client.rb') \ 79 | .with_content(/ohai.optional_plugins =\s+\[:mdadm\]/) 80 | end 81 | 82 | it 'specifies an ohai plugin path' do 83 | expect(chef_run).to render_file('/etc/chef/client.rb') \ 84 | .with_content(%(ohai.plugin_path << "/etc/chef/ohai_plugins")) 85 | end 86 | 87 | it 'converts log_level to a symbol' do 88 | expect(chef_run).to render_file('/etc/chef/client.rb') \ 89 | .with_content(/^log_level :debug/) 90 | end 91 | 92 | it 'renders log_location with quotes' do 93 | expect(chef_run).to render_file('/etc/chef/client.rb') \ 94 | .with_content(%r{^log_location "/dev/null"$}) 95 | end 96 | 97 | it 'converts ssl_verify_mode to a symbol' do 98 | expect(chef_run).to render_file('/etc/chef/client.rb') \ 99 | .with_content(/^ssl_verify_mode :verify_none/) 100 | end 101 | 102 | it 'enables exception_handlers' do 103 | expect(chef_run).to render_file('/etc/chef/client.rb') \ 104 | .with_content(%(exception_handlers << SimpleReport::UpdatedResources.new)) 105 | end 106 | 107 | it 'requires handler libraries' do 108 | expect(chef_run).to install_chef_gem('chef-handler-updated-resources') 109 | expect(chef_run).to render_file('/etc/chef/client.rb') \ 110 | .with_content(%(\["chef/handler/updated_resources"\].each do |lib|)) 111 | end 112 | 113 | it 'configures an HTTP Proxy' do 114 | expect(chef_run).to render_file('/etc/chef/client.rb') \ 115 | .with_content(%r{^http_proxy "http://proxy.vmware.com:3128"}) 116 | end 117 | 118 | it 'configures an HTTPS Proxy' do 119 | expect(chef_run).to render_file('/etc/chef/client.rb') \ 120 | .with_content(%r{^https_proxy "http://proxy.vmware.com:3128"}) 121 | end 122 | 123 | it 'configures no_proxy' do 124 | expect(chef_run).to render_file('/etc/chef/client.rb') \ 125 | .with_content(/^no_proxy "\*.vmware.com,10.\*"/) 126 | end 127 | end 128 | 129 | context 'STDOUT Log Location' do 130 | cached(:chef_run) do 131 | ChefSpec::ServerRunner.new(platform: 'ubuntu', version: '18.04') do |node| 132 | node.normal['chef_client']['config']['log_level'] = ':debug' 133 | node.normal['chef_client']['config']['log_location'] = 'STDOUT' 134 | node.normal['chef_client']['config']['ssl_verify_mode'] = ':verify_none' 135 | end.converge(described_recipe) 136 | end 137 | 138 | it 'renders log_location without quotes' do 139 | expect(chef_run).to render_file('/etc/chef/client.rb') \ 140 | .with_content(/^log_location STDOUT$/) 141 | end 142 | end 143 | 144 | context 'Symbol-ized Log Location' do 145 | cached(:chef_run) do 146 | ChefSpec::ServerRunner.new(platform: 'ubuntu', version: '18.04') do |node| 147 | node.normal['chef_client']['config']['log_level'] = ':debug' 148 | node.normal['chef_client']['config']['log_location'] = :syslog 149 | node.normal['chef_client']['config']['ssl_verify_mode'] = ':verify_none' 150 | end.converge(described_recipe) 151 | end 152 | 153 | it 'renders log_location as a symbol' do 154 | expect(chef_run).to render_file('/etc/chef/client.rb') \ 155 | .with_content(/^log_location :syslog$/) 156 | end 157 | end 158 | 159 | context 'Stringy Symbol-ized Log Location' do 160 | # use let instead of cached because we're going to change an attribute 161 | let(:chef_run) do 162 | ChefSpec::ServerRunner.new(platform: 'ubuntu', version: '16.04') do |node| 163 | node.normal['chef_client']['config']['log_level'] = ':debug' 164 | node.normal['chef_client']['config']['log_location'] = log_location 165 | node.normal['chef_client']['config']['ssl_verify_mode'] = ':verify_none' 166 | end.converge(described_recipe) 167 | end 168 | 169 | %w(:syslog syslog).each do |string| 170 | context "with #{string}" do 171 | let(:log_location) { string } 172 | 173 | it 'renders log_location as a symbol' do 174 | expect(chef_run).to render_file('/etc/chef/client.rb') \ 175 | .with_content(/^log_location :syslog$/) 176 | end 177 | end 178 | end 179 | 180 | %w(:win_evt win_evt).each do |string| 181 | context "with #{string}" do 182 | let(:log_location) { string } 183 | 184 | it 'renders log_location as a symbol' do 185 | expect(chef_run).to render_file('/etc/chef/client.rb') \ 186 | .with_content(/^log_location :win_evt$/) 187 | end 188 | end 189 | end 190 | end 191 | end 192 | -------------------------------------------------------------------------------- /spec/unit/cron_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'chef-client::cron' do 4 | cached(:chef_run) { ChefSpec::ServerRunner.new(platform: 'ubuntu', version: '18.04').converge(described_recipe) } 5 | 6 | [ 7 | '/var/run/chef', 8 | # '/var/cache/chef', 9 | # '/var/cache/chef', 10 | '/var/log/chef', 11 | '/etc/chef', 12 | ].each do |dir| 13 | it "creates #{dir} with the correct attributes" do 14 | expect(chef_run).to create_directory(dir).with( 15 | user: 'root', 16 | group: 'root' 17 | ) 18 | end 19 | end 20 | 21 | context 'environmental variables and append_log' do 22 | cached(:chef_run) do 23 | ChefSpec::ServerRunner.new(platform: 'ubuntu', version: '18.04') do |node| 24 | node.normal['chef_client']['cron']['environment_variables'] = 'FOO=BAR' 25 | node.normal['chef_client']['cron']['append_log'] = true 26 | node.normal['chef_client']['cron']['use_cron_d'] = false 27 | end.converge(described_recipe) 28 | end 29 | 30 | it 'sets the FOO=BAR environment variable' do 31 | expect(chef_run).to create_cron('chef-client') \ 32 | .with(command: /FOO=BAR.*chef-client/) 33 | end 34 | 35 | it 'creates a cron job appending to the log' do 36 | expect(chef_run).to create_cron('chef-client') \ 37 | .with(command: /chef-client >>/) 38 | end 39 | end 40 | 41 | context 'when the chef-client process priority is set' do 42 | cached(:redhat_chef_run) do 43 | ChefSpec::ServerRunner.new(platform: 'redhat', version: '7') do |node| 44 | node.normal['chef_client']['cron']['priority'] = 19 45 | node.normal['chef_client']['cron']['use_cron_d'] = false 46 | end.converge(described_recipe) 47 | end 48 | 49 | cached(:invalid_priority_chef_run) do 50 | ChefSpec::ServerRunner.new(platform: 'redhat', version: '7') do |node| 51 | node.normal['chef_client']['cron']['priority'] = 42 52 | node.normal['chef_client']['cron']['use_cron_d'] = false 53 | end.converge(described_recipe) 54 | end 55 | 56 | cached(:string_but_valid_chef_run) do 57 | ChefSpec::ServerRunner.new(platform: 'redhat', version: '7') do |node| 58 | node.normal['chef_client']['cron']['priority'] = '-5' 59 | node.normal['chef_client']['cron']['use_cron_d'] = false 60 | end.converge(described_recipe) 61 | end 62 | 63 | cached(:string_but_invalid_chef_run) do 64 | ChefSpec::ServerRunner.new(platform: 'redhat', version: '7') do |node| 65 | node.normal['chef_client']['cron']['priority'] = '123' 66 | node.normal['chef_client']['cron']['use_cron_d'] = false 67 | end.converge(described_recipe) 68 | end 69 | 70 | cached(:gobbledeegook_chef_run) do 71 | ChefSpec::ServerRunner.new(platform: 'redhat', version: '7') do |node| 72 | node.normal['chef_client']['cron']['priority'] = 'hibbitydibbity-123' 73 | node.normal['chef_client']['cron']['use_cron_d'] = false 74 | end.converge(described_recipe) 75 | end 76 | 77 | it 'creates a cron job with a prioritized chef-client with an in-bounds priority' do 78 | expect(redhat_chef_run).to create_cron('chef-client') \ 79 | .with(command: /nice -n 19 .*chef-client/) 80 | end 81 | 82 | it 'creates a cron job with a non-prioritized chef-client with an out-of-bounds priority' do 83 | expect(invalid_priority_chef_run).to create_cron('chef-client') \ 84 | .with(command: /sleep \d+; .*chef-client/) 85 | end 86 | 87 | it 'creates a cron job with a prioritized chef-client with an in-bounds priority (string)' do 88 | expect(string_but_valid_chef_run).to create_cron('chef-client') \ 89 | .with(command: /nice -n -5 .*chef-client/) 90 | end 91 | 92 | it 'creates a cron job with a non-prioritized chef-client with an out-of-bounds priority (string)' do 93 | expect(string_but_invalid_chef_run).to create_cron('chef-client') \ 94 | .with(command: /sleep \d+; .*chef-client/) 95 | end 96 | 97 | it 'creates a cron job with a non-prioritized chef-client with a garbled string value' do 98 | expect(gobbledeegook_chef_run).to create_cron('chef-client') \ 99 | .with(command: /sleep \d+; .*chef-client/) 100 | end 101 | end 102 | end 103 | -------------------------------------------------------------------------------- /spec/unit/init_service_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'chef-client::init_service' do 4 | centos6 = { platform: 'centos', version: '6', conf_dir: 'sysconfig' } 5 | 6 | context "#{centos6[:platform]} #{centos6[:version]}" do 7 | let(:chef_run) do 8 | ChefSpec::ServerRunner.new(platform: centos6[:platform], version: centos6[:version]) do |node| 9 | node.normal['chef_client']['daemon_options'] = ['-E client-args'] 10 | end.converge(described_recipe) 11 | end 12 | 13 | it 'should set -E client-args' do 14 | expect(chef_run).to render_file("/etc/#{centos6[:conf_dir]}/chef-client") \ 15 | .with_content(/OPTIONS="-E client-args"/) 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /spec/unit/launchd_service_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'chef-client::launchd_service' do 4 | context 'when self-update attribute is true' do 5 | let(:chef_run) do 6 | ChefSpec::ServerRunner.new(platform: 'mac_os_x') do |node| 7 | node.normal['chef_client']['launchd_self-update'] = true 8 | end.converge(described_recipe) 9 | end 10 | 11 | it 'creates the launchd daemon plist' do 12 | expect(chef_run).to create_template('/Library/LaunchDaemons/com.chef.chef-client.plist') 13 | end 14 | 15 | it 'create / enable the launchd daemon' do 16 | expect(chef_run).to create_launchd('com.chef.chef-client') 17 | expect(chef_run).to enable_launchd('com.chef.chef-client') 18 | end 19 | 20 | it 'restarts the launchd daemon when template is changed' do 21 | expect(chef_run.template('/Library/LaunchDaemons/com.chef.chef-client.plist')).to notify('launchd[com.chef.chef-client]').to(:restart) 22 | end 23 | end 24 | end 25 | 26 | describe 'chef-client::launchd_service' do 27 | context 'when self-update attribute is false' do 28 | let(:chef_run) do 29 | ChefSpec::ServerRunner.new(platform: 'mac_os_x') do |node| 30 | node.normal['chef_client']['launchd_self-update'] = false 31 | end.converge(described_recipe) 32 | end 33 | 34 | it 'creates the launch daemon plist' do 35 | expect(chef_run).to create_template('/Library/LaunchDaemons/com.chef.chef-client.plist') 36 | end 37 | 38 | it 'create / enable the launchd daemon' do 39 | expect(chef_run).to create_launchd('com.chef.chef-client') 40 | expect(chef_run).to enable_launchd('com.chef.chef-client') 41 | end 42 | 43 | it 'does not restart the service when daemon is changed' do 44 | expect(chef_run.template('/Library/LaunchDaemons/com.chef.chef-client.plist')).to_not notify('launchd[com.chef.chef-client]') 45 | end 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /spec/unit/scheduled_task_spec.rb: -------------------------------------------------------------------------------- 1 | # Chefspec and windows aren't the best of friends. Running this on a non-windows 2 | # host results in win32ole load errors. 3 | 4 | # require 'spec_helper' 5 | # 6 | # describe 'chef-client::task' do 7 | # context 'when given override attributes' do 8 | # let(:chef_run) do 9 | # ChefSpec::ServerRunner.new(platform: 'windows', version: '2012R2', step_into: ['chef_client_scheduled_task']) do |node| 10 | # node.override['chef_client']['task']['start_time'] = 'Tue Sep 13 15:46:33 EDT 2016' 11 | # node.override['chef_client']['task']['user'] = 'system' 12 | # node.override['chef_client']['task']['password'] = 'secret' 13 | # node.override['chef_client']['task']['frequency'] = 'hourly' 14 | # node.override['chef_client']['task']['frequency_modifier'] = 60 15 | # end.converge(described_recipe) 16 | # end 17 | # 18 | # it 'creates the windows_task resource with desired settings' do 19 | # expect(chef_run).to create_windows_task('chef-client').with( 20 | # command: 'cmd /c "C:/opscode/chef/bin/chef-client -L C:/chef/log/client.log -c C:/chef/client.rb -s 300 ^> NUL 2^>^&1"', 21 | # user: 'system', 22 | # password: 'secret', 23 | # frequency: :hourly, 24 | # frequency_modifier: 60, 25 | # start_time: 'Tue Sep 13 15:46:33 EDT 2016' 26 | # ) 27 | # end 28 | # end 29 | # end 30 | -------------------------------------------------------------------------------- /spec/unit/service_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'chef-client::service' do 4 | context 'AIX' do 5 | let(:chef_run) { ChefSpec::SoloRunner.new(platform: 'aix').converge(described_recipe) } 6 | before do 7 | stub_command('lssrc -s chef').and_return(true) 8 | stub_command('lsitab chef').and_return(true) 9 | end 10 | it 'should use the src service' do 11 | expect(chef_run).to include_recipe('chef-client::src_service') 12 | end 13 | end 14 | 15 | context 'Amazon Linux 201X' do 16 | let(:chef_run) { ChefSpec::SoloRunner.new(platform: 'amazon', version: '2018.03').converge(described_recipe) } 17 | it 'should use the init service' do 18 | expect(chef_run).to include_recipe('chef-client::init_service') 19 | end 20 | end 21 | 22 | context 'Amazon Linux 2' do 23 | let(:chef_run) { ChefSpec::SoloRunner.new(platform: 'amazon', version: '2').converge(described_recipe) } 24 | it 'should use the systemd service' do 25 | expect(chef_run).to include_recipe('chef-client::systemd_service') 26 | end 27 | end 28 | 29 | context 'CentOS 6' do 30 | let(:chef_run) { ChefSpec::SoloRunner.new(platform: 'centos', version: '6').converge(described_recipe) } 31 | it 'should use the init service' do 32 | expect(chef_run).to include_recipe('chef-client::init_service') 33 | end 34 | end 35 | 36 | context 'CentOS 7' do 37 | let(:chef_run) { ChefSpec::SoloRunner.new(platform: 'centos', version: '7').converge(described_recipe) } 38 | it 'should use the systemd service' do 39 | expect(chef_run).to include_recipe('chef-client::systemd_service') 40 | end 41 | end 42 | 43 | context 'CentOS 8' do 44 | let(:chef_run) { ChefSpec::SoloRunner.new(platform: 'centos', version: '8').converge(described_recipe) } 45 | it 'should use the systemd service' do 46 | expect(chef_run).to include_recipe('chef-client::systemd_service') 47 | end 48 | end 49 | 50 | context 'Debian' do 51 | let(:chef_run) { ChefSpec::SoloRunner.new(platform: 'debian').converge(described_recipe) } 52 | it 'should use the systemd service' do 53 | expect(chef_run).to include_recipe('chef-client::systemd_service') 54 | end 55 | end 56 | 57 | context 'Fedora' do 58 | let(:chef_run) { ChefSpec::SoloRunner.new(platform: 'fedora').converge(described_recipe) } 59 | it 'should use the systemd service' do 60 | expect(chef_run).to include_recipe('chef-client::systemd_service') 61 | end 62 | end 63 | 64 | context 'FreeBSD' do 65 | let(:chef_run) { ChefSpec::SoloRunner.new(platform: 'freebsd').converge(described_recipe) } 66 | it 'should use the bsd service' do 67 | expect(chef_run).to include_recipe('chef-client::bsd_service') 68 | end 69 | end 70 | 71 | context 'macOS' do 72 | let(:chef_run) { ChefSpec::SoloRunner.new(platform: 'mac_os_x').converge(described_recipe) } 73 | it 'should use the launchd service' do 74 | expect(chef_run).to include_recipe('chef-client::launchd_service') 75 | end 76 | end 77 | 78 | context 'SLES' do 79 | let(:chef_run) { ChefSpec::SoloRunner.new(platform: 'suse').converge(described_recipe) } 80 | it 'should use the systemd service' do 81 | expect(chef_run).to include_recipe('chef-client::systemd_service') 82 | end 83 | end 84 | 85 | context 'openSUSE Leap' do 86 | let(:chef_run) { ChefSpec::SoloRunner.new(platform: 'opensuse').converge(described_recipe) } 87 | it 'should use the systemd service' do 88 | expect(chef_run).to include_recipe('chef-client::systemd_service') 89 | end 90 | end 91 | 92 | context 'Ubuntu' do 93 | let(:chef_run) { ChefSpec::SoloRunner.new(platform: 'ubuntu').converge(described_recipe) } 94 | it 'should use the systemd service' do 95 | expect(chef_run).to include_recipe('chef-client::systemd_service') 96 | end 97 | end 98 | 99 | context 'Solaris' do 100 | let(:chef_run) { ChefSpec::SoloRunner.new(platform: 'solaris2').converge(described_recipe) } 101 | it 'should use the smf service' do 102 | expect(chef_run).to include_recipe('chef-client::smf_service') 103 | end 104 | end 105 | end 106 | -------------------------------------------------------------------------------- /templates/default/clearlinux/chef/chef-client.erb: -------------------------------------------------------------------------------- 1 | CONFIG=<%= node["chef_client"]["conf_dir"] %>/client.rb 2 | INTERVAL=<%= node["chef_client"]["interval"] %> 3 | SPLAY=<%= node["chef_client"]["splay"] %> -------------------------------------------------------------------------------- /templates/default/client.rb.erb: -------------------------------------------------------------------------------- 1 | <% unless @chef_requires.empty? -%> 2 | <%= @chef_requires.inspect %>.each do |lib| 3 | begin 4 | require lib 5 | rescue LoadError 6 | Chef::Log.warn "Failed to load #{lib}. This should be resolved after a chef run." 7 | end 8 | end 9 | 10 | <% end -%> 11 | <% unless @chef_license.nil? -%> 12 | chef_license "<%= @chef_license %>" 13 | <% end -%> 14 | <% @chef_config.keys.sort.each do |option| -%> 15 | <% next if %w{ node_name exception_handlers report_handlers start_handlers http_proxy https_proxy no_proxy }.include?(option) -%> 16 | <% case option -%> 17 | <% when 'log_level', 'ssl_verify_mode', 'audit_mode' -%> 18 | <%= option %> <%= @chef_config[option].to_s.gsub(/^:/, '').to_sym.inspect %> 19 | <% when 'log_location' -%> 20 | <% if (@chef_config[option].instance_of? String) && @chef_config[option].match(/^(STDOUT|STDERR)$/) -%> 21 | <%= option %> <%= @chef_config[option] %> 22 | <% elsif (@chef_config[option].instance_of? String) && @chef_config[option].match(/^:?(syslog|win_evt)$/) -%> 23 | <%= option %> <%= @chef_config[option].to_s.gsub(/^:/, '').to_sym.inspect %> 24 | <% else -%> 25 | <%= option %> <%= @chef_config[option].inspect %> 26 | <% end -%> 27 | <% else -%> 28 | <%= option %> <%= @chef_config[option].inspect %> 29 | <% end -%> 30 | <% end -%> 31 | <% if @chef_config['node_name'] -%> 32 | node_name <%= @chef_config['node_name'].inspect %> 33 | <% else -%> 34 | # Using default node name (fqdn) 35 | <% end -%> 36 | <% unless node["chef_client"]["config"]["http_proxy"].nil? -%> 37 | # set the proxy env variable so rubygems works correctly 38 | http_proxy "<%= node["chef_client"]["config"]["http_proxy"] %>" 39 | <% end -%> 40 | <% unless node["chef_client"]["config"]["https_proxy"].nil? -%> 41 | https_proxy "<%= node["chef_client"]["config"]["https_proxy"] %>" 42 | <% end -%> 43 | <% unless node["chef_client"]["config"]["no_proxy"].nil? -%> 44 | no_proxy "<%= node["chef_client"]["config"]["no_proxy"] %>" 45 | <% end -%> 46 | <% unless node["ohai"]["plugin_path"].nil? -%> 47 | ohai.plugin_path << "<%= node["ohai"]["plugin_path"] %>" 48 | <% end -%> 49 | <% unless @ohai_disabled_plugins.empty? -%> 50 | ohai.disabled_plugins = [<%= @ohai_disabled_plugins.map { |k| k.match(/:/) ? k.gsub(/^:/, '').to_sym.inspect : k.inspect }.join(",") %>] 51 | <% end -%> 52 | <% unless @ohai_optional_plugins.empty? -%> 53 | ohai.optional_plugins = [<%= @ohai_optional_plugins.map { |k| k.match(/:/) ? k.gsub(/^:/, '').to_sym.inspect : k.inspect }.join(",") %>] 54 | <% end -%> 55 | <% if @start_handlers.is_a?(Array) && @start_handlers.any? -%> 56 | # Do not crash if a start handler is missing / not installed yet 57 | begin 58 | <% @start_handlers.each do |handler| -%> 59 | start_handlers << <%= handler["class"] %>.new(<%= handler["arguments"].join(',') %>) 60 | <% end -%> 61 | rescue NameError => e 62 | Chef::Log.error e 63 | end 64 | <% end -%> 65 | <% if @report_handlers.is_a?(Array) && @report_handlers.any? -%> 66 | # Do not crash if a report handler is missing / not installed yet 67 | begin 68 | <% @report_handlers.each do |handler| -%> 69 | report_handlers << <%= handler["class"] %>.new(<%= handler["arguments"].join(',') %>) 70 | <% end -%> 71 | rescue NameError => e 72 | Chef::Log.error e 73 | end 74 | <% end -%> 75 | <% if @exception_handlers.is_a?(Array) && @exception_handlers.any? -%> 76 | # Do not crash if an exception handler is missing / not installed yet 77 | begin 78 | <% @exception_handlers.each do |handler| -%> 79 | exception_handlers << <%= handler["class"] %>.new(<%= handler["arguments"].join(',') %>) 80 | <% end -%> 81 | rescue NameError => e 82 | Chef::Log.error e 83 | end 84 | <% end -%> 85 | <% unless node['chef_client']['file_cache_path'].nil? -%> 86 | file_cache_path "<%= node['chef_client']['file_cache_path'] %>" 87 | <% end -%> 88 | <% unless node['chef_client']['file_backup_path'].nil? -%> 89 | file_backup_path "<%= node['chef_client']['file_backup_path'] %>" 90 | <% end -%> 91 | <% unless node['chef_client']['run_path'].nil? -%> 92 | run_path "<%= node['chef_client']['run_path'] %>" 93 | <% end -%> 94 | <% unless node['chef_client']['file_staging_uses_destdir'].nil? -%> 95 | file_staging_uses_destdir <%= node['chef_client']['file_staging_uses_destdir'] %> 96 | <% end -%> 97 | -------------------------------------------------------------------------------- /templates/default/com.chef.chef-client.plist.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Label 7 | com.chef.chef-client 8 | <%- if @launchd_mode == "interval" %> 9 | Program 10 | <%= @client_bin %> 11 | StartInterval 12 | <%= @interval %> 13 | RunAtLoad 14 | 15 | WorkingDirectory 16 | <%= @working_dir %> 17 | <%- else %> 18 | ProgramArguments 19 | 20 | <%= @client_bin %> 21 | -i <%= @interval %> 22 | -s <%= @splay %> 23 | <% @daemon_options.each do |option| -%> 24 | <%= option %> 25 | <% end -%> 26 | 27 | KeepAlive 28 | 29 | <%- end %> 30 | StandardOutPath 31 | <%= @log_dir %>/<%= @log_file %> 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /templates/default/debian/default/chef-client.erb: -------------------------------------------------------------------------------- 1 | CONFIG=<%= node["chef_client"]["conf_dir"] %>/client.rb 2 | INTERVAL=<%= node["chef_client"]["interval"] %> 3 | SPLAY=<%= node["chef_client"]["splay"] %> 4 | OPTIONS="<%= node["chef_client"]["daemon_options"].join(' ') %>" 5 | -------------------------------------------------------------------------------- /templates/default/debian/init.d/chef-client.erb: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | ### BEGIN INIT INFO 3 | # Provides: chef-client 4 | # Required-Start: $remote_fs $network 5 | # Required-Stop: $remote_fs $network 6 | # Default-Start: 2 3 4 5 7 | # Default-Stop: 0 1 6 8 | # Short-Description: Start a chef-client. 9 | ### END INIT INFO 10 | # 11 | # Copyright (c) 2009-2010 Chef Software, Inc, 12 | # 13 | # chef-client Startup script for chef-client. 14 | # chkconfig: - 99 02 15 | # description: starts up chef-client in daemon mode. 16 | 17 | PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 18 | DAEMON=<%= @client_bin %> 19 | NAME=chef-client 20 | DESC=chef-client 21 | PIDFILE=<%= node["chef_client"]["run_path"] %>/client.pid 22 | 23 | test -x $DAEMON || exit 1 24 | 25 | . /lib/lsb/init-functions 26 | 27 | [ -r /etc/default/$NAME ] && . /etc/default/$NAME 28 | 29 | if [ ! -d /var/run/chef ]; then 30 | mkdir /var/run/chef 31 | fi 32 | 33 | DAEMON_OPTS="-d -P $PIDFILE -c $CONFIG -i $INTERVAL -s $SPLAY <%= node["chef_client"]["daemon_options"].join(' ') %>" 34 | 35 | running_pid() { 36 | pid=$1 37 | name=$2 38 | [ -z "$pid" ] && return 1 39 | [ ! -d /proc/$pid ] && return 1 40 | cat /proc/$pid/cmdline | tr '\000' ' ' | grep -q "$name" 41 | } 42 | 43 | running() { 44 | [ ! -f "$PIDFILE" ] && return 1 45 | pid=`cat $PIDFILE` 46 | running_pid $pid $DAEMON || return 1 47 | return 0 48 | } 49 | 50 | start_server() { 51 | if [ -z "$DAEMONUSER" ] ; then 52 | start_daemon -p $PIDFILE $DAEMON $DAEMON_OPTS 53 | errcode=$? 54 | else 55 | start-stop-daemon --start --quiet --pidfile $PIDFILE \ 56 | --chuid $DAEMONUSER \ 57 | --exec $DAEMON -- $DAEMON_OPTS 58 | errcode=$? 59 | fi 60 | return $errcode 61 | } 62 | 63 | stop_server() { 64 | if [ -z "$DAEMONUSER" ] ; then 65 | killproc -p $PIDFILE $DAEMON 66 | errcode=$? 67 | else 68 | start-stop-daemon --stop --quiet --pidfile $PIDFILE \ 69 | --user $DAEMONUSER \ 70 | --exec $DAEMON 71 | errcode=$? 72 | fi 73 | return $errcode 74 | } 75 | 76 | reload_server() { 77 | if [ -z "$DAEMONUSER" ] ; then 78 | killproc -p $PIDFILE $DAEMON -HUP 79 | errcode=$? 80 | else 81 | start-stop-daemon --stop --signal HUP --quiet --pidfile $PIDFILE \ 82 | --user $DAEMONUSER \ 83 | --exec $DAEMON 84 | errcode=$? 85 | fi 86 | return $errcode 87 | } 88 | 89 | run_server() { 90 | if [ -z "$DAEMONUSER" ] ; then 91 | killproc -p $PIDFILE $DAEMON -USR1 92 | errcode=$? 93 | else 94 | start-stop-daemon --stop --signal USR1 --quiet --pidfile $PIDFILE \ 95 | --user $DAEMONUSER \ 96 | --exec $DAEMON 97 | errcode=$? 98 | fi 99 | return $errcode 100 | } 101 | 102 | force_stop() { 103 | [ ! -e "$PIDFILE" ] && return 104 | if running ; then 105 | /bin/kill -15 $pid 106 | sleep "$DIETIME"s 107 | if running ; then 108 | /bin/kill -9 $pid 109 | sleep "$DIETIME"s 110 | if running ; then 111 | echo "Cannot kill $NAME (pid=$pid)!" 112 | exit 1 113 | fi 114 | fi 115 | fi 116 | rm -f $PIDFILE 117 | } 118 | 119 | case "$1" in 120 | start) 121 | log_daemon_msg "Starting $DESC " "$NAME" 122 | if running ; then 123 | log_progress_msg "apparently already running" 124 | log_end_msg 0 125 | exit 0 126 | fi 127 | if start_server ; then 128 | [ -n "$STARTTIME" ] && sleep $STARTTIME # Wait some time 129 | if running ; then 130 | log_end_msg 0 131 | else 132 | log_end_msg 1 133 | fi 134 | else 135 | log_end_msg 1 136 | fi 137 | ;; 138 | stop) 139 | log_daemon_msg "Stopping $DESC" "$NAME" 140 | if running ; then 141 | errcode=0 142 | stop_server || errcode=$? 143 | log_end_msg $errcode 144 | else 145 | log_progress_msg "apparently not running" 146 | log_end_msg 0 147 | exit 0 148 | fi 149 | ;; 150 | force-stop) 151 | $0 stop 152 | if running; then 153 | log_daemon_msg "Stopping (force) $DESC" "$NAME" 154 | errcode=0 155 | force_stop || errcode=$? 156 | log_end_msg $errcode 157 | fi 158 | ;; 159 | restart|force-reload) 160 | log_daemon_msg "Restarting $DESC" "$NAME" 161 | errcode=0 162 | stop_server || errcode=$? 163 | [ -n "$DIETIME" ] && sleep $DIETIME 164 | start_server || errcode=$? 165 | [ -n "$STARTTIME" ] && sleep $STARTTIME 166 | running || errcode=$? 167 | log_end_msg $errcode 168 | ;; 169 | status) 170 | log_daemon_msg "Checking status of $DESC" "$NAME" 171 | if running ; then 172 | log_progress_msg "running" 173 | log_end_msg 0 174 | else 175 | log_progress_msg "apparently not running" 176 | log_end_msg 1 177 | exit 3 178 | fi 179 | ;; 180 | reload) 181 | if running; then 182 | log_daemon_msg "Reloading $DESC" "$NAME" 183 | errcode=0 184 | reload_server || errcode=$? 185 | log_end_msg $errcode 186 | fi 187 | ;; 188 | run) 189 | if running; then 190 | log_daemon_msg "Triggering run of $DESC" "$NAME" 191 | errcode=0 192 | run_server || errcode=$? 193 | log_end_msg $errcode 194 | fi 195 | ;; 196 | *) 197 | N=/etc/init.d/$NAME 198 | echo "Usage: $N {start|stop|force-stop|restart|force-reload|status|run}" >&2 199 | exit 1 200 | ;; 201 | esac 202 | 203 | exit 0 204 | -------------------------------------------------------------------------------- /templates/default/fedora/sysconfig/chef-client.erb: -------------------------------------------------------------------------------- 1 | # Configuration file for the chef-client service 2 | 3 | CONFIG=<%= node["chef_client"]["conf_dir"] %>/client.rb 4 | PIDFILE=<%= node["chef_client"]["run_path"] %>/client.pid 5 | #LOCKFILE=/var/lock/subsys/chef-client 6 | # Sleep interval between runs. 7 | # This value is in seconds. 8 | INTERVAL=<%= node["chef_client"]["interval"] %> 9 | # Maximum amount of random delay before starting a run. Prevents every client 10 | # from contacting the server at the exact same time. 11 | # This value is in seconds. 12 | SPLAY=<%= node["chef_client"]["splay"] %> 13 | # Any additional chef-client options. 14 | OPTIONS="<%= node["chef_client"]["daemon_options"].join(' ') %>" 15 | <% if node["chef_client"]["ca_cert_path"] %> 16 | SSL_CERT_FILE="<%= node["chef_client"]["ca_cert_path"] %>" 17 | export SSL_CERT_FILE 18 | <% end %> 19 | -------------------------------------------------------------------------------- /templates/default/freebsd/chef-client.erb: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # PROVIDE: chef 4 | # REQUIRE: LOGIN 5 | # KEYWORD: shutdown 6 | 7 | . /etc/rc.subr 8 | 9 | <% if node["chef_client"]["ca_cert_path"] %> 10 | SSL_CERT_FILE="<%= node["chef_client"]["ca_cert_path"] %>" 11 | export SSL_CERT_FILE 12 | <% end %> 13 | 14 | name="chef" 15 | pidfile="<%= node["chef_client"]["run_path"] %>/${name}.pid" 16 | command="<%= @client_bin %>" 17 | command_interpreter="<%= RbConfig.ruby %>" 18 | command_args="-i <%= node["chef_client"]["interval"] %> -s <%= node["chef_client"]["splay"] %> -d -P ${pidfile}" 19 | load_rc_config $name 20 | run_rc_command "$1" 21 | -------------------------------------------------------------------------------- /templates/default/freebsd/chef.erb: -------------------------------------------------------------------------------- 1 | chef_enable="YES" 2 | -------------------------------------------------------------------------------- /templates/default/redhat/init.d/chef-client.erb: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # chef-client Startup script for the Chef client 4 | # 5 | # chkconfig: - <%= @chkconfig_start_order -%> <%= @chkconfig_stop_order %> 6 | # description: Client component of the Chef systems integration framework. 7 | 8 | ### BEGIN INIT INFO 9 | # Provides: chef-client 10 | # Required-Start: $local_fs $network $remote_fs 11 | # Required-Stop: $local_fs $network $remote_fs 12 | # Should-Start: $named $time 13 | # Should-Stop: $named $time 14 | # Short-Description: Startup script for the Chef client 15 | # Description: Client component of the Chef systems integration framework. 16 | ### END INIT INFO 17 | 18 | # Source function library 19 | . /etc/init.d/functions 20 | 21 | exec="<%= @client_bin %>" 22 | prog="chef-client" 23 | 24 | [ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog 25 | 26 | config=${CONFIG-/etc/chef/client.rb} 27 | pidfile=${PIDFILE-/var/run/chef/client.pid} 28 | lockfile=${LOCKFILE-/var/lock/subsys/$prog} 29 | interval=${INTERVAL-1800} 30 | splay=${SPLAY-20} 31 | options=${OPTIONS-} 32 | 33 | start() { 34 | [ -x $exec ] || exit 5 35 | [ -f $config ] || exit 6 36 | echo -n $"Starting $prog: " 37 | daemon $exec -d -c "$config" -P "$pidfile" -i "$interval" -s "$splay" "$options" 38 | retval=$? 39 | echo 40 | [ $retval -eq 0 ] && touch $lockfile 41 | return $retval 42 | } 43 | 44 | stop() { 45 | echo -n $"Stopping $prog: " 46 | # It will pick the process id directly from the running process and adding into $pidfile. 47 | ps -ef |grep $exec |grep -v grep |awk '{print $2}' > $pidfile 48 | killproc -p $pidfile $exec 49 | retval=$? 50 | echo 51 | [ $retval -eq 0 ] && rm -f $lockfile 52 | return $retval 53 | } 54 | 55 | restart () { 56 | stop 57 | start 58 | } 59 | 60 | reload() { 61 | echo -n $"Reloading $prog: " 62 | killproc -p $pidfile $exec -HUP 63 | retval=$? 64 | echo 65 | return $retval 66 | } 67 | 68 | force_reload() { 69 | restart 70 | } 71 | 72 | rh_status() { 73 | # run checks to determine if the service is running or use generic status 74 | status -p $pidfile $prog 75 | } 76 | 77 | rh_status_q() { 78 | rh_status >/dev/null 2>&1 79 | } 80 | 81 | case "$1" in 82 | start) 83 | rh_status_q && exit 0 84 | $1 85 | ;; 86 | stop) 87 | rh_status_q || exit 0 88 | $1 89 | ;; 90 | restart) 91 | $1 92 | ;; 93 | reload) 94 | rh_status_q || exit 7 95 | $1 96 | ;; 97 | force-reload) 98 | force_reload 99 | ;; 100 | status) 101 | rh_status 102 | ;; 103 | condrestart|try-restart) 104 | rh_status_q || exit 0 105 | restart 106 | ;; 107 | *) 108 | echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}" 109 | exit 2 110 | esac 111 | exit $? 112 | -------------------------------------------------------------------------------- /templates/default/redhat/sysconfig/chef-client.erb: -------------------------------------------------------------------------------- 1 | # Configuration file for the chef-client service 2 | 3 | CONFIG=<%= node["chef_client"]["conf_dir"] %>/client.rb 4 | PIDFILE=<%= node["chef_client"]["run_path"] %>/client.pid 5 | #LOCKFILE=/var/lock/subsys/chef-client 6 | # Sleep interval between runs. 7 | # This value is in seconds. 8 | INTERVAL=<%= node["chef_client"]["interval"] %> 9 | # Maximum amount of random delay before starting a run. Prevents every client 10 | # from contacting the server at the exact same time. 11 | # This value is in seconds. 12 | SPLAY=<%= node["chef_client"]["splay"] %> 13 | # Any additional chef-client options. 14 | OPTIONS="<%= node["chef_client"]["daemon_options"].join(' ') %>" 15 | <% if node["chef_client"]["ca_cert_path"] %> 16 | SSL_CERT_FILE="<%= node["chef_client"]["ca_cert_path"] %>" 17 | export SSL_CERT_FILE 18 | <% end %> 19 | -------------------------------------------------------------------------------- /templates/default/solaris/chef-client.erb: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #################################################################### 3 | # COOKBOOK NAME: chef-client 4 | # RECIPE: default 5 | # DESCRIPTION: chef-client start/stop script for Solaris SMF 6 | # 7 | #################################################################### 8 | # (C)2011 DigiTar, All Rights Reserved 9 | # Distributed under the BSD License 10 | # 11 | # Redistribution and use in source and binary forms, with or without modification, 12 | # are permitted provided that the following conditions are met: 13 | # 14 | # * Redistributions of source code must retain the above copyright notice, 15 | # this list of conditions and the following disclaimer. 16 | # * Redistributions in binary form must reproduce the above copyright notice, 17 | # this list of conditions and the following disclaimer in the documentation 18 | # and/or other materials provided with the distribution. 19 | # * Neither the name of DigiTar nor the names of its contributors may be 20 | # used to endorse or promote products derived from this software without 21 | # specific prior written permission. 22 | # 23 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 24 | # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 | # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 26 | # SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 28 | # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 29 | # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 | # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 32 | # DAMAGE. 33 | # 34 | #################################################################### 35 | 36 | . /lib/svc/share/smf_include.sh 37 | 38 | PATH=<%= node["chef_client"]["env_path"] %> 39 | DAEMON=<%= node["chef_client"]["bin_dir"] %>/chef-client 40 | NAME=chef-client 41 | DESC=chef-client 42 | PIDFILE=<%= node["chef_client"]["run_path"] %>/client.pid 43 | CONFIG=<%= node["chef_client"]["conf_dir"] %>/client.rb 44 | INTERVAL=<%= node["chef_client"]["interval"] %> 45 | SPLAY=<%= node["chef_client"]["splay"] %> 46 | 47 | DAEMON_OPTS="-d -P $PIDFILE -c $CONFIG -i $INTERVAL -s $SPLAY <%= node["chef_client"]["daemon_options"].join(' ') %>" 48 | 49 | if [ ! -d <%= node["chef_client"]["run_path"] %> ]; then 50 | mkdir <%= node["chef_client"]["run_path"] %> 51 | fi 52 | 53 | case "$1" in 54 | 'start') 55 | $DAEMON $DAEMON_OPTS 56 | ;; 57 | 58 | *) 59 | echo $"Usage: $0 (start)" 60 | exit 1 61 | ;; 62 | 63 | esac 64 | exit $SMF_EXIT_OK 65 | -------------------------------------------------------------------------------- /templates/default/solaris/manifest-5.11.xml.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 11 | 12 | 13 | 14 | 15 | 20 | 21 | 22 | 23 | 24 | 29 | 30 | 31 | 32 | 37 | 38 | 39 | 40 | 45 | 46 | 47 | 48 | 53 | 55 | 56 | 57 | /chef-client %m' 61 | timeout_seconds='60'> 62 | <% if node['chef_client']['locale'] || node["chef_client"]["ca_cert_path"] %> 63 | 64 | 65 | <% if node['chef_client']['locale'] %> 66 | 67 | 68 | <% end %> 69 | <% if node["chef_client"]["ca_cert_path"] %> 70 | "/> 71 | <% end %> 72 | 73 | 74 | <% end %> 75 | 76 | 77 | 82 | 83 | 84 | 89 | 90 | 91 | 92 | 93 | 95 | 96 | 97 | 98 | 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /templates/default/solaris/manifest.xml.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 11 | 12 | 13 | 14 | 15 | 20 | 21 | 22 | 23 | 24 | 29 | 30 | 31 | 32 | 37 | 38 | 39 | 40 | 45 | 46 | 47 | 48 | 53 | 55 | 56 | 57 | /chef-client %m' 61 | timeout_seconds='60'> 62 | <% if node['chef_client']['locale'] || node["chef_client"]["ca_cert_path"] %> 63 | 64 | 65 | <% if node['chef_client']['locale'] %> 66 | 67 | 68 | <% end %> 69 | <% if node["chef_client"]["ca_cert_path"] %> 70 | "/> 71 | <% end %> 72 | 73 | 74 | <% end %> 75 | 76 | 77 | 82 | 83 | 84 | 89 | 90 | 91 | 92 | 93 | 95 | 96 | 97 | 98 | 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /templates/default/suse/init.d/chef-client.erb: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ### BEGIN INIT INFO 3 | # Provides: chef-client 4 | # Required-Start: $syslog $remote_fs 5 | # Should-Start: $time 6 | # Required-Stop: $syslog $remote_fs 7 | # Should-Stop: 8 | # Default-Start: 3 5 9 | # Default-Stop: 0 1 2 6 10 | # Short-Description: Startup script for the Chef client 11 | # Description: Client component of the Chef systems integration framework. 12 | ### END INIT INFO 13 | 14 | 15 | CHEF_CLIENT=<%= @client_bin %> 16 | test -x $CHEF_CLIENT || { echo "$CHEF_CLIENT not installed"; 17 | if [ "$1" = "stop" ]; then exit 0; 18 | else exit 5; fi; } 19 | 20 | PIDFILE=<%= node["chef_client"]["run_path"] %>/client.pid 21 | 22 | # Read sysconfig 23 | if [ -f "/etc/sysconfig/chef-client" ]; then 24 | . /etc/sysconfig/chef-client 25 | fi 26 | 27 | CONFIG=${CONFIG-<%= node["chef_client"]["conf_dir"] %>/client.rb} 28 | PIDFILE=${PIDFILE-<%= node["chef_client"]["run_path"] %>/client.pid} 29 | LOCKFILE=${LOCKFILE-/var/lock/subsys/chef-client} 30 | INTERVAL=${INTERVAL-<%= node["chef_client"]["interval"] %>} 31 | SPLAY=${SPLAY-<%= node["chef_client"]["splay"] %>} 32 | <% unless node["chef_client"]["daemon_options"].empty? -%> 33 | OPTIONS=${OPTIONS-<%= node["chef_client"]["daemon_options"] %>} 34 | <% end %> 35 | 36 | # Source LSB init functions 37 | # providing start_daemon, killproc, pidofproc, 38 | # log_success_msg, log_failure_msg and log_warning_msg. 39 | . /lib/lsb/init-functions 40 | 41 | # Shell functions sourced from /etc/rc.status: 42 | # rc_check check and set local and overall rc status 43 | # rc_status check and set local and overall rc status 44 | # rc_status -v be verbose in local rc status and clear it afterwards 45 | # rc_status -v -r ditto and clear both the local and overall rc status 46 | # rc_status -s display "skipped" and exit with status 3 47 | # rc_status -u display "unused" and exit with status 3 48 | # rc_failed set local and overall rc status to failed 49 | # rc_failed set local and overall rc status to 50 | # rc_reset clear both the local and overall rc status 51 | # rc_exit exit appropriate to overall rc status 52 | # rc_active checks whether a service is activated by symlinks 53 | . /etc/rc.status 54 | 55 | # Reset status of this service 56 | rc_reset 57 | 58 | # Return values acc. to LSB for all commands but status: 59 | # 0 - success 60 | # 1 - generic or unspecified error 61 | # 2 - invalid or excess argument(s) 62 | # 3 - unimplemented feature (e.g. "reload") 63 | # 4 - user had insufficient privileges 64 | # 5 - program is not installed 65 | # 6 - program is not configured 66 | # 7 - program is not running 67 | # 8--199 - reserved (8--99 LSB, 100--149 distrib, 150--199 appl) 68 | # 69 | # Note that starting an already running service, stopping 70 | # or restarting a not-running service as well as the restart 71 | # with force-reload (in case signaling is not supported) are 72 | # considered a success. 73 | 74 | case "$1" in 75 | start) 76 | echo -n "Starting chef-client " 77 | ## Start daemon with startproc(8). If this fails 78 | ## the return value is set appropriately by startproc. 79 | /sbin/startproc -p $PIDFILE $CHEF_CLIENT -d -c "$CONFIG" -P "$PIDFILE" -i "$INTERVAL" -s "$SPLAY" <% unless node["chef_client"]["daemon_options"].empty? %>"$OPTIONS"<% end %> 80 | 81 | # Remember status and be verbose 82 | rc_status -v 83 | ;; 84 | stop) 85 | echo -n "Shutting down chef-client " 86 | ## Stop daemon with killproc(8) and if this fails 87 | ## killproc sets the return value according to LSB. 88 | 89 | /sbin/killproc -p $PIDFILE -TERM $CHEF_CLIENT 90 | 91 | # Remember status and be verbose 92 | rc_status -v 93 | ;; 94 | try-restart|condrestart) 95 | ## Do a restart only if the service was active before. 96 | ## Note: try-restart is now part of LSB (as of 1.9). 97 | ## RH has a similar command named condrestart. 98 | if test "$1" = "condrestart"; then 99 | echo "${attn} Use try-restart ${done}(LSB)${attn} rather than condrestart ${warn}(RH)${norm}" 100 | fi 101 | $0 status 102 | if test $? = 0; then 103 | $0 restart 104 | else 105 | rc_reset # Not running is not a failure. 106 | fi 107 | # Remember status and be quiet 108 | rc_status 109 | ;; 110 | force-reload|reload|restart) 111 | ## Stop the service and regardless of whether it was 112 | ## running or not, start it again. 113 | $0 stop 114 | $0 start 115 | 116 | # Remember status and be quiet 117 | rc_status 118 | ;; 119 | status) 120 | echo -n "Checking for service chef-client " 121 | ## Check status with checkproc(8), if process is running 122 | ## checkproc will return with exit status 0. 123 | 124 | # Return value is slightly different for the status command: 125 | # 0 - service up and running 126 | # 1 - service dead, but /var/run/ pid file exists 127 | # 2 - service dead, but /var/lock/ lock file exists 128 | # 3 - service not running (unused) 129 | # 4 - service status unknown :-( 130 | # 5--199 reserved (5--99 LSB, 100--149 distro, 150--199 appl.) 131 | 132 | # NOTE: checkproc returns LSB compliant status values. 133 | /sbin/checkproc -p $PIDFILE $CHEF_CLIENT 134 | # NOTE: rc_status knows that we called this init script with 135 | # "status" option and adapts its messages accordingly. 136 | rc_status -v 137 | ;; 138 | *) 139 | echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload}" 140 | exit 1 141 | ;; 142 | esac 143 | rc_exit 144 | 145 | -------------------------------------------------------------------------------- /templates/default/suse/sysconfig/chef-client.erb: -------------------------------------------------------------------------------- 1 | # Configuration file for the chef-client service 2 | 3 | CONFIG=<%= node["chef_client"]["conf_dir"] %>/client.rb 4 | PIDFILE=<%= node["chef_client"]["run_path"] %>/client.pid 5 | #LOCKFILE=/var/lock/subsys/chef-client 6 | # Sleep interval between runs. 7 | # This value is in seconds. 8 | INTERVAL=<%= node["chef_client"]["interval"] %> 9 | # Maximum amount of random delay before starting a run. Prevents every client 10 | # from contacting the server at the exact same time. 11 | # This value is in seconds. 12 | SPLAY=<%= node["chef_client"]["splay"] %> 13 | # Any additional chef-client options. 14 | OPTIONS="<%= node["chef_client"]["daemon_options"].join(' ') %>" 15 | <% if node["chef_client"]["ca_cert_path"] %> 16 | SSL_CERT_FILE="<%= node["chef_client"]["ca_cert_path"] %>" 17 | export SSL_CERT_FILE 18 | <% end %> 19 | -------------------------------------------------------------------------------- /templates/default/windows/client.service.rb.erb: -------------------------------------------------------------------------------- 1 | if File.exist?(%q|<%= node["chef_client"]["conf_dir"] %>/client.rb|) 2 | Chef::Config.from_file(%q|<%= node["chef_client"]["conf_dir"] %>/client.rb|) 3 | end 4 | 5 | log_location "<%= File.join(node['chef_client']['log_dir'], node['chef_client']['log_file']) %>" 6 | 7 | <% unless node["chef_client"]["interval"].nil? -%> 8 | interval <%= node["chef_client"]["interval"] %> 9 | <% end -%> 10 | 11 | <% unless node["chef_client"]["splay"].nil? -%> 12 | splay <%= node["chef_client"]["splay"] %> 13 | <% end -%> 14 | -------------------------------------------------------------------------------- /test/cookbooks/test/metadata.rb: -------------------------------------------------------------------------------- 1 | name 'test' 2 | license 'Apache-2.0' 3 | version '0.1.0' 4 | depends 'chef-client' 5 | -------------------------------------------------------------------------------- /test/cookbooks/test/recipes/config.rb: -------------------------------------------------------------------------------- 1 | node.override['ohai']['disabled_plugins'] = ['Mdadm'] 2 | node.override['ohai']['optional_plugins'] = ['Passwd'] 3 | node.override['ohai']['plugin_path'] = '/tmp/kitchen/ohai/plugins' 4 | node.override['chef_client']['chef_license'] = 'accept-no-persist' 5 | node.override['chef_client']['cron']['environment_variables'] = { 'FOO' => 'bar' } 6 | include_recipe 'chef-client::config' 7 | 8 | chef_client_trusted_certificate 'self-signed.badssl.com' do 9 | certificate <<~CERT 10 | -----BEGIN CERTIFICATE----- 11 | MIIDeTCCAmGgAwIBAgIJAPziuikCTox4MA0GCSqGSIb3DQEBCwUAMGIxCzAJBgNV 12 | BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNp 13 | c2NvMQ8wDQYDVQQKDAZCYWRTU0wxFTATBgNVBAMMDCouYmFkc3NsLmNvbTAeFw0x 14 | OTEwMDkyMzQxNTJaFw0yMTEwMDgyMzQxNTJaMGIxCzAJBgNVBAYTAlVTMRMwEQYD 15 | VQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMQ8wDQYDVQQK 16 | DAZCYWRTU0wxFTATBgNVBAMMDCouYmFkc3NsLmNvbTCCASIwDQYJKoZIhvcNAQEB 17 | BQADggEPADCCAQoCggEBAMIE7PiM7gTCs9hQ1XBYzJMY61yoaEmwIrX5lZ6xKyx2 18 | PmzAS2BMTOqytMAPgLaw+XLJhgL5XEFdEyt/ccRLvOmULlA3pmccYYz2QULFRtMW 19 | hyefdOsKnRFSJiFzbIRMeVXk0WvoBj1IFVKtsyjbqv9u/2CVSndrOfEk0TG23U3A 20 | xPxTuW1CrbV8/q71FdIzSOciccfCFHpsKOo3St/qbLVytH5aohbcabFXRNsKEqve 21 | ww9HdFxBIuGa+RuT5q0iBikusbpJHAwnnqP7i/dAcgCskgjZjFeEU4EFy+b+a1SY 22 | QCeFxxC7c3DvaRhBB0VVfPlkPz0sw6l865MaTIbRyoUCAwEAAaMyMDAwCQYDVR0T 23 | BAIwADAjBgNVHREEHDAaggwqLmJhZHNzbC5jb22CCmJhZHNzbC5jb20wDQYJKoZI 24 | hvcNAQELBQADggEBAGlwCdbPxflZfYOaukZGCaxYK6gpincX4Lla4Ui2WdeQxE95 25 | w7fChXvP3YkE3UYUE7mupZ0eg4ZILr/A0e7JQDsgIu/SRTUE0domCKgPZ8v99k3A 26 | vka4LpLK51jHJJK7EFgo3ca2nldd97GM0MU41xHFk8qaK1tWJkfrrfcGwDJ4GQPI 27 | iLlm6i0yHq1Qg1RypAXJy5dTlRXlCLd8ufWhhiwW0W75Va5AEnJuqpQrKwl3KQVe 28 | wGj67WWRgLfSr+4QG1mNvCZb2CkjZWmxkGPuoP40/y7Yu5OFqxP5tAjj4YixCYTW 29 | EVA0pmzIzgBg+JIe3PdRy27T0asgQW/F4TY61Yk= 30 | -----END CERTIFICATE----- 31 | CERT 32 | end 33 | 34 | # see if we can fetch from our new trusted domain 35 | remote_file ::File.join(Chef::Config[:file_cache_path], 'index.html') do 36 | source 'https://self-signed.badssl.com/index.html' 37 | end 38 | 39 | chef_client_trusted_certificate 'nothing' do 40 | action :remove 41 | end 42 | -------------------------------------------------------------------------------- /test/cookbooks/test/recipes/cron.rb: -------------------------------------------------------------------------------- 1 | apt_update 'update' 2 | include_recipe 'test::config' 3 | include_recipe 'cron::default' 4 | package 'crontabs' if platform?('fedora') # ensures we actually have the /etc/cron.d dir 5 | include_recipe 'chef-client::cron' 6 | include_recipe 'chef-client::delete_validation' 7 | -------------------------------------------------------------------------------- /test/cookbooks/test/recipes/cron_resource.rb: -------------------------------------------------------------------------------- 1 | chef_client_cron 'schedule chef-client to run as cron job' do 2 | daemon_options ['--run-lock-timeout 0'] 3 | end 4 | -------------------------------------------------------------------------------- /test/cookbooks/test/recipes/license.rb: -------------------------------------------------------------------------------- 1 | node.override['chef_client']['chef_license'] = 'accept-no-persist' 2 | include_recipe 'chef-client::config' 3 | -------------------------------------------------------------------------------- /test/cookbooks/test/recipes/service.rb: -------------------------------------------------------------------------------- 1 | include_recipe 'test::config' 2 | include_recipe 'chef-client::service' 3 | include_recipe 'chef-client::delete_validation' 4 | -------------------------------------------------------------------------------- /test/cookbooks/test/recipes/systemd_timer_resource.rb: -------------------------------------------------------------------------------- 1 | chef_client_systemd_timer 'schedule chef-client to run as cron job' do 2 | accept_chef_license true 3 | daemon_options ['--run-lock-timeout 0'] 4 | environment 'FOO' => '1', 'BAR' => '2' 5 | end 6 | 7 | chef_client_systemd_timer 'a timer that does not exist' do 8 | action :remove 9 | end 10 | -------------------------------------------------------------------------------- /test/cookbooks/test/recipes/task.rb: -------------------------------------------------------------------------------- 1 | node.override['chef_client']['interval'] = 900 2 | node.override['chef_client']['task']['frequency_modifier'] = '31' # this is a string to test that "typo" 3 | node.override['chef_client']['task']['start_date'] = Time.now.strftime('%m/%d/%Y') 4 | 5 | include_recipe 'test::config' 6 | include_recipe 'chef-client::task' 7 | include_recipe 'chef-client::delete_validation' 8 | 9 | chef_client_scheduled_task 'Chef Client on start' do 10 | user node['chef_client']['task']['user'] 11 | password node['chef_client']['task']['password'] 12 | frequency 'onstart' 13 | config_directory node['chef_client']['conf_dir'] 14 | log_directory node['chef_client']['log_dir'] 15 | log_file_name node['chef_client']['log_file'] 16 | chef_binary_path node['chef_client']['bin'] 17 | daemon_options node['chef_client']['daemon_options'] 18 | task_name "#{node['chef_client']['task']['name']}-onstart" 19 | end 20 | -------------------------------------------------------------------------------- /test/integration/config/client_rb_spec.rb: -------------------------------------------------------------------------------- 1 | config = if os.windows? 2 | 'C:\chef\client.rb' 3 | else 4 | '/etc/chef/client.rb' 5 | end 6 | 7 | path = if os.windows? 8 | 'C:\opscode\chef\embedded\bin\ohai.bat' 9 | else 10 | '/opt/chef/embedded/bin/ohai' 11 | end 12 | 13 | describe command("#{path} virtualization -c #{config}") do 14 | its(:exit_status) { should eq(0) } 15 | end 16 | 17 | describe file(config) do 18 | its('content') { should match(/ohai.disabled_plugins = \["Mdadm"\]/) } 19 | its('content') { should match(/ohai.optional_plugins = \["Passwd"\]/) } 20 | its('content') { should match(%r{ohai.plugin_path << "/tmp/kitchen/ohai/plugins"}) } 21 | its('content') { should match(/chef_license "accept-no-persist"/) } 22 | end 23 | -------------------------------------------------------------------------------- /test/integration/cron/cron_spec.rb: -------------------------------------------------------------------------------- 1 | if os.linux? 2 | describe file('/etc/cron.d/chef-client') do 3 | its('content') { should match(/chef-client/) } 4 | its('content') { should match(/^FOO=bar$/) } 5 | its('content') { should match(%r{> /dev/null}) } 6 | end 7 | else 8 | describe command('crontab -u root -l') do 9 | its(:stdout) { should match(/chef-client/) } 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /test/integration/cron_resource/cron_spec.rb: -------------------------------------------------------------------------------- 1 | describe file('/etc/cron.d/chef-client') do 2 | its('content') { should match(/chef-client/) } 3 | its('content') { should match(/--run-lock-timeout 0/) } 4 | end 5 | -------------------------------------------------------------------------------- /test/integration/license/client_rb_spec.rb: -------------------------------------------------------------------------------- 1 | config = if os.windows? 2 | 'C:\chef\client.rb' 3 | else 4 | '/etc/chef/client.rb' 5 | end 6 | 7 | describe file(config) do 8 | its('content') { should match(/chef_license "accept-no-persist"/) } 9 | end 10 | -------------------------------------------------------------------------------- /test/integration/service_bsd/service_bsd_spec.rb: -------------------------------------------------------------------------------- 1 | describe processes('chef-client') do 2 | it { should exist } 3 | end 4 | 5 | describe service('chef-client') do 6 | it { should be_enabled } 7 | it { should be_installed } 8 | it { should be_running } 9 | end 10 | -------------------------------------------------------------------------------- /test/integration/service_init/service_init_spec.rb: -------------------------------------------------------------------------------- 1 | describe processes('chef-client') do 2 | it { should exist } 3 | end 4 | 5 | describe service('chef-client') do 6 | it { should be_enabled } 7 | it { should be_installed } 8 | it { should be_running } 9 | end 10 | -------------------------------------------------------------------------------- /test/integration/service_systemd/service_init_spec.rb: -------------------------------------------------------------------------------- 1 | describe processes('chef-client') do 2 | it { should exist } 3 | end 4 | 5 | describe service('chef-client') do 6 | it { should be_enabled } 7 | it { should be_installed } 8 | it { should be_running } 9 | end 10 | -------------------------------------------------------------------------------- /test/integration/task/task_spec.rb: -------------------------------------------------------------------------------- 1 | describe command('C:/opscode/chef/embedded/bin/ohai virtualization -c C:/chef/client.rb') do 2 | its('exit_status') { should eq 0 } 3 | end 4 | 5 | describe file('C:/chef/client.rb') do 6 | its('content') { should match(/ohai.disabled_plugins = \["Mdadm"\]/) } 7 | its('content') { should match(/ohai.optional_plugins = \["Passwd"\]/) } 8 | its('content') { should match(%r{ohai.plugin_path << "/tmp/kitchen/ohai/plugins"}) } 9 | end 10 | 11 | # the inspec resource requires PS 3.0+ and 2k8r2 only has PS 2.0 by default 12 | unless os.release.to_f == 6.1 13 | describe windows_task('chef-client') do 14 | it { should be_enabled } 15 | its('run_as_user') { should eq 'SYSTEM' } 16 | its('task_to_run') { should match 'cmd.exe /c C:/opscode/chef/bin/chef-client -L C:/chef/log/client.log -c C:/chef/client.rb -s 300' } 17 | end 18 | 19 | describe windows_task('chef-client-onstart') do 20 | it { should be_enabled } 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /test/integration/timer_systemd/timer_systemd_spec.rb: -------------------------------------------------------------------------------- 1 | control 'timer is active' do 2 | describe systemd_service('chef-client.timer') do 3 | it { should be_enabled } 4 | it { should be_running } 5 | end 6 | end 7 | 8 | control 'has expected unit content' do 9 | describe file('/etc/systemd/system/chef-client.timer') do 10 | its('content') { should match 'OnBootSec = 1min' } 11 | its('content') { should match 'OnUnitInactiveSec = 1800sec' } 12 | its('content') { should match 'RandomizedDelaySec = 300sec' } 13 | end 14 | end 15 | 16 | control 'timer targets service unit' do 17 | describe command('systemctl show -p Triggers chef-client.timer') do 18 | its('stdout') { should match 'Triggers=chef-client.service' } 19 | end 20 | end 21 | 22 | control 'schedules trigger on-boot' do 23 | describe command('systemctl show -p NextElapseUSecMonotonic chef-client.timer') do 24 | before { sleep 5 } 25 | its('stdout') { should_not match 'NextElapseUSecMonotonic=infinity' } 26 | end 27 | end 28 | --------------------------------------------------------------------------------