chef 11.14.0.rc.2 → 11.14.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6879b03746a23afbc56120b255c2b4c6c992eb32
4
+ data.tar.gz: 4e4177fbaab45b8a27ab56d0cdfd7495641b7975
5
+ SHA512:
6
+ metadata.gz: 33582852620cb90c193f276dfe34cf12952132252cf3a07dfc9d5c2626126a03d74fb2fe38e13e3155de808fbd501377fc2418174a0af658d435f2c55cc5f8b7
7
+ data.tar.gz: ae27cdd8586f76f2904ffd88990f8149f162c84dea819a4c343c00a960017e7c318dc281a279f82b027b94aec59640a200889c6890c8fef08f185789b02dd865
@@ -93,6 +93,13 @@ class Chef
93
93
 
94
94
  def indent_by(amount)
95
95
  @output.indent += amount
96
+ if @output.indent < 0
97
+ # This is left commented out for now. We need to uncomment it and fix at least one bug in
98
+ # the formatter, and then leave this line uncommented in the future.
99
+ #Chef::Log.warn "Internal Formatter Error -- Attempt to indent by negative number of spaces"
100
+ @output.indent = 0
101
+ end
102
+ @output.indent
96
103
  end
97
104
 
98
105
  # Input: a Formatters::ErrorDescription object.
@@ -84,7 +84,13 @@ class Chef
84
84
  #adapted from buildr/lib/buildr/core/transports.rb
85
85
  def proxy_uri
86
86
  proxy = Chef::Config["#{url.scheme}_proxy"]
87
- proxy = URI.parse(proxy) if String === proxy
87
+ # Check if the proxy string contains a scheme. If not, add the url's scheme to the
88
+ # proxy before parsing. The regex /^.*:\/\// matches, for example, http://.
89
+ proxy = if proxy.match(/^.*:\/\//)
90
+ URI.parse(proxy)
91
+ else
92
+ URI.parse("#{url.scheme}://#{proxy}")
93
+ end if String === proxy
88
94
  excludes = Chef::Config[:no_proxy].to_s.split(/\s*,\s*/).compact
89
95
  excludes = excludes.map { |exclude| exclude =~ /:\d+$/ ? exclude : "#{exclude}:*" }
90
96
  return proxy unless excludes.any? { |exclude| File.fnmatch(exclude, "#{host}:#{port}") }
@@ -17,11 +17,14 @@
17
17
  #
18
18
 
19
19
  require 'chef/knife'
20
+ require 'chef/mixin/shell_out'
20
21
 
21
22
  class Chef
22
23
  class Knife
23
24
  class CookbookSiteShare < Knife
24
25
 
26
+ include Chef::Mixin::ShellOut
27
+
25
28
  deps do
26
29
  require 'chef/cookbook_loader'
27
30
  require 'chef/cookbook_uploader'
@@ -56,7 +59,7 @@ class Chef
56
59
  begin
57
60
  Chef::Log.debug("Temp cookbook directory is #{tmp_cookbook_dir.inspect}")
58
61
  ui.info("Making tarball #{cookbook_name}.tgz")
59
- Chef::Mixin::Command.run_command(:command => "tar -czf #{cookbook_name}.tgz #{cookbook_name}", :cwd => tmp_cookbook_dir)
62
+ shell_out!("tar -czf #{cookbook_name}.tgz #{cookbook_name}", :cwd => tmp_cookbook_dir)
60
63
  rescue => e
61
64
  ui.error("Error making tarball #{cookbook_name}.tgz: #{e.message}. Increase log verbosity (-VV) for more information.")
62
65
  Chef::Log.debug("\n#{e.backtrace.join("\n")}")
@@ -18,13 +18,16 @@
18
18
  # limitations under the License.
19
19
  #
20
20
 
21
+ if Chef::Platform.windows?
22
+ require 'chef/win32/file'
23
+ end
24
+
21
25
  class Chef
22
26
  module Mixin
23
27
  module FileClass
24
28
 
25
29
  def file_class
26
30
  @host_os_file ||= if Chef::Platform.windows?
27
- require 'chef/win32/file'
28
31
  Chef::ReservedNames::Win32::File
29
32
  else
30
33
  ::File
@@ -95,6 +95,13 @@ class Chef
95
95
  val = arg
96
96
  else
97
97
  val = validate({ symbol => arg }, { symbol => validation })[symbol]
98
+
99
+ # Handle the case where the "default" was a DelayedEvaluator. In
100
+ # this case, the block yields an optional parameter of +self+,
101
+ # which is the equivalent of "new_resource"
102
+ if val.is_a?(DelayedEvaluator)
103
+ val = val.call(self)
104
+ end
98
105
  end
99
106
  self.instance_variable_set(iv_symbol, val)
100
107
  end
@@ -25,9 +25,6 @@ class Chef
25
25
  # Chef log provider, allows logging to chef's logs from recipes
26
26
  class ChefLog < Chef::Provider
27
27
 
28
- # ordered array of the log levels
29
- @@levels = [ :debug, :info, :warn, :error, :fatal ]
30
-
31
28
  # No concept of a 'current' resource for logs, this is a no-op
32
29
  #
33
30
  # === Return
@@ -42,18 +39,7 @@ class Chef
42
39
  # true:: Always return true
43
40
  def action_write
44
41
  Chef::Log.send(@new_resource.level, @new_resource.message)
45
-
46
- # resolve the integers for the current log levels
47
- global_level = Mixlib::Log::LEVELS.fetch(Chef::Log.level)
48
- resource_level = Mixlib::Log::LEVELS.fetch(@new_resource.level)
49
-
50
- # If the resource level is greater than or the same os the global
51
- # level, then it should have been written to the log. Mark the
52
- # resource as updated.
53
- if resource_level >= global_level
54
- @new_resource.updated_by_last_action(true)
55
- end
56
-
42
+ @new_resource.updated_by_last_action(true)
57
43
  end
58
44
 
59
45
  end
@@ -31,6 +31,7 @@ class Chef
31
31
  DPKG_VERSION = /^Version: (.+)$/
32
32
 
33
33
  include Chef::Mixin::GetSourceFromPackage
34
+ include Chef::Mixin::ShellOut
34
35
 
35
36
  def define_resource_requirements
36
37
  super
@@ -64,9 +64,7 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
64
64
  Chef::Log.debug "#{@new_resource} already started - nothing to do"
65
65
  elsif state == START_PENDING
66
66
  Chef::Log.debug "#{@new_resource} already sent start signal - waiting for start"
67
- spawn_command_thread do
68
- wait_for_state(RUNNING)
69
- end
67
+ wait_for_state(RUNNING)
70
68
  elsif state == STOPPED
71
69
  if @new_resource.start_command
72
70
  Chef::Log.debug "#{@new_resource} starting service using the given start_command"
@@ -74,8 +72,8 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
74
72
  else
75
73
  spawn_command_thread do
76
74
  Win32::Service.start(@new_resource.service_name)
77
- wait_for_state(RUNNING)
78
75
  end
76
+ wait_for_state(RUNNING)
79
77
  end
80
78
  @new_resource.updated_by_last_action(true)
81
79
  else
@@ -96,17 +94,15 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
96
94
  else
97
95
  spawn_command_thread do
98
96
  Win32::Service.stop(@new_resource.service_name)
99
- wait_for_state(STOPPED)
100
97
  end
98
+ wait_for_state(STOPPED)
101
99
  end
102
100
  @new_resource.updated_by_last_action(true)
103
101
  elsif state == STOPPED
104
102
  Chef::Log.debug "#{@new_resource} already stopped - nothing to do"
105
103
  elsif state == STOP_PENDING
106
104
  Chef::Log.debug "#{@new_resource} already sent stop signal - waiting for stop"
107
- spawn_command_thread do
108
- wait_for_state(STOPPED)
109
- end
105
+ wait_for_state(STOPPED)
110
106
  else
111
107
  raise Chef::Exceptions::Service, "Service #{@new_resource} can't be stopped from state [#{state}]"
112
108
  end
@@ -174,7 +170,16 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
174
170
  # Helper method that waits for a status to change its state since state
175
171
  # changes aren't usually instantaneous.
176
172
  def wait_for_state(desired_state)
177
- sleep 1 until current_state == desired_state
173
+ retries = 0
174
+ loop do
175
+ break if current_state == desired_state
176
+ raise Timeout::Error if ( retries += 1 ) > resource_timeout
177
+ sleep 1
178
+ end
179
+ end
180
+
181
+ def resource_timeout
182
+ @resource_timeout ||= @new_resource.timeout || TIMEOUT
178
183
  end
179
184
 
180
185
  def spawn_command_thread
@@ -182,8 +187,6 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
182
187
  yield
183
188
  end
184
189
 
185
- resource_timeout = @new_resource.timeout if @new_resource.timeout
186
- resource_timeout ||= TIMEOUT
187
190
  Timeout.timeout(resource_timeout) do
188
191
  worker.join
189
192
  end
@@ -59,15 +59,17 @@ class Chef
59
59
  resource_class
60
60
  end
61
61
 
62
- # Set the resource snake_case name. Should only be called via
63
- # build_from_file.
64
- def self.resource_name=(resource_name)
65
- @resource_name = resource_name
62
+ # Set the resource name for this LWRP
63
+ def self.resource_name(arg = NULL_ARG)
64
+ if arg.equal?(NULL_ARG)
65
+ @resource_name
66
+ else
67
+ @resource_name = arg
68
+ end
66
69
  end
67
70
 
68
- # Returns the resource snake_case name
69
- def self.resource_name
70
- @resource_name
71
+ class << self
72
+ alias_method :resource_name=, :resource_name
71
73
  end
72
74
 
73
75
  # Define an attribute on this resource, including optional validation
@@ -90,19 +92,39 @@ class Chef
90
92
  # Sets the default action
91
93
  def self.default_action(action_name=NULL_ARG)
92
94
  unless action_name.equal?(NULL_ARG)
93
- valid_actions.push(action_name)
94
- @default_action = action_name
95
+ @actions ||= []
96
+ if action_name.is_a?(Array)
97
+ action = action_name.map { |arg| arg.to_sym }
98
+ @actions = actions | action
99
+ @default_action = action
100
+ else
101
+ action = action_name.to_sym
102
+ @actions.push(action) unless @actions.include?(action)
103
+ @default_action = action
104
+ end
95
105
  end
96
- @default_action
106
+
107
+ @default_action ||= from_superclass(:default_action)
97
108
  end
98
109
 
99
110
  # Adds +action_names+ to the list of valid actions for this resource.
100
111
  def self.actions(*action_names)
101
- valid_actions.push(*action_names)
112
+ if action_names.empty?
113
+ defined?(@actions) ? @actions : from_superclass(:actions, []).dup
114
+ else
115
+ # BC-compat way for checking if actions have already been defined
116
+ if defined?(@actions)
117
+ @actions.push(*action_names)
118
+ else
119
+ @actions = action_names
120
+ end
121
+ end
102
122
  end
103
123
 
104
- def self.valid_actions
105
- @valid_actions ||= []
124
+ # @deprecated
125
+ def self.valid_actions(*args)
126
+ Chef::Log.warn("`valid_actions' is deprecated, please use actions `instead'!")
127
+ actions(*args)
106
128
  end
107
129
 
108
130
  # Set the run context on the class. Used to provide access to the node
@@ -119,12 +141,34 @@ class Chef
119
141
  run_context.node
120
142
  end
121
143
 
144
+ def self.lazy(&block)
145
+ DelayedEvaluator.new(&block)
146
+ end
147
+
148
+ private
149
+
150
+ # Get the value from the superclass, if it responds, otherwise return
151
+ # +nil+. Since class instance variables are **not** inherited upon
152
+ # subclassing, this is a required check to ensure Chef pulls the
153
+ # +default_action+ and other DSL-y methods when extending LWRP::Base.
154
+ def self.from_superclass(m, default = nil)
155
+ return default if superclass == Chef::Resource::LWRPBase
156
+ superclass.respond_to?(m) ? superclass.send(m) : default
157
+ end
158
+
122
159
  # Default initializer. Sets the default action and allowed actions.
123
160
  def initialize(name, run_context=nil)
124
161
  super(name, run_context)
162
+
163
+ # Raise an exception if the resource_name was not defined
164
+ if self.class.resource_name.nil?
165
+ raise Chef::Exceptions::InvalidResourceSpecification,
166
+ "You must specify `resource_name'!"
167
+ end
168
+
125
169
  @resource_name = self.class.resource_name.to_sym
126
170
  @action = self.class.default_action
127
- allowed_actions.push(self.class.valid_actions).flatten!
171
+ allowed_actions.push(self.class.actions).flatten!
128
172
  end
129
173
 
130
174
  end
@@ -17,7 +17,7 @@
17
17
 
18
18
  class Chef
19
19
  CHEF_ROOT = File.dirname(File.expand_path(File.dirname(__FILE__)))
20
- VERSION = '11.14.0.rc.2'
20
+ VERSION = '11.14.2'
21
21
  end
22
22
 
23
23
  # NOTE: the Chef::Version class is defined in version_class.rb
@@ -0,0 +1,90 @@
1
+ #
2
+ # Author:: Serdar Sutay (<serdar@getchef.com>)
3
+ # Copyright:: Copyright 2014 Chef Software, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef/win32/api'
20
+
21
+ class Chef
22
+ module ReservedNames::Win32
23
+ module API
24
+ module Net
25
+ extend Chef::ReservedNames::Win32::API
26
+
27
+ FILTER_TEMP_DUPLICATE_ACCOUNT = 0x0001
28
+ FILTER_NORMAL_ACCOUNT = 0x0002
29
+ FILTER_INTERDOMAIN_TRUST_ACCOUNT = 0x0008
30
+ FILTER_WORKSTATION_TRUST_ACCOUNT = 0x0010
31
+ FILTER_SERVER_TRUST_ACCOUNT = 0x0020
32
+
33
+ MAX_PREFERRED_LENGTH = 0xFFFF
34
+
35
+ NERR_Success = 0
36
+
37
+ ffi_lib "netapi32"
38
+
39
+ class USER_INFO_3 < FFI::Struct
40
+ layout :usri3_name, :LPWSTR,
41
+ :usri3_password, :LPWSTR,
42
+ :usri3_password_age, :DWORD,
43
+ :usri3_priv, :DWORD,
44
+ :usri3_home_dir, :LPWSTR,
45
+ :usri3_comment, :LPWSTR,
46
+ :usri3_flags, :DWORD,
47
+ :usri3_script_path, :LPWSTR,
48
+ :usri3_auth_flags, :DWORD,
49
+ :usri3_full_name, :LPWSTR,
50
+ :usri3_usr_comment, :LPWSTR,
51
+ :usri3_parms, :LPWSTR,
52
+ :usri3_workstations, :LPWSTR,
53
+ :usri3_last_logon, :DWORD,
54
+ :usri3_last_logoff, :DWORD,
55
+ :usri3_acct_expires, :DWORD,
56
+ :usri3_max_storage, :DWORD,
57
+ :usri3_units_per_week, :DWORD,
58
+ :usri3_logon_hours, :PBYTE,
59
+ :usri3_bad_pw_count, :DWORD,
60
+ :usri3_num_logons, :DWORD,
61
+ :usri3_logon_server, :LPWSTR,
62
+ :usri3_country_code, :DWORD,
63
+ :usri3_code_page, :DWORD,
64
+ :usri3_user_id, :DWORD,
65
+ :usri3_primary_group_id, :DWORD,
66
+ :usri3_profile, :LPWSTR,
67
+ :usri3_home_dir_drive, :LPWSTR,
68
+ :usri3_password_expired, :DWORD
69
+ end
70
+
71
+ # NET_API_STATUS NetUserEnum(
72
+ # _In_ LPCWSTR servername,
73
+ # _In_ DWORD level,
74
+ # _In_ DWORD filter,
75
+ # _Out_ LPBYTE *bufptr,
76
+ # _In_ DWORD prefmaxlen,
77
+ # _Out_ LPDWORD entriesread,
78
+ # _Out_ LPDWORD totalentries,
79
+ # _Inout_ LPDWORD resume_handle
80
+ # );
81
+ safe_attach_function :NetUserEnum, [ :LPCWSTR, :DWORD, :DWORD, :LPBYTE, :DWORD, :LPDWORD, :LPDWORD, :LPDWORD ], :DWORD
82
+
83
+ # NET_API_STATUS NetApiBufferFree(
84
+ # _In_ LPVOID Buffer
85
+ # );
86
+ safe_attach_function :NetApiBufferFree, [ :LPVOID ], :DWORD
87
+ end
88
+ end
89
+ end
90
+ end
@@ -17,11 +17,22 @@
17
17
  #
18
18
 
19
19
  require 'chef/win32/security'
20
+ require 'chef/win32/api/net'
21
+ require 'chef/win32/api/error'
22
+
23
+ require 'wmi-lite/wmi'
20
24
 
21
25
  class Chef
22
26
  module ReservedNames::Win32
23
27
  class Security
24
28
  class SID
29
+ include Chef::ReservedNames::Win32::API::Net
30
+ include Chef::ReservedNames::Win32::API::Error
31
+
32
+ class << self
33
+ include Chef::ReservedNames::Win32::API::Net
34
+ include Chef::ReservedNames::Win32::API::Error
35
+ end
25
36
 
26
37
  def initialize(pointer, owner = nil)
27
38
  @pointer = pointer
@@ -178,13 +189,11 @@ class Chef
178
189
  SID.from_string_sid('S-1-5-32-544')
179
190
  end
180
191
 
181
- # Machine-specific, well-known SIDs
182
- # TODO: don't use strings, dummy
183
192
  def self.None
184
193
  SID.from_account("#{::ENV['COMPUTERNAME']}\\None")
185
194
  end
186
195
  def self.Administrator
187
- SID.from_account("#{::ENV['COMPUTERNAME']}\\Administrator")
196
+ SID.from_account("#{::ENV['COMPUTERNAME']}\\#{SID.admin_account_name}")
188
197
  end
189
198
  def self.Guest
190
199
  SID.from_account("#{::ENV['COMPUTERNAME']}\\Guest")
@@ -193,6 +202,47 @@ class Chef
193
202
  def self.current_user
194
203
  SID.from_account("#{::ENV['USERDOMAIN']}\\#{::ENV['USERNAME']}")
195
204
  end
205
+
206
+ def self.admin_account_name
207
+ @admin_account_name ||= begin
208
+ admin_account_name = nil
209
+
210
+ # Call NetUserEnum to enumerate the users without hitting network
211
+ # http://msdn.microsoft.com/en-us/library/windows/desktop/aa370652(v=vs.85).aspx
212
+ servername = nil # We are querying the local server
213
+ level = 3 # We want USER_INFO_3 structure which contains the SID
214
+ filter = FILTER_NORMAL_ACCOUNT # Only query the user accounts
215
+ bufptr = FFI::MemoryPointer.new(:pointer) # Buffer which will receive the data
216
+ prefmaxlen = MAX_PREFERRED_LENGTH # Let the system allocate the needed amount of memory
217
+ entriesread = FFI::Buffer.new(:long).write_long(0)
218
+ totalentries = FFI::Buffer.new(:long).write_long(0)
219
+ resume_handle = FFI::Buffer.new(:long).write_long(0)
220
+
221
+ status = ERROR_MORE_DATA
222
+
223
+ while(status == ERROR_MORE_DATA) do
224
+ status = NetUserEnum(servername, level, filter, bufptr, prefmaxlen, entriesread, totalentries, resume_handle)
225
+
226
+ if (status == NERR_Success || status == ERROR_MORE_DATA)
227
+ entriesread.read_long.times.collect do |i|
228
+ user_info = USER_INFO_3.new(bufptr.read_pointer + i * USER_INFO_3.size)
229
+ # Check if the account is the Administrator account
230
+ # RID for the Administrator account is always 500 and it's privilage is set to USER_PRIV_ADMIN
231
+ if user_info[:usri3_user_id] == 500 && user_info[:usri3_priv] == 2 # USER_PRIV_ADMIN (2) - Administrator
232
+ admin_account_name = user_info[:usri3_name].read_wstring
233
+ break
234
+ end
235
+ end
236
+
237
+ # Free the memory allocated by the system
238
+ NetApiBufferFree(bufptr.read_pointer)
239
+ end
240
+ end
241
+
242
+ raise "Can not determine the administrator account name." if admin_account_name.nil?
243
+ admin_account_name
244
+ end
245
+ end
196
246
  end
197
247
  end
198
248
  end