puppet 0.9.2 → 0.13.0

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 (213) hide show
  1. data/CHANGELOG +58 -0
  2. data/README +21 -18
  3. data/Rakefile +176 -36
  4. data/bin/puppet +34 -48
  5. data/bin/puppetca +41 -28
  6. data/bin/puppetd +87 -65
  7. data/bin/puppetdoc +99 -23
  8. data/bin/puppetmasterd +72 -91
  9. data/conf/redhat/client.init +80 -0
  10. data/conf/redhat/client.sysconfig +11 -0
  11. data/conf/redhat/fileserver.conf +12 -0
  12. data/conf/redhat/puppet.spec +130 -0
  13. data/conf/redhat/server.init +89 -0
  14. data/conf/redhat/server.sysconfig +9 -0
  15. data/examples/code/allatonce +2 -2
  16. data/examples/code/assignments +1 -1
  17. data/examples/code/classing +2 -2
  18. data/examples/code/components +2 -2
  19. data/examples/code/file.bl +5 -5
  20. data/examples/code/filedefaults +2 -2
  21. data/examples/code/fileparsing +1 -1
  22. data/examples/code/filerecursion +1 -1
  23. data/examples/code/functions +1 -1
  24. data/examples/code/groups +1 -1
  25. data/examples/code/importing +1 -1
  26. data/examples/code/nodes +1 -1
  27. data/examples/code/one +1 -1
  28. data/examples/code/relationships +2 -2
  29. data/examples/code/simpletests +5 -5
  30. data/examples/code/snippets/argumentdefaults +2 -2
  31. data/examples/code/snippets/casestatement +16 -8
  32. data/examples/code/snippets/classheirarchy.pp +4 -4
  33. data/examples/code/snippets/classincludes.pp +4 -4
  34. data/examples/code/snippets/classpathtest +2 -2
  35. data/examples/code/snippets/componentmetaparams.pp +11 -0
  36. data/examples/code/snippets/dirchmod +5 -5
  37. data/examples/code/snippets/emptyclass.pp +9 -0
  38. data/examples/code/snippets/failmissingexecpath.pp +1 -1
  39. data/examples/code/snippets/falsevalues.pp +1 -1
  40. data/examples/code/snippets/filecreate +5 -5
  41. data/examples/code/snippets/implicititeration +5 -5
  42. data/examples/code/snippets/multipleinstances +4 -4
  43. data/examples/code/snippets/namevartest +3 -3
  44. data/examples/code/snippets/scopetest +1 -1
  45. data/examples/code/snippets/selectorvalues.pp +3 -3
  46. data/examples/code/snippets/simpledefaults +2 -2
  47. data/examples/code/snippets/simpleselector +5 -5
  48. data/examples/code/snippets/singleary.pp +19 -0
  49. data/examples/root/etc/init.d/sleeper +3 -2
  50. data/ext/emacs/puppet-mode-init.el +6 -0
  51. data/ext/emacs/puppet-mode.el +189 -0
  52. data/ext/ldap/puppet.schema +17 -0
  53. data/ext/{module:puppet → module_puppet} +30 -31
  54. data/ext/vim/filetype.vim +9 -0
  55. data/ext/vim/puppet.vim +87 -0
  56. data/install.rb +63 -30
  57. data/lib/puppet.rb +216 -122
  58. data/lib/puppet/client.rb +51 -416
  59. data/lib/puppet/client/ca.rb +17 -0
  60. data/lib/puppet/client/dipper.rb +78 -0
  61. data/lib/puppet/client/file.rb +20 -0
  62. data/lib/puppet/client/log.rb +17 -0
  63. data/lib/puppet/client/master.rb +246 -0
  64. data/lib/puppet/client/proxy.rb +27 -0
  65. data/lib/puppet/client/status.rb +7 -0
  66. data/lib/puppet/config.rb +563 -13
  67. data/lib/puppet/daemon.rb +50 -22
  68. data/lib/puppet/element.rb +4 -4
  69. data/lib/puppet/event-loop.rb +1 -0
  70. data/lib/puppet/event-loop/better-definers.rb +367 -0
  71. data/lib/puppet/event-loop/event-loop.rb +355 -0
  72. data/lib/puppet/event-loop/signal-system.rb +220 -0
  73. data/lib/puppet/event.rb +9 -11
  74. data/lib/puppet/filetype.rb +195 -0
  75. data/lib/puppet/log.rb +35 -12
  76. data/lib/puppet/metric.rb +2 -2
  77. data/lib/puppet/networkclient.rb +145 -0
  78. data/lib/puppet/parameter.rb +335 -0
  79. data/lib/puppet/parser/ast.rb +42 -1453
  80. data/lib/puppet/parser/ast/astarray.rb +88 -0
  81. data/lib/puppet/parser/ast/branch.rb +47 -0
  82. data/lib/puppet/parser/ast/caseopt.rb +66 -0
  83. data/lib/puppet/parser/ast/casestatement.rb +78 -0
  84. data/lib/puppet/parser/ast/classdef.rb +78 -0
  85. data/lib/puppet/parser/ast/compdef.rb +111 -0
  86. data/lib/puppet/parser/ast/component.rb +105 -0
  87. data/lib/puppet/parser/ast/hostclass.rb +82 -0
  88. data/lib/puppet/parser/ast/leaf.rb +86 -0
  89. data/lib/puppet/parser/ast/node.rb +103 -0
  90. data/lib/puppet/parser/ast/nodedef.rb +68 -0
  91. data/lib/puppet/parser/ast/objectdef.rb +336 -0
  92. data/lib/puppet/parser/ast/objectparam.rb +30 -0
  93. data/lib/puppet/parser/ast/objectref.rb +76 -0
  94. data/lib/puppet/parser/ast/selector.rb +60 -0
  95. data/lib/puppet/parser/ast/typedefaults.rb +45 -0
  96. data/lib/puppet/parser/ast/vardef.rb +44 -0
  97. data/lib/puppet/parser/interpreter.rb +31 -14
  98. data/lib/puppet/parser/lexer.rb +2 -4
  99. data/lib/puppet/parser/parser.rb +332 -242
  100. data/lib/puppet/parser/scope.rb +55 -38
  101. data/lib/puppet/server.rb +43 -44
  102. data/lib/puppet/server/authstore.rb +3 -6
  103. data/lib/puppet/server/ca.rb +5 -2
  104. data/lib/puppet/server/filebucket.rb +2 -4
  105. data/lib/puppet/server/fileserver.rb +28 -12
  106. data/lib/puppet/server/logger.rb +15 -4
  107. data/lib/puppet/server/master.rb +62 -7
  108. data/lib/puppet/sslcertificates.rb +41 -607
  109. data/lib/puppet/sslcertificates/ca.rb +291 -0
  110. data/lib/puppet/sslcertificates/certificate.rb +283 -0
  111. data/lib/puppet/statechange.rb +6 -1
  112. data/lib/puppet/storage.rb +67 -56
  113. data/lib/puppet/transaction.rb +25 -9
  114. data/lib/puppet/transportable.rb +102 -22
  115. data/lib/puppet/type.rb +1096 -315
  116. data/lib/puppet/type/component.rb +30 -21
  117. data/lib/puppet/type/cron.rb +409 -448
  118. data/lib/puppet/type/exec.rb +234 -174
  119. data/lib/puppet/type/group.rb +65 -82
  120. data/lib/puppet/type/nameservice.rb +247 -3
  121. data/lib/puppet/type/nameservice/netinfo.rb +29 -40
  122. data/lib/puppet/type/nameservice/objectadd.rb +52 -66
  123. data/lib/puppet/type/nameservice/posix.rb +6 -194
  124. data/lib/puppet/type/package.rb +447 -295
  125. data/lib/puppet/type/package/apt.rb +51 -50
  126. data/lib/puppet/type/package/bsd.rb +82 -0
  127. data/lib/puppet/type/package/dpkg.rb +85 -88
  128. data/lib/puppet/type/package/rpm.rb +67 -63
  129. data/lib/puppet/type/package/sun.rb +119 -98
  130. data/lib/puppet/type/package/yum.rb +41 -37
  131. data/lib/puppet/type/parsedtype.rb +295 -0
  132. data/lib/puppet/type/parsedtype/host.rb +143 -0
  133. data/lib/puppet/type/parsedtype/port.rb +232 -0
  134. data/lib/puppet/type/parsedtype/sshkey.rb +129 -0
  135. data/lib/puppet/type/pfile.rb +484 -460
  136. data/lib/puppet/type/pfile/checksum.rb +237 -181
  137. data/lib/puppet/type/pfile/content.rb +67 -0
  138. data/lib/puppet/type/pfile/ensure.rb +212 -0
  139. data/lib/puppet/type/pfile/group.rb +106 -105
  140. data/lib/puppet/type/pfile/mode.rb +98 -101
  141. data/lib/puppet/type/pfile/source.rb +228 -209
  142. data/lib/puppet/type/pfile/type.rb +18 -21
  143. data/lib/puppet/type/pfile/uid.rb +127 -130
  144. data/lib/puppet/type/pfilebucket.rb +68 -63
  145. data/lib/puppet/type/schedule.rb +341 -0
  146. data/lib/puppet/type/service.rb +351 -255
  147. data/lib/puppet/type/service/base.rb +9 -14
  148. data/lib/puppet/type/service/debian.rb +32 -38
  149. data/lib/puppet/type/service/init.rb +130 -130
  150. data/lib/puppet/type/service/smf.rb +48 -20
  151. data/lib/puppet/type/state.rb +229 -16
  152. data/lib/puppet/type/symlink.rb +51 -63
  153. data/lib/puppet/type/tidy.rb +105 -102
  154. data/lib/puppet/type/user.rb +118 -180
  155. data/lib/puppet/util.rb +100 -6
  156. data/test/certmgr/certmgr.rb +0 -1
  157. data/test/client/client.rb +4 -4
  158. data/test/executables/puppetbin.rb +7 -14
  159. data/test/executables/puppetca.rb +18 -24
  160. data/test/executables/puppetd.rb +7 -16
  161. data/test/executables/puppetmasterd.rb +7 -9
  162. data/test/executables/puppetmodule.rb +11 -16
  163. data/test/language/ast.rb +11 -7
  164. data/test/language/interpreter.rb +1 -1
  165. data/test/language/scope.rb +2 -0
  166. data/test/language/snippets.rb +30 -5
  167. data/test/language/transportable.rb +77 -0
  168. data/test/other/config.rb +316 -0
  169. data/test/other/events.rb +22 -21
  170. data/test/other/log.rb +14 -14
  171. data/test/other/metrics.rb +4 -8
  172. data/test/other/overrides.rb +5 -5
  173. data/test/other/relationships.rb +4 -2
  174. data/test/other/storage.rb +64 -3
  175. data/test/other/transactions.rb +20 -20
  176. data/test/parser/parser.rb +7 -4
  177. data/test/puppet/conffiles.rb +12 -12
  178. data/test/puppet/defaults.rb +13 -11
  179. data/test/puppet/utiltest.rb +14 -11
  180. data/test/puppettest.rb +156 -48
  181. data/test/server/bucket.rb +2 -2
  182. data/test/server/fileserver.rb +6 -6
  183. data/test/server/logger.rb +19 -11
  184. data/test/server/master.rb +33 -4
  185. data/test/server/server.rb +2 -7
  186. data/test/types/basic.rb +5 -7
  187. data/test/types/component.rb +22 -18
  188. data/test/types/cron.rb +111 -44
  189. data/test/types/exec.rb +116 -59
  190. data/test/types/file.rb +262 -137
  191. data/test/types/filebucket.rb +13 -15
  192. data/test/types/fileignoresource.rb +12 -16
  193. data/test/types/filesources.rb +73 -48
  194. data/test/types/filetype.rb +13 -15
  195. data/test/types/group.rb +15 -13
  196. data/test/types/host.rb +146 -0
  197. data/test/types/package.rb +74 -63
  198. data/test/types/port.rb +139 -0
  199. data/test/types/query.rb +8 -8
  200. data/test/types/schedule.rb +335 -0
  201. data/test/types/service.rb +137 -21
  202. data/test/types/sshkey.rb +140 -0
  203. data/test/types/symlink.rb +3 -5
  204. data/test/types/tidy.rb +5 -14
  205. data/test/types/type.rb +67 -11
  206. data/test/types/user.rb +25 -23
  207. metadata +186 -122
  208. data/lib/puppet/type/pfile/create.rb +0 -108
  209. data/lib/puppet/type/pprocess.rb +0 -97
  210. data/lib/puppet/type/typegen.rb +0 -149
  211. data/lib/puppet/type/typegen/filerecord.rb +0 -243
  212. data/lib/puppet/type/typegen/filetype.rb +0 -316
  213. data/test/other/state.rb +0 -106
@@ -2,130 +2,127 @@
2
2
  # for specification (e.g., u+rwx, or -0011), but for now only supports
3
3
  # specifying the full mode.
4
4
  module Puppet
5
- class State
6
- class PFileMode < Puppet::State
7
- require 'etc'
8
- @doc = "Mode the file should be. Currently relatively limited:
9
- you must specify the exact mode the file should be."
10
- @name = :mode
11
- @event = :inode_changed
5
+ Puppet.type(:file).newstate(:mode) do
6
+ require 'etc'
7
+ desc "Mode the file should be. Currently relatively limited:
8
+ you must specify the exact mode the file should be."
9
+ @event = :file_changed
12
10
 
13
- # Our modes are octal, so make sure they print correctly. Other
14
- # valid values are symbols, basically
15
- def is_to_s
16
- case @is
17
- when Integer
18
- return "%o" % @is
19
- when Symbol
20
- return @is
21
- else
22
- raise Puppet::DevError, "Invalid 'is' value for mode: %s" %
23
- @is.inspect
24
- end
11
+ # Our modes are octal, so make sure they print correctly. Other
12
+ # valid values are symbols, basically
13
+ def is_to_s
14
+ case @is
15
+ when Integer
16
+ return "%o" % @is
17
+ when Symbol
18
+ return @is
19
+ else
20
+ raise Puppet::DevError, "Invalid 'is' value for mode: %s" %
21
+ @is.inspect
25
22
  end
23
+ end
26
24
 
27
- def should_to_s
28
- case self.should
29
- when Integer
30
- return "%o" % self.should
31
- when Symbol
32
- return self.should
33
- else
34
- raise Puppet::DevError, "Invalid 'should' value for mode: %s" %
35
- self.should.inspect
36
- end
25
+ def should_to_s
26
+ case self.should
27
+ when Integer
28
+ return "%o" % self.should
29
+ when Symbol
30
+ return self.should
31
+ else
32
+ raise Puppet::DevError, "Invalid 'should' value for mode: %s" %
33
+ self.should.inspect
37
34
  end
35
+ end
38
36
 
39
- def shouldprocess(should)
40
- # this is pretty hackish, but i need to make sure the number is in
41
- # octal, yet the number can only be specified as a string right now
42
- value = should
43
- if value.is_a?(String)
44
- unless value =~ /^[0-9]+$/
45
- raise Puppet::Error, "File modes can only be numbers"
46
- end
47
- unless value =~ /^0/
48
- value = "0" + value
49
- end
50
- begin
51
- value = Integer(value)
52
- rescue ArgumentError => detail
53
- raise Puppet::DevError, "Could not convert %s to integer" %
54
- value.inspect
55
- end
37
+ munge do |should|
38
+ # this is pretty hackish, but i need to make sure the number is in
39
+ # octal, yet the number can only be specified as a string right now
40
+ value = should
41
+ if value.is_a?(String)
42
+ unless value =~ /^[0-9]+$/
43
+ raise Puppet::Error, "File modes can only be numbers"
56
44
  end
57
-
58
- return value
59
- end
60
-
61
- # If we're a directory, we need to be executable for all cases
62
- # that are readable. This should probably be selectable, but eh.
63
- def dirmask(value)
64
- if FileTest.directory?(@parent.name)
65
- if value & 0400 != 0
66
- value |= 0100
67
- end
68
- if value & 040 != 0
69
- value |= 010
70
- end
71
- if value & 04 != 0
72
- value |= 01
73
- end
45
+ unless value =~ /^0/
46
+ value = "0" + value
47
+ end
48
+ begin
49
+ value = Integer(value)
50
+ rescue ArgumentError => detail
51
+ raise Puppet::DevError, "Could not convert %s to integer" %
52
+ value.inspect
74
53
  end
75
-
76
- return value
77
54
  end
78
55
 
79
- def retrieve
80
- if stat = @parent.stat(true)
81
- self.is = stat.mode & 007777
82
- unless defined? @fixed
83
- if defined? @should and @should
84
- @should = @should.collect { |s| self.dirmask(s) }
85
- end
86
- end
87
- else
88
- self.is = :notfound
89
- end
56
+ return value
57
+ end
90
58
 
91
- #self.debug "chmod state is %o" % self.is
59
+ # If we're a directory, we need to be executable for all cases
60
+ # that are readable. This should probably be selectable, but eh.
61
+ def dirmask(value)
62
+ if FileTest.directory?(@parent.name)
63
+ if value & 0400 != 0
64
+ value |= 0100
65
+ end
66
+ if value & 040 != 0
67
+ value |= 010
68
+ end
69
+ if value & 04 != 0
70
+ value |= 01
71
+ end
92
72
  end
93
73
 
94
- def sync
95
- if @is == :notfound
96
- @parent.stat(true)
97
- self.retrieve
98
- #self.debug "%s: after refresh, is '%s'" % [self.class.name,@is]
99
- if @is == :notfound
100
- self.info "File does not exist; cannot set mode" %
101
- @parent.name
102
- return nil
103
- end
74
+ return value
75
+ end
104
76
 
105
- if self.insync?
106
- # we're already in sync
107
- return nil
77
+ def retrieve
78
+ if stat = @parent.stat(false)
79
+ self.is = stat.mode & 007777
80
+ unless defined? @fixed
81
+ if defined? @should and @should
82
+ @should = @should.collect { |s| self.dirmask(s) }
108
83
  end
109
84
  end
85
+ else
86
+ self.is = :absent
87
+ end
110
88
 
111
- mode = self.should
89
+ #self.debug "chmod state is %o" % self.is
90
+ end
112
91
 
113
- if mode == :notfound
114
- # This is really only valid for create states...
92
+ def sync
93
+ if @is == :absent
94
+ @parent.stat(true)
95
+ self.retrieve
96
+ #self.debug "%s: after refresh, is '%s'" % [self.class.name,@is]
97
+ if @is == :absent
98
+ self.info "File does not exist; cannot set mode" %
99
+ @parent.name
115
100
  return nil
116
101
  end
117
102
 
118
- begin
119
- File.chmod(mode,@parent[:path])
120
- rescue => detail
121
- error = Puppet::Error.new("failed to chmod %s: %s" %
122
- [@parent.name, detail.message])
123
- raise error
103
+ if self.insync?
104
+ # we're already in sync
105
+ return nil
124
106
  end
125
- return :inode_changed
126
107
  end
108
+
109
+ mode = self.should
110
+
111
+ if mode == :absent
112
+ # This is really only valid for create states...
113
+ return nil
114
+ end
115
+
116
+ begin
117
+ File.chmod(mode,@parent[:path])
118
+ rescue => detail
119
+ error = Puppet::Error.new("failed to chmod %s: %s" %
120
+ [@parent.name, detail.message])
121
+ raise error
122
+ end
123
+ return :file_changed
127
124
  end
128
125
  end
129
126
  end
130
127
 
131
- # $Id: mode.rb 740 2005-11-01 20:22:19Z luke $
128
+ # $Id: mode.rb 862 2006-01-31 02:07:56Z luke $
@@ -1,264 +1,283 @@
1
1
  module Puppet
2
- class State
3
- # Copy files from a local or remote source.
4
- class PFileSource < Puppet::State
5
- attr_accessor :source, :local
6
- @doc = "Copy a file over the current file. Uses `checksum` to
7
- determine when a file should be copied. Valid values are either
8
- fully qualified paths to files, or URIs. Currently supported URI
9
- types are *puppet* and *file*."
10
- @name = :source
11
-
12
- # Ask the file server to describe our file.
13
- def describe(source)
14
- sourceobj, path = @parent.uri2obj(source)
15
- server = sourceobj.server
2
+ # Copy files from a local or remote source.
3
+ Puppet.type(:file).newstate(:source) do
4
+ PINPARAMS = [:mode, :type, :owner, :group, :checksum]
5
+
6
+ attr_accessor :source, :local
7
+ desc "Copy a file over the current file. Uses `checksum` to
8
+ determine when a file should be copied. Valid values are either
9
+ fully qualified paths to files, or URIs. Currently supported URI
10
+ types are *puppet* and *file*.
11
+
12
+ This is one of the primary mechanisms for getting content into
13
+ applications that Puppet does not directly support and is very
14
+ useful for those configuration files that don't change much across
15
+ sytems. For instance::
16
+
17
+ class sendmail {
18
+ file { \"/etc/mail/sendmail.cf\":
19
+ source => \"puppet://server/module/sendmail.cf\"
20
+ }
21
+ }
22
+
23
+ See the `fileserver docs`_ for information on how to configure
24
+ and use file services within Puppet.
16
25
 
17
- begin
18
- desc = server.describe(path)
19
- rescue NetworkClientError => detail
20
- self.err "Could not describe %s: %s" %
21
- [path, detail]
22
- return nil
23
- end
24
26
 
25
- args = {}
26
- Puppet::Type::PFile::PINPARAMS.zip(
27
- desc.split("\t")
28
- ).each { |param, value|
29
- if value =~ /^[0-9]+$/
30
- value = value.to_i
31
- end
32
- unless value.nil?
33
- args[param] = value
34
- end
35
- }
27
+ .. _fileserver docs: /projects/puppet/documentation/fsconfigref
36
28
 
37
- # we can't manage ownership as root, so don't even try
38
- unless Process.uid == 0
39
- args.delete(:owner)
40
- end
29
+ "
41
30
 
42
- if args.empty?
43
- return nil
44
- else
45
- return args
31
+ # Ask the file server to describe our file.
32
+ def describe(source)
33
+ sourceobj, path = @parent.uri2obj(source)
34
+ server = sourceobj.server
35
+
36
+ begin
37
+ desc = server.describe(path)
38
+ rescue NetworkClientError => detail
39
+ self.err "Could not describe %s: %s" %
40
+ [path, detail]
41
+ return nil
42
+ end
43
+
44
+ args = {}
45
+ PINPARAMS.zip(
46
+ desc.split("\t")
47
+ ).each { |param, value|
48
+ if value =~ /^[0-9]+$/
49
+ value = value.to_i
46
50
  end
51
+ unless value.nil?
52
+ args[param] = value
53
+ end
54
+ }
55
+
56
+ # we can't manage ownership as root, so don't even try
57
+ unless Process.uid == 0
58
+ args.delete(:owner)
47
59
  end
48
60
 
49
- # This basically calls describe() on our file, and then sets all
50
- # of the local states appropriately. If the remote file is a normal
51
- # file then we set it to copy; if it's a directory, then we just mark
52
- # that the local directory should be created.
53
- def retrieve
54
- sum = nil
61
+ if args.empty?
62
+ return nil
63
+ else
64
+ return args
65
+ end
66
+ end
55
67
 
56
- unless defined? @shouldorig
57
- raise Puppet::DevError, "No sources defined for %s" %
58
- @parent.name
59
- end
68
+ # This basically calls describe() on our file, and then sets all
69
+ # of the local states appropriately. If the remote file is a normal
70
+ # file then we set it to copy; if it's a directory, then we just mark
71
+ # that the local directory should be created.
72
+ def retrieve
73
+ sum = nil
60
74
 
61
- @source = nil
62
-
63
- # Find the first source that exists. @shouldorig contains
64
- # the sources as specified by the user.
65
- @shouldorig.each { |source|
66
- if @stats = self.describe(source)
67
- @source = source
68
- break
69
- end
70
- }
75
+ unless defined? @shouldorig
76
+ raise Puppet::DevError, "No sources defined for %s" %
77
+ @parent.name
78
+ end
71
79
 
72
- if @stats.nil? or @stats[:type].nil?
73
- @is = :notdescribed
74
- @source = nil
75
- return nil
80
+ @source = nil
81
+
82
+ # Find the first source that exists. @shouldorig contains
83
+ # the sources as specified by the user.
84
+ @shouldorig.each { |source|
85
+ if @stats = self.describe(source)
86
+ @source = source
87
+ break
76
88
  end
89
+ }
77
90
 
78
- # Take each of the stats and set them as states on the local file
79
- # if a value has not already been provided.
80
- @stats.each { |stat, value|
81
- next if stat == :checksum
82
- next if stat == :type
83
-
84
- # was the stat already specified, or should the value
85
- # be inherited from the source?
86
- unless @parent.argument?(stat)
87
- if state = @parent.state(stat)
88
- state.should = value
89
- else
90
- @parent[stat] = value
91
- end
92
- end
93
- }
91
+ if @stats.nil? or @stats[:type].nil?
92
+ @is = :notdescribed
93
+ @source = nil
94
+ return nil
95
+ end
94
96
 
95
- # If we're a normal file, then set things up to copy the file down.
96
- case @stats[:type]
97
- when "file":
98
- if sum = @parent.state(:checksum)
99
- if sum.is
100
- if sum.is == :notfound
101
- sum.retrieve
102
- end
103
- @is = sum.is
104
- else
105
- @is = :notfound
106
- end
97
+ # Take each of the stats and set them as states on the local file
98
+ # if a value has not already been provided.
99
+ @stats.each { |stat, value|
100
+ next if stat == :checksum
101
+ next if stat == :type
102
+
103
+ # was the stat already specified, or should the value
104
+ # be inherited from the source?
105
+ unless @parent.argument?(stat)
106
+ if state = @parent.state(stat)
107
+ state.should = value
107
108
  else
108
- self.info "File does not have checksum"
109
- @is = :notfound
110
- end
111
-
112
- @should = [@stats[:checksum]]
113
-
114
- if state = @parent.state(:create)
115
- unless state.should == "file"
116
- self.notice(
117
- "File %s had both create and source enabled" %
118
- @parent.name
119
- )
120
- @parent.delete(:create)
121
- end
109
+ @parent[stat] = value
122
110
  end
123
- # If we're a directory, then do not copy anything, and instead just
124
- # create the directory using the 'create' state.
125
- when "directory":
126
- if state = @parent.state(:create)
127
- unless state.should == "directory"
128
- state.should = "directory"
111
+ end
112
+ }
113
+
114
+ # If we're a normal file, then set things up to copy the file down.
115
+ case @stats[:type]
116
+ when "file":
117
+ if sum = @parent.state(:checksum)
118
+ if sum.is
119
+ if sum.is == :absent
120
+ sum.retrieve
129
121
  end
122
+ @is = sum.is
130
123
  else
131
- @parent[:create] = "directory"
132
- @parent.state(:create).retrieve
124
+ @is = :absent
133
125
  end
134
- # we'll let the :create state do our work
135
- @should.clear
136
- @is = true
137
- # FIXME We should at least support symlinks, I would think...
138
126
  else
139
- self.err "Cannot use files of type %s as sources" %
140
- @stats[:type]
141
- @should = nil
142
- @is = true
127
+ self.info "File does not have checksum"
128
+ @is = :absent
143
129
  end
144
- end
145
130
 
146
- # The special thing here is that we need to make sure that 'should'
147
- # is only set for files, not directories. The processing we're doing
148
- # here doesn't really matter, because the @should values will be
149
- # overridden when we 'retrieve'.
150
- def shouldprocess(source)
151
- unless @parent.uri2obj(source)
152
- raise Puppet::Error, "Invalid source %s" % source
131
+ @should = [@stats[:checksum]]
132
+ # If we're a directory, then do not copy anything, and instead just
133
+ # create the directory using the 'create' state.
134
+ when "directory":
135
+ if state = @parent.state(:ensure)
136
+ unless state.should == "directory"
137
+ state.should = "directory"
138
+ end
139
+ else
140
+ @parent[:ensure] = "directory"
141
+ @parent.state(:ensure).retrieve
153
142
  end
143
+ # we'll let the :ensure state do our work
144
+ @should.clear
145
+ @is = true
146
+ # FIXME We should at least support symlinks, I would think...
147
+ else
148
+ self.err "Cannot use files of type %s as sources" %
149
+ @stats[:type]
150
+ @should = nil
151
+ @is = true
152
+ end
153
+ end
154
154
 
155
- if ! defined? @stats or @stats.nil?
156
- # stupid hack for now; it'll get overriden
157
- return source
155
+ # The special thing here is that we need to make sure that 'should'
156
+ # is only set for files, not directories. The processing we're doing
157
+ # here doesn't really matter, because the @should values will be
158
+ # overridden when we 'retrieve'.
159
+ munge do |source|
160
+ unless @parent.uri2obj(source)
161
+ raise Puppet::Error, "Invalid source %s" % source
162
+ end
163
+
164
+ if ! defined? @stats or @stats.nil?
165
+ # stupid hack for now; it'll get overriden
166
+ return source
167
+ else
168
+ if @stats[:type] == "directory"
169
+ @is = true
170
+ return nil
158
171
  else
159
- if @stats[:type] == "directory"
160
- @is = true
161
- return nil
162
- else
163
- return source
164
- end
172
+ return source
165
173
  end
166
174
  end
175
+ end
167
176
 
168
- def sync
177
+ def sync
178
+ if @is == :notdescribed
179
+ self.retrieve # try again
169
180
  if @is == :notdescribed
170
- self.retrieve # try again
171
- if @is == :notdescribed
172
- @parent.log "Could not retreive information on %s" %
173
- @parent.name
174
- return nil
175
- end
176
- if @is == @should
177
- return nil
178
- end
179
- end
180
-
181
- unless @stats[:type] == "file"
182
- if @stats[:type] == "directory"
183
- [@parent.name, @is.inspect, @should.inspect]
184
- end
185
- raise Puppet::DevError, "Got told to copy non-file %s" %
181
+ @parent.log "Could not retreive information on %s" %
186
182
  @parent.name
183
+ return nil
187
184
  end
185
+ if @is == @should
186
+ return nil
187
+ end
188
+ end
188
189
 
189
- unless defined? @source
190
- raise Puppet::DevError, "Somehow source is still undefined"
190
+ unless @stats[:type] == "file"
191
+ if @stats[:type] == "directory"
192
+ [@parent.name, @is.inspect, @should.inspect]
191
193
  end
194
+ raise Puppet::DevError, "Got told to copy non-file %s" %
195
+ @parent.name
196
+ end
192
197
 
193
- sourceobj, path = @parent.uri2obj(@source)
198
+ unless defined? @source
199
+ raise Puppet::DevError, "Somehow source is still undefined"
200
+ end
194
201
 
195
- begin
196
- contents = sourceobj.server.retrieve(path)
197
- rescue NetworkClientError => detail
198
- self.err "Could not retrieve %s: %s" %
199
- [path, detail]
200
- return nil
201
- end
202
+ sourceobj, path = @parent.uri2obj(@source)
202
203
 
203
- # FIXME It's stupid that this isn't taken care of in the
204
- # protocol.
205
- unless sourceobj.server.local
206
- contents = CGI.unescape(contents)
207
- end
204
+ begin
205
+ contents = sourceobj.server.retrieve(path)
206
+ rescue NetworkClientError => detail
207
+ self.err "Could not retrieve %s: %s" %
208
+ [path, detail]
209
+ return nil
210
+ end
208
211
 
209
- if contents == ""
210
- self.notice "Could not retrieve contents for %s" %
211
- @source
212
- end
212
+ # FIXME It's stupid that this isn't taken care of in the
213
+ # protocol.
214
+ unless sourceobj.server.local
215
+ contents = CGI.unescape(contents)
216
+ end
213
217
 
214
- if FileTest.exists?(@parent.name)
215
- # this makes sure we have a copy for posterity
216
- @backed = @parent.handlebackup
217
- end
218
+ if contents == ""
219
+ self.notice "Could not retrieve contents for %s" %
220
+ @source
221
+ end
218
222
 
219
- # create the file in a tmp location
220
- args = [@parent.name + ".puppettmp",
221
- File::CREAT | File::WRONLY | File::TRUNC]
223
+ if FileTest.exists?(@parent.name)
224
+ # this makes sure we have a copy for posterity
225
+ @backed = @parent.handlebackup
226
+ end
222
227
 
223
- # try to create it with the correct modes to start
224
- # we should also be changing our effective uid/gid, but...
225
- if @parent.should(:mode) and @parent.should(:mode) != :notfound
226
- args.push @parent.should(:mode)
227
- end
228
+ # create the file in a tmp location
229
+ args = [@parent.name + ".puppettmp",
230
+ File::CREAT | File::WRONLY | File::TRUNC]
228
231
 
229
- # FIXME we should also change our effective user and group id
232
+ # try to create it with the correct modes to start
233
+ # we should also be changing our effective uid/gid, but...
234
+ if @parent.should(:mode) and @parent.should(:mode) != :absent
235
+ args.push @parent.should(:mode)
236
+ end
230
237
 
231
- begin
232
- File.open(*args) { |f|
233
- f.print contents
234
- }
235
- rescue => detail
236
- # since they said they want a backup, let's error out
237
- # if we couldn't make one
238
- raise Puppet::Error, "Could not create %s to %s: %s" %
239
- [@source, @parent.name, detail.message]
240
- end
238
+ # FIXME we should also change our effective user and group id
241
239
 
242
- if FileTest.exists?(@parent.name)
243
- begin
244
- File.unlink(@parent.name)
245
- rescue => detail
246
- self.err "Could not remove %s for replacing: %s" %
247
- [@parent.name, detail]
248
- end
249
- end
240
+ exists = File.exists?(@parent.name)
241
+ begin
242
+ File.open(*args) { |f|
243
+ f.print contents
244
+ }
245
+ rescue => detail
246
+ # since they said they want a backup, let's error out
247
+ # if we couldn't make one
248
+ raise Puppet::Error, "Could not create %s to %s: %s" %
249
+ [@source, @parent.name, detail.message]
250
+ end
250
251
 
252
+ if FileTest.exists?(@parent.name)
251
253
  begin
252
- File.rename(@parent.name + ".puppettmp", @parent.name)
254
+ File.unlink(@parent.name)
253
255
  rescue => detail
254
- self.err "Could not rename tmp %s for replacing: %s" %
256
+ self.err "Could not remove %s for replacing: %s" %
255
257
  [@parent.name, detail]
256
258
  end
259
+ end
260
+
261
+ begin
262
+ File.rename(@parent.name + ".puppettmp", @parent.name)
263
+ rescue => detail
264
+ self.err "Could not rename tmp %s for replacing: %s" %
265
+ [@parent.name, detail]
266
+ end
267
+
268
+ if @stats.include? :checksum
269
+ @parent.setchecksum @stats[:checksum]
270
+ else
271
+ raise Puppet::DevError, "We're somehow missing the remote checksum"
272
+ end
257
273
 
274
+ if exists
258
275
  return :file_changed
276
+ else
277
+ return :file_created
259
278
  end
260
279
  end
261
280
  end
262
281
  end
263
282
 
264
- # $Id: source.rb 745 2005-11-16 22:17:29Z luke $
283
+ # $Id: source.rb 885 2006-02-08 17:44:44Z luke $