├── .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 | [](https://travis-ci.org/chef-cookbooks/chef-client) [](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 |
99 |
100 |
101 | chef-client Chef Client
102 |
103 |
104 |
105 |
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 |
99 |
100 |
101 | chef-client Chef Client
102 |
103 |
104 |
105 |
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 |
--------------------------------------------------------------------------------