chef 12.0.0.alpha.1 → 12.0.0.alpha.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (180) hide show
  1. checksums.yaml +4 -4
  2. data/lib/chef/application.rb +8 -1
  3. data/lib/chef/application/apply.rb +4 -0
  4. data/lib/chef/application/client.rb +7 -7
  5. data/lib/chef/application/solo.rb +21 -13
  6. data/lib/chef/chef_fs/chef_fs_data_store.rb +60 -6
  7. data/lib/chef/chef_fs/config.rb +78 -4
  8. data/lib/chef/chef_fs/data_handler/acl_data_handler.rb +2 -2
  9. data/lib/chef/chef_fs/data_handler/client_data_handler.rb +1 -1
  10. data/lib/chef/chef_fs/data_handler/container_data_handler.rb +1 -1
  11. data/lib/chef/chef_fs/data_handler/cookbook_data_handler.rb +1 -1
  12. data/lib/chef/chef_fs/data_handler/data_bag_item_data_handler.rb +1 -1
  13. data/lib/chef/chef_fs/data_handler/data_handler_base.rb +76 -2
  14. data/lib/chef/chef_fs/data_handler/environment_data_handler.rb +1 -1
  15. data/lib/chef/chef_fs/data_handler/group_data_handler.rb +1 -1
  16. data/lib/chef/chef_fs/data_handler/node_data_handler.rb +1 -1
  17. data/lib/chef/chef_fs/data_handler/organization_data_handler.rb +30 -0
  18. data/lib/chef/chef_fs/data_handler/organization_invites_data_handler.rb +17 -0
  19. data/lib/chef/chef_fs/data_handler/organization_members_data_handler.rb +17 -0
  20. data/lib/chef/chef_fs/data_handler/role_data_handler.rb +1 -1
  21. data/lib/chef/chef_fs/data_handler/user_data_handler.rb +2 -1
  22. data/lib/chef/chef_fs/file_system.rb +0 -1
  23. data/lib/chef/chef_fs/file_system/acl_entry.rb +1 -1
  24. data/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_dir.rb +1 -1
  25. data/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb +5 -1
  26. data/lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb +73 -13
  27. data/lib/chef/chef_fs/file_system/chef_server_root_dir.rb +44 -5
  28. data/lib/chef/chef_fs/file_system/cookbook_dir.rb +1 -1
  29. data/lib/chef/chef_fs/file_system/cookbooks_dir.rb +3 -3
  30. data/lib/chef/chef_fs/file_system/org_entry.rb +34 -0
  31. data/lib/chef/chef_fs/file_system/organization_invites_entry.rb +58 -0
  32. data/lib/chef/chef_fs/file_system/organization_members_entry.rb +57 -0
  33. data/lib/chef/chef_fs/file_system/rest_list_entry.rb +13 -4
  34. data/lib/chef/chef_fs/knife.rb +1 -1
  35. data/lib/chef/client.rb +8 -2
  36. data/lib/chef/config.rb +75 -57
  37. data/lib/chef/config_fetcher.rb +6 -21
  38. data/lib/chef/dsl/data_query.rb +48 -3
  39. data/lib/chef/dsl/platform_introspection.rb +42 -0
  40. data/lib/chef/dsl/reboot_pending.rb +6 -3
  41. data/lib/chef/encrypted_data_bag_item.rb +1 -1
  42. data/lib/chef/encrypted_data_bag_item/encryptor.rb +12 -0
  43. data/lib/chef/exceptions.rb +2 -0
  44. data/lib/chef/http/basic_client.rb +14 -0
  45. data/lib/chef/http/json_output.rb +7 -2
  46. data/lib/chef/knife.rb +36 -121
  47. data/lib/chef/knife/bootstrap.rb +68 -54
  48. data/lib/chef/knife/bootstrap/archlinux-gems.erb +6 -1
  49. data/lib/chef/knife/bootstrap/chef-aix.erb +5 -0
  50. data/lib/chef/knife/bootstrap/chef-full.erb +5 -1
  51. data/lib/chef/knife/core/bootstrap_context.rb +70 -29
  52. data/lib/chef/knife/search.rb +56 -12
  53. data/lib/chef/knife/serve.rb +1 -1
  54. data/lib/chef/local_mode.rb +10 -4
  55. data/lib/chef/mixin/deep_merge.rb +6 -3
  56. data/lib/chef/mixin/shell_out.rb +33 -17
  57. data/lib/chef/null_logger.rb +72 -0
  58. data/lib/chef/platform.rb +2 -1
  59. data/lib/chef/platform/provider_mapping.rb +1 -1
  60. data/lib/chef/platform/rebooter.rb +54 -0
  61. data/lib/chef/provider/ifconfig.rb +15 -16
  62. data/lib/chef/provider/link.rb +1 -1
  63. data/lib/chef/provider/mount/mount.rb +1 -1
  64. data/lib/chef/provider/mount/solaris.rb +102 -64
  65. data/lib/chef/provider/package/aix.rb +4 -12
  66. data/lib/chef/provider/package/ips.rb +8 -12
  67. data/lib/chef/provider/package/macports.rb +4 -12
  68. data/lib/chef/provider/package/pacman.rb +2 -6
  69. data/lib/chef/provider/package/portage.rb +2 -6
  70. data/lib/chef/provider/package/rpm.rb +4 -12
  71. data/lib/chef/provider/package/solaris.rb +4 -12
  72. data/lib/chef/provider/reboot.rb +69 -0
  73. data/lib/chef/provider/service/debian.rb +10 -10
  74. data/lib/chef/provider/service/freebsd.rb +89 -73
  75. data/lib/chef/provider/service/gentoo.rb +2 -2
  76. data/lib/chef/provider/service/init.rb +6 -4
  77. data/lib/chef/provider/service/insserv.rb +3 -3
  78. data/lib/chef/provider/service/macosx.rb +2 -2
  79. data/lib/chef/provider/service/simple.rb +6 -4
  80. data/lib/chef/provider/service/solaris.rb +1 -1
  81. data/lib/chef/provider/service/systemd.rb +9 -9
  82. data/lib/chef/provider/service/upstart.rb +6 -6
  83. data/lib/chef/provider/subversion.rb +6 -6
  84. data/lib/chef/provider/user/dscl.rb +32 -28
  85. data/lib/chef/provider/user/windows.rb +6 -6
  86. data/lib/chef/provider/whyrun_safe_ruby_block.rb +1 -1
  87. data/lib/chef/providers.rb +1 -0
  88. data/lib/chef/recipe.rb +0 -1
  89. data/lib/chef/resource.rb +3 -5
  90. data/lib/chef/resource/mount.rb +9 -0
  91. data/lib/chef/resource/reboot.rb +48 -0
  92. data/lib/chef/resources.rb +1 -0
  93. data/lib/chef/run_context.rb +25 -0
  94. data/lib/chef/search/query.rb +122 -14
  95. data/lib/chef/util/path_helper.rb +54 -6
  96. data/lib/chef/util/windows/net_user.rb +4 -1
  97. data/lib/chef/version.rb +1 -1
  98. data/lib/chef/win32/api/file.rb +1 -5
  99. data/lib/chef/win32/api/net.rb +1 -0
  100. data/lib/chef/workstation_config_loader.rb +177 -0
  101. data/spec/functional/http/simple_spec.rb +57 -1
  102. data/spec/functional/mixin/shell_out_spec.rb +2 -2
  103. data/spec/functional/provider/whyrun_safe_ruby_block_spec.rb +51 -0
  104. data/spec/functional/rebooter_spec.rb +105 -0
  105. data/spec/functional/resource/deploy_revision_spec.rb +0 -4
  106. data/spec/functional/resource/file_spec.rb +26 -3
  107. data/spec/functional/resource/group_spec.rb +5 -3
  108. data/spec/functional/resource/link_spec.rb +16 -16
  109. data/spec/functional/resource/reboot_spec.rb +103 -0
  110. data/spec/integration/client/client_spec.rb +4 -8
  111. data/spec/integration/client/ipv6_spec.rb +1 -1
  112. data/spec/integration/knife/cookbook_api_ipv6_spec.rb +3 -2
  113. data/spec/integration/knife/delete_spec.rb +39 -0
  114. data/spec/integration/knife/deps_spec.rb +30 -20
  115. data/spec/integration/knife/download_spec.rb +77 -1
  116. data/spec/integration/knife/list_spec.rb +221 -0
  117. data/spec/integration/knife/raw_spec.rb +1 -1
  118. data/spec/integration/knife/show_spec.rb +2 -2
  119. data/spec/integration/knife/upload_spec.rb +154 -1
  120. data/spec/support/pedant/run_pedant.rb +0 -1
  121. data/spec/support/shared/functional/http.rb +8 -1
  122. data/spec/support/shared/integration/integration_helper.rb +11 -19
  123. data/spec/support/shared/unit/platform_introspector.rb +22 -0
  124. data/spec/unit/application/apply.rb +11 -1
  125. data/spec/unit/application/solo_spec.rb +19 -3
  126. data/spec/unit/chef_fs/config_spec.rb +58 -0
  127. data/spec/unit/config_fetcher_spec.rb +1 -3
  128. data/spec/unit/config_spec.rb +247 -220
  129. data/spec/unit/dsl/data_query_spec.rb +165 -23
  130. data/spec/unit/dsl/reboot_pending_spec.rb +1 -7
  131. data/spec/unit/encrypted_data_bag_item_spec.rb +1 -1
  132. data/spec/unit/knife/bootstrap_spec.rb +354 -182
  133. data/spec/unit/knife/core/bootstrap_context_spec.rb +67 -30
  134. data/spec/unit/knife_spec.rb +3 -30
  135. data/spec/unit/mixin/deep_merge_spec.rb +14 -0
  136. data/spec/unit/mixin/shell_out_spec.rb +134 -64
  137. data/spec/unit/provider/ifconfig/debian_spec.rb +19 -9
  138. data/spec/unit/provider/ifconfig/redhat_spec.rb +16 -14
  139. data/spec/unit/provider/ifconfig_spec.rb +3 -3
  140. data/spec/unit/provider/link_spec.rb +5 -5
  141. data/spec/unit/provider/mount/mount_spec.rb +10 -1
  142. data/spec/unit/provider/mount/solaris_spec.rb +185 -11
  143. data/spec/unit/provider/package/aix_spec.rb +5 -17
  144. data/spec/unit/provider/package/ips_spec.rb +8 -21
  145. data/spec/unit/provider/package/macports_spec.rb +12 -12
  146. data/spec/unit/provider/package/pacman_spec.rb +4 -12
  147. data/spec/unit/provider/package/portage_spec.rb +5 -15
  148. data/spec/unit/provider/package/rpm_spec.rb +7 -22
  149. data/spec/unit/provider/package/solaris_spec.rb +5 -16
  150. data/spec/unit/provider/service/arch_service_spec.rb +8 -14
  151. data/spec/unit/provider/service/debian_service_spec.rb +1 -1
  152. data/spec/unit/provider/service/freebsd_service_spec.rb +457 -225
  153. data/spec/unit/provider/service/gentoo_service_spec.rb +2 -2
  154. data/spec/unit/provider/service/init_service_spec.rb +10 -10
  155. data/spec/unit/provider/service/insserv_service_spec.rb +3 -4
  156. data/spec/unit/provider/service/invokercd_service_spec.rb +8 -9
  157. data/spec/unit/provider/service/macosx_spec.rb +5 -5
  158. data/spec/unit/provider/service/simple_service_spec.rb +4 -6
  159. data/spec/unit/provider/service/solaris_smf_service_spec.rb +1 -3
  160. data/spec/unit/provider/service/systemd_service_spec.rb +20 -20
  161. data/spec/unit/provider/service/upstart_service_spec.rb +15 -17
  162. data/spec/unit/provider/subversion_spec.rb +5 -6
  163. data/spec/unit/provider/user/dscl_spec.rb +2 -1
  164. data/spec/unit/provider/user/windows_spec.rb +7 -0
  165. data/spec/unit/provider/whyrun_safe_ruby_block_spec.rb +2 -2
  166. data/spec/unit/resource/mount_spec.rb +9 -0
  167. data/spec/unit/resource_spec.rb +0 -4
  168. data/spec/unit/rest_spec.rb +1 -1
  169. data/spec/unit/run_context_spec.rb +15 -0
  170. data/spec/unit/search/query_spec.rb +196 -40
  171. data/spec/unit/util/path_helper_spec.rb +111 -28
  172. data/spec/unit/workstation_config_loader_spec.rb +283 -0
  173. metadata +36 -20
  174. data/lib/chef/knife/bootstrap/centos5-gems.erb +0 -62
  175. data/lib/chef/knife/bootstrap/fedora13-gems.erb +0 -44
  176. data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +0 -53
  177. data/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb +0 -48
  178. data/lib/chef/knife/bootstrap/ubuntu12.04-gems.erb +0 -46
  179. data/spec/support/shared/integration/chef_zero_support.rb +0 -130
  180. data/spec/unit/knife/config_file_selection_spec.rb +0 -135
@@ -33,7 +33,7 @@ class Chef
33
33
  def run
34
34
  server = Chef::LocalMode.chef_zero_server
35
35
  begin
36
- output "Serving files from:\n#{server.options[:data_store].chef_fs.fs_description}"
36
+ output "Serving files from:\n#{Chef::LocalMode.chef_fs.fs_description}"
37
37
  server.stop
38
38
  server.start(stdout) # to print header
39
39
  ensure
@@ -52,9 +52,10 @@ class Chef
52
52
  require 'chef/chef_fs/chef_fs_data_store'
53
53
  require 'chef/chef_fs/config'
54
54
 
55
- chef_fs = Chef::ChefFS::Config.new.local_fs
56
- chef_fs.write_pretty_json = true
57
- data_store = Chef::ChefFS::ChefFSDataStore.new(chef_fs)
55
+ @chef_fs = Chef::ChefFS::Config.new.local_fs
56
+ @chef_fs.write_pretty_json = true
57
+ data_store = Chef::ChefFS::ChefFSDataStore.new(@chef_fs)
58
+ data_store = ChefZero::DataStore::V1ToV2Adapter.new(data_store, 'chef')
58
59
  server_options = {}
59
60
  server_options[:data_store] = data_store
60
61
  server_options[:log_level] = Chef::Log.level
@@ -62,7 +63,7 @@ class Chef
62
63
  server_options[:port] = parse_port(Chef::Config.chef_zero.port)
63
64
  @chef_zero_server = ChefZero::Server.new(server_options)
64
65
  @chef_zero_server.start_background
65
- Chef::Log.info("Started chef-zero at #{@chef_zero_server.url} with #{chef_fs.fs_description}")
66
+ Chef::Log.info("Started chef-zero at #{@chef_zero_server.url} with #{@chef_fs.fs_description}")
66
67
  Chef::Config.chef_server_url = @chef_zero_server.url
67
68
  end
68
69
  end
@@ -72,6 +73,11 @@ class Chef
72
73
  @chef_zero_server
73
74
  end
74
75
 
76
+ # Return the chef_fs object for the current chef-zero server.
77
+ def self.chef_fs
78
+ @chef_fs
79
+ end
80
+
75
81
  # If chef_zero_server is non-nil, stop it and remove references to it.
76
82
  def self.destroy_server_connectivity
77
83
  if @chef_zero_server
@@ -29,7 +29,6 @@ class Chef
29
29
 
30
30
  class InvalidSubtractiveMerge < ArgumentError; end
31
31
 
32
-
33
32
  OLD_KNOCKOUT_PREFIX = "!merge:".freeze
34
33
 
35
34
  # Regex to match the "knockout prefix" that was used to indicate
@@ -86,8 +85,12 @@ class Chef
86
85
  when Hash
87
86
  if dest.kind_of?(Hash)
88
87
  source.each do |src_key, src_value|
89
- if dest[src_key]
90
- dest[src_key] = deep_merge!(src_value, dest[src_key])
88
+ if dest.has_key? src_key
89
+ if dest[src_key].nil?
90
+ dest[src_key] = nil
91
+ else
92
+ dest[src_key] = deep_merge!(src_value, dest[src_key])
93
+ end
91
94
  else # dest[src_key] doesn't exist so we take whatever source has
92
95
  raise_if_knockout_used!(src_value)
93
96
  dest[src_key] = src_value
@@ -20,7 +20,6 @@
20
20
  require 'chef/shell_out'
21
21
 
22
22
  require 'mixlib/shellout'
23
- require 'chef/config'
24
23
 
25
24
  class Chef
26
25
  module Mixin
@@ -31,32 +30,39 @@ class Chef
31
30
  # Generally speaking, 'extend Chef::Mixin::ShellOut' in your recipes and include 'Chef::Mixin::ShellOut' in your LWRPs
32
31
  # You can also call Mixlib::Shellout.new directly, but you lose all of the above functionality
33
32
 
33
+ # we use 'en_US.UTF-8' by default because we parse localized strings in English as an API and
34
+ # generally must support UTF-8 unicode.
34
35
  def shell_out(*command_args)
35
- cmd = Mixlib::ShellOut.new(*run_command_compatible_options(command_args))
36
- cmd.live_stream ||= io_for_live_stream
37
- cmd.run_command
38
- cmd
36
+ args = command_args.dup
37
+ if args.last.is_a?(Hash)
38
+ options = args.pop.dup
39
+ env_key = options.has_key?(:env) ? :env : :environment
40
+ options[env_key] ||= {}
41
+ options[env_key] = options[env_key].dup
42
+ options[env_key]['LC_ALL'] ||= Chef::Config[:internal_locale] unless options[env_key].has_key?('LC_ALL')
43
+ args << options
44
+ else
45
+ args << { :environment => { 'LC_ALL' => Chef::Config[:internal_locale] } }
46
+ end
47
+
48
+ shell_out_command(*args)
39
49
  end
40
50
 
51
+ # call shell_out (using en_US.UTF-8) and raise errors
41
52
  def shell_out!(*command_args)
42
- cmd= shell_out(*command_args)
53
+ cmd = shell_out(*command_args)
43
54
  cmd.error!
44
55
  cmd
45
56
  end
46
57
 
47
- # environment['LC_ALL'] should be nil or what the user specified
48
58
  def shell_out_with_systems_locale(*command_args)
49
- args = command_args.dup
50
- if args.last.is_a?(Hash)
51
- options = args.last
52
- env_key = options.has_key?(:env) ? :env : :environment
53
- options[env_key] ||= {}
54
- options[env_key]['LC_ALL'] ||= nil
55
- else
56
- args << { :environment => { 'LC_ALL' => nil } }
57
- end
59
+ shell_out_command(*command_args)
60
+ end
58
61
 
59
- shell_out(*args)
62
+ def shell_out_with_systems_locale!(*command_args)
63
+ cmd = shell_out_with_systems_locale(*command_args)
64
+ cmd.error!
65
+ cmd
60
66
  end
61
67
 
62
68
  DEPRECATED_OPTIONS =
@@ -83,6 +89,13 @@ class Chef
83
89
 
84
90
  private
85
91
 
92
+ def shell_out_command(*command_args)
93
+ cmd = Mixlib::ShellOut.new(*run_command_compatible_options(command_args))
94
+ cmd.live_stream ||= io_for_live_stream
95
+ cmd.run_command
96
+ cmd
97
+ end
98
+
86
99
  def deprecate_option(old_option, new_option)
87
100
  Chef::Log.logger.warn "DEPRECATION: Chef::Mixin::ShellOut option :#{old_option} is deprecated. Use :#{new_option}"
88
101
  end
@@ -97,3 +110,6 @@ class Chef
97
110
  end
98
111
  end
99
112
  end
113
+
114
+ # Break circular dep
115
+ require 'chef/config'
@@ -0,0 +1,72 @@
1
+ #
2
+ # Author:: Daniel DeLeo (<dan@getchef.com>)
3
+ # Copyright:: Copyright (c) 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
+ class Chef
19
+
20
+ # Null logger implementation that just ignores everything. This is used by
21
+ # classes that are intended to be reused outside of Chef, but need to offer
22
+ # logging functionality when used by other Chef code.
23
+ #
24
+ # It does not define the full interface provided by Logger, just enough to be
25
+ # a reasonable duck type. In particular, methods setting the log level, log
26
+ # device, etc., are not implemented because any code calling those methods
27
+ # probably expected a real logger and not this "fake" one.
28
+ class NullLogger
29
+
30
+ def fatal(message, &block)
31
+ end
32
+
33
+ def error(message, &block)
34
+ end
35
+
36
+ def warn(message, &block)
37
+ end
38
+
39
+ def info(message, &block)
40
+ end
41
+
42
+ def debug(message, &block)
43
+ end
44
+
45
+ def add(severity, message=nil, progname=nil)
46
+ end
47
+
48
+ def <<(message)
49
+ end
50
+
51
+ def fatal?
52
+ false
53
+ end
54
+
55
+ def error?
56
+ false
57
+ end
58
+
59
+ def warn?
60
+ false
61
+ end
62
+
63
+ def info?
64
+ false
65
+ end
66
+
67
+ def debug?
68
+ false
69
+ end
70
+
71
+ end
72
+ end
data/lib/chef/platform.rb CHANGED
@@ -16,8 +16,9 @@
16
16
  # limitations under the License.
17
17
  #
18
18
 
19
- require 'chef/platform/provider_mapping'
19
+ # Order of these headers is important: query helpers is needed by many things
20
20
  require 'chef/platform/query_helpers'
21
+ require 'chef/platform/provider_mapping'
21
22
 
22
23
  class Chef
23
24
  class Platform
@@ -16,8 +16,8 @@
16
16
  # limitations under the License.
17
17
  #
18
18
 
19
- require 'chef/config'
20
19
  require 'chef/log'
20
+ require 'chef/exceptions'
21
21
  require 'chef/mixin/params_validate'
22
22
  require 'chef/version_constraint/platform'
23
23
 
@@ -0,0 +1,54 @@
1
+ #
2
+ # Author:: Chris Doherty <cdoherty@getchef.com>)
3
+ # Copyright:: Copyright (c) 2014 Chef, 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/dsl/reboot_pending'
20
+ require 'chef/log'
21
+ require 'chef/platform'
22
+
23
+ class Chef
24
+ class Platform
25
+ module Rebooter
26
+ extend Chef::Mixin::ShellOut
27
+
28
+ class << self
29
+
30
+ def reboot!(node)
31
+ reboot_info = node.run_context.reboot_info
32
+
33
+ cmd = if Chef::Platform.windows?
34
+ # should this do /f as well? do we then need a minimum delay to let apps quit?
35
+ "shutdown /r /t #{reboot_info[:delay_mins]} /c \"#{reboot_info[:reason]}\""
36
+ else
37
+ # probably Linux-only.
38
+ "shutdown -r +#{reboot_info[:delay_mins]} \"#{reboot_info[:reason]}\""
39
+ end
40
+
41
+ Chef::Log.warn "Rebooting server at a recipe's request. Details: #{reboot_info.inspect}"
42
+ shell_out!(cmd)
43
+ end
44
+
45
+ # this is a wrapper function so Chef::Client only needs a single line of code.
46
+ def reboot_if_needed!(node)
47
+ if node.run_context.reboot_requested?
48
+ reboot!(node)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -19,6 +19,7 @@
19
19
  require 'chef/log'
20
20
  require 'chef/mixin/command'
21
21
  require 'chef/provider'
22
+ require 'chef/resource/file'
22
23
  require 'chef/exceptions'
23
24
  require 'erb'
24
25
 
@@ -109,11 +110,11 @@ class Chef
109
110
  :command => command
110
111
  )
111
112
  Chef::Log.info("#{@new_resource} added")
112
- # Write out the config files
113
- generate_config
114
113
  end
115
114
  end
116
115
  end
116
+ # Write out the config files
117
+ generate_config
117
118
  end
118
119
 
119
120
  def action_enable
@@ -140,12 +141,12 @@ class Chef
140
141
  run_command(
141
142
  :command => command
142
143
  )
143
- delete_config
144
144
  Chef::Log.info("#{@new_resource} deleted")
145
145
  end
146
146
  else
147
147
  Chef::Log.debug("#{@new_resource} does not exist - nothing to do")
148
148
  end
149
+ delete_config
149
150
  end
150
151
 
151
152
  def action_disable
@@ -168,27 +169,25 @@ class Chef
168
169
  ! @config_template.nil? and ! @config_path.nil?
169
170
  end
170
171
 
172
+ def resource_for_config(path)
173
+ Chef::Resource::File.new(path, run_context)
174
+ end
175
+
171
176
  def generate_config
172
177
  return unless can_generate_config?
173
178
  b = binding
174
179
  template = ::ERB.new(@config_template)
175
- converge_by ("generate configuration file : #{@config_path}") do
176
- network_file = ::File.new(@config_path, "w")
177
- network_file.puts(template.result(b))
178
- network_file.close
179
- end
180
- Chef::Log.info("#{@new_resource} created configuration file")
180
+ config = resource_for_config(@config_path)
181
+ config.content(template.result(b))
182
+ config.run_action(:create)
183
+ @new_resource.updated_by_last_action(true) if config.updated?
181
184
  end
182
185
 
183
186
  def delete_config
184
187
  return unless can_generate_config?
185
- require 'fileutils'
186
- if ::File.exist?(@config_path)
187
- converge_by ("delete the #{@config_path}") do
188
- FileUtils.rm_f(@config_path, :verbose => false)
189
- end
190
- end
191
- Chef::Log.info("#{@new_resource} deleted configuration file")
188
+ config = resource_for_config(@config_path)
189
+ config.run_action(:delete)
190
+ @new_resource.updated_by_last_action(true) if config.updated?
192
191
  end
193
192
 
194
193
  private
@@ -83,7 +83,7 @@ class Chef
83
83
  end
84
84
 
85
85
  def canonicalize(path)
86
- Chef::Platform.windows? ? path.gsub('/', '\\') : path
86
+ Chef::Util::PathHelper.canonical_path(path)
87
87
  end
88
88
 
89
89
  def action_create
@@ -127,7 +127,7 @@ class Chef
127
127
  end
128
128
 
129
129
  def remount_command
130
- return "mount -o remount #{@new_resource.mount_point}"
130
+ return "mount -o remount,#{@new_resource.options.join(',')} #{@new_resource.mount_point}"
131
131
  end
132
132
 
133
133
  def remount_fs
@@ -1,4 +1,4 @@
1
- #
1
+ # Encoding: utf-8
2
2
  # Author:: Hugo Fichter
3
3
  # Author:: Lamont Granquist (<lamont@getchef.com>)
4
4
  # Author:: Joshua Timberman (<joshua@getchef.com>)
@@ -25,14 +25,16 @@ require 'forwardable'
25
25
  class Chef
26
26
  class Provider
27
27
  class Mount
28
+ # Mount Solaris File systems
28
29
  class Solaris < Chef::Provider::Mount
29
30
  extend Forwardable
30
31
 
31
- VFSTAB = "/etc/vfstab".freeze
32
+ VFSTAB = '/etc/vfstab'.freeze
32
33
 
33
34
  def_delegator :@new_resource, :device, :device
34
35
  def_delegator :@new_resource, :device_type, :device_type
35
36
  def_delegator :@new_resource, :dump, :dump
37
+ def_delegator :@new_resource, :fsck_device, :fsck_device
36
38
  def_delegator :@new_resource, :fstype, :fstype
37
39
  def_delegator :@new_resource, :mount_point, :mount_point
38
40
  def_delegator :@new_resource, :options, :options
@@ -42,6 +44,7 @@ class Chef
42
44
  @current_resource = Chef::Resource::Mount.new(new_resource.name)
43
45
  current_resource.mount_point(mount_point)
44
46
  current_resource.device(device)
47
+ current_resource.fsck_device(fsck_device)
45
48
  current_resource.device_type(device_type)
46
49
  update_current_resource_state
47
50
  end
@@ -53,6 +56,14 @@ class Chef
53
56
  a.whyrun("Assuming device #{device} would have been created")
54
57
  end
55
58
 
59
+ unless fsck_device == '-'
60
+ requirements.assert(:mount, :remount) do |a|
61
+ a.assertion { ::File.exist?(fsck_device) }
62
+ a.failure_message(Chef::Exceptions::Mount, "Device #{fsck_device} does not exist")
63
+ a.whyrun("Assuming device #{fsck_device} would have been created")
64
+ end
65
+ end
66
+
56
67
  requirements.assert(:mount, :remount) do |a|
57
68
  a.assertion { ::File.exist?(mount_point) }
58
69
  a.failure_message(Chef::Exceptions::Mount, "Mount point #{mount_point} does not exist")
@@ -62,7 +73,7 @@ class Chef
62
73
 
63
74
  def mount_fs
64
75
  actual_options = options || []
65
- actual_options.delete("noauto")
76
+ actual_options.delete('noauto')
66
77
  command = "mount -F #{fstype}"
67
78
  command << " -o #{actual_options.join(',')}" unless actual_options.empty?
68
79
  command << " #{device} #{mount_point}"
@@ -74,59 +85,28 @@ class Chef
74
85
  end
75
86
 
76
87
  def remount_fs
77
- # FIXME: what about options like "-o remount,logging" to enable logging on a UFS device?
78
- shell_out!("mount -o remount #{mount_point}")
88
+ # FIXME: Should remount always do the remount or only if the options change?
89
+ actual_options = options || []
90
+ actual_options.delete('noauto')
91
+ mount_options = actual_options.empty? ? '' : ",#{actual_options.join(',')}"
92
+ shell_out!("mount -o remount#{mount_options} #{mount_point}")
79
93
  end
80
94
 
81
95
  def enable_fs
82
- if !mount_options_unchanged?
96
+ unless mount_options_unchanged?
83
97
  # we are enabling because our options have changed, so disable first then re-enable.
84
98
  # XXX: this should be refactored to be the responsibility of the caller
85
99
  disable_fs if current_resource.enabled
86
100
  end
87
101
 
88
- auto = options.nil? || ! options.include?("noauto")
89
- actual_options = unless options.nil?
90
- options.delete("noauto")
91
- options
92
- end
93
-
94
- autostr = auto ? 'yes' : 'no'
95
- passstr = pass == 0 ? "-" : pass
96
- optstr = (actual_options.nil? || actual_options.empty?) ? "-" : actual_options.join(',')
97
-
98
- etc_tempfile do |f|
99
- f.write(IO.read(VFSTAB).chomp)
100
- f.puts("\n#{device}\t-\t#{mount_point}\t#{fstype}\t#{passstr}\t#{autostr}\t#{optstr}")
101
- f.close
102
- # move, preserving modes of destination file
103
- mover = Chef::FileContentManagement::Deploy.strategy(true)
104
- mover.deploy(f.path, VFSTAB)
105
- end
106
-
102
+ vfstab_write(merge_vfstab_entry)
107
103
  end
108
104
 
109
105
  def disable_fs
110
- contents = []
111
-
112
- found = false
113
- ::File.readlines(VFSTAB).reverse_each do |line|
114
- if !found && line =~ /^#{device_regex}\s+\S+\s+#{Regexp.escape(mount_point)}/
115
- found = true
116
- Chef::Log.debug("#{new_resource} is removed from vfstab")
117
- next
118
- end
119
- contents << line
120
- end
106
+ contents, found = delete_vfstab_entry
121
107
 
122
108
  if found
123
- etc_tempfile do |f|
124
- f.write(contents.reverse.join(''))
125
- f.close
126
- # move, preserving modes of destination file
127
- mover = Chef::FileContentManagement::Deploy.strategy(true)
128
- mover.deploy(f.path, VFSTAB)
129
- end
109
+ vfstab_write(contents.reverse)
130
110
  else
131
111
  # this is likely some kind of internal error, since we should only call disable_fs when there
132
112
  # the filesystem we want to disable is enabled.
@@ -135,19 +115,24 @@ class Chef
135
115
  end
136
116
 
137
117
  def etc_tempfile
138
- yield Tempfile.open("vfstab", "/etc")
118
+ yield Tempfile.open('vfstab', '/etc')
139
119
  end
140
120
 
141
121
  def mount_options_unchanged?
142
- current_resource.fstype == fstype and
143
- current_resource.options == options and
144
- current_resource.dump == dump and
145
- current_resource.pass == pass
122
+ new_options = options_remove_noauto(options)
123
+ current_options = options_remove_noauto(current_resource.nil? ? nil : current_resource.options)
124
+
125
+ current_resource.fsck_device == fsck_device &&
126
+ current_resource.fstype == fstype &&
127
+ current_options == new_options &&
128
+ current_resource.dump == dump &&
129
+ current_resource.pass == pass &&
130
+ current_resource.options.include?('noauto') == !mount_at_boot?
146
131
  end
147
132
 
148
133
  def update_current_resource_state
149
134
  current_resource.mounted(mounted?)
150
- ( enabled, fstype, options, pass ) = read_vfstab_status
135
+ (enabled, fstype, options, pass) = read_vfstab_status
151
136
  current_resource.enabled(enabled)
152
137
  current_resource.fstype(fstype)
153
138
  current_resource.options(options)
@@ -158,17 +143,18 @@ class Chef
158
143
  read_vfstab_status[0]
159
144
  end
160
145
 
146
+ # Check for the device in mounttab.
147
+ # <device> on <mountpoint> type <fstype> <options> on <date>
148
+ # /dev/dsk/c1t0d0s0 on / type ufs read/write/setuid/devices/intr/largefiles/logging/xattr/onerror=panic/dev=700040 on Tue May 1 11:33:55 2012
161
149
  def mounted?
162
150
  mounted = false
163
- shell_out!("mount -v").stdout.each_line do |line|
164
- # <device> on <mountpoint> type <fstype> <options> on <date>
165
- # /dev/dsk/c1t0d0s0 on / type ufs read/write/setuid/devices/intr/largefiles/logging/xattr/onerror=panic/dev=700040 on Tue May 1 11:33:55 2012
151
+ shell_out!('mount -v').stdout.each_line do |line|
166
152
  case line
167
153
  when /^#{device_regex}\s+on\s+#{Regexp.escape(mount_point)}\s+/
168
154
  Chef::Log.debug("Special device #{device} is mounted as #{mount_point}")
169
155
  mounted = true
170
156
  when /^([\/\w]+)\son\s#{Regexp.escape(mount_point)}\s+/
171
- Chef::Log.debug("Special device #{$1} is mounted as #{mount_point}")
157
+ Chef::Log.debug("Special device #{Regexp.last_match[1]} is mounted as #{mount_point}")
172
158
  mounted = false
173
159
  end
174
160
  end
@@ -178,7 +164,7 @@ class Chef
178
164
  private
179
165
 
180
166
  def read_vfstab_status
181
- # Check to see if there is a entry in /etc/vfstab. Last entry for a volume wins.
167
+ # Check to see if there is an entry in /etc/vfstab. Last entry for a volume wins.
182
168
  enabled = false
183
169
  fstype = options = pass = nil
184
170
  ::File.foreach(VFSTAB) do |line|
@@ -190,18 +176,18 @@ class Chef
190
176
  # to mount to fsck point type pass at boot options
191
177
  when /^#{device_regex}\s+[-\/\w]+\s+#{Regexp.escape(mount_point)}\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/
192
178
  enabled = true
193
- fstype = $1
194
- options = $4
179
+ fstype = Regexp.last_match[1]
180
+ options = Regexp.last_match[4]
195
181
  # Store the 'mount at boot' column from vfstab as the 'noauto' option
196
182
  # in current_resource.options (linux style)
197
- if $3 == "yes"
183
+ if Regexp.last_match[3] == 'no'
198
184
  if options.nil? || options.empty?
199
- options = "noauto"
185
+ options = 'noauto'
200
186
  else
201
- options += ",noauto"
187
+ options += ',noauto'
202
188
  end
203
189
  end
204
- pass = ( $2 == "-" ) ? 0 : $2.to_i
190
+ pass = (Regexp.last_match[2] == '-') ? 0 : Regexp.last_match[2].to_i
205
191
  Chef::Log.debug("Found mount #{device} to #{mount_point} in #{VFSTAB}")
206
192
  next
207
193
  when /^[-\/\w]+\s+[-\/\w]+\s+#{Regexp.escape(mount_point)}\s+/
@@ -210,21 +196,73 @@ class Chef
210
196
  Chef::Log.debug("Found conflicting mount point #{mount_point} in #{VFSTAB}")
211
197
  end
212
198
  end
213
- [ enabled, fstype, options, pass ]
199
+ [enabled, fstype, options, pass]
214
200
  end
215
201
 
216
202
  def device_should_exist?
217
- !%w{tmpfs nfs ctfs proc mntfs objfs sharefs fd smbfs}.include?(fstype)
203
+ !%w(tmpfs nfs ctfs proc mntfs objfs sharefs fd smbfs vxfs).include?(fstype)
204
+ end
205
+
206
+ def mount_at_boot?
207
+ options.nil? || !options.include?('noauto')
208
+ end
209
+
210
+ def vfstab_write(contents)
211
+ etc_tempfile do |f|
212
+ f.write(contents.join(''))
213
+ f.close
214
+ # move, preserving modes of destination file
215
+ mover = Chef::FileContentManagement::Deploy.strategy(true)
216
+ mover.deploy(f.path, VFSTAB)
217
+ end
218
+ end
219
+
220
+ def vfstab_entry
221
+ actual_options = unless options.nil?
222
+ tempops = options.dup
223
+ tempops.delete('noauto')
224
+ tempops
225
+ end
226
+ autostr = mount_at_boot? ? 'yes' : 'no'
227
+ passstr = pass == 0 ? '-' : pass
228
+ optstr = (actual_options.nil? || actual_options.empty?) ? '-' : actual_options.join(',')
229
+ "\n#{device}\t#{fsck_device}\t#{mount_point}\t#{fstype}\t#{passstr}\t#{autostr}\t#{optstr}\n"
230
+ end
231
+
232
+ def delete_vfstab_entry
233
+ contents = []
234
+ found = false
235
+ ::File.readlines(VFSTAB).reverse_each do |line|
236
+ if !found && line =~ /^#{device_regex}\s+\S+\s+#{Regexp.escape(mount_point)}/
237
+ found = true
238
+ Chef::Log.debug("#{new_resource} is removed from vfstab")
239
+ next
240
+ end
241
+ contents << line
242
+ end
243
+ [contents, found]
244
+ end
245
+
246
+ def merge_vfstab_entry
247
+ contents = ::File.readlines(VFSTAB)
248
+ contents[-1].chomp!
249
+ contents << vfstab_entry
250
+ end
251
+
252
+ def options_remove_noauto(temp_options)
253
+ new_options = []
254
+ new_options += temp_options.nil? ? [] : temp_options
255
+ new_options.delete('noauto')
256
+ new_options
218
257
  end
219
258
 
220
259
  def device_regex
221
260
  if ::File.symlink?(device)
222
- "(?:#{Regexp.escape(device)}|#{Regexp.escape(::File.expand_path(::File.readlink(device),::File.dirname(device)))})"
261
+ "(?:#{Regexp.escape(device)}|#{Regexp.escape(::File.expand_path(::File.readlink(device), ::File.dirname(device)))})"
223
262
  else
224
263
  Regexp.escape(device)
225
264
  end
226
265
  end
227
-
228
266
  end
229
267
  end
230
268
  end