chef 16.1.16 → 16.2.44
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +2 -3
- data/README.md +3 -3
- data/Rakefile +2 -2
- data/chef.gemspec +3 -3
- data/lib/chef/application/apply.rb +1 -1
- data/lib/chef/application/base.rb +1 -1
- data/lib/chef/application/client.rb +1 -1
- data/lib/chef/application/windows_service_manager.rb +1 -1
- data/lib/chef/chef_fs/data_handler/data_bag_item_data_handler.rb +1 -1
- data/lib/chef/chef_fs/path_utils.rb +1 -1
- data/lib/chef/cookbook/chefignore.rb +1 -1
- data/lib/chef/cookbook/metadata.rb +1 -1
- data/lib/chef/cookbook_version.rb +2 -2
- data/lib/chef/data_bag.rb +4 -4
- data/lib/chef/deprecated.rb +4 -0
- data/lib/chef/file_access_control.rb +1 -1
- data/lib/chef/formatters/error_inspectors/compile_error_inspector.rb +1 -1
- data/lib/chef/formatters/error_inspectors/resource_failure_inspector.rb +3 -3
- data/lib/chef/http.rb +17 -2
- data/lib/chef/http/http_request.rb +1 -1
- data/lib/chef/http/json_output.rb +1 -1
- data/lib/chef/http/ssl_policies.rb +18 -0
- data/lib/chef/knife.rb +1 -1
- data/lib/chef/knife/bootstrap.rb +3 -6
- data/lib/chef/knife/bootstrap/templates/chef-full.erb +9 -9
- data/lib/chef/knife/client_bulk_delete.rb +1 -1
- data/lib/chef/knife/config_get.rb +1 -1
- data/lib/chef/knife/cookbook_delete.rb +1 -1
- data/lib/chef/knife/core/cookbook_scm_repo.rb +1 -1
- data/lib/chef/knife/data_bag_create.rb +1 -1
- data/lib/chef/knife/node_bulk_delete.rb +1 -1
- data/lib/chef/knife/node_run_list_remove.rb +1 -1
- data/lib/chef/knife/role_bulk_delete.rb +1 -1
- data/lib/chef/knife/ssh.rb +1 -1
- data/lib/chef/knife/supermarket_share.rb +1 -1
- data/lib/chef/knife/supermarket_unshare.rb +1 -1
- data/lib/chef/log.rb +1 -1
- data/lib/chef/mixin/securable.rb +2 -2
- data/lib/chef/powershell.rb +1 -1
- data/lib/chef/provider/batch.rb +3 -10
- data/lib/chef/provider/cron.rb +2 -14
- data/lib/chef/provider/execute.rb +2 -1
- data/lib/chef/provider/group/dscl.rb +2 -2
- data/lib/chef/provider/group/windows.rb +1 -1
- data/lib/chef/provider/ifconfig.rb +7 -7
- data/lib/chef/provider/mount/aix.rb +1 -1
- data/lib/chef/provider/mount/windows.rb +2 -2
- data/lib/chef/provider/noop.rb +1 -1
- data/lib/chef/provider/package/openbsd.rb +1 -1
- data/lib/chef/provider/package/portage.rb +2 -2
- data/lib/chef/provider/package/powershell.rb +6 -2
- data/lib/chef/provider/package/rubygems.rb +2 -2
- data/lib/chef/provider/package/snap.rb +96 -27
- data/lib/chef/provider/package/windows/msi.rb +3 -3
- data/lib/chef/provider/package/windows/registry_uninstall_entry.rb +1 -1
- data/lib/chef/provider/powershell_script.rb +10 -14
- data/lib/chef/provider/remote_file/http.rb +4 -1
- data/lib/chef/provider/script.rb +4 -75
- data/lib/chef/provider/service/arch.rb +1 -1
- data/lib/chef/provider/service/debian.rb +2 -2
- data/lib/chef/provider/service/openbsd.rb +4 -4
- data/lib/chef/provider/service/redhat.rb +1 -1
- data/lib/chef/provider/service/windows.rb +1 -1
- data/lib/chef/provider/subversion.rb +2 -2
- data/lib/chef/provider/user/dscl.rb +4 -4
- data/lib/chef/provider/user/linux.rb +3 -3
- data/lib/chef/provider/user/mac.rb +5 -5
- data/lib/chef/provider/windows_script.rb +87 -25
- data/lib/chef/provider/zypper_repository.rb +30 -10
- data/lib/chef/resource.rb +22 -11
- data/lib/chef/resource/apt_package.rb +1 -1
- data/lib/chef/resource/archive_file.rb +28 -8
- data/lib/chef/resource/bash.rb +0 -1
- data/lib/chef/resource/batch.rb +4 -2
- data/lib/chef/resource/chef_client_scheduled_task.rb +13 -1
- data/lib/chef/resource/cron/_cron_shared.rb +98 -0
- data/lib/chef/resource/cron/cron.rb +46 -0
- data/lib/chef/resource/{cron_d.rb → cron/cron_d.rb} +7 -87
- data/lib/chef/resource/cron_access.rb +11 -3
- data/lib/chef/resource/csh.rb +0 -1
- data/lib/chef/resource/execute.rb +477 -7
- data/lib/chef/resource/file.rb +1 -1
- data/lib/chef/resource/freebsd_package.rb +1 -1
- data/lib/chef/resource/helpers/cron_validations.rb +6 -3
- data/lib/chef/resource/homebrew_package.rb +30 -1
- data/lib/chef/resource/homebrew_update.rb +107 -0
- data/lib/chef/resource/hostname.rb +6 -19
- data/lib/chef/resource/kernel_module.rb +14 -1
- data/lib/chef/resource/mount.rb +1 -1
- data/lib/chef/resource/perl.rb +0 -1
- data/lib/chef/resource/plist.rb +23 -4
- data/lib/chef/resource/powershell_script.rb +4 -2
- data/lib/chef/resource/python.rb +0 -1
- data/lib/chef/resource/remote_file.rb +26 -10
- data/lib/chef/resource/ruby.rb +0 -1
- data/lib/chef/resource/template.rb +1 -1
- data/lib/chef/resource/windows_ad_join.rb +30 -1
- data/lib/chef/resource/windows_audit_policy.rb +227 -0
- data/lib/chef/resource/windows_auto_run.rb +11 -0
- data/lib/chef/resource/windows_certificate.rb +26 -0
- data/lib/chef/resource/windows_font.rb +3 -3
- data/lib/chef/resource/windows_package.rb +1 -1
- data/lib/chef/resource/windows_pagefile.rb +1 -1
- data/lib/chef/resource/windows_script.rb +2 -16
- data/lib/chef/resource/windows_security_policy.rb +17 -15
- data/lib/chef/resource/windows_shortcut.rb +1 -2
- data/lib/chef/resource/windows_task.rb +4 -4
- data/lib/chef/resource/windows_user_privilege.rb +5 -5
- data/lib/chef/resource/yum_repository.rb +9 -9
- data/lib/chef/resources.rb +4 -2
- data/lib/chef/search/query.rb +1 -1
- data/lib/chef/util/diff.rb +2 -2
- data/lib/chef/util/windows/net_user.rb +1 -1
- data/lib/chef/util/windows/volume.rb +1 -1
- data/lib/chef/version.rb +1 -1
- data/lib/chef/win32/file.rb +1 -1
- data/lib/chef/win32/registry.rb +2 -2
- data/lib/chef/win32/security.rb +1 -1
- data/spec/data/lwrp/providers/buck_passer.rb +1 -1
- data/spec/data/lwrp/providers/buck_passer_2.rb +1 -1
- data/spec/data/lwrp/providers/embedded_resource_accesses_providers_scope.rb +1 -1
- data/spec/functional/resource/cron_spec.rb +10 -0
- data/spec/functional/resource/remote_file_spec.rb +2 -2
- data/spec/functional/resource/windows_task_spec.rb +8 -8
- data/spec/support/platform_helpers.rb +1 -1
- data/spec/support/platforms/win32/spec_service.rb +1 -1
- data/spec/support/shared/functional/execute_resource.rb +1 -1
- data/spec/support/shared/unit/execute_resource.rb +1 -1
- data/spec/unit/application_spec.rb +7 -0
- data/spec/unit/data_bag_spec.rb +1 -1
- data/spec/unit/http/ssl_policies_spec.rb +20 -0
- data/spec/unit/knife/bootstrap_spec.rb +2 -2
- data/spec/unit/mixin/user_context_spec.rb +1 -9
- data/spec/unit/property_spec.rb +1 -1
- data/spec/unit/provider/batch_spec.rb +130 -0
- data/spec/unit/provider/cron_spec.rb +9 -49
- data/spec/unit/provider/package/powershell_spec.rb +95 -86
- data/spec/unit/provider/package/snap_spec.rb +1 -1
- data/spec/unit/provider/powershell_script_spec.rb +3 -45
- data/spec/unit/provider/script_spec.rb +20 -110
- data/spec/unit/provider/zypper_repository_spec.rb +60 -10
- data/spec/unit/resource/archive_file_spec.rb +11 -2
- data/spec/unit/resource/chef_client_scheduled_task_spec.rb +17 -7
- data/spec/unit/resource/cron_spec.rb +2 -2
- data/spec/unit/resource/helpers/cron_validations_spec.rb +5 -1
- data/spec/unit/resource/homebrew_update_spec.rb +30 -0
- data/spec/unit/resource/powershell_script_spec.rb +10 -15
- data/spec/unit/resource/timezone_spec.rb +1 -1
- data/spec/unit/resource/windows_audit_policy_spec.rb +64 -0
- data/spec/unit/resource/windows_dns_record_spec.rb +3 -3
- data/spec/unit/resource/windows_dns_zone_spec.rb +2 -2
- data/spec/unit/resource/windows_task_spec.rb +1 -1
- data/spec/unit/resource/windows_uac_spec.rb +2 -2
- data/spec/unit/resource/yum_repository_spec.rb +21 -21
- data/spec/unit/resource_spec.rb +67 -1
- data/spec/unit/util/dsc/configuration_generator_spec.rb +1 -1
- data/spec/unit/util/threaded_job_queue_spec.rb +9 -0
- metadata +22 -22
- data/lib/chef/resource/cron.rb +0 -157
@@ -115,28 +115,48 @@ class Chef
|
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
118
|
+
# the version of gpg installed on the system
|
119
|
+
#
|
120
|
+
# @return [Gem::Version] the version of GPG
|
121
|
+
def gpg_version
|
122
|
+
so = shell_out!("gpg --version")
|
123
|
+
# matches 2.0 and 2.2 versions from SLES 12 and 15: https://rubular.com/r/e6D0WfGK6SXvUp
|
124
|
+
version = /gpg \(GnuPG\)\s*(.*)/.match(so.stdout)[1]
|
125
|
+
logger.trace("GPG package version is #{version}")
|
126
|
+
Gem::Version.new(version)
|
127
|
+
end
|
128
|
+
|
118
129
|
# is the provided key already installed
|
119
130
|
# @param [String] key_path the path to the key on the local filesystem
|
120
131
|
#
|
121
132
|
# @return [boolean] is the key already known by rpm
|
122
133
|
def key_installed?(key_path)
|
123
|
-
so = shell_out("rpm -qa gpg-pubkey*")
|
134
|
+
so = shell_out("/bin/rpm -qa gpg-pubkey*")
|
124
135
|
# expected output & match: http://rubular.com/r/RdF7EcXEtb
|
125
|
-
status = /gpg-pubkey-#{
|
136
|
+
status = /gpg-pubkey-#{short_key_id(key_path)}/.match(so.stdout)
|
126
137
|
logger.trace("GPG key at #{key_path} is known by rpm? #{status ? "true" : "false"}")
|
127
138
|
status
|
128
139
|
end
|
129
140
|
|
130
|
-
# extract the gpg key
|
141
|
+
# extract the gpg key's short key id from a local file. Learning moment: This 8 hex value ID
|
142
|
+
# is sometimes incorrectly called the fingerprint. The fingerprint is the full length value
|
143
|
+
# and googling for that will just result in sad times.
|
144
|
+
#
|
131
145
|
# @param [String] key_path the path to the key on the local filesystem
|
132
146
|
#
|
133
|
-
# @return [String] the
|
134
|
-
def
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
147
|
+
# @return [String] the short key id of the key
|
148
|
+
def short_key_id(key_path)
|
149
|
+
if gpg_version >= Gem::Version.new("2.2") # SLES 15+
|
150
|
+
so = shell_out!("gpg --import-options import-show --dry-run --import --with-colons #{key_path}")
|
151
|
+
# expected output and match: https://rubular.com/r/uXWJo3yfkli1qA
|
152
|
+
short_key_id = /fpr:*\h*(\h{8}):/.match(so.stdout)[1].downcase
|
153
|
+
else # SLES 12 and earlier
|
154
|
+
so = shell_out!("gpg --with-fingerprint #{key_path}")
|
155
|
+
# expected output and match: http://rubular.com/r/BpfMjxySQM
|
156
|
+
short_key_id = %r{pub\s*\S*/(\S*)}.match(so.stdout)[1].downcase
|
157
|
+
end
|
158
|
+
logger.trace("GPG short key ID of key at #{key_path} is #{short_key_id}")
|
159
|
+
short_key_id
|
140
160
|
end
|
141
161
|
|
142
162
|
# install the provided gpg key
|
data/lib/chef/resource.rb
CHANGED
@@ -451,6 +451,17 @@ class Chef
|
|
451
451
|
description: "Determines whether or not the resource is executed during the compile time phase.",
|
452
452
|
default: false, desired_state: false
|
453
453
|
|
454
|
+
# Set a umask to be used for the duration of converging the resource.
|
455
|
+
# Defaults to `nil`, which means to use the system umask.
|
456
|
+
#
|
457
|
+
# @param arg [String] The umask to apply while converging the resource.
|
458
|
+
# @return [Boolean] The umask to apply while converging the resource.
|
459
|
+
#
|
460
|
+
property :umask, String,
|
461
|
+
desired_state: false,
|
462
|
+
introduced: "16.2",
|
463
|
+
description: "Set a umask to be used for the duration of converging the resource. Defaults to `nil`, which means to use the system umask."
|
464
|
+
|
454
465
|
# The time it took (in seconds) to run the most recently-run action. Not
|
455
466
|
# cumulative across actions. This is set to 0 as soon as a new action starts
|
456
467
|
# running, and set to the elapsed time at the end of the action.
|
@@ -588,7 +599,9 @@ class Chef
|
|
588
599
|
begin
|
589
600
|
return if should_skip?(action)
|
590
601
|
|
591
|
-
|
602
|
+
with_umask do
|
603
|
+
provider_for_action(action).run_action
|
604
|
+
end
|
592
605
|
rescue StandardError => e
|
593
606
|
if ignore_failure
|
594
607
|
logger.error("#{custom_exception_message(e)}; ignore_failure is set, continuing")
|
@@ -612,6 +625,13 @@ class Chef
|
|
612
625
|
events.resource_completed(self)
|
613
626
|
end
|
614
627
|
|
628
|
+
def with_umask
|
629
|
+
old_value = ::File.umask(umask.oct) if umask
|
630
|
+
yield
|
631
|
+
ensure
|
632
|
+
::File.umask(old_value) if umask
|
633
|
+
end
|
634
|
+
|
615
635
|
#
|
616
636
|
# If we are currently initializing the resource, this will be true.
|
617
637
|
#
|
@@ -950,16 +970,7 @@ class Chef
|
|
950
970
|
def self.resource_name(name = NOT_PASSED)
|
951
971
|
# Setter
|
952
972
|
if name != NOT_PASSED
|
953
|
-
|
954
|
-
@resource_name = name.to_sym
|
955
|
-
name = name.to_sym
|
956
|
-
# FIXME: determine a way to deprecate this magic behavior
|
957
|
-
unless Chef::ResourceResolver.includes_handler?(name, self)
|
958
|
-
provides name
|
959
|
-
end
|
960
|
-
else
|
961
|
-
@resource_name = nil
|
962
|
-
end
|
973
|
+
@resource_name = name.to_sym rescue nil
|
963
974
|
end
|
964
975
|
|
965
976
|
@resource_name = nil unless defined?(@resource_name)
|
@@ -19,6 +19,7 @@
|
|
19
19
|
#
|
20
20
|
|
21
21
|
require_relative "../resource"
|
22
|
+
require "fileutils" unless defined?(FileUtils)
|
22
23
|
|
23
24
|
class Chef
|
24
25
|
class Resource
|
@@ -39,6 +40,18 @@ class Chef
|
|
39
40
|
destination '/srv/files'
|
40
41
|
end
|
41
42
|
```
|
43
|
+
|
44
|
+
**Set specific permissions on the extracted files**:
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
archive_file 'Precompiled.zip' do
|
48
|
+
owner 'tsmith'
|
49
|
+
group 'staff'
|
50
|
+
mode '700'
|
51
|
+
path '/tmp/Precompiled.zip'
|
52
|
+
destination '/srv/files'
|
53
|
+
end
|
54
|
+
```
|
42
55
|
DOC
|
43
56
|
|
44
57
|
property :path, String,
|
@@ -53,7 +66,7 @@ class Chef
|
|
53
66
|
description: "The group of the extracted files."
|
54
67
|
|
55
68
|
property :mode, [String, Integer],
|
56
|
-
description: "The mode of the extracted files.",
|
69
|
+
description: "The mode of the extracted files. Integer values are deprecated as octal values (ex. 0755) would not be interpreted correctly.",
|
57
70
|
default: "755"
|
58
71
|
|
59
72
|
property :destination, String,
|
@@ -72,11 +85,11 @@ class Chef
|
|
72
85
|
alias_method :extract_options, :options
|
73
86
|
alias_method :extract_to, :destination
|
74
87
|
|
75
|
-
require "fileutils" unless defined?(FileUtils)
|
76
|
-
|
77
88
|
action :extract do
|
78
89
|
description "Extract and archive file."
|
79
90
|
|
91
|
+
require_libarchive
|
92
|
+
|
80
93
|
unless ::File.exist?(new_resource.path)
|
81
94
|
raise Errno::ENOENT, "No archive found at #{new_resource.path}! Cannot continue."
|
82
95
|
end
|
@@ -85,7 +98,8 @@ class Chef
|
|
85
98
|
Chef::Log.trace("File or directory does not exist at destination path: #{new_resource.destination}")
|
86
99
|
|
87
100
|
converge_by("create directory #{new_resource.destination}") do
|
88
|
-
|
101
|
+
# @todo when we remove the ability for mode to be an int we can remove the .to_s below
|
102
|
+
FileUtils.mkdir_p(new_resource.destination, mode: new_resource.mode.to_s.to_i(8))
|
89
103
|
end
|
90
104
|
|
91
105
|
extract(new_resource.path, new_resource.destination, Array(new_resource.options))
|
@@ -113,6 +127,16 @@ class Chef
|
|
113
127
|
end
|
114
128
|
|
115
129
|
action_class do
|
130
|
+
def require_libarchive
|
131
|
+
require "ffi-libarchive"
|
132
|
+
end
|
133
|
+
|
134
|
+
def define_resource_requirements
|
135
|
+
if new_resource.mode.is_a?(Integer)
|
136
|
+
Chef.deprecated(:archive_file_integer_file_mode, "The mode property should be passed to archive_file resources as a String and not an Integer to ensure the value is properly interpreted.")
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
116
140
|
# This can't be a constant since we might not have required 'ffi-libarchive' yet.
|
117
141
|
def extract_option_map
|
118
142
|
{
|
@@ -136,8 +160,6 @@ class Chef
|
|
136
160
|
#
|
137
161
|
# @return [Boolean]
|
138
162
|
def archive_differs_from_disk?(src, dest)
|
139
|
-
require "ffi-libarchive"
|
140
|
-
|
141
163
|
modified = false
|
142
164
|
Dir.chdir(dest) do
|
143
165
|
archive = Archive::Reader.open_filename(src)
|
@@ -164,8 +186,6 @@ class Chef
|
|
164
186
|
#
|
165
187
|
# @return [void]
|
166
188
|
def extract(src, dest, options = [])
|
167
|
-
require "ffi-libarchive"
|
168
|
-
|
169
189
|
converge_by("extract #{src} to #{dest}") do
|
170
190
|
flags = [options].flatten.map { |option| extract_option_map[option] }.compact.reduce(:|)
|
171
191
|
|
data/lib/chef/resource/bash.rb
CHANGED
data/lib/chef/resource/batch.rb
CHANGED
@@ -27,8 +27,10 @@ class Chef
|
|
27
27
|
|
28
28
|
description "Use the **batch** resource to execute a batch script using the cmd.exe interpreter on Windows. The batch resource creates and executes a temporary file (similar to how the script resource behaves), rather than running the command inline. Commands that are executed with this resource are (by their nature) not idempotent, as they are typically unique to the environment in which they are run. Use not_if and only_if to guard this resource for idempotence."
|
29
29
|
|
30
|
-
def initialize(
|
31
|
-
super
|
30
|
+
def initialize(*args)
|
31
|
+
super
|
32
|
+
@interpreter = "cmd.exe"
|
33
|
+
@default_guard_interpreter = resource_name
|
32
34
|
end
|
33
35
|
|
34
36
|
end
|
@@ -48,6 +48,16 @@ class Chef
|
|
48
48
|
daemon_options ["--override-runlist mycorp_base::default"]
|
49
49
|
end
|
50
50
|
```
|
51
|
+
|
52
|
+
**Run #{Chef::Dist::PRODUCT} daily at 01:00 am, specifying a named run-list**:
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
chef_client_scheduled_task "Run chef-client named run-list daily" do
|
56
|
+
frequency 'daily'
|
57
|
+
start_time '01:00'
|
58
|
+
daemon_options ['-n audit_only']
|
59
|
+
end
|
60
|
+
```
|
51
61
|
DOC
|
52
62
|
|
53
63
|
resource_name :chef_client_scheduled_task
|
@@ -72,7 +82,8 @@ class Chef
|
|
72
82
|
coerce: proc { |x| Integer(x) },
|
73
83
|
callbacks: { "should be a positive number" => proc { |v| v > 0 } },
|
74
84
|
description: "Numeric value to go with the scheduled task frequency",
|
75
|
-
default: 30
|
85
|
+
default: lazy { frequency == "minute" ? 30 : 1 },
|
86
|
+
default_description: "30 if frequency is 'minute', 1 otherwise"
|
76
87
|
|
77
88
|
property :accept_chef_license, [true, false],
|
78
89
|
description: "Accept the Chef Online Master License and Services Agreement. See <https://www.chef.io/online-master-agreement/>",
|
@@ -129,6 +140,7 @@ class Chef
|
|
129
140
|
|
130
141
|
# According to https://docs.microsoft.com/en-us/windows/desktop/taskschd/schtasks,
|
131
142
|
# the :once, :onstart, :onlogon, and :onidle schedules don't accept schedule modifiers
|
143
|
+
|
132
144
|
windows_task new_resource.task_name do
|
133
145
|
run_level :highest
|
134
146
|
command full_command
|
@@ -0,0 +1,98 @@
|
|
1
|
+
unified_mode true
|
2
|
+
|
3
|
+
TIMEOUT_OPTS = %w{duration preserve-status foreground kill-after signal}.freeze
|
4
|
+
TIMEOUT_REGEX = /\A\S+/.freeze
|
5
|
+
WEEKDAYS = {
|
6
|
+
sunday: "0", monday: "1", tuesday: "2", wednesday: "3", thursday: "4", friday: "5", saturday: "6",
|
7
|
+
sun: "0", mon: "1", tue: "2", wed: "3", thu: "4", fri: "5", sat: "6"
|
8
|
+
}.freeze
|
9
|
+
|
10
|
+
property :minute, [Integer, String],
|
11
|
+
description: "The minute at which the cron entry should run (`0 - 59`).",
|
12
|
+
default: "*", callbacks: {
|
13
|
+
"should be a valid minute spec" => ->(spec) { Chef::ResourceHelpers::CronValidations.validate_numeric(spec, 0, 59) },
|
14
|
+
}
|
15
|
+
|
16
|
+
property :hour, [Integer, String],
|
17
|
+
description: "The hour at which the cron entry is to run (`0 - 23`).",
|
18
|
+
default: "*", callbacks: {
|
19
|
+
"should be a valid hour spec" => ->(spec) { Chef::ResourceHelpers::CronValidations.validate_numeric(spec, 0, 23) },
|
20
|
+
}
|
21
|
+
|
22
|
+
property :day, [Integer, String],
|
23
|
+
description: "The day of month at which the cron entry should run (`1 - 31`).",
|
24
|
+
default: "*", callbacks: {
|
25
|
+
"should be a valid day spec" => ->(spec) { Chef::ResourceHelpers::CronValidations.validate_numeric(spec, 1, 31) },
|
26
|
+
}
|
27
|
+
|
28
|
+
property :month, [Integer, String],
|
29
|
+
description: "The month in the year on which a cron entry is to run (`1 - 12`, `jan-dec`, or `*`).",
|
30
|
+
default: "*", callbacks: {
|
31
|
+
"should be a valid month spec" => ->(spec) { Chef::ResourceHelpers::CronValidations.validate_month(spec) },
|
32
|
+
}
|
33
|
+
|
34
|
+
property :weekday, [Integer, String, Symbol],
|
35
|
+
description: "The day of the week on which this entry is to run (`0-7`, `mon-sun`, `monday-sunday`, or `*`), where Sunday is both `0` and `7`.",
|
36
|
+
default: "*", coerce: proc { |day| weekday_in_crontab(day) },
|
37
|
+
callbacks: {
|
38
|
+
"should be a valid weekday spec" => ->(spec) { Chef::ResourceHelpers::CronValidations.validate_dow(spec) },
|
39
|
+
}
|
40
|
+
|
41
|
+
property :shell, String,
|
42
|
+
description: "Set the `SHELL` environment variable."
|
43
|
+
|
44
|
+
property :path, String,
|
45
|
+
description: "Set the `PATH` environment variable."
|
46
|
+
|
47
|
+
property :home, String,
|
48
|
+
description: "Set the `HOME` environment variable."
|
49
|
+
|
50
|
+
property :mailto, String,
|
51
|
+
description: "Set the `MAILTO` environment variable."
|
52
|
+
|
53
|
+
property :command, String,
|
54
|
+
description: "The command to be run, or the path to a file that contains the command to be run.",
|
55
|
+
identity: true,
|
56
|
+
required: [:create]
|
57
|
+
|
58
|
+
property :user, String,
|
59
|
+
description: "The name of the user that runs the command.",
|
60
|
+
default: "root"
|
61
|
+
|
62
|
+
property :environment, Hash,
|
63
|
+
description: "A Hash containing additional arbitrary environment variables under which the cron job will be run in the form of `({'ENV_VARIABLE' => 'VALUE'})`. **Note**: These variables must exist for a command to be run successfully.",
|
64
|
+
default: lazy { {} }
|
65
|
+
|
66
|
+
property :time_out, Hash,
|
67
|
+
description: "A Hash of timeouts in the form of `({'OPTION' => 'VALUE'})`. Accepted valid options are:
|
68
|
+
- `preserve-status` (BOOL, default: 'false'),
|
69
|
+
- `foreground` (BOOL, default: 'false'),
|
70
|
+
- `kill-after` (in seconds),
|
71
|
+
- `signal` (a name like 'HUP' or a number)",
|
72
|
+
default: lazy { {} },
|
73
|
+
introduced: "15.7",
|
74
|
+
coerce: proc { |h|
|
75
|
+
if h.is_a?(Hash)
|
76
|
+
invalid_keys = h.keys - TIMEOUT_OPTS
|
77
|
+
unless invalid_keys.empty?
|
78
|
+
error_msg = "Key of option time_out must be equal to one of: \"#{TIMEOUT_OPTS.join('", "')}\"! You passed \"#{invalid_keys.join(", ")}\"."
|
79
|
+
raise Chef::Exceptions::ValidationFailed, error_msg
|
80
|
+
end
|
81
|
+
unless h.values.all? { |x| x =~ TIMEOUT_REGEX }
|
82
|
+
error_msg = "Values of option time_out should be non-empty strings without any leading whitespace."
|
83
|
+
raise Chef::Exceptions::ValidationFailed, error_msg
|
84
|
+
end
|
85
|
+
h
|
86
|
+
elsif h.is_a?(Integer) || h.is_a?(String)
|
87
|
+
{ "duration" => h }
|
88
|
+
end
|
89
|
+
}
|
90
|
+
|
91
|
+
private
|
92
|
+
# Convert weekday input value into crontab format that
|
93
|
+
# could be written in the crontab
|
94
|
+
# @return [Integer, String] A weekday formed as per the user inputs.
|
95
|
+
def weekday_in_crontab(day)
|
96
|
+
weekday = day.to_s.downcase.to_sym
|
97
|
+
WEEKDAYS[weekday] || day
|
98
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Bryan McLellan (btm@loftninjas.org)
|
3
|
+
# Author:: Tyler Cloke (<tyler@chef.io>)
|
4
|
+
# Copyright:: Copyright 2009-2016, Bryan McLellan
|
5
|
+
# License:: Apache License, Version 2.0
|
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
|
+
require_relative "../../resource"
|
21
|
+
require_relative "../helpers/cron_validations"
|
22
|
+
require_relative "../../provider/cron" # do not remove. we actually need this below
|
23
|
+
|
24
|
+
class Chef
|
25
|
+
class Resource
|
26
|
+
class Cron < Chef::Resource
|
27
|
+
unified_mode true
|
28
|
+
|
29
|
+
use "cron_shared"
|
30
|
+
|
31
|
+
provides :cron
|
32
|
+
|
33
|
+
description "Use the **cron** resource to manage cron entries for time-based job scheduling. Properties for a schedule will default to * if not provided. The cron resource requires access to a crontab program, typically cron."
|
34
|
+
|
35
|
+
state_attrs :minute, :hour, :day, :month, :weekday, :user
|
36
|
+
|
37
|
+
default_action :create
|
38
|
+
allowed_actions :create, :delete
|
39
|
+
|
40
|
+
property :time, Symbol,
|
41
|
+
description: "A time interval.",
|
42
|
+
equal_to: Chef::Provider::Cron::SPECIAL_TIME_VALUES
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -15,15 +15,18 @@
|
|
15
15
|
# limitations under the License.
|
16
16
|
#
|
17
17
|
|
18
|
-
require_relative "
|
19
|
-
require_relative "helpers/cron_validations"
|
18
|
+
require_relative "../../resource"
|
19
|
+
require_relative "../helpers/cron_validations"
|
20
20
|
require "shellwords" unless defined?(Shellwords)
|
21
|
-
require_relative "
|
21
|
+
require_relative "../../dist"
|
22
22
|
|
23
23
|
class Chef
|
24
24
|
class Resource
|
25
25
|
class CronD < Chef::Resource
|
26
26
|
unified_mode true
|
27
|
+
|
28
|
+
use "cron_shared"
|
29
|
+
|
27
30
|
provides :cron_d
|
28
31
|
|
29
32
|
introduced "14.4"
|
@@ -98,92 +101,9 @@ class Chef
|
|
98
101
|
description: "Schedule your cron job with one of the special predefined value instead of ** * pattern.",
|
99
102
|
equal_to: %w{ @reboot @yearly @annually @monthly @weekly @daily @midnight @hourly }
|
100
103
|
|
101
|
-
property :minute, [Integer, String],
|
102
|
-
description: "The minute at which the cron entry should run (`0 - 59`).",
|
103
|
-
default: "*", callbacks: {
|
104
|
-
"should be a valid minute spec" => ->(spec) { Chef::ResourceHelpers::CronValidations.validate_numeric(spec, 0, 59) },
|
105
|
-
}
|
106
|
-
|
107
|
-
property :hour, [Integer, String],
|
108
|
-
description: "The hour at which the cron entry is to run (`0 - 23`).",
|
109
|
-
default: "*", callbacks: {
|
110
|
-
"should be a valid hour spec" => ->(spec) { Chef::ResourceHelpers::CronValidations.validate_numeric(spec, 0, 23) },
|
111
|
-
}
|
112
|
-
|
113
|
-
property :day, [Integer, String],
|
114
|
-
description: "The day of month at which the cron entry should run (`1 - 31`).",
|
115
|
-
default: "*", callbacks: {
|
116
|
-
"should be a valid day spec" => ->(spec) { Chef::ResourceHelpers::CronValidations.validate_numeric(spec, 1, 31) },
|
117
|
-
}
|
118
|
-
|
119
|
-
property :month, [Integer, String],
|
120
|
-
description: "The month in the year on which a cron entry is to run (`1 - 12`, `jan-dec`, or `*`).",
|
121
|
-
default: "*", callbacks: {
|
122
|
-
"should be a valid month spec" => ->(spec) { Chef::ResourceHelpers::CronValidations.validate_month(spec) },
|
123
|
-
}
|
124
|
-
|
125
|
-
property :weekday, [Integer, String],
|
126
|
-
description: "The day of the week on which this entry is to run (`0-7`, `mon-sun`, or `*`), where Sunday is both `0` and `7`.",
|
127
|
-
default: "*", callbacks: {
|
128
|
-
"should be a valid weekday spec" => ->(spec) { Chef::ResourceHelpers::CronValidations.validate_dow(spec) },
|
129
|
-
}
|
130
|
-
|
131
|
-
property :command, String,
|
132
|
-
description: "The command to run.",
|
133
|
-
required: [:create]
|
134
|
-
|
135
|
-
property :user, String,
|
136
|
-
description: "The name of the user that runs the command.",
|
137
|
-
default: "root"
|
138
|
-
|
139
|
-
property :mailto, String,
|
140
|
-
description: "Set the `MAILTO` environment variable in the cron.d file."
|
141
|
-
|
142
|
-
property :path, String,
|
143
|
-
description: "Set the `PATH` environment variable in the cron.d file."
|
144
|
-
|
145
|
-
property :home, String,
|
146
|
-
description: "Set the `HOME` environment variable in the cron.d file."
|
147
|
-
|
148
|
-
property :shell, String,
|
149
|
-
description: "Set the `SHELL` environment variable in the cron.d file."
|
150
|
-
|
151
104
|
property :comment, String,
|
152
105
|
description: "A comment to place in the cron.d file."
|
153
106
|
|
154
|
-
property :environment, Hash,
|
155
|
-
description: "A Hash containing additional arbitrary environment variables under which the cron job will be run in the form of `({'ENV_VARIABLE' => 'VALUE'})`.",
|
156
|
-
default: lazy { {} }
|
157
|
-
|
158
|
-
TIMEOUT_OPTS = %w{duration preserve-status foreground kill-after signal}.freeze
|
159
|
-
TIMEOUT_REGEX = /\A\S+/.freeze
|
160
|
-
|
161
|
-
property :time_out, Hash,
|
162
|
-
description: "A Hash of timeouts in the form of `({'OPTION' => 'VALUE'})`.
|
163
|
-
Accepted valid options are:
|
164
|
-
`preserve-status` (BOOL, default: 'false'),
|
165
|
-
`foreground` (BOOL, default: 'false'),
|
166
|
-
`kill-after` (in seconds),
|
167
|
-
`signal` (a name like 'HUP' or a number)",
|
168
|
-
default: lazy { {} },
|
169
|
-
introduced: "15.7",
|
170
|
-
coerce: proc { |h|
|
171
|
-
if h.is_a?(Hash)
|
172
|
-
invalid_keys = h.keys - TIMEOUT_OPTS
|
173
|
-
unless invalid_keys.empty?
|
174
|
-
error_msg = "Key of option time_out must be equal to one of: \"#{TIMEOUT_OPTS.join('", "')}\"! You passed \"#{invalid_keys.join(", ")}\"."
|
175
|
-
raise Chef::Exceptions::ValidationFailed, error_msg
|
176
|
-
end
|
177
|
-
unless h.values.all? { |x| x =~ TIMEOUT_REGEX }
|
178
|
-
error_msg = "Values of option time_out should be non-empty string without any leading whitespace."
|
179
|
-
raise Chef::Exceptions::ValidationFailed, error_msg
|
180
|
-
end
|
181
|
-
h
|
182
|
-
elsif h.is_a?(Integer) || h.is_a?(String)
|
183
|
-
{ "duration" => h }
|
184
|
-
end
|
185
|
-
}
|
186
|
-
|
187
107
|
property :mode, [String, Integer],
|
188
108
|
description: "The octal mode of the generated crontab file.",
|
189
109
|
default: "0600"
|
@@ -238,7 +158,7 @@ class Chef
|
|
238
158
|
|
239
159
|
# @todo this is Chef 12 era cleanup. Someday we should remove it all
|
240
160
|
template "/etc/cron.d/#{sanitized_name}" do
|
241
|
-
source ::File.expand_path("
|
161
|
+
source ::File.expand_path("../../support/cron.d.erb", __FILE__)
|
242
162
|
local true
|
243
163
|
mode new_resource.mode
|
244
164
|
variables(
|