chef 13.2.20 → 13.3.42
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +1 -1
- data/Gemfile +2 -8
- data/README.md +6 -2
- data/Rakefile +0 -11
- data/VERSION +1 -1
- data/acceptance/Gemfile.lock +1 -1
- data/acceptance/data-collector/.acceptance/data-collector-test/files/default/api.rb +34 -18
- data/acceptance/data-collector/.acceptance/data-collector-test/recipes/default.rb +6 -0
- data/lib/chef/cookbook/metadata.rb +2 -2
- data/lib/chef/deprecation/warnings.rb +3 -1
- data/lib/chef/exceptions.rb +1 -1
- data/lib/chef/http.rb +9 -10
- data/lib/chef/http/api_versions.rb +2 -0
- data/lib/chef/http/http_request.rb +3 -0
- data/lib/chef/knife/core/bootstrap_context.rb +1 -0
- data/lib/chef/knife/core/status_presenter.rb +1 -1
- data/lib/chef/knife/ssh.rb +4 -0
- data/lib/chef/provider/apt_preference.rb +99 -0
- data/lib/chef/provider/execute.rb +3 -2
- data/lib/chef/provider/http_request.rb +14 -0
- data/lib/chef/provider/mount/aix.rb +49 -8
- data/lib/chef/provider/package/windows/registry_uninstall_entry.rb +1 -1
- data/lib/chef/provider/package/zypper.rb +5 -5
- data/lib/chef/provider/service/systemd.rb +12 -11
- data/lib/chef/provider/support/zypper_repo.erb +17 -0
- data/lib/chef/provider/systemd_unit.rb +3 -2
- data/lib/chef/provider/windows_task.rb +92 -71
- data/lib/chef/provider/zypper_repository.rb +81 -0
- data/lib/chef/providers.rb +2 -0
- data/lib/chef/resource/apt_preference.rb +36 -0
- data/lib/chef/resource/execute.rb +12 -2
- data/lib/chef/resource/http_request.rb +1 -1
- data/lib/chef/resource/zypper_repository.rb +51 -0
- data/lib/chef/resources.rb +2 -0
- data/lib/chef/search/query.rb +6 -1
- data/lib/chef/server_api_versions.rb +21 -2
- data/lib/chef/version.rb +3 -4
- data/lib/chef/win32/api/file.rb +1 -0
- data/lib/chef/win32/file.rb +2 -0
- data/lib/chef/win32/version.rb +6 -0
- data/spec/functional/knife/ssh_spec.rb +1 -1
- data/spec/functional/resource/execute_spec.rb +2 -2
- data/spec/spec_helper.rb +8 -1
- data/spec/unit/cookbook/metadata_spec.rb +3 -3
- data/spec/unit/http/api_versions_spec.rb +6 -3
- data/spec/unit/knife/bootstrap_spec.rb +4 -0
- data/spec/unit/knife/cookbook_show_spec.rb +3 -3
- data/spec/unit/knife/ssh_spec.rb +7 -1
- data/spec/unit/knife/status_spec.rb +2 -0
- data/spec/unit/provider/apt_preference_spec.rb +87 -0
- data/spec/unit/provider/apt_update_spec.rb +7 -7
- data/spec/unit/provider/dsc_resource_spec.rb +2 -2
- data/spec/unit/provider/execute_spec.rb +32 -14
- data/spec/unit/provider/mount/aix_spec.rb +33 -1
- data/spec/unit/provider/package/rubygems_spec.rb +1 -1
- data/spec/unit/provider/package/windows/registry_uninstall_entry_spec.rb +56 -3
- data/spec/unit/provider/package/windows_spec.rb +1 -1
- data/spec/unit/provider/package/zypper_spec.rb +43 -0
- data/spec/unit/provider/script_spec.rb +1 -1
- data/spec/unit/provider/service/systemd_service_spec.rb +23 -21
- data/spec/unit/provider/systemd_unit_spec.rb +42 -41
- data/spec/unit/provider/windows_task_spec.rb +40 -0
- data/spec/unit/resource/apt_preference_spec.rb +41 -0
- data/spec/unit/resource/execute_spec.rb +21 -1
- data/spec/unit/resource/powershell_script_spec.rb +2 -2
- data/spec/unit/resource/zypper_repository_spec.rb +65 -0
- data/spec/unit/search/query_spec.rb +13 -18
- data/spec/unit/server_api_spec.rb +75 -1
- data/spec/unit/server_api_versions_spec.rb +22 -0
- data/spec/unit/win32/link_spec.rb +73 -0
- data/tasks/dependencies.rb +0 -1
- metadata +13 -6
- data/tasks/changelog.rb +0 -37
- data/tasks/version.rb +0 -41
@@ -27,7 +27,7 @@ class Chef
|
|
27
27
|
|
28
28
|
provides :execute
|
29
29
|
|
30
|
-
def_delegators :new_resource, :command, :returns, :environment, :user, :domain, :password, :group, :cwd, :umask, :creates
|
30
|
+
def_delegators :new_resource, :command, :returns, :environment, :user, :domain, :password, :group, :cwd, :umask, :creates, :elevated
|
31
31
|
|
32
32
|
def load_current_resource
|
33
33
|
current_resource = Chef::Resource::Execute.new(new_resource.name)
|
@@ -55,7 +55,7 @@ class Chef
|
|
55
55
|
|
56
56
|
converge_by("execute #{description}") do
|
57
57
|
begin
|
58
|
-
|
58
|
+
shell_out_with_systems_locale!(command, opts)
|
59
59
|
rescue Mixlib::ShellOut::ShellCommandFailed
|
60
60
|
if sensitive?
|
61
61
|
raise Mixlib::ShellOut::ShellCommandFailed,
|
@@ -102,6 +102,7 @@ class Chef
|
|
102
102
|
opts[:live_stream] = STDOUT
|
103
103
|
end
|
104
104
|
end
|
105
|
+
opts[:elevated] = elevated if elevated
|
105
106
|
opts
|
106
107
|
end
|
107
108
|
|
@@ -62,6 +62,20 @@ class Chef
|
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
+
# Send a PATCH request to new_resource.url, with the message as the payload
|
66
|
+
def action_patch
|
67
|
+
converge_by("#{new_resource} PATCH to #{new_resource.url}") do
|
68
|
+
message = check_message(new_resource.message)
|
69
|
+
body = @http.patch(
|
70
|
+
"#{new_resource.url}",
|
71
|
+
message,
|
72
|
+
new_resource.headers
|
73
|
+
)
|
74
|
+
Chef::Log.info("#{new_resource} PATCH to #{new_resource.url} successful")
|
75
|
+
Chef::Log.debug("#{new_resource} PATCH request response: #{body}")
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
65
79
|
# Send a PUT request to new_resource.url, with the message as the payload
|
66
80
|
def action_put
|
67
81
|
converge_by("#{new_resource} PUT to #{new_resource.url}") do
|
@@ -40,30 +40,60 @@ class Chef
|
|
40
40
|
# Check to see if there is an entry in /etc/filesystems. Last entry for a volume wins. Using command "lsfs" to fetch entries.
|
41
41
|
enabled = false
|
42
42
|
|
43
|
+
regex_arr = device_fstab_regex.split(":")
|
44
|
+
if regex_arr.size.eql?(2)
|
45
|
+
nodename = regex_arr[0]
|
46
|
+
devicename = regex_arr[1]
|
47
|
+
else
|
48
|
+
devicename = regex_arr[0]
|
49
|
+
end
|
43
50
|
# lsfs o/p = #MountPoint:Device:Vfs:Nodename:Type:Size:Options:AutoMount:Acct
|
44
51
|
# search only for current mount point
|
45
52
|
shell_out("lsfs -c #{@new_resource.mount_point}").stdout.each_line do |line|
|
46
53
|
case line
|
47
54
|
when /^#\s/
|
48
55
|
next
|
49
|
-
when /^#{Regexp.escape(@new_resource.mount_point)}:#{
|
56
|
+
when /^#{Regexp.escape(@new_resource.mount_point)}:#{devicename}:(\S+):#{nodename}:(\S+)?:(\S+):(\S+):(\S+):(\S+)/
|
50
57
|
# mount point entry with ipv6 address for nodename (ipv6 address use ':')
|
51
58
|
enabled = true
|
52
59
|
@current_resource.fstype($1)
|
53
|
-
@current_resource.options($
|
54
|
-
Chef::Log.debug("Found mount #{
|
60
|
+
@current_resource.options($4)
|
61
|
+
Chef::Log.debug("Found mount point #{@new_resource.mount_point} :: device_type #{@current_resource.device_type} in /etc/filesystems")
|
55
62
|
next
|
56
|
-
when /^#{Regexp.escape(@new_resource.mount_point)}:#{
|
63
|
+
when /^#{Regexp.escape(@new_resource.mount_point)}:#{nodename}:(\S+)::(\S+)?:(\S+):(\S+):(\S+):(\S+)/
|
57
64
|
# mount point entry with hostname or ipv4 address
|
58
65
|
enabled = true
|
59
66
|
@current_resource.fstype($1)
|
67
|
+
@current_resource.options($4)
|
68
|
+
@current_resource.device("")
|
69
|
+
Chef::Log.debug("Found mount point #{@new_resource.mount_point} :: device_type #{@current_resource.device_type} in /etc/filesystems")
|
70
|
+
next
|
71
|
+
when /^#{Regexp.escape(@new_resource.mount_point)}:(\S+)?:(\S+):#{devicename}:(\S+)?:(\S+):(\S+):(\S+):(\S+)/
|
72
|
+
# mount point entry with hostname or ipv4 address
|
73
|
+
enabled = true
|
74
|
+
@current_resource.fstype($2)
|
60
75
|
@current_resource.options($5)
|
61
|
-
|
76
|
+
@current_resource.device(devicename + "/")
|
77
|
+
Chef::Log.debug("Found mount point #{@new_resource.mount_point} :: device_type #{@current_resource.device_type} in /etc/filesystems")
|
62
78
|
next
|
63
|
-
when /^#{Regexp.escape(@new_resource.mount_point)}/
|
64
|
-
|
65
|
-
|
79
|
+
when /^#{Regexp.escape(@new_resource.mount_point)}:(.*?):(.*?):(.*?):(.*?):(.*?):(.*?):(.*?):(.*?)/
|
80
|
+
if $3.split("=")[0].eql?("LABEL") || $1.split("=")[0].eql?("LABEL")
|
81
|
+
@current_resource.device_type("label")
|
82
|
+
elsif $3.split("=")[0].eql?("UUID") || $1.split("=")[0].eql?("UUID")
|
83
|
+
@current_resource.device_type("uuid")
|
84
|
+
else
|
85
|
+
@current_resource.device_type("device")
|
86
|
+
end
|
87
|
+
|
88
|
+
if @current_resource.device_type != @new_resource.device_type
|
89
|
+
enabled = true
|
90
|
+
Chef::Log.debug("Found mount point #{@new_resource.mount_point} :: device_type #{@current_resource.device_type} in /etc/filesystems")
|
91
|
+
else
|
92
|
+
enabled = false
|
93
|
+
Chef::Log.debug("Found conflicting mount point #{@new_resource.mount_point} in /etc/filesystems")
|
94
|
+
end
|
66
95
|
end
|
96
|
+
|
67
97
|
end
|
68
98
|
@current_resource.enabled(enabled)
|
69
99
|
end
|
@@ -149,6 +179,17 @@ class Chef
|
|
149
179
|
end
|
150
180
|
end
|
151
181
|
|
182
|
+
def mount_options_unchanged?
|
183
|
+
current_resource_options = @current_resource.options.delete_if { |x| x == "rw" }
|
184
|
+
|
185
|
+
@current_resource.device == @new_resource.device &&
|
186
|
+
@current_resource.fsck_device == @new_resource.fsck_device &&
|
187
|
+
@current_resource.fstype == @new_resource.fstype &&
|
188
|
+
current_resource_options == @new_resource.options &&
|
189
|
+
@current_resource.dump == @new_resource.dump &&
|
190
|
+
@current_resource.pass == @new_resource.pass
|
191
|
+
end
|
192
|
+
|
152
193
|
def disable_fs
|
153
194
|
contents = []
|
154
195
|
if @current_resource.enabled
|
@@ -40,7 +40,7 @@ class Chef
|
|
40
40
|
begin
|
41
41
|
entry = reg.open(key, desired)
|
42
42
|
display_name = read_registry_property(entry, "DisplayName")
|
43
|
-
if display_name == package_name
|
43
|
+
if display_name.to_s.rstrip == package_name
|
44
44
|
quiet_uninstall_string = RegistryUninstallEntry.read_registry_property(entry, "QuietUninstallString")
|
45
45
|
entries.push(quiet_uninstall_string_key?(quiet_uninstall_string, hkey, key, entry))
|
46
46
|
end
|
@@ -103,7 +103,7 @@ class Chef
|
|
103
103
|
end
|
104
104
|
|
105
105
|
def install_package(name, version)
|
106
|
-
zypper_package("install", "--auto-agree-with-licenses", name, version)
|
106
|
+
zypper_package("install", *options, "--auto-agree-with-licenses", name, version)
|
107
107
|
end
|
108
108
|
|
109
109
|
def upgrade_package(name, version)
|
@@ -112,19 +112,19 @@ class Chef
|
|
112
112
|
end
|
113
113
|
|
114
114
|
def remove_package(name, version)
|
115
|
-
zypper_package("remove", name, version)
|
115
|
+
zypper_package("remove", *options, name, version)
|
116
116
|
end
|
117
117
|
|
118
118
|
def purge_package(name, version)
|
119
|
-
zypper_package("remove", "--clean-deps", name, version)
|
119
|
+
zypper_package("remove", *options, "--clean-deps", name, version)
|
120
120
|
end
|
121
121
|
|
122
122
|
def lock_package(name, version)
|
123
|
-
zypper_package("addlock", name, version)
|
123
|
+
zypper_package("addlock", *options, name, version)
|
124
124
|
end
|
125
125
|
|
126
126
|
def unlock_package(name, version)
|
127
|
-
zypper_package("removelock", name, version)
|
127
|
+
zypper_package("removelock", *options, name, version)
|
128
128
|
end
|
129
129
|
|
130
130
|
private
|
@@ -20,6 +20,7 @@
|
|
20
20
|
require "chef/resource/service"
|
21
21
|
require "chef/provider/service/simple"
|
22
22
|
require "chef/mixin/which"
|
23
|
+
require "shellwords"
|
23
24
|
|
24
25
|
class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple
|
25
26
|
|
@@ -100,7 +101,7 @@ class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple
|
|
100
101
|
super
|
101
102
|
else
|
102
103
|
options, args = get_systemctl_options_args
|
103
|
-
shell_out_with_systems_locale!("#{systemctl_path} #{args} start #{new_resource.service_name}", options)
|
104
|
+
shell_out_with_systems_locale!("#{systemctl_path} #{args} start #{Shellwords.escape(new_resource.service_name)}", options)
|
104
105
|
end
|
105
106
|
end
|
106
107
|
end
|
@@ -113,7 +114,7 @@ class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple
|
|
113
114
|
super
|
114
115
|
else
|
115
116
|
options, args = get_systemctl_options_args
|
116
|
-
shell_out_with_systems_locale!("#{systemctl_path} #{args} stop #{new_resource.service_name}", options)
|
117
|
+
shell_out_with_systems_locale!("#{systemctl_path} #{args} stop #{Shellwords.escape(new_resource.service_name)}", options)
|
117
118
|
end
|
118
119
|
end
|
119
120
|
end
|
@@ -123,7 +124,7 @@ class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple
|
|
123
124
|
super
|
124
125
|
else
|
125
126
|
options, args = get_systemctl_options_args
|
126
|
-
shell_out_with_systems_locale!("#{systemctl_path} #{args} restart #{new_resource.service_name}", options)
|
127
|
+
shell_out_with_systems_locale!("#{systemctl_path} #{args} restart #{Shellwords.escape(new_resource.service_name)}", options)
|
127
128
|
end
|
128
129
|
end
|
129
130
|
|
@@ -133,7 +134,7 @@ class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple
|
|
133
134
|
else
|
134
135
|
if current_resource.running
|
135
136
|
options, args = get_systemctl_options_args
|
136
|
-
shell_out_with_systems_locale!("#{systemctl_path} #{args} reload #{new_resource.service_name}", options)
|
137
|
+
shell_out_with_systems_locale!("#{systemctl_path} #{args} reload #{Shellwords.escape(new_resource.service_name)}", options)
|
137
138
|
else
|
138
139
|
start_service
|
139
140
|
end
|
@@ -142,37 +143,37 @@ class Chef::Provider::Service::Systemd < Chef::Provider::Service::Simple
|
|
142
143
|
|
143
144
|
def enable_service
|
144
145
|
options, args = get_systemctl_options_args
|
145
|
-
shell_out!("#{systemctl_path} #{args} enable #{new_resource.service_name}", options)
|
146
|
+
shell_out!("#{systemctl_path} #{args} enable #{Shellwords.escape(new_resource.service_name)}", options)
|
146
147
|
end
|
147
148
|
|
148
149
|
def disable_service
|
149
150
|
options, args = get_systemctl_options_args
|
150
|
-
shell_out!("#{systemctl_path} #{args} disable #{new_resource.service_name}", options)
|
151
|
+
shell_out!("#{systemctl_path} #{args} disable #{Shellwords.escape(new_resource.service_name)}", options)
|
151
152
|
end
|
152
153
|
|
153
154
|
def mask_service
|
154
155
|
options, args = get_systemctl_options_args
|
155
|
-
shell_out!("#{systemctl_path} #{args} mask #{new_resource.service_name}", options)
|
156
|
+
shell_out!("#{systemctl_path} #{args} mask #{Shellwords.escape(new_resource.service_name)}", options)
|
156
157
|
end
|
157
158
|
|
158
159
|
def unmask_service
|
159
160
|
options, args = get_systemctl_options_args
|
160
|
-
shell_out!("#{systemctl_path} #{args} unmask #{new_resource.service_name}", options)
|
161
|
+
shell_out!("#{systemctl_path} #{args} unmask #{Shellwords.escape(new_resource.service_name)}", options)
|
161
162
|
end
|
162
163
|
|
163
164
|
def is_active?
|
164
165
|
options, args = get_systemctl_options_args
|
165
|
-
shell_out("#{systemctl_path} #{args} is-active #{new_resource.service_name} --quiet", options).exitstatus == 0
|
166
|
+
shell_out("#{systemctl_path} #{args} is-active #{Shellwords.escape(new_resource.service_name)} --quiet", options).exitstatus == 0
|
166
167
|
end
|
167
168
|
|
168
169
|
def is_enabled?
|
169
170
|
options, args = get_systemctl_options_args
|
170
|
-
shell_out("#{systemctl_path} #{args} is-enabled #{new_resource.service_name} --quiet", options).exitstatus == 0
|
171
|
+
shell_out("#{systemctl_path} #{args} is-enabled #{Shellwords.escape(new_resource.service_name)} --quiet", options).exitstatus == 0
|
171
172
|
end
|
172
173
|
|
173
174
|
def is_masked?
|
174
175
|
options, args = get_systemctl_options_args
|
175
|
-
s = shell_out("#{systemctl_path} #{args} is-enabled #{new_resource.service_name}", options)
|
176
|
+
s = shell_out("#{systemctl_path} #{args} is-enabled #{Shellwords.escape(new_resource.service_name)}", options)
|
176
177
|
s.exitstatus != 0 && s.stdout.include?("masked")
|
177
178
|
end
|
178
179
|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# This file was generated by Chef
|
2
|
+
# Do NOT modify this file by hand.
|
3
|
+
|
4
|
+
[<%= @config.repo_name %>]
|
5
|
+
<% %w{ type enabled autorefresh gpgcheck gpgkey baseurl mirrorlist path priority keeppackages mode refresh_cache }.each do |prop| -%>
|
6
|
+
<% next if @config.send(prop.to_sym).nil? -%>
|
7
|
+
<%= prop %>=<%=
|
8
|
+
case @config.send(prop.to_sym)
|
9
|
+
when TrueClass
|
10
|
+
'1'
|
11
|
+
when FalseClass
|
12
|
+
'0'
|
13
|
+
else
|
14
|
+
@config.send(prop.to_sym)
|
15
|
+
end %>
|
16
|
+
<% end -%>
|
17
|
+
name=<%= @config.description || @config.repo_name %>
|
@@ -22,6 +22,7 @@ require "chef/mixin/shell_out"
|
|
22
22
|
require "chef/resource/file"
|
23
23
|
require "chef/resource/file/verification/systemd_unit"
|
24
24
|
require "iniparse"
|
25
|
+
require "shellwords"
|
25
26
|
|
26
27
|
class Chef
|
27
28
|
class Provider
|
@@ -203,11 +204,11 @@ class Chef
|
|
203
204
|
end
|
204
205
|
|
205
206
|
def systemctl_execute!(action, unit)
|
206
|
-
shell_out_with_systems_locale!("#{systemctl_cmd} #{action} #{unit}", systemctl_opts)
|
207
|
+
shell_out_with_systems_locale!("#{systemctl_cmd} #{action} #{Shellwords.escape(unit)}", systemctl_opts)
|
207
208
|
end
|
208
209
|
|
209
210
|
def systemctl_execute(action, unit)
|
210
|
-
shell_out("#{systemctl_cmd} #{action} #{unit}", systemctl_opts)
|
211
|
+
shell_out("#{systemctl_cmd} #{action} #{Shellwords.escape(unit)}", systemctl_opts)
|
211
212
|
end
|
212
213
|
|
213
214
|
def systemctl_cmd
|
@@ -52,53 +52,74 @@ class Chef
|
|
52
52
|
set_current_idle_time(task_hash[:idle_time]) if task_hash[:idle_time]
|
53
53
|
@current_resource.random_delay(task_hash[:random_delay]) if task_hash[:random_delay]
|
54
54
|
@current_resource.execution_time_limit(task_hash[:execution_time_limit]) if task_hash[:execution_time_limit]
|
55
|
-
|
56
55
|
@current_resource.status = :running if task_hash[:Status] == "Running"
|
57
56
|
@current_resource.enabled = true if task_hash[:ScheduledTaskState] == "Enabled"
|
58
57
|
end
|
59
58
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
options["I"] = @new_resource.idle_time unless @new_resource.idle_time.nil?
|
69
|
-
options["SD"] = @new_resource.start_day unless @new_resource.start_day.nil?
|
70
|
-
options["ST"] = @new_resource.start_time unless @new_resource.start_time.nil?
|
71
|
-
options["TR"] = @new_resource.command
|
72
|
-
options["RU"] = @new_resource.user
|
73
|
-
options["RP"] = @new_resource.password if use_password?
|
74
|
-
options["RL"] = "HIGHEST" if @new_resource.run_level == :highest
|
75
|
-
options["IT"] = "" if @new_resource.interactive_enabled
|
76
|
-
options["D"] = @new_resource.day if @new_resource.day
|
77
|
-
options["M"] = @new_resource.months unless @new_resource.months.nil?
|
78
|
-
|
79
|
-
run_schtasks "CREATE", options
|
80
|
-
xml_options = []
|
81
|
-
xml_options << "cwd" if new_resource.cwd
|
82
|
-
xml_options << "random_delay" if new_resource.random_delay
|
83
|
-
xml_options << "execution_time_limit" if new_resource.execution_time_limit
|
84
|
-
update_task_xml(xml_options) unless xml_options.empty?
|
59
|
+
# This method checks if task and command attributes exist since those two are mandatory attributes to create a schedules task.
|
60
|
+
def basic_validation
|
61
|
+
validate = []
|
62
|
+
validate << "Command" if new_resource.command.nil? || new_resource.command.empty?
|
63
|
+
validate << "Task Name" if new_resource.task_name.nil? || new_resource.task_name.empty?
|
64
|
+
return true if validate.empty?
|
65
|
+
raise Chef::Exceptions::ValidationFailed.new "Value for '#{validate.join(', ')}' option cannot be empty"
|
66
|
+
end
|
85
67
|
|
86
|
-
|
87
|
-
|
68
|
+
# get array of windows task resource attributes
|
69
|
+
def resource_attributes
|
70
|
+
%w{ command user run_level cwd frequency_modifier frequency idle_time random_delay execution_time_limit start_day start_time }
|
71
|
+
end
|
72
|
+
|
73
|
+
def action_create
|
74
|
+
if @current_resource.exists
|
75
|
+
if !(task_need_update? || new_resource.force)
|
76
|
+
Chef::Log.info "#{new_resource} task already exists - nothing to do"
|
77
|
+
return
|
78
|
+
end
|
79
|
+
# To merge current resource and new resource attributes
|
80
|
+
resource_attributes.each do |attribute|
|
81
|
+
new_resource_attribute = new_resource.send(attribute)
|
82
|
+
current_resource_attribute = @current_resource.send(attribute)
|
83
|
+
new_resource.send("#{attribute}=", current_resource_attribute ) if current_resource_attribute && new_resource_attribute.nil?
|
84
|
+
end
|
88
85
|
end
|
86
|
+
basic_validation
|
87
|
+
options = {}
|
88
|
+
options["F"] = "" if new_resource.force || task_need_update?
|
89
|
+
options["SC"] = schedule
|
90
|
+
options["MO"] = new_resource.frequency_modifier if frequency_modifier_allowed
|
91
|
+
options["I"] = new_resource.idle_time unless new_resource.idle_time.nil?
|
92
|
+
options["SD"] = new_resource.start_day unless new_resource.start_day.nil?
|
93
|
+
options["ST"] = new_resource.start_time unless new_resource.start_time.nil?
|
94
|
+
options["TR"] = new_resource.command
|
95
|
+
options["RU"] = new_resource.user
|
96
|
+
options["RP"] = new_resource.password if use_password?
|
97
|
+
options["RL"] = "HIGHEST" if new_resource.run_level == :highest
|
98
|
+
options["IT"] = "" if new_resource.interactive_enabled
|
99
|
+
options["D"] = new_resource.day if new_resource.day
|
100
|
+
options["M"] = new_resource.months unless new_resource.months.nil?
|
101
|
+
run_schtasks "CREATE", options
|
102
|
+
xml_options = []
|
103
|
+
xml_options << "cwd" if new_resource.cwd
|
104
|
+
xml_options << "random_delay" if new_resource.random_delay
|
105
|
+
xml_options << "execution_time_limit" if new_resource.execution_time_limit
|
106
|
+
update_task_xml(xml_options) unless xml_options.empty?
|
107
|
+
|
108
|
+
new_resource.updated_by_last_action true
|
109
|
+
Chef::Log.info "#{new_resource} task created"
|
89
110
|
end
|
90
111
|
|
91
112
|
def action_run
|
92
113
|
if @current_resource.exists
|
93
114
|
if @current_resource.status == :running
|
94
|
-
Chef::Log.info "#{
|
115
|
+
Chef::Log.info "#{new_resource} task is currently running, skipping run"
|
95
116
|
else
|
96
117
|
run_schtasks "RUN"
|
97
118
|
new_resource.updated_by_last_action true
|
98
|
-
Chef::Log.info "#{
|
119
|
+
Chef::Log.info "#{new_resource} task ran"
|
99
120
|
end
|
100
121
|
else
|
101
|
-
Chef::Log.warn "#{
|
122
|
+
Chef::Log.warn "#{new_resource} task doesn't exists - nothing to do"
|
102
123
|
end
|
103
124
|
end
|
104
125
|
|
@@ -107,38 +128,38 @@ class Chef
|
|
107
128
|
# always need to force deletion
|
108
129
|
run_schtasks "DELETE", "F" => ""
|
109
130
|
new_resource.updated_by_last_action true
|
110
|
-
Chef::Log.info "#{
|
131
|
+
Chef::Log.info "#{new_resource} task deleted"
|
111
132
|
else
|
112
|
-
Chef::Log.warn "#{
|
133
|
+
Chef::Log.warn "#{new_resource} task doesn't exists - nothing to do"
|
113
134
|
end
|
114
135
|
end
|
115
136
|
|
116
137
|
def action_end
|
117
138
|
if @current_resource.exists
|
118
139
|
if @current_resource.status != :running
|
119
|
-
Chef::Log.debug "#{
|
140
|
+
Chef::Log.debug "#{new_resource} is not running - nothing to do"
|
120
141
|
else
|
121
142
|
run_schtasks "END"
|
122
|
-
|
123
|
-
Chef::Log.info "#{
|
143
|
+
new_resource.updated_by_last_action true
|
144
|
+
Chef::Log.info "#{new_resource} task ended"
|
124
145
|
end
|
125
146
|
else
|
126
|
-
Chef::Log.warn "#{
|
147
|
+
Chef::Log.warn "#{new_resource} task doesn't exist - nothing to do"
|
127
148
|
end
|
128
149
|
end
|
129
150
|
|
130
151
|
def action_enable
|
131
152
|
if @current_resource.exists
|
132
153
|
if @current_resource.enabled
|
133
|
-
Chef::Log.debug "#{
|
154
|
+
Chef::Log.debug "#{new_resource} already enabled - nothing to do"
|
134
155
|
else
|
135
156
|
run_schtasks "CHANGE", "ENABLE" => ""
|
136
|
-
|
137
|
-
Chef::Log.info "#{
|
157
|
+
new_resource.updated_by_last_action true
|
158
|
+
Chef::Log.info "#{new_resource} task enabled"
|
138
159
|
end
|
139
160
|
else
|
140
|
-
Chef::Log.fatal "#{
|
141
|
-
raise Errno::ENOENT, "#{
|
161
|
+
Chef::Log.fatal "#{new_resource} task doesn't exist - nothing to do"
|
162
|
+
raise Errno::ENOENT, "#{new_resource}: task does not exist, cannot enable"
|
142
163
|
end
|
143
164
|
end
|
144
165
|
|
@@ -146,13 +167,13 @@ class Chef
|
|
146
167
|
if @current_resource.exists
|
147
168
|
if @current_resource.enabled
|
148
169
|
run_schtasks "CHANGE", "DISABLE" => ""
|
149
|
-
|
150
|
-
Chef::Log.info "#{
|
170
|
+
new_resource.updated_by_last_action true
|
171
|
+
Chef::Log.info "#{new_resource} task disabled"
|
151
172
|
else
|
152
|
-
Chef::Log.warn "#{
|
173
|
+
Chef::Log.warn "#{new_resource} already disabled - nothing to do"
|
153
174
|
end
|
154
175
|
else
|
155
|
-
Chef::Log.warn "#{
|
176
|
+
Chef::Log.warn "#{new_resource} task doesn't exist - nothing to do"
|
156
177
|
end
|
157
178
|
end
|
158
179
|
|
@@ -160,7 +181,7 @@ class Chef
|
|
160
181
|
|
161
182
|
# rubocop:disable Style/StringLiteralsInInterpolation
|
162
183
|
def run_schtasks(task_action, options = {})
|
163
|
-
cmd = "schtasks /#{task_action} /TN \"#{
|
184
|
+
cmd = "schtasks /#{task_action} /TN \"#{new_resource.task_name}\" "
|
164
185
|
options.keys.each do |option|
|
165
186
|
cmd += "/#{option} "
|
166
187
|
cmd += "\"#{options[option].to_s.gsub('"', "\\\"")}\" " unless options[option] == ""
|
@@ -172,20 +193,20 @@ class Chef
|
|
172
193
|
# rubocop:enable Style/StringLiteralsInInterpolation
|
173
194
|
|
174
195
|
def task_need_update?
|
175
|
-
return true if
|
176
|
-
@current_resource.
|
177
|
-
@current_resource.
|
178
|
-
@current_resource.
|
179
|
-
@current_resource.
|
180
|
-
@current_resource.
|
181
|
-
@current_resource.
|
182
|
-
@current_resource.
|
183
|
-
@current_resource.
|
184
|
-
|
185
|
-
|
196
|
+
return true if (new_resource.command &&
|
197
|
+
@current_resource.command != new_resource.command.tr("'", '"')) ||
|
198
|
+
@current_resource.user != new_resource.user ||
|
199
|
+
@current_resource.run_level != new_resource.run_level ||
|
200
|
+
@current_resource.cwd != new_resource.cwd ||
|
201
|
+
@current_resource.frequency_modifier != new_resource.frequency_modifier ||
|
202
|
+
@current_resource.frequency != new_resource.frequency ||
|
203
|
+
@current_resource.idle_time != new_resource.idle_time ||
|
204
|
+
@current_resource.random_delay != new_resource.random_delay ||
|
205
|
+
@current_resource.execution_time_limit != new_resource.execution_time_limit ||
|
206
|
+
!new_resource.start_day.nil? || !new_resource.start_time.nil?
|
186
207
|
begin
|
187
|
-
return true if
|
188
|
-
|
208
|
+
return true if new_resource.day.to_s.casecmp(@current_resource.day.to_s) != 0 ||
|
209
|
+
new_resource.months.to_s.casecmp(@current_resource.months.to_s) != 0
|
189
210
|
rescue
|
190
211
|
Chef::Log.debug "caught a raise in task_needs_update?"
|
191
212
|
end
|
@@ -206,7 +227,7 @@ class Chef
|
|
206
227
|
|
207
228
|
xml_element_mapping = {
|
208
229
|
"cwd" => "Actions/Exec/WorkingDirectory",
|
209
|
-
"random_delay" => random_delay_xml_element[
|
230
|
+
"random_delay" => random_delay_xml_element[new_resource.frequency],
|
210
231
|
"execution_time_limit" => "Settings/ExecutionTimeLimit",
|
211
232
|
}
|
212
233
|
|
@@ -214,7 +235,7 @@ class Chef
|
|
214
235
|
|
215
236
|
task_script = <<-EOH
|
216
237
|
[Console]::OutputEncoding = [Text.UTF8Encoding]::UTF8
|
217
|
-
schtasks /Query /TN \"#{
|
238
|
+
schtasks /Query /TN \"#{new_resource.task_name}\" /XML
|
218
239
|
EOH
|
219
240
|
xml_cmd = powershell_out(task_script)
|
220
241
|
|
@@ -225,7 +246,7 @@ class Chef
|
|
225
246
|
options.each do |option|
|
226
247
|
Chef::Log.debug 'Removing former #{option} if any'
|
227
248
|
doc.root.elements.delete(xml_element_mapping[option])
|
228
|
-
option_value =
|
249
|
+
option_value = new_resource.send("#{option}")
|
229
250
|
|
230
251
|
if option_value
|
231
252
|
Chef::Log.debug "Setting #option as #option_value"
|
@@ -246,9 +267,9 @@ class Chef
|
|
246
267
|
end
|
247
268
|
|
248
269
|
options = {}
|
249
|
-
options["RU"] =
|
250
|
-
options["RP"] =
|
251
|
-
options["IT"] = "" if
|
270
|
+
options["RU"] = new_resource.user if new_resource.user
|
271
|
+
options["RP"] = new_resource.password if new_resource.password
|
272
|
+
options["IT"] = "" if new_resource.interactive_enabled
|
252
273
|
options["XML"] = temp_task_file
|
253
274
|
|
254
275
|
run_schtasks("DELETE", "F" => "")
|
@@ -345,26 +366,26 @@ class Chef
|
|
345
366
|
SYSTEM_USERS = ['NT AUTHORITY\SYSTEM', "SYSTEM", 'NT AUTHORITY\LOCALSERVICE', 'NT AUTHORITY\NETWORKSERVICE', 'BUILTIN\USERS', "USERS"].freeze
|
346
367
|
|
347
368
|
def use_password?
|
348
|
-
@use_password ||= !SYSTEM_USERS.include?(
|
369
|
+
@use_password ||= !SYSTEM_USERS.include?(new_resource.user.upcase)
|
349
370
|
end
|
350
371
|
|
351
372
|
def schedule
|
352
|
-
case
|
373
|
+
case new_resource.frequency
|
353
374
|
when :on_logon
|
354
375
|
"ONLOGON"
|
355
376
|
when :on_idle
|
356
377
|
"ONIDLE"
|
357
378
|
else
|
358
|
-
|
379
|
+
new_resource.frequency
|
359
380
|
end
|
360
381
|
end
|
361
382
|
|
362
383
|
def frequency_modifier_allowed
|
363
|
-
case
|
384
|
+
case new_resource.frequency
|
364
385
|
when :minute, :hourly, :daily, :weekly
|
365
386
|
true
|
366
387
|
when :monthly
|
367
|
-
|
388
|
+
new_resource.months.nil? || %w{ FIRST SECOND THIRD FOURTH LAST LASTDAY }.include?(new_resource.frequency_modifier)
|
368
389
|
else
|
369
390
|
false
|
370
391
|
end
|