puppet 2.6.6 → 2.6.7

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

Files changed (140) hide show
  1. data/CHANGELOG +107 -1
  2. data/README.queueing +1 -1
  3. data/Rakefile +1 -1
  4. data/conf/solaris/smf/svc-puppetd +0 -2
  5. data/conf/solaris/smf/svc-puppetmasterd +0 -2
  6. data/examples/etc/init.d/sleeper +0 -2
  7. data/examples/modules/sample-module/README.txt +2 -2
  8. data/ext/puppetstoredconfigclean.rb +1 -1
  9. data/install.rb +20 -25
  10. data/lib/puppet.rb +1 -1
  11. data/lib/puppet/application/agent.rb +2 -2
  12. data/lib/puppet/application/apply.rb +2 -2
  13. data/lib/puppet/application/cert.rb +27 -11
  14. data/lib/puppet/application/filebucket.rb +1 -1
  15. data/lib/puppet/application/inspect.rb +1 -1
  16. data/lib/puppet/application/kick.rb +2 -2
  17. data/lib/puppet/application/master.rb +1 -1
  18. data/lib/puppet/application/queue.rb +2 -2
  19. data/lib/puppet/configurer/downloader.rb +1 -0
  20. data/lib/puppet/configurer/plugin_handler.rb +8 -1
  21. data/lib/puppet/daemon.rb +1 -1
  22. data/lib/puppet/defaults.rb +18 -2
  23. data/lib/puppet/external/nagios.rb +0 -2
  24. data/lib/puppet/external/nagios/base.rb +0 -2
  25. data/lib/puppet/indirector/facts/inventory_active_record.rb +97 -0
  26. data/lib/puppet/indirector/facts/rest.rb +2 -0
  27. data/lib/puppet/indirector/facts/yaml.rb +75 -0
  28. data/lib/puppet/indirector/indirection.rb +1 -0
  29. data/lib/puppet/module.rb +1 -1
  30. data/lib/puppet/network/http/api/v1.rb +3 -4
  31. data/lib/puppet/network/http/compression.rb +4 -1
  32. data/lib/puppet/network/http/handler.rb +1 -1
  33. data/lib/puppet/network/rest_authconfig.rb +1 -1
  34. data/lib/puppet/node/facts.rb +29 -0
  35. data/lib/puppet/parser/ast/collection.rb +5 -4
  36. data/lib/puppet/parser/ast/leaf.rb +1 -1
  37. data/lib/puppet/parser/functions/regsubst.rb +7 -14
  38. data/lib/puppet/parser/functions/split.rb +7 -7
  39. data/lib/puppet/parser/grammar.ra +2 -4
  40. data/lib/puppet/parser/lexer.rb +4 -1
  41. data/lib/puppet/parser/parser.rb +2062 -1976
  42. data/lib/puppet/parser/parser_support.rb +3 -3
  43. data/lib/puppet/provider/computer/computer.rb +1 -3
  44. data/lib/puppet/provider/mount.rb +12 -16
  45. data/lib/puppet/provider/mount/parsed.rb +67 -8
  46. data/lib/puppet/provider/parsedfile.rb +3 -1
  47. data/lib/puppet/provider/service/daemontools.rb +6 -6
  48. data/lib/puppet/provider/service/gentoo.rb +0 -2
  49. data/lib/puppet/provider/service/launchd.rb +11 -8
  50. data/lib/puppet/provider/service/runit.rb +4 -4
  51. data/lib/puppet/provider/user/useradd.rb +6 -1
  52. data/lib/puppet/rails/database/004_add_inventory_service_tables.rb +36 -0
  53. data/lib/puppet/rails/database/schema.rb +17 -0
  54. data/lib/puppet/rails/fact_name.rb +0 -2
  55. data/lib/puppet/rails/fact_value.rb +0 -2
  56. data/lib/puppet/rails/inventory_fact.rb +5 -0
  57. data/lib/puppet/rails/inventory_node.rb +25 -0
  58. data/lib/puppet/reference/configuration.rb +1 -1
  59. data/lib/puppet/reference/metaparameter.rb +1 -1
  60. data/lib/puppet/reports/store.rb +4 -1
  61. data/lib/puppet/resource.rb +39 -25
  62. data/lib/puppet/type.rb +5 -5
  63. data/lib/puppet/type/augeas.rb +4 -4
  64. data/lib/puppet/type/computer.rb +5 -1
  65. data/lib/puppet/type/exec.rb +3 -1
  66. data/lib/puppet/type/file.rb +3 -1
  67. data/lib/puppet/type/file/content.rb +13 -15
  68. data/lib/puppet/type/file/ensure.rb +11 -17
  69. data/lib/puppet/type/file/selcontext.rb +16 -0
  70. data/lib/puppet/type/file/target.rb +14 -1
  71. data/lib/puppet/type/k5login.rb +0 -2
  72. data/lib/puppet/type/macauthorization.rb +4 -1
  73. data/lib/puppet/type/mcx.rb +4 -1
  74. data/lib/puppet/type/mount.rb +37 -21
  75. data/lib/puppet/type/package.rb +5 -1
  76. data/lib/puppet/type/schedule.rb +20 -20
  77. data/lib/puppet/type/selmodule.rb +3 -1
  78. data/lib/puppet/type/ssh_authorized_key.rb +5 -1
  79. data/lib/puppet/type/user.rb +14 -1
  80. data/lib/puppet/type/zfs.rb +3 -1
  81. data/lib/puppet/type/zone.rb +3 -1
  82. data/lib/puppet/type/zpool.rb +7 -5
  83. data/lib/puppet/util.rb +5 -0
  84. data/lib/puppet/util/command_line.rb +1 -1
  85. data/lib/puppet/util/execution.rb +4 -5
  86. data/lib/puppet/util/execution_stub.rb +26 -0
  87. data/lib/puppet/util/monkey_patches.rb +21 -0
  88. data/lib/puppet/util/rdoc/code_objects.rb +39 -0
  89. data/lib/puppet/util/rdoc/generators/puppet_generator.rb +18 -0
  90. data/lib/puppet/util/rdoc/parser.rb +5 -3
  91. data/lib/puppet/util/settings.rb +1 -1
  92. data/spec/integration/parser/parser_spec.rb +7 -0
  93. data/spec/integration/provider/mount_spec.rb +151 -0
  94. data/spec/integration/type/file_spec.rb +32 -29
  95. data/spec/spec_helper.rb +2 -0
  96. data/spec/unit/application/agent_spec.rb +3 -7
  97. data/spec/unit/application/apply_spec.rb +17 -2
  98. data/spec/unit/application/cert_spec.rb +54 -14
  99. data/spec/unit/application/filebucket_spec.rb +1 -1
  100. data/spec/unit/application/queue_spec.rb +1 -5
  101. data/spec/unit/configurer/downloader_spec.rb +22 -10
  102. data/spec/unit/daemon_spec.rb +1 -5
  103. data/spec/unit/indirector/facts/inventory_active_record_spec.rb +163 -0
  104. data/spec/unit/indirector/facts/yaml_spec.rb +216 -2
  105. data/spec/unit/indirector/queue_spec.rb +3 -0
  106. data/spec/unit/module_spec.rb +2 -2
  107. data/spec/unit/network/handler/fileserver_spec.rb +1 -1
  108. data/spec/unit/network/http/api/v1_spec.rb +28 -0
  109. data/spec/unit/network/http/compression_spec.rb +1 -1
  110. data/spec/unit/network/http/handler_spec.rb +7 -4
  111. data/spec/unit/node/facts_spec.rb +24 -0
  112. data/spec/unit/parser/ast/collection_spec.rb +16 -12
  113. data/spec/unit/parser/lexer_spec.rb +16 -0
  114. data/spec/unit/parser/parser_spec.rb +35 -2
  115. data/spec/unit/provider/mount/parsed_spec.rb +199 -114
  116. data/spec/unit/provider/mount_spec.rb +54 -53
  117. data/spec/unit/provider/ssh_authorized_key/parsed_spec.rb +1 -0
  118. data/spec/unit/provider/user/user_role_add_spec.rb +1 -0
  119. data/spec/unit/provider/user/useradd_spec.rb +43 -3
  120. data/spec/unit/reports/store_spec.rb +1 -1
  121. data/spec/unit/resource_spec.rb +39 -13
  122. data/spec/unit/type/file/content_spec.rb +38 -137
  123. data/spec/unit/type/file/selinux_spec.rb +5 -0
  124. data/spec/unit/type/mount_spec.rb +167 -122
  125. data/spec/unit/type/user_spec.rb +4 -0
  126. data/spec/unit/type_spec.rb +12 -1
  127. data/spec/unit/util/execution_spec.rb +49 -0
  128. data/spec/unit/util/execution_stub_spec.rb +35 -0
  129. data/spec/unit/util/rdoc/parser_spec.rb +15 -3
  130. data/spec/unit/util/settings_spec.rb +11 -2
  131. data/tasks/rake/git_workflow.rake +1 -1
  132. data/test/Rakefile +0 -2
  133. data/test/data/providers/mount/parsed/aix.mount +7 -0
  134. data/test/data/providers/mount/parsed/darwin.mount +6 -0
  135. data/test/data/providers/mount/parsed/hpux.mount +17 -0
  136. data/test/data/providers/mount/parsed/linux.mount +5 -0
  137. data/test/data/providers/mount/parsed/solaris.mount +6 -0
  138. data/test/data/types/mount/linux.fstab +1 -0
  139. data/test/data/types/mount/solaris.fstab +1 -0
  140. metadata +18 -4
@@ -15,7 +15,11 @@ module Puppet
15
15
  using based on the platform you are on, but you can override it
16
16
  using the `provider` parameter; each provider defines what it
17
17
  requires in order to function, and you must meet those requirements
18
- to use a given provider."
18
+ to use a given provider.
19
+
20
+ **Autorequires:** If Puppet is managing the files specified as a package's
21
+ `adminfile`, `responsefile`, or `source`, the package resource will autorequire
22
+ those files."
19
23
 
20
24
  feature :installable, "The provider can install packages.",
21
25
  :methods => [:install]
@@ -18,11 +18,11 @@ module Puppet
18
18
  wanted to restrict certain resources to only running once, between
19
19
  the hours of two and 4 AM, then you would use this schedule:
20
20
 
21
- schedule { maint:
22
- range => \"2 - 4\",
23
- period => daily,
24
- repeat => 1
25
- }
21
+ schedule { maint:
22
+ range => \"2 - 4\",
23
+ period => daily,
24
+ repeat => 1
25
+ }
26
26
 
27
27
  With this schedule, the first time that Puppet runs between 2 and 4 AM,
28
28
  all resources with this schedule will get applied, but they won't
@@ -35,10 +35,10 @@ module Puppet
35
35
  a schedule named *puppet* is created and used as the default,
36
36
  with the following attributes:
37
37
 
38
- schedule { puppet:
39
- period => hourly,
40
- repeat => 2
41
- }
38
+ schedule { puppet:
39
+ period => hourly,
40
+ repeat => 2
41
+ }
42
42
 
43
43
  This will cause resources to be applied every 30 minutes by default.
44
44
  "
@@ -47,14 +47,14 @@ module Puppet
47
47
  desc "The name of the schedule. This name is used to retrieve the
48
48
  schedule when assigning it to an object:
49
49
 
50
- schedule { daily:
51
- period => daily,
52
- range => \"2 - 4\",
53
- }
54
-
55
- exec { \"/usr/bin/apt-get update\":
56
- schedule => daily
57
- }
50
+ schedule { daily:
51
+ period => daily,
52
+ range => \"2 - 4\",
53
+ }
54
+
55
+ exec { \"/usr/bin/apt-get update\":
56
+ schedule => daily
57
+ }
58
58
 
59
59
  "
60
60
  isnamevar
@@ -67,9 +67,9 @@ module Puppet
67
67
  seconds can be provided, using the normal colon as a separator.
68
68
  For instance:
69
69
 
70
- schedule { maintenance:
71
- range => \"1:30 - 4:30\"
72
- }
70
+ schedule { maintenance:
71
+ range => \"1:30 - 4:30\"
72
+ }
73
73
 
74
74
  This is mostly useful for restricting certain resources to being
75
75
  applied in maintenance windows or during off-peak hours."
@@ -5,7 +5,9 @@
5
5
  Puppet::Type.newtype(:selmodule) do
6
6
  @doc = "Manages loading and unloading of SELinux policy modules
7
7
  on the system. Requires SELinux support. See man semodule(8)
8
- for more information on SELinux policy modules."
8
+ for more information on SELinux policy modules.
9
+
10
+ **Autorequires:** If Puppet is managing the file containing this SELinux policy module (which is either explicitly specified in the `selmodulepath` attribute or will be found at {`selmoduledir`}/{`name`}.pp), the selmodule resource will autorequire that file."
9
11
 
10
12
  ensurable
11
13
 
@@ -1,7 +1,11 @@
1
1
  module Puppet
2
2
  newtype(:ssh_authorized_key) do
3
3
  @doc = "Manages SSH authorized keys. Currently only type 2 keys are
4
- supported."
4
+ supported.
5
+
6
+ **Autorequires:** If Puppet is managing the user account in which this
7
+ SSH key should be installed, the `ssh_authorized_key` resource will autorequire
8
+ that user."
5
9
 
6
10
  ensurable
7
11
 
@@ -12,7 +12,9 @@ module Puppet
12
12
 
13
13
  This resource type uses the prescribed native tools for creating
14
14
  groups and generally uses POSIX APIs for retrieving information
15
- about them. It does not directly modify `/etc/passwd` or anything."
15
+ about them. It does not directly modify `/etc/passwd` or anything.
16
+
17
+ **Autorequires:** If Puppet is managing the user's primary group (as provided in the `gid` attribute), the user resource will autorequire that group. If Puppet is managing any role accounts corresponding to the user's roles, the user resource will autorequire those role accounts."
16
18
 
17
19
  feature :allows_duplicates,
18
20
  "The provider supports duplicate users with the same UID."
@@ -34,6 +36,9 @@ module Puppet
34
36
  feature :manages_expiry,
35
37
  "The provider can manage the expiry date for a user."
36
38
 
39
+ feature :system_users,
40
+ "The provider allows you to create system users with lower UIDs."
41
+
37
42
  newproperty(:ensure, :parent => Puppet::Property::Ensure) do
38
43
  newvalue(:present, :event => :user_created) do
39
44
  provider.create
@@ -230,6 +235,14 @@ module Puppet
230
235
  defaultto :minimum
231
236
  end
232
237
 
238
+ newparam(:system, :boolean => true) do
239
+ desc "Whether the user is a system user with lower UID."
240
+
241
+ newvalues(:true, :false)
242
+
243
+ defaultto false
244
+ end
245
+
233
246
  newparam(:allowdupe, :boolean => true) do
234
247
  desc "Whether to allow duplicate UIDs."
235
248
 
@@ -1,6 +1,8 @@
1
1
  module Puppet
2
2
  newtype(:zfs) do
3
- @doc = "Manage zfs. Create destroy and set properties on zfs instances."
3
+ @doc = "Manage zfs. Create destroy and set properties on zfs instances.
4
+
5
+ **Autorequires:** If Puppet is managing the zpool at the root of this zfs instance, the zfs resource will autorequire it. If Puppet is managing any parent zfs instances, the zfs resource will autorequire them."
4
6
 
5
7
  ensurable
6
8
 
@@ -1,5 +1,7 @@
1
1
  Puppet::Type.newtype(:zone) do
2
- @doc = "Solaris zones."
2
+ @doc = "Solaris zones.
3
+
4
+ **Autorequires:** If Puppet is managing the directory specified as the root of the zone's filesystem (with the `path` attribute), the zone resource will autorequire that directory."
3
5
 
4
6
  # These properties modify the zone configuration, and they need to provide
5
7
  # the text separately from syncing it, so all config statements can be rolled
@@ -40,9 +40,10 @@ module Puppet
40
40
  end
41
41
 
42
42
  newproperty(:mirror, :array_matching => :all, :parent => Puppet::Property::MultiVDev) do
43
- desc "List of all the devices to mirror for this pool. Each mirror should be a space separated string:
43
+ desc "List of all the devices to mirror for this pool. Each mirror should be a
44
+ space separated string:
44
45
 
45
- mirror => [\"disk1 disk2\", \"disk3 disk4\"]
46
+ mirror => [\"disk1 disk2\", \"disk3 disk4\"],
46
47
 
47
48
  "
48
49
 
@@ -52,9 +53,10 @@ module Puppet
52
53
  end
53
54
 
54
55
  newproperty(:raidz, :array_matching => :all, :parent => Puppet::Property::MultiVDev) do
55
- desc "List of all the devices to raid for this pool. Should be an array of space separated strings:
56
-
57
- raidz => [\"disk1 disk2\", \"disk3 disk4\"]
56
+ desc "List of all the devices to raid for this pool. Should be an array of
57
+ space separated strings:
58
+
59
+ raidz => [\"disk1 disk2\", \"disk3 disk4\"],
58
60
 
59
61
  "
60
62
 
@@ -4,6 +4,7 @@ require 'puppet/util/monkey_patches'
4
4
  require 'sync'
5
5
  require 'puppet/external/lock'
6
6
  require 'monitor'
7
+ require 'puppet/util/execution_stub'
7
8
 
8
9
  module Puppet
9
10
  # A command failed to execute.
@@ -264,6 +265,10 @@ module Util
264
265
  arguments[:uid] = Puppet::Util::SUIDManager.convert_xid(:uid, arguments[:uid]) if arguments[:uid]
265
266
  arguments[:gid] = Puppet::Util::SUIDManager.convert_xid(:gid, arguments[:gid]) if arguments[:gid]
266
267
 
268
+ if execution_stub = Puppet::Util::ExecutionStub.current_value
269
+ return execution_stub.call(command, arguments)
270
+ end
271
+
267
272
  @@os ||= Facter.value(:operatingsystem)
268
273
  output = nil
269
274
  child_pid, child_status = nil
@@ -85,7 +85,7 @@ module Puppet
85
85
  if zero == 'puppet'
86
86
  case argv.first
87
87
  when nil; [ stdin.tty? ? nil : "apply", argv] # ttys get usage info
88
- when "--help"; [nil, argv] # help should give you usage, not the help for `puppet apply`
88
+ when "--help", "-h"; [nil, argv] # help should give you usage, not the help for `puppet apply`
89
89
  when /^-|\.pp$|\.rb$/; ["apply", argv]
90
90
  else [ argv.first, argv[1..-1] ]
91
91
  end
@@ -4,16 +4,15 @@ module Puppet::Util::Execution
4
4
  # Run some code with a specific environment. Resets the environment back to
5
5
  # what it was at the end of the code.
6
6
  def withenv(hash)
7
- oldvals = {}
7
+ saved = ENV.to_hash
8
8
  hash.each do |name, val|
9
- name = name.to_s
10
- oldvals[name] = ENV[name]
11
- ENV[name] = val
9
+ ENV[name.to_s] = val
12
10
  end
13
11
 
14
12
  yield
15
13
  ensure
16
- oldvals.each do |name, val|
14
+ ENV.clear
15
+ saved.each do |name, val|
17
16
  ENV[name] = val
18
17
  end
19
18
  end
@@ -0,0 +1,26 @@
1
+ module Puppet::Util
2
+ class ExecutionStub
3
+ class << self
4
+ # Set a stub block that Puppet::Util.execute() should invoke instead
5
+ # of actually executing commands on the target machine. Intended
6
+ # for spec testing.
7
+ #
8
+ # The arguments passed to the block are |command, options|, where
9
+ # command is an array of strings and options is an options hash.
10
+ def set(&block)
11
+ @value = block
12
+ end
13
+
14
+ # Uninstall any execution stub, so that calls to
15
+ # Puppet::Util.execute() behave normally again.
16
+ def reset
17
+ @value = nil
18
+ end
19
+
20
+ # Retrieve the current execution stub, or nil if there is no stub.
21
+ def current_value
22
+ @value
23
+ end
24
+ end
25
+ end
26
+ end
@@ -21,6 +21,9 @@ class Symbol
21
21
  z.emit("!ruby/sym ")
22
22
  to_s.to_zaml(z)
23
23
  end
24
+ def <=> (other)
25
+ self.to_s <=> other.to_s
26
+ end
24
27
  end
25
28
 
26
29
  [Object, Exception, Integer, Struct, Date, Time, Range, Regexp, Hash, Array, Float, String, FalseClass, TrueClass, Symbol, NilClass, Class].each { |cls|
@@ -48,3 +51,21 @@ if RUBY_VERSION == '1.8.7'
48
51
  end
49
52
  end
50
53
 
54
+ class Object
55
+ # The following code allows callers to make assertions that are only
56
+ # checked when the environment variable PUPPET_ENABLE_ASSERTIONS is
57
+ # set to a non-empty string. For example:
58
+ #
59
+ # assert_that { condition }
60
+ # assert_that(message) { condition }
61
+ if ENV["PUPPET_ENABLE_ASSERTIONS"].to_s != ''
62
+ def assert_that(message = nil)
63
+ unless yield
64
+ raise Exception.new("Assertion failure: #{message}")
65
+ end
66
+ end
67
+ else
68
+ def assert_that(message = nil)
69
+ end
70
+ end
71
+ end
@@ -124,6 +124,45 @@ module RDoc
124
124
  def add_child(child)
125
125
  @childs << child
126
126
  end
127
+
128
+ # Look up the given symbol. RDoc only looks for class1::class2.method
129
+ # or class1::class2#method. Since our definitions are mapped to RDoc methods
130
+ # but are written class1::class2::define we need to perform the lookup by
131
+ # ourselves.
132
+ def find_symbol(symbol, method=nil)
133
+ result = super
134
+ if not result and symbol =~ /::/
135
+ modules = symbol.split(/::/)
136
+ unless modules.empty?
137
+ module_name = modules.shift
138
+ result = find_module_named(module_name)
139
+ if result
140
+ last_name = ""
141
+ previous = nil
142
+ modules.each do |module_name|
143
+ previous = result
144
+ last_name = module_name
145
+ result = result.find_module_named(module_name)
146
+ break unless result
147
+ end
148
+ unless result
149
+ result = previous
150
+ method = last_name
151
+ end
152
+ end
153
+ end
154
+ if result && method
155
+ if !result.respond_to?(:find_local_symbol)
156
+ p result.name
157
+ p method
158
+ fail
159
+ end
160
+ result = result.find_local_symbol(method)
161
+ end
162
+ end
163
+ result
164
+ end
165
+
127
166
  end
128
167
 
129
168
  # PuppetNode holds a puppet node
@@ -31,6 +31,24 @@ module Generators
31
31
  NODE_DIR = "nodes"
32
32
  PLUGIN_DIR = "plugins"
33
33
 
34
+ # We're monkey patching RDoc markup to allow
35
+ # lowercase class1::class2::class3 crossref hyperlinking
36
+ module MarkUp
37
+ alias :old_markup :markup
38
+
39
+ def new_markup(str, remove_para=false)
40
+ first = @markup.nil?
41
+ res = old_markup(str, remove_para)
42
+ if first and not @markup.nil?
43
+ @markup.add_special(/\b([a-z]\w+(::\w+)*)/,:CROSSREF)
44
+ # we need to call it again, since we added a rule
45
+ res = old_markup(str, remove_para)
46
+ end
47
+ res
48
+ end
49
+ alias :markup :new_markup
50
+ end
51
+
34
52
  # This is a specialized HTMLGenerator tailored to Puppet manifests
35
53
  class PuppetGenerator < HTMLGenerator
36
54
 
@@ -41,8 +41,10 @@ class Parser
41
41
  @parser.file = @input_file_name
42
42
  @ast = @parser.parse
43
43
  end
44
- scan_top_level(@top_level)
44
+ else
45
+ @ast = env.known_resource_types
45
46
  end
47
+ scan_top_level(@top_level)
46
48
  @top_level
47
49
  end
48
50
 
@@ -157,8 +159,8 @@ class Parser
157
159
 
158
160
  if stmt.is_a?(Puppet::Parser::AST::Function) and ['include','require'].include?(stmt.name)
159
161
  stmt.arguments.each do |included|
160
- Puppet.debug "found #{stmt.name}: #{included.value}"
161
- container.send("add_#{stmt.name}",Include.new(included.value, stmt.doc))
162
+ Puppet.debug "found #{stmt.name}: #{included}"
163
+ container.send("add_#{stmt.name}",Include.new(included.to_s, stmt.doc))
162
164
  end
163
165
  end
164
166
  end
@@ -91,7 +91,7 @@ class Puppet::Util::Settings
91
91
  varname = $2 || $1
92
92
  if varname == "environment" and environment
93
93
  environment
94
- elsif pval = self.value(varname)
94
+ elsif pval = self.value(varname, environment)
95
95
  pval
96
96
  else
97
97
  raise Puppet::DevError, "Could not find value for #{value}"
@@ -109,5 +109,12 @@ describe Puppet::Parser::Parser do
109
109
  it "should correctly set the arrow type of a relationship" do
110
110
  "Notify[foo] <~ Notify[bar]".should parse_with { |rel| rel.arrow == "<~" }
111
111
  end
112
+
113
+ it "should be able to parse deep hash access" do
114
+ %q{
115
+ $hash = { 'a' => { 'b' => { 'c' => 'it works' } } }
116
+ $out = $hash['a']['b']['c']
117
+ }.should parse_with { |v| v.value.is_a?(Puppet::Parser::AST::ASTHash) }
118
+ end
112
119
  end
113
120
  end
@@ -0,0 +1,151 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ require 'puppet/file_bucket/dipper'
4
+
5
+ describe "mount provider (integration)" do
6
+ include PuppetSpec::Files
7
+
8
+ def create_fake_fstab(initially_contains_entry)
9
+ File.open(@fake_fstab, 'w') do |f|
10
+ if initially_contains_entry
11
+ f.puts("/dev/disk1s1\t/Volumes/foo_disk\tmsdos\tlocal\t0\t0")
12
+ end
13
+ end
14
+ end
15
+
16
+ before :each do
17
+ @fake_fstab = tmpfile('fstab')
18
+ @current_options = "local"
19
+ @current_device = "/dev/disk1s1"
20
+ Puppet::Type.type(:mount).defaultprovider.stubs(:default_target).returns(@fake_fstab)
21
+ Facter.stubs(:value).with(:operatingsystem).returns('Darwin')
22
+ Puppet::Util::ExecutionStub.set do |command, options|
23
+ case command[0]
24
+ when %r{/s?bin/mount}
25
+ if command.length == 1
26
+ if @mounted
27
+ "#{@current_device} on /Volumes/foo_disk (msdos, #{@current_options})\n"
28
+ else
29
+ ''
30
+ end
31
+ else
32
+ command.length.should == 4
33
+ command[1].should == '-o'
34
+ command[3].should == '/Volumes/foo_disk'
35
+ @mounted.should == false # verify that we don't try to call "mount" redundantly
36
+ @current_options = command[2]
37
+ @current_device = check_fstab(true)
38
+ @mounted = true
39
+ ''
40
+ end
41
+ when %r{/s?bin/umount}
42
+ command.length.should == 2
43
+ command[1].should == '/Volumes/foo_disk'
44
+ @mounted.should == true # "umount" doesn't work when device not mounted (see #6632)
45
+ @mounted = false
46
+ ''
47
+ else
48
+ fail "Unexpected command #{command.inspect} executed"
49
+ end
50
+ end
51
+ end
52
+
53
+ after :each do
54
+ Puppet::Type::Mount::ProviderParsed.clear # Work around bug #6628
55
+ end
56
+
57
+ def check_fstab(expected_to_be_present)
58
+ # Verify that the fake fstab has the expected data in it
59
+ fstab_contents = File.read(@fake_fstab).lines.map(&:chomp).reject { |x| x =~ /^#|^$/ }
60
+ if expected_to_be_present
61
+ fstab_contents.length().should == 1
62
+ device, rest_of_line = fstab_contents[0].split(/\t/,2)
63
+ rest_of_line.should == "/Volumes/foo_disk\tmsdos\t#{@desired_options}\t0\t0"
64
+ device
65
+ else
66
+ fstab_contents.length().should == 0
67
+ nil
68
+ end
69
+ end
70
+
71
+ def run_in_catalog(settings)
72
+ resource = Puppet::Type.type(:mount).new(settings.merge(:name => "/Volumes/foo_disk",
73
+ :device => "/dev/disk1s1", :fstype => "msdos"))
74
+ Puppet::FileBucket::Dipper.any_instance.stubs(:backup) # Don't backup to the filebucket
75
+ resource.expects(:err).never
76
+ catalog = Puppet::Resource::Catalog.new
77
+ catalog.host_config = false # Stop Puppet from doing a bunch of magic
78
+ catalog.add_resource resource
79
+ catalog.apply
80
+ end
81
+
82
+ [false, true].each do |initial_state|
83
+ describe "When initially #{initial_state ? 'mounted' : 'unmounted'}" do
84
+ before :each do
85
+ @mounted = initial_state
86
+ end
87
+
88
+ [false, true].each do |initial_fstab_entry|
89
+ describe "When there is #{initial_fstab_entry ? 'an' : 'no'} initial fstab entry" do
90
+ before :each do
91
+ create_fake_fstab(initial_fstab_entry)
92
+ end
93
+
94
+ [:defined, :present, :mounted, :unmounted, :absent].each do |ensure_setting|
95
+ expected_final_state = case ensure_setting
96
+ when :mounted
97
+ true
98
+ when :unmounted, :absent
99
+ false
100
+ when :defined, :present
101
+ initial_state
102
+ else
103
+ fail "Unknown ensure_setting #{ensure_setting}"
104
+ end
105
+ expected_fstab_data = (ensure_setting != :absent)
106
+ describe "When setting ensure => #{ensure_setting}" do
107
+ ["local", "journaled"].each do |options_setting|
108
+ describe "When setting options => #{options_setting}" do
109
+ it "should leave the system in the #{expected_final_state ? 'mounted' : 'unmounted'} state, #{expected_fstab_data ? 'with' : 'without'} data in /etc/fstab" do
110
+ @desired_options = options_setting
111
+ run_in_catalog(:ensure=>ensure_setting, :options => options_setting)
112
+ @mounted.should == expected_final_state
113
+ if expected_fstab_data
114
+ check_fstab(expected_fstab_data).should == "/dev/disk1s1"
115
+ else
116
+ check_fstab(expected_fstab_data).should == nil
117
+ end
118
+ if @mounted
119
+ if ![:defined, :present].include?(ensure_setting)
120
+ @current_options.should == @desired_options
121
+ elsif initial_fstab_entry
122
+ @current_options.should == @desired_options
123
+ else
124
+ @current_options.should == 'local' #Workaround for #6645
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
136
+
137
+ describe "When the wrong device is mounted" do
138
+ it "should remount the correct device" do
139
+ pending "Due to bug 6309"
140
+ @mounted = true
141
+ @current_device = "/dev/disk2s2"
142
+ create_fake_fstab(true)
143
+ @desired_options = "local"
144
+ run_in_catalog(:ensure=>:mounted, :options=>'local')
145
+ @current_device.should=="/dev/disk1s1"
146
+ @mounted.should==true
147
+ @current_options.should=='local'
148
+ check_fstab(true).should == "/dev/disk1s1"
149
+ end
150
+ end
151
+ end