summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2006-01-17 07:11:50 +0000
committerluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2006-01-17 07:11:50 +0000
commit3700b37e2386e7dbaabd90b7ba13c3dce06203d2 (patch)
tree28a691598edd5e56332c0d8e254263fb4fe8a9f4
parent92a780a3106f863e442c12897184abbe39fe3310 (diff)
downloadpuppet-3700b37e2386e7dbaabd90b7ba13c3dce06203d2.tar.gz
puppet-3700b37e2386e7dbaabd90b7ba13c3dce06203d2.tar.xz
puppet-3700b37e2386e7dbaabd90b7ba13c3dce06203d2.zip
Adding an "ensure" state where appropriate, and significantly reworking the builtin docs.
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@832 980ebf18-57e1-0310-9a29-db15c13687c0
-rw-r--r--Rakefile15
-rwxr-xr-xbin/puppetdoc99
-rw-r--r--examples/code/allatonce2
-rw-r--r--examples/code/classing2
-rw-r--r--examples/code/components2
-rw-r--r--examples/code/file.bl8
-rw-r--r--examples/code/filedefaults2
-rw-r--r--examples/code/relationships2
-rw-r--r--examples/code/simpletests8
-rw-r--r--examples/code/snippets/argumentdefaults2
-rw-r--r--examples/code/snippets/casestatement16
-rw-r--r--examples/code/snippets/classheirarchy.pp6
-rw-r--r--examples/code/snippets/classincludes.pp6
-rw-r--r--examples/code/snippets/classpathtest2
-rw-r--r--examples/code/snippets/dirchmod8
-rw-r--r--examples/code/snippets/failmissingexecpath.pp2
-rw-r--r--examples/code/snippets/falsevalues.pp2
-rw-r--r--examples/code/snippets/filecreate8
-rw-r--r--examples/code/snippets/implicititeration8
-rw-r--r--examples/code/snippets/multipleinstances6
-rw-r--r--examples/code/snippets/namevartest6
-rw-r--r--examples/code/snippets/scopetest2
-rw-r--r--examples/code/snippets/selectorvalues.pp6
-rw-r--r--examples/code/snippets/simpledefaults2
-rw-r--r--examples/code/snippets/simpleselector8
-rw-r--r--lib/puppet/parameter.rb6
-rwxr-xr-xlib/puppet/sslcertificates.rb2
-rw-r--r--lib/puppet/storage.rb40
-rw-r--r--lib/puppet/type.rb108
-rwxr-xr-xlib/puppet/type/cron.rb29
-rwxr-xr-xlib/puppet/type/exec.rb80
-rwxr-xr-xlib/puppet/type/group.rb9
-rw-r--r--lib/puppet/type/package.rb138
-rwxr-xr-xlib/puppet/type/package/dpkg.rb2
-rwxr-xr-xlib/puppet/type/package/rpm.rb5
-rwxr-xr-xlib/puppet/type/package/sun.rb2
-rwxr-xr-xlib/puppet/type/package/yum.rb7
-rw-r--r--lib/puppet/type/pfile.rb42
-rwxr-xr-xlib/puppet/type/pfile/checksum.rb15
-rwxr-xr-xlib/puppet/type/pfile/content.rb21
-rwxr-xr-xlib/puppet/type/pfile/ensure.rb (renamed from lib/puppet/type/pfile/create.rb)114
-rwxr-xr-xlib/puppet/type/pfile/group.rb8
-rwxr-xr-xlib/puppet/type/pfile/mode.rb12
-rwxr-xr-xlib/puppet/type/pfile/source.rb65
-rwxr-xr-xlib/puppet/type/pfile/type.rb2
-rwxr-xr-xlib/puppet/type/pfile/uid.rb12
-rwxr-xr-xlib/puppet/type/pfilebucket.rb8
-rw-r--r--lib/puppet/type/pprocess.rb95
-rw-r--r--lib/puppet/type/service.rb64
-rw-r--r--lib/puppet/type/state.rb84
-rwxr-xr-xlib/puppet/type/symlink.rb13
-rwxr-xr-xlib/puppet/type/tidy.rb10
-rwxr-xr-xlib/puppet/type/user.rb10
-rwxr-xr-xtest/executables/puppetmodule.rb2
-rwxr-xr-xtest/language/interpreter.rb2
-rwxr-xr-xtest/other/events.rb6
-rw-r--r--test/other/log.rb2
-rwxr-xr-xtest/other/storage.rb10
-rw-r--r--test/other/transactions.rb10
-rw-r--r--test/parser/parser.rb2
-rw-r--r--test/puppettest.rb2
-rw-r--r--test/server/master.rb2
-rw-r--r--test/types/basic.rb2
-rwxr-xr-xtest/types/exec.rb4
-rw-r--r--test/types/file.rb69
-rwxr-xr-xtest/types/filesources.rb2
-rw-r--r--test/types/package.rb3
-rw-r--r--test/types/type.rb6
68 files changed, 916 insertions, 441 deletions
diff --git a/Rakefile b/Rakefile
index 55683f49e..de7626f34 100644
--- a/Rakefile
+++ b/Rakefile
@@ -52,12 +52,16 @@ task :default => :alltests
task :u => :unittests
task :a => :alltests
-Rake::TestTask.new(:alltests) do |t|
- t.test_files = FileList['test/*/*.rb']
- t.warning = true
- t.verbose = false
+task :alltests do
+ sh %{cd test; ./test}
end
+#Rake::TestTask.new(:alltests) do |t|
+# t.test_files = FileList['test/*/*.rb']
+# t.warning = true
+# t.verbose = false
+#end
+
#Rake::TestTask.new(:unittests) do |t|
# t.test_files = FileList['test/test']
# t.warning = true
@@ -348,6 +352,9 @@ task :hosttest do
out += %x{ssh #{host} 'cd puppet/test; sudo ./test' 2>&1}
if $? != 0
+ file = File.join("/tmp", "%stest.out" % host)
+ File.open(file, "w") { |of| of.print out }
+ puts "%s failed; output is in %s" % [host, file]
puts out
end
#sh %{ssh #{host} 'cd #{cwd}/test; sudo ./test' 2>&1}
diff --git a/bin/puppetdoc b/bin/puppetdoc
index 4d4dba082..6ff42743b 100755
--- a/bin/puppetdoc
+++ b/bin/puppetdoc
@@ -45,17 +45,13 @@ rescue LoadError
$haveusage = false
end
-def tab(num)
- return $tab * num
-end
-
result = GetoptLong.new(
[ "--help", "-h", GetoptLong::NO_ARGUMENT ]
)
debug = false
-$tab = " "
+$tab = " "
begin
result.each { |opt,arg|
@@ -77,6 +73,33 @@ rescue GetoptLong::InvalidOption => detail
exit(1)
end
+def scrub(text)
+ # For text with no carriage returns, there's nothing to do.
+ if text !~ /\n/
+ return text
+ end
+ indent = nil
+
+ # If we can match an indentation, then just remove that same level of
+ # indent from every line.
+ if text =~ /^(\s+)/
+ indent = $1
+ return text.gsub(/^#{indent}/,'')
+ else
+ return text
+ end
+
+end
+
+# Indent every line in the chunk except those which begin with '..'.
+def indent(text, tab)
+ return text.gsub(/(^|\A)/, tab).gsub(/^ +\.\./, "..")
+end
+
+#def tab(num)
+# return $tab * num
+#end
+
puts %{
==============
Type Reference
@@ -93,6 +116,11 @@ puts %{
Meta-Parameters
---------------
+Metaparameters are parameters that work with any element; they are part of the
+Puppet framework itself rather than being part of the implementation of any
+given instance. Thus, any defined metaparameter can be used with any instance
+in your manifest, including defined components.
+
}
begin
params = []
@@ -104,10 +132,11 @@ begin
a.to_s <=> b.to_s
}.each { |param|
puts "- **" + param.to_s + "**"
- puts tab(1) + Puppet::Type.metaparamdoc(param).gsub(/\n\s*/,' ')
+ #puts tab(1) + Puppet::Type.metaparamdoc(param).scrub.indent($tab)gsub(/\n\s*/,' ')
+ puts indent(scrub(Puppet::Type.metaparamdoc(param)), $tab)
}
rescue => detail
- puts "type %s had incorrect params: %s" % detail
+ puts "incorrect metaparams: %s" % detail
exit(1)
end
@@ -118,9 +147,25 @@ Types
- *namevar* is the parameter used to uniquely identify a type instance.
This is the parameter that gets assigned when a string is provided before
- the colon in a type declaration.
-- *parameters* determine the specific configuration of the instance.
+ the colon in a type declaration. In general, only developers will need to
+ worry about which parameter is the ``namevar``.
+
+ In the following code::
+ file { "/etc/passwd":
+ owner => root,
+ group => root,
+ mode => 644
+ }
+
+ "/etc/passwd" is considered the name of the file object (used for things like
+ dependency handling), and because ``path`` is the namevar for ``file``, that
+ string is assigned to the ``path`` parameter.
+
+- *parameters* determine the specific configuration of the instance. They either
+ directly modify the system (internally, these are called states) or they affect
+ how the instance behaves (e.g., adding a search path for ``exec`` instances
+ or determining recursion on ``file`` instances).
}
@@ -141,8 +186,8 @@ types.sort { |a,b|
%s" % [name, "=" * (name.to_s.length + 4)]
#String.new('n%s\n') % name.to_s
#puts "**" + type.doc.gsub(/\n\s*/, ' ') + "**\n\n"
- puts type.doc.gsub(/\n\s*/, ' ') + "\n\n"
- type.buildstatehash
+ puts scrub(type.doc) + "\n\n"
+
#puts tab(1) + "* namevar: %s" % type.namevar
docs = {}
#puts "%s States\n'''''''''''''''''''''''''''''''" % name.to_s.capitalize
@@ -153,7 +198,33 @@ types.sort { |a,b|
state.nodoc
}.each { |sname|
state = type.statebyname(sname)
- docs[sname] = state.doc.gsub(/\n\s*/,' ')
+
+ doc = nil
+ str = nil
+ unless doc = state.doc.dup
+ $stderr.puts "No docs for %s[%s]" % [type, sname]
+ next
+ end
+ str = doc
+ #puts "A---" + str + "---"
+ str = scrub(str)
+ #puts "B---" + str + "---"
+ #str = indent(str, $tab)
+ #puts "C---" + str + "---"
+ #str = indent($tab, scrub(doc))
+
+ # If the state has values, then add them:
+
+ #if values = state.values
+ # unless values.empty?
+ # extra = "Acceptable values are %s." % values.join(", ")
+ # str += "\n\n#{extra}"
+ # end
+ #end
+
+ str = indent(str, $tab)
+ #puts "---" + str + "---"
+ docs[sname] = str
#puts "- **%s**" % sname
#puts tab(1) + state.doc.gsub(/\n\s*/,' ')
}
@@ -162,7 +233,7 @@ types.sort { |a,b|
type.parameters.sort { |a,b|
a.to_s <=> b.to_s
}.each { |name,param|
- docs[name] = type.paramdoc(name).gsub(/\n\s*/,' ')
+ docs[name] = indent(scrub(type.paramdoc(name)), $tab)
}
docs.sort { |a, b|
@@ -174,7 +245,7 @@ types.sort { |a,b|
else
puts ""
end
- puts tab(1) + doc
+ puts doc
}
puts "\n"
}
diff --git a/examples/code/allatonce b/examples/code/allatonce
index 2857b9b62..8912ec4e7 100644
--- a/examples/code/allatonce
+++ b/examples/code/allatonce
@@ -1,7 +1,7 @@
# $Id$
define thingie {
- file { "/tmp/classtest": create => true, mode => 755 }
+ file { "/tmp/classtest": ensure => file, mode => 755 }
#testing {}
}
diff --git a/examples/code/classing b/examples/code/classing
index 8f9477721..0eeb713b9 100644
--- a/examples/code/classing
+++ b/examples/code/classing
@@ -12,7 +12,7 @@ class base() {
class server inherits base {
file { "/tmp/puppetfiletest":
- create => true
+ ensure => file
}
}
diff --git a/examples/code/components b/examples/code/components
index 15f131d0e..3da43c571 100644
--- a/examples/code/components
+++ b/examples/code/components
@@ -59,7 +59,7 @@ define sleeper(path,mode) {
}
$files = ["/tmp/testness","/tmp/funtest"]
file { $files:
- create => true
+ ensure => file
}
}
diff --git a/examples/code/file.bl b/examples/code/file.bl
index 41d80b53d..ef46ba223 100644
--- a/examples/code/file.bl
+++ b/examples/code/file.bl
@@ -1,11 +1,11 @@
# $Id$
file {
- "/tmp/atest": create => true, mode => 755;
- "/tmp/btest": create => true, mode => 755
+ "/tmp/atest": ensure => file, mode => 755;
+ "/tmp/btest": ensure => file, mode => 755
}
file {
- "/tmp/ctest": create => true;
- "/tmp/dtest": create => true;
+ "/tmp/ctest": ensure => file;
+ "/tmp/dtest": ensure => file;
}
diff --git a/examples/code/filedefaults b/examples/code/filedefaults
index cb005c093..56cf76a9a 100644
--- a/examples/code/filedefaults
+++ b/examples/code/filedefaults
@@ -6,5 +6,5 @@ File {
}
file { "/tmp/filedefaultstest":
- create => true
+ ensure => file
}
diff --git a/examples/code/relationships b/examples/code/relationships
index f2319d5e4..795788947 100644
--- a/examples/code/relationships
+++ b/examples/code/relationships
@@ -8,7 +8,7 @@ $path = "../examples/root/etc/configfile"
define files {
file { "/tmp/yaytest":
- create => true,
+ ensure => file,
mode => 755
}
file { "/tmp/exists":
diff --git a/examples/code/simpletests b/examples/code/simpletests
index 6a2d5c5ff..b4fd3234e 100644
--- a/examples/code/simpletests
+++ b/examples/code/simpletests
@@ -1,11 +1,11 @@
# $Id$
file {
- "/tmp/atest": create => true;
- "/tmp/btest": create => true
+ "/tmp/atest": ensure => file;
+ "/tmp/btest": ensure => file
}
file {
- "/tmp/ctest": create => true;
- "/tmp/dtest": create => true;
+ "/tmp/ctest": ensure => file;
+ "/tmp/dtest": ensure => file;
}
diff --git a/examples/code/snippets/argumentdefaults b/examples/code/snippets/argumentdefaults
index b4081e9b0..7d814f2fb 100644
--- a/examples/code/snippets/argumentdefaults
+++ b/examples/code/snippets/argumentdefaults
@@ -1,7 +1,7 @@
# $Id$
define testargs(file, mode = 755) {
- file { $file: create => true, mode => $mode }
+ file { $file: ensure => file, mode => $mode }
}
testargs { "testingname":
diff --git a/examples/code/snippets/casestatement b/examples/code/snippets/casestatement
index 565b8b422..05ac031e6 100644
--- a/examples/code/snippets/casestatement
+++ b/examples/code/snippets/casestatement
@@ -4,10 +4,10 @@ $var = "value"
case $var {
"nope": {
- file { "/tmp/fakefile": mode => 644, create => true }
+ file { "/tmp/fakefile": mode => 644, ensure => file }
}
"value": {
- file { "/tmp/existsfile": mode => 755, create => true }
+ file { "/tmp/existsfile": mode => 755, ensure => file }
}
}
@@ -15,15 +15,15 @@ $ovar = "yayness"
case $ovar {
"fooness": {
- file { "/tmp/nostillexistsfile": mode => 644, create => true }
+ file { "/tmp/nostillexistsfile": mode => 644, ensure => file }
}
"booness", "yayness": {
case $var {
"nep": {
- file { "/tmp/noexistsfile": mode => 644, create => true }
+ file { "/tmp/noexistsfile": mode => 644, ensure => file }
}
"value": {
- file { "/tmp/existsfile2": mode => 755, create => true }
+ file { "/tmp/existsfile2": mode => 755, ensure => file }
}
}
}
@@ -31,10 +31,10 @@ case $ovar {
case $ovar {
"fooness": {
- file { "/tmp/nostillexistsfile": mode => 644, create => true }
+ file { "/tmp/nostillexistsfile": mode => 644, ensure => file }
}
default: {
- file { "/tmp/existsfile3": mode => 755, create => true }
+ file { "/tmp/existsfile3": mode => 755, ensure => file }
}
}
@@ -42,6 +42,6 @@ $bool = true
case $bool {
true: {
- file { "/tmp/existsfile4": mode => 755, create => true }
+ file { "/tmp/existsfile4": mode => 755, ensure => file }
}
}
diff --git a/examples/code/snippets/classheirarchy.pp b/examples/code/snippets/classheirarchy.pp
index 3f9527573..36619d8b9 100644
--- a/examples/code/snippets/classheirarchy.pp
+++ b/examples/code/snippets/classheirarchy.pp
@@ -1,15 +1,15 @@
# $Id$
class base {
- file { "/tmp/classheir1": create => true, mode => 755 }
+ file { "/tmp/classheir1": ensure => file, mode => 755 }
}
class sub1 inherits base {
- file { "/tmp/classheir2": create => true, mode => 755 }
+ file { "/tmp/classheir2": ensure => file, mode => 755 }
}
class sub2 inherits base {
- file { "/tmp/classheir3": create => true, mode => 755 }
+ file { "/tmp/classheir3": ensure => file, mode => 755 }
}
include sub1, sub2
diff --git a/examples/code/snippets/classincludes.pp b/examples/code/snippets/classincludes.pp
index 3cf2bbd44..927800599 100644
--- a/examples/code/snippets/classincludes.pp
+++ b/examples/code/snippets/classincludes.pp
@@ -1,15 +1,15 @@
# $Id$
class base {
- file { "/tmp/classincludes1": create => true, mode => 755 }
+ file { "/tmp/classincludes1": ensure => file, mode => 755 }
}
class sub1 inherits base {
- file { "/tmp/classincludes2": create => true, mode => 755 }
+ file { "/tmp/classincludes2": ensure => file, mode => 755 }
}
class sub2 inherits base {
- file { "/tmp/classincludes3": create => true, mode => 755 }
+ file { "/tmp/classincludes3": ensure => file, mode => 755 }
}
$sub = "sub2"
diff --git a/examples/code/snippets/classpathtest b/examples/code/snippets/classpathtest
index 07b9e5aea..68610958b 100644
--- a/examples/code/snippets/classpathtest
+++ b/examples/code/snippets/classpathtest
@@ -1,7 +1,7 @@
# $Id$
define component {
- file { "/tmp/classtest": create => true, mode => 755 }
+ file { "/tmp/classtest": ensure => file, mode => 755 }
}
class testing {
diff --git a/examples/code/snippets/dirchmod b/examples/code/snippets/dirchmod
index 0a8268fa8..dc2cc8949 100644
--- a/examples/code/snippets/dirchmod
+++ b/examples/code/snippets/dirchmod
@@ -1,8 +1,8 @@
# $Id$
file {
- "/tmp/dirchmodtesta": create => directory;
- "/tmp/dirchmodtesta/testing": create => true
+ "/tmp/dirchmodtesta": ensure => directory;
+ "/tmp/dirchmodtesta/testing": ensure => file
}
file { "/tmp/dirchmodtesta":
@@ -10,8 +10,8 @@ file { "/tmp/dirchmodtesta":
}
file {
- "/tmp/dirchmodtestb": create => directory;
- "/tmp/dirchmodtestb/testing": create => true
+ "/tmp/dirchmodtestb": ensure => directory;
+ "/tmp/dirchmodtestb/testing": ensure => file
}
file { "/tmp/dirchmodtestb":
diff --git a/examples/code/snippets/failmissingexecpath.pp b/examples/code/snippets/failmissingexecpath.pp
index 3f43be325..fe17b049b 100644
--- a/examples/code/snippets/failmissingexecpath.pp
+++ b/examples/code/snippets/failmissingexecpath.pp
@@ -1,6 +1,6 @@
define distloc(path) {
file { "/tmp/exectesting1":
- create => file
+ ensure => file
}
exec { "touch $path":
subscribe => file["/tmp/exectesting1"],
diff --git a/examples/code/snippets/falsevalues.pp b/examples/code/snippets/falsevalues.pp
index 21f957bd2..2143b79a7 100644
--- a/examples/code/snippets/falsevalues.pp
+++ b/examples/code/snippets/falsevalues.pp
@@ -1,3 +1,3 @@
$value = false
-file { "/tmp/falsevalues$value": create => true }
+file { "/tmp/falsevalues$value": ensure => file }
diff --git a/examples/code/snippets/filecreate b/examples/code/snippets/filecreate
index 7a4cdbb1e..d7972c234 100644
--- a/examples/code/snippets/filecreate
+++ b/examples/code/snippets/filecreate
@@ -1,11 +1,11 @@
# $Id$
file {
- "/tmp/createatest": create => true, mode => 755;
- "/tmp/createbtest": create => true, mode => 755
+ "/tmp/createatest": ensure => file, mode => 755;
+ "/tmp/createbtest": ensure => file, mode => 755
}
file {
- "/tmp/createctest": create => true;
- "/tmp/createdtest": create => true;
+ "/tmp/createctest": ensure => file;
+ "/tmp/createdtest": ensure => file;
}
diff --git a/examples/code/snippets/implicititeration b/examples/code/snippets/implicititeration
index c4a850a94..6f34cb29c 100644
--- a/examples/code/snippets/implicititeration
+++ b/examples/code/snippets/implicititeration
@@ -2,14 +2,14 @@
$files = ["/tmp/iterationatest", "/tmp/iterationbtest"]
-file { $files: create => true, mode => 755 }
+file { $files: ensure => file, mode => 755 }
file { ["/tmp/iterationctest", "/tmp/iterationdtest"]:
- create => true,
+ ensure => file,
mode => 755
}
file {
- ["/tmp/iterationetest", "/tmp/iterationftest"]: create => true, mode => 755;
- ["/tmp/iterationgtest", "/tmp/iterationhtest"]: create => true, mode => 755;
+ ["/tmp/iterationetest", "/tmp/iterationftest"]: ensure => file, mode => 755;
+ ["/tmp/iterationgtest", "/tmp/iterationhtest"]: ensure => file, mode => 755;
}
diff --git a/examples/code/snippets/multipleinstances b/examples/code/snippets/multipleinstances
index abc060316..2f9b3c2e8 100644
--- a/examples/code/snippets/multipleinstances
+++ b/examples/code/snippets/multipleinstances
@@ -1,7 +1,7 @@
# $Id$
file {
- "/tmp/multipleinstancesa": create => true, mode => 755;
- "/tmp/multipleinstancesb": create => true, mode => 755;
- "/tmp/multipleinstancesc": create => true, mode => 755;
+ "/tmp/multipleinstancesa": ensure => file, mode => 755;
+ "/tmp/multipleinstancesb": ensure => file, mode => 755;
+ "/tmp/multipleinstancesc": ensure => file, mode => 755;
}
diff --git a/examples/code/snippets/namevartest b/examples/code/snippets/namevartest
index 93a263dd4..b4db5bacf 100644
--- a/examples/code/snippets/namevartest
+++ b/examples/code/snippets/namevartest
@@ -1,9 +1,9 @@
-define filetest(mode, create = true) {
+define filetest(mode, ensure = file) {
file { $name:
mode => $mode,
- create => $create
+ ensure => $ensure
}
}
filetest { "/tmp/testfiletest": mode => 644}
-filetest { "/tmp/testdirtest": mode => 755, create => directory}
+filetest { "/tmp/testdirtest": mode => 755, ensure => directory}
diff --git a/examples/code/snippets/scopetest b/examples/code/snippets/scopetest
index b00560372..3d3b31d8a 100644
--- a/examples/code/snippets/scopetest
+++ b/examples/code/snippets/scopetest
@@ -2,7 +2,7 @@
$mode = 640
define thing {
- file { "/tmp/scopetest": create => true, mode => $mode }
+ file { "/tmp/scopetest": ensure => file, mode => $mode }
}
class testing {
diff --git a/examples/code/snippets/selectorvalues.pp b/examples/code/snippets/selectorvalues.pp
index e4d1ce444..dcbf16c70 100644
--- a/examples/code/snippets/selectorvalues.pp
+++ b/examples/code/snippets/selectorvalues.pp
@@ -17,6 +17,6 @@ $mode3 = $value3 ? {
default => 644
}
-file { "/tmp/selectorvalues1": create => true, mode => $mode1 }
-file { "/tmp/selectorvalues2": create => true, mode => $mode2 }
-file { "/tmp/selectorvalues3": create => true, mode => $mode3 }
+file { "/tmp/selectorvalues1": ensure => file, mode => $mode1 }
+file { "/tmp/selectorvalues2": ensure => file, mode => $mode2 }
+file { "/tmp/selectorvalues3": ensure => file, mode => $mode3 }
diff --git a/examples/code/snippets/simpledefaults b/examples/code/snippets/simpledefaults
index a8f6190b1..63d199a68 100644
--- a/examples/code/snippets/simpledefaults
+++ b/examples/code/snippets/simpledefaults
@@ -2,4 +2,4 @@
File { mode => 755 }
-file { "/tmp/defaulttest": create => true }
+file { "/tmp/defaulttest": ensure => file }
diff --git a/examples/code/snippets/simpleselector b/examples/code/snippets/simpleselector
index 52a06c773..8b9bc7292 100644
--- a/examples/code/snippets/simpleselector
+++ b/examples/code/snippets/simpleselector
@@ -3,7 +3,7 @@
$var = "value"
file { "/tmp/snippetselectatest":
- create => true,
+ ensure => file,
mode => $var ? {
nottrue => 641,
value => 755
@@ -11,7 +11,7 @@ file { "/tmp/snippetselectatest":
}
file { "/tmp/snippetselectbtest":
- create => true,
+ ensure => file,
mode => $var ? {
nottrue => 644,
default => 755
@@ -21,7 +21,7 @@ file { "/tmp/snippetselectbtest":
$othervar = "complex value"
file { "/tmp/snippetselectctest":
- create => true,
+ ensure => file,
mode => $othervar ? {
"complex value" => 755,
default => 644
@@ -30,7 +30,7 @@ file { "/tmp/snippetselectctest":
$anothervar = Yayness
file { "/tmp/snippetselectdtest":
- create => true,
+ ensure => file,
mode => $anothervar ? {
Yayness => 755,
default => 644
diff --git a/lib/puppet/parameter.rb b/lib/puppet/parameter.rb
index 6f3b0f184..d6662ef1a 100644
--- a/lib/puppet/parameter.rb
+++ b/lib/puppet/parameter.rb
@@ -15,6 +15,12 @@ module Puppet
end
end
+ def nodefault
+ undef_method :default
+ #if defined_method? :default
+ #end
+ end
+
# Store documentation for this parameter.
def desc(str)
@doc = str
diff --git a/lib/puppet/sslcertificates.rb b/lib/puppet/sslcertificates.rb
index 9196da61b..6c21f7c49 100755
--- a/lib/puppet/sslcertificates.rb
+++ b/lib/puppet/sslcertificates.rb
@@ -28,7 +28,7 @@ module SSLCertificates
obj = Puppet::Type.type(:file).create(
:name => File.join(path),
:mode => "750",
- :create => "directory"
+ :ensure => "directory"
)
comp.push obj
diff --git a/lib/puppet/storage.rb b/lib/puppet/storage.rb
index af59efa19..b174e0183 100644
--- a/lib/puppet/storage.rb
+++ b/lib/puppet/storage.rb
@@ -2,34 +2,32 @@ require 'yaml'
module Puppet
# a class for storing state
- class Storage
- include Singleton
-
- def initialize
- self.class.load
- end
+ class Storage
+ include Singleton
+
+ def initialize
+ self.class.load
+ end
def self.clear
- @@state = nil
+ @@state.clear
Storage.init
end
def self.init
Puppet.debug "Initializing Storage"
- @@state = Hash.new { |hash,key|
- hash[key] = Hash.new(nil)
- }
+ @@state = {}
@@splitchar = "\t"
end
self.init
- def self.load
+ def self.load
if Puppet[:checksumfile].nil?
raise Puppet::DevError, "Somehow the statefile is nil"
end
- unless File.exists?(Puppet[:checksumfile])
+ unless File.exists?(Puppet[:checksumfile])
Puppet.info "Statefile %s does not exist" % Puppet[:checksumfile]
unless defined? @@state and ! @@state.nil?
self.init
@@ -56,16 +54,22 @@ module Puppet
}
#Puppet.debug "Loaded state is %s" % @@state.inspect
- end
+ end
+
+ def self.stateinspect
+ @@state.inspect
+ end
- def self.state(myclass)
+ def self.state(myclass)
unless myclass.is_a? Class
myclass = myclass.class
end
+
+ @@state[myclass.to_s] ||= {}
return @@state[myclass.to_s]
- end
+ end
- def self.store
+ def self.store
unless FileTest.directory?(File.dirname(Puppet[:checksumfile]))
begin
Puppet.recmkdir(File.dirname(Puppet[:checksumfile]))
@@ -95,8 +99,8 @@ module Puppet
# }
#}
}
- end
- end
+ end
+ end
end
# $Id$
diff --git a/lib/puppet/type.rb b/lib/puppet/type.rb
index 05da74d30..ca85f92aa 100644
--- a/lib/puppet/type.rb
+++ b/lib/puppet/type.rb
@@ -219,7 +219,7 @@ class Type < Puppet::Element
self.newstate(:ensure, Puppet::State::Ensure, &block)
else
self.newstate(:ensure, Puppet::State::Ensure) do
- # don't actually do anything with the block, but it's required...
+ self.defaultvalues
end
end
end
@@ -227,6 +227,10 @@ class Type < Puppet::Element
# Return a Type instance by name.
def self.type(name)
@types ||= {}
+
+ if name.is_a?(String)
+ name = name.intern
+ end
@types[name]
end
@@ -1245,7 +1249,7 @@ class Type < Puppet::Element
end
if klass.method_defined?(:default)
obj = self.newattr(type, klass)
- self.info "defaulting %s to %s" % [obj.name, obj.default]
+ #self.debug "defaulting %s to %s" % [obj.name, obj.default]
obj.value = obj.default
end
}
@@ -1511,7 +1515,7 @@ class Type < Puppet::Element
states.each { |state|
unless state.insync?
self.debug("%s is not in sync: %s vs %s" %
- [state, state.is, state.should])
+ [state, state.is.inspect, state.should.inspect])
insync = false
end
}
@@ -1709,15 +1713,15 @@ class Type < Puppet::Element
end
# Add all of the meta parameters.
- newmetaparam(:onerror) do
- desc "How to handle errors -- roll back innermost
- transaction, roll back entire transaction, ignore, etc. Currently
- non-functional."
- end
+ #newmetaparam(:onerror) do
+ # desc "How to handle errors -- roll back innermost
+ # transaction, roll back entire transaction, ignore, etc. Currently
+ # non-functional."
+ #end
newmetaparam(:noop) do
desc "Boolean flag indicating whether work should actually
- be done."
+ be done. *true*/**false**"
munge do |noop|
if noop == "true" or noop == true
return true
@@ -1729,15 +1733,18 @@ class Type < Puppet::Element
end
end
- newmetaparam(:schedule) do
- desc "On what schedule the object should be managed.
- Currently non-functional."
- end
+ #newmetaparam(:schedule) do
+ # desc "On what schedule the object should be managed.
+ # Currently non-functional."
+ #end
newmetaparam(:check) do
desc "States which should have their values retrieved
but which should not actually be modified. This is currently used
- internally, but will eventually be used for querying."
+ internally, but will eventually be used for querying, so that you
+ could specify that you wanted to check the install state of all
+ packages, and then query the Puppet client daemon to get reports
+ on all packages."
munge do |args|
unless args.is_a?(Array)
@@ -1764,7 +1771,37 @@ class Type < Puppet::Element
newmetaparam(:require) do
desc "One or more objects that this object depends on.
This is used purely for guaranteeing that changes to required objects
- happen before the dependent object."
+ happen before the dependent object. For instance::
+
+ # Create the destination directory before you copy things down
+ file { \"/usr/local/scripts\":
+ ensure => directory
+ }
+
+ file { \"/usr/local/scripts/myscript\":
+ source => \"puppet://server/module/myscript\",
+ mode => 755,
+ require => file[\"/usr/local/scripts\"]
+ }
+
+ Note that Puppet will autorequire everything that it can, and
+ there are hooks in place so that it's easy for elements to add new
+ ways to autorequire objects, so if you think Puppet could be
+ smarter here, let us know.
+
+ In fact, the above code was redundant -- Puppet will autorequire
+ any parent directories that are being managed; it will
+ automatically realize that the parent directory should be created
+ before the script is pulled down.
+
+ Currently, exec_ elements will autorequire their CWD (if it is
+ specified) plus any fully qualified paths that appear in the
+ command. For instance, if you had an ``exec`` command that ran
+ the ``myscript`` mentioned above, the above code that pulls the
+ file down would be automatically listed as a requirement to the
+ ``exec`` code, so that you would always be running againts the
+ most recent version.
+ "
# Take whatever dependencies currently exist and add these.
# Note that this probably doesn't behave correctly with unsubscribe.
@@ -1788,9 +1825,22 @@ class Type < Puppet::Element
# For each object we require, subscribe to all events that it generates.
# We might reduce the level of subscription eventually, but for now...
newmetaparam(:subscribe) do
- desc "One or more objects that this object depends on.
- Changes in the subscribed to objects result in the dependent objects being
- refreshed (e.g., a service will get restarted)."
+ desc "One or more objects that this object depends on. Changes in the
+ subscribed to objects result in the dependent objects being
+ refreshed (e.g., a service will get restarted). For instance::
+
+ class nagios {
+ file { \"/etc/nagios/nagios.conf\":
+ source => \"puppet://server/module/nagios.conf\",
+ alias => nagconf # just to make things easier for me
+ }
+
+ service { nagios:
+ running => true,
+ require => file[nagconf]
+ }
+ }
+ "
munge do |requires|
if values = @parent[:subscribe]
@@ -1803,7 +1853,9 @@ class Type < Puppet::Element
newmetaparam(:loglevel) do
desc "Sets the level that information will be logged:
- debug, info, verbose, notice, warning, err, alert, emerg or crit"
+ debug, info, verbose, notice, warning, err, alert, emerg or crit.
+ The log levels have the biggest impact when logs are sent to
+ syslog (which is currently the default)."
defaultto :notice
validate do |loglevel|
@@ -1830,7 +1882,23 @@ class Type < Puppet::Element
desc "Creates an alias for the object. This simplifies lookup of the
object so is useful in the language. It is especially useful when
you are creating long commands using exec or when many different
- systems call a given package different names."
+ systems call a given package_ different names::
+
+
+ file { \"/usr/local/scripts/myscript\":
+ source => \"puppet://server/module/myscript\",
+ mode => 755,
+ alias => myscript
+ }
+
+ exec { \"/usr/local/scripts/myscript\":
+ require => file[myscript]
+ }
+
+ Again, this is somewhat redundant, since any sane person would
+ just use a variable (unless the two statements were in different
+ scopes), and Puppet will autorequire the script anyway, but it
+ gets the point across."
munge do |aliases|
unless aliases.is_a?(Array)
diff --git a/lib/puppet/type/cron.rb b/lib/puppet/type/cron.rb
index c6acbfea0..03b27eef5 100755
--- a/lib/puppet/type/cron.rb
+++ b/lib/puppet/type/cron.rb
@@ -156,7 +156,12 @@ module Puppet
newparam(:name) do
desc "The symbolic name of the cron job. This name
- is used for human reference only."
+ is used for human reference only and is generated
+ automatically for cron jobs found on the system. This generally
+ won't matter, as Puppet will do its best to match existing
+ cron jobs against specified jobs (and Puppet adds a tag to
+ cron jobs it adds), but it is at least possible that converting
+ from unmanaged jobs to managed jobs might require manual intervention."
isnamevar
end
@@ -186,11 +191,23 @@ module Puppet
and the user are optional, although specifying no periodic
fields would result in the command being executed every
minute. While the name of the cron job is not part of the actual
- job, it is used by Puppet to store and retrieve it. If you specify
- a cron job that matches an existing job in every way except name,
- then the jobs will be considered equivalent and the new name will
- be permanently associated with that job. Once this association is
- made and synced to disk, you can then manage the job normally."
+ job, it is used by Puppet to store and retrieve it.
+
+ If you specify a cron job that matches an existing job in every way
+ except name, then the jobs will be considered equivalent and the
+ new name will be permanently associated with that job. Once this
+ association is made and synced to disk, you can then manage the job
+ normally (e.g., change the schedule of the job).
+
+ Example::
+
+ cron { logrotate:
+ command => \"/usr/sbin/logrotate\",
+ user => root,
+ hour => 2,
+ minute => 0
+ }
+ "
@instances = {}
@tabs = {}
diff --git a/lib/puppet/type/exec.rb b/lib/puppet/type/exec.rb
index 9570c86b8..78f96d9a7 100755
--- a/lib/puppet/type/exec.rb
+++ b/lib/puppet/type/exec.rb
@@ -5,7 +5,7 @@ module Puppet
harm, i.e., they are *idempotent*. One useful way to create idempotent
commands is to use the *creates* parameter.
- It is worth nothing that ``exec`` is special, in that it is not
+ It is worth noting that ``exec`` is special, in that it is not
currently considered an error to have multiple ``exec`` instances
with the same name. This was done purely because it had to be this
way in order to get certain functionality, but it complicates things.
@@ -13,7 +13,34 @@ module Puppet
share their commands with other instances as a dependency, since
Puppet has no way of knowing which instance you mean.
- It is recommended to avoid duplicate names whenever possible."
+ For example::
+
+ # defined in the production class
+ exec { \"make\":
+ cwd => \"/prod/build/dir\"
+ }
+
+ . etc. .
+
+ # defined in the test class
+ exec { \"make\":
+ cwd => \"/test/build/dir\"
+ }
+
+ Any other type would throw an error, complaining that you had
+ the same instance being managed in multiple places, but these are
+ obviously different images, so ``exec`` had to be treated specially.
+
+ It is recommended to avoid duplicate names whenever possible.
+
+ There is a strong tendency to use ``exec`` to do whatever work Puppet
+ can't already do; while this is obviously acceptable (and unavoidable)
+ in the short term, it is highly recommended to migrate work from ``exec``
+ to real Puppet element types as quickly as possible. If you find that
+ you are doing a lot of work with ``exec``, please at least notify
+ us at Reductive Labs what you are doing, and hopefully we can work with
+ you to get a native element type for the work you are doing. In general,
+ it is a Puppet bug if you need ``exec`` to do your work."
require 'open3'
require 'puppet/type/state'
@@ -27,7 +54,7 @@ module Puppet
attr_reader :output
desc "The expected return code. An error will be returned if the
- executed command returns something else."
+ executed command returns something else. Defaults to 0."
# Make output a bit prettier
def change_to_s
@@ -153,18 +180,24 @@ module Puppet
newparam(:command) do
isnamevar
- desc "The actual command to execute."
+ desc "The actual command to execute. Must either be fully qualified
+ or a search path for the command must be provided. If the command
+ succeeds, any output produced will be logged at the instance's
+ normal log level (usually ``notice``), but if the command fails
+ (meaning its return code does not match the specified code) then
+ any output is logged at the ``err`` log level."
end
newparam(:path) do
desc "The search path used for command execution.
- Commands must be fully qualified if no path is specified."
+ Commands must be fully qualified if no path is specified. Paths
+ must be specified as an array, not as a colon-separated list."
end
newparam(:user) do
desc "The user to run the command as. Note that if you
use this then any error output is not currently captured. This
- is mostly because of a bug within Ruby."
+ is because of a bug within Ruby."
munge do |user|
unless Process.uid == 0
@@ -192,7 +225,10 @@ module Puppet
end
newparam(:group) do
- desc "The group to run the command as."
+ desc "The group to run the command as. This seems to work quite
+ haphazardly on different platforms -- it is a platform issue
+ not a Ruby or Puppet one, since the same variety exists when
+ running commnands as different users in the shell."
# Execute the command as the specified group
munge do |group|
@@ -234,13 +270,39 @@ module Puppet
newparam(:refreshonly) do
desc "The command should only be run as a
- refresh mechanism for when a dependent object is changed."
+ refresh mechanism for when a dependent object is changed. It only
+ makes sense to use this option when this command depends on some
+ other object; it is useful for triggering an action::
+
+ # Pull down the main aliases file
+ file { \"/etc/aliases\":
+ source => \"puppet://server/module/aliases\"
+ }
+
+ # Rebuild the database, but only when the file changes
+ exec { newaliases:
+ path => [\"/usr/bin\", \"/usr/sbin\"],
+ require => file[\"/etc/aliases\"],
+ refreshonly => true
+ }
+
+ "
end
newparam(:creates) do
desc "A file that this command creates. If this
parameter is provided, then the command will only be run
- if the specified file does not exist."
+ if the specified file does not exist.
+
+ ::
+
+ exec { \"tar xf /my/tar/file.tar\":
+ cwd => \"/var/tmp\",
+ creates => \"/var/tmp/myfile\",
+ path => [\"/usr/bin\", \"/usr/sbin\"]
+ }
+
+ "
# FIXME if they try to set this and fail, then we should probably
# fail the entire exec, right?
diff --git a/lib/puppet/type/group.rb b/lib/puppet/type/group.rb
index 2e4ad2441..4bb5f9d95 100755
--- a/lib/puppet/type/group.rb
+++ b/lib/puppet/type/group.rb
@@ -14,7 +14,14 @@ require 'puppet/type/nameservice'
module Puppet
newtype(:group, Puppet::Type::NSSType) do
@doc = "Manage groups. This type can only create groups. Group
- membership must be managed on individual users."
+ membership must be managed on individual users. This element type
+ uses the prescribed native tools for creating groups and generally
+ uses POSIX APIs for retrieving information about them. It does
+ not directly modify /etc/group or anything.
+
+ For most platforms, the tools used are ``groupadd`` and its ilk;
+ for Mac OS X, NetInfo is used. This is currently unconfigurable,
+ but if you desperately need it to be so, please contact us."
case Facter["operatingsystem"].value
when "Darwin":
diff --git a/lib/puppet/type/package.rb b/lib/puppet/type/package.rb
index dd53c13ed..75bf04bfa 100644
--- a/lib/puppet/type/package.rb
+++ b/lib/puppet/type/package.rb
@@ -8,9 +8,17 @@ require 'puppet/type/state'
module Puppet
class PackageError < Puppet::Error; end
newtype(:package) do
- @doc = "Manage packages. Eventually will support retrieving packages
- from remote sources but currently only supports packaging
- systems which can retrieve their own packages, like ``apt``."
+ @doc = "Manage packages. There is a basic dichotomy in package
+ support right now: Some package types (e.g., yum and apt) can
+ retrieve their own package files, while others (e.g., rpm and
+ sunpkg) cannot. For those package formats that cannot retrieve
+ their own files, you can use the ``source`` parameter to point to
+ the correct file.
+
+ Puppet will automatically guess the packaging format that you are
+ using based on the platform you are on, but you can override it
+ using the ``type`` parameter; obviously, if you specify that you
+ want to use ``rpm`` then the ``rpm`` tools must be available."
# Create a new packaging type
def self.newpkgtype(name, parent = nil, &block)
@@ -64,43 +72,57 @@ module Puppet
end
ensurable do
- desc "What state the package should be in. Specifying *true* will
- only result in a change if the package is not installed at all;
- use *latest* to keep the package (and, depending on the package
- system, its prerequisites) up to date. Specifying *false* will
- uninstall the package if it is installed.
- *true*/*false*/*latest*"
-
- munge do |value|
- # possible values are: true, false, and a version number
- case value
- when "latest":
- unless @parent.respond_to?(:latest)
- self.err @parent.inspect
- raise Puppet::Error,
- "Package type %s cannot install later versions" %
- @parent[:type].name
- end
- return :latest
- when true, :present:
- return :present
- when false, :absent:
- return :absent
- else
- # We allow them to set a should value however they want,
- # but only specific package types will be able to use this
- # value
- return value
- end
+ desc "What state the package should be in. The primary options
+ are *installed* (also called *present*), *uninstalled* (also
+ called *absent*), and *latest*. *latest* only makes sense for
+ those packaging formats that can retrieve new packages on
+ their own."
+
+ #munge do |value|
+ # # possible values are: true, false, and a version number
+ # case value
+ # when "latest":
+ # unless @parent.respond_to?(:latest)
+ # self.err @parent.inspect
+ # raise Puppet::Error,
+ # "Package type %s cannot install later versions" %
+ # @parent[:type].name
+ # end
+ # return :latest
+ # when true, :present:
+ # return :present
+ # when false, :absent:
+ # return :absent
+ # else
+ # # We allow them to set a should value however they want,
+ # # but only specific package types will be able to use this
+ # # value
+ # return value
+ # end
+ #end
+
+ newvalue(:present) do
+ @parent.install
end
- # Alias the 'present' value.
- newvalue(:installed) do
- self.set(:present)
+ newvalue(:absent) do
+ @parent.uninstall
end
+ # Alias the 'present' value.
+ aliasvalue(:installed, :present)
+ #newvalue(:installed) do
+ # self.set(:present)
+ #end
+
newvalue(:latest) do
@parent.update
+
+ if self.is == :absent
+ return :package_created
+ else
+ return :package_changed
+ end
end
# Override the parent method, because we've got all kinds of
@@ -168,12 +190,47 @@ module Puppet
attr_reader :pkgtype
newparam(:name) do
- desc "The package name."
+ desc "The package name. This is the name that the packaging
+ system uses internally, which is sometimes (especially on Solaris)
+ a name that is basically useless to humans. If you want to
+ abstract package installation, then you can use aliases to provide
+ a common name to packages::
+
+ # In the 'openssl' class
+ $ssl = $operationgsystem ? {
+ solaris => SMCossl,
+ default => openssl
+ }
+
+ # It is not an error to set an alias to the same value as the
+ # object name.
+ package { $ssl:
+ ensure => installed,
+ alias => openssl
+ }
+
+ . etc. .
+
+ $ssh = $operationgsystem ? {
+ solaris => SMCossh,
+ default => openssh
+ }
+
+ # Use the alias to specify a dependency, rather than
+ # having another selector to figure it out again.
+ package { $ssh:
+ ensure => installed,
+ alias => openssh,
+ require => package[openssl]
+ }
+
+ "
isnamevar
end
newparam(:type) do
- desc "The package format, e.g., rpm or dpkg."
+ desc "The package format. You will seldom need to specify this -- Puppet
+ will discover the appropriate format for your platform."
defaultto { @parent.class.default }
@@ -206,7 +263,10 @@ module Puppet
# it almost seems like versions should be a read-only state,
# supporting syncing only in certain cases.
newparam(:version) do
- desc "A read-only parameter set by the package."
+ desc "For some platforms this is a read-only parameter set by the
+ package, but for others, setting this parameter will cause
+ the package of that version to be installed. It just depends
+ on the features of the packaging system."
# validate do |value|
# unless @parent.respond_to?(:versionable?) and @parent.versionable?
@@ -356,10 +416,6 @@ module Puppet
end
end
- def create
- self.install
- end
-
# The 'query' method returns a hash of info if the package
# exists and returns nil if it does not.
def exists?
diff --git a/lib/puppet/type/package/dpkg.rb b/lib/puppet/type/package/dpkg.rb
index 9b76c6d92..97220d2fd 100755
--- a/lib/puppet/type/package/dpkg.rb
+++ b/lib/puppet/type/package/dpkg.rb
@@ -92,7 +92,7 @@ module Puppet
return packages
end
- def destroy
+ def uninstall
cmd = "dpkg -r %s" % self.name
output = %x{#{cmd} 2>&1}
if $? != 0
diff --git a/lib/puppet/type/package/rpm.rb b/lib/puppet/type/package/rpm.rb
index cf1bb4534..cf84c3536 100755
--- a/lib/puppet/type/package/rpm.rb
+++ b/lib/puppet/type/package/rpm.rb
@@ -14,6 +14,9 @@ module Puppet
output = %x{#{cmd} 2>/dev/null}.chomp
if $? != 0
+ #if Puppet[:debug]
+ # puts output
+ #end
return nil
end
@@ -68,7 +71,7 @@ module Puppet
# raise "installation not implemented yet"
#}
- def remove
+ def uninstall
cmd = "rpm -e %s" % self.name
output = %x{#{cmd}}
if $? != 0
diff --git a/lib/puppet/type/package/sun.rb b/lib/puppet/type/package/sun.rb
index b67bdaf5a..a9a8116d7 100755
--- a/lib/puppet/type/package/sun.rb
+++ b/lib/puppet/type/package/sun.rb
@@ -118,7 +118,7 @@ module Puppet
# raise "installation not implemented yet"
#}
- def remove
+ def uninstall
cmd = "pkgrm -n %s 2>&1" % self.name
output = %x{#{cmd}}
if $? != 0
diff --git a/lib/puppet/type/package/yum.rb b/lib/puppet/type/package/yum.rb
index b7b833e9c..5a9361392 100755
--- a/lib/puppet/type/package/yum.rb
+++ b/lib/puppet/type/package/yum.rb
@@ -19,6 +19,7 @@ module Puppet
# What's the latest package version available?
def latest
cmd = "yum list %s" % self.name
+ self.info "Executing %s" % cmd.inspect
output = %x{#{cmd} 2>&1}
unless $? == 0
@@ -38,6 +39,12 @@ module Puppet
end
def update
+ # Yum can't update packages that aren't there; we have to install
+ # them first
+ if self.is(:ensure) == :absent
+ self.info "performing initial install"
+ return self.install
+ end
cmd = "yum -y update %s" % self.name
self.info "Executing %s" % cmd.inspect
diff --git a/lib/puppet/type/pfile.rb b/lib/puppet/type/pfile.rb
index 6a52d31e9..2b553abd3 100644
--- a/lib/puppet/type/pfile.rb
+++ b/lib/puppet/type/pfile.rb
@@ -9,7 +9,15 @@ require 'puppet/server/fileserver'
module Puppet
newtype(:file) do
@doc = "Manages local files, including setting ownership and
- permissions, and allowing creation of both files and directories."
+ permissions, creation of both files and directories, and
+ retrieving entire files from remote servers. As Puppet matures, it
+ expected that the ``file`` element will be used less and less to
+ manage content, and instead native elements will be used to do so.
+
+ If you find that you are often copying files in from a central
+ location, rather than using native elements, please contact
+ Reductive Labs and we can hopefully work with you to develop a
+ native element to support what you are doing."
newparam(:path) do
desc "The path to the file to manage. Must be fully qualified."
@@ -18,7 +26,7 @@ module Puppet
newparam(:backup) do
desc "Whether files should be backed up before
- being replaced. If a ``filebucket`` is specified, files will be
+ being replaced. If a filebucket_ is specified, files will be
backed up there; else, they will be backed up in the same directory
with a ``.puppet-bak`` extension."
@@ -391,8 +399,8 @@ module Puppet
sourceobj, path = uri2obj(source)
# we'll set this manually as necessary
- if @arghash.include?(:create)
- @arghash.delete(:create)
+ if @arghash.include?(:ensure)
+ @arghash.delete(:ensure)
end
# okay, we've got our source object; now we need to
@@ -453,7 +461,7 @@ module Puppet
# want to overwrite whatever it did. This is a bit
# of a hack, but oh well, source is definitely special.
next if name == :source
- state.is = :notfound
+ state.is = :absent
}
return
end
@@ -539,17 +547,17 @@ module Puppet
class FileSource
attr_accessor :mount, :root, :server, :local
end
-end
-# We put all of the states in separate files, because there are so many
-# of them. The order these are loaded is important, because it determines
-# the order they are in the state list.
-require 'puppet/type/pfile/create'
-require 'puppet/type/pfile/checksum'
-require 'puppet/type/pfile/content'
-require 'puppet/type/pfile/source'
-require 'puppet/type/pfile/uid'
-require 'puppet/type/pfile/group'
-require 'puppet/type/pfile/mode'
-require 'puppet/type/pfile/type'
+ # We put all of the states in separate files, because there are so many
+ # of them. The order these are loaded is important, because it determines
+ # the order they are in the state list.
+ require 'puppet/type/pfile/ensure'
+ require 'puppet/type/pfile/checksum'
+ require 'puppet/type/pfile/content'
+ require 'puppet/type/pfile/source'
+ require 'puppet/type/pfile/uid'
+ require 'puppet/type/pfile/group'
+ require 'puppet/type/pfile/mode'
+ require 'puppet/type/pfile/type'
+end
# $Id$
diff --git a/lib/puppet/type/pfile/checksum.rb b/lib/puppet/type/pfile/checksum.rb
index 813157d51..2e8d68d96 100755
--- a/lib/puppet/type/pfile/checksum.rb
+++ b/lib/puppet/type/pfile/checksum.rb
@@ -6,7 +6,7 @@ module Puppet
Puppet.type(:file).newstate(:checksum) do
desc "How to check whether a file has changed. **md5**/*lite-md5*/
*time*/*mtime*"
- @event = :file_modified
+ @event = :file_changed
@unmanaged = true
@@ -96,7 +96,7 @@ module Puppet
return :nosum
end
else
- # We can't use :notfound here, because then it'll match on
+ # We can't use :absent here, because then it'll match on
# non-existent files
return :nosum
end
@@ -111,7 +111,7 @@ module Puppet
end
unless FileTest.exists?(@parent.name)
- self.is = :notfound
+ self.is = :absent
return
end
@@ -141,7 +141,7 @@ module Puppet
@parent.name
end
- if @is == :notfound
+ if @is == :absent
self.retrieve
if self.insync?
@@ -153,7 +153,7 @@ module Puppet
# If we still can't retrieve a checksum, it means that
# the file still doesn't exist
- if @is == :notfound
+ if @is == :absent
# if they're copying, then we won't worry about the file
# not existing yet
unless @parent.state(:source)
@@ -168,7 +168,7 @@ module Puppet
# If the sums are different, then return an event.
if self.updatesum
- return :file_modified
+ return :file_changed
else
return nil
end
@@ -188,7 +188,7 @@ module Puppet
error = Puppet::Error.new("%s has invalid checksum" %
@parent.name)
raise error
- #elsif @should == :notfound
+ #elsif @should == :absent
# error = Puppet::Error.new("%s has invalid 'should' checksum" %
# @parent.name)
# raise error
@@ -212,6 +212,7 @@ module Puppet
result = false
end
state[@parent.name][@checktypes[0]] = @is
+ self.info "result is %s" % result.inspect
return result
end
end
diff --git a/lib/puppet/type/pfile/content.rb b/lib/puppet/type/pfile/content.rb
index f11377275..9468f2140 100755
--- a/lib/puppet/type/pfile/content.rb
+++ b/lib/puppet/type/pfile/content.rb
@@ -3,7 +3,22 @@ module Puppet
desc "Specify the contents of a file as a string. Newlines, tabs, and spaces
can be specified using the escaped syntax (e.g., \\n for a newline). The
primary purpose of this parameter is to provide a kind of limited
- templating."
+ templating::
+
+ define resolve(nameserver1, nameserver2, domain, search) {
+ $str = \"search $search
+ domain $domain
+ nameserver $nameserver1
+ nameserver $nameserver2
+ \"
+
+ file { \"/etc/resolv.conf\":
+ content => $str
+ }
+ }
+
+ Yes, it's very primitive, and it's useless for larger files, but it
+ is mostly meant as a stopgap measure for simple cases."
def change_to_s
"synced"
@@ -13,7 +28,7 @@ module Puppet
# but I really don't feel like dealing with the complexity right now.
def retrieve
unless FileTest.exists?(@parent.name)
- @is = :notfound
+ @is = :absent
return
end
begin
@@ -38,7 +53,7 @@ module Puppet
[@parent.name, detail]
end
- if @is == :notfound
+ if @is == :absent
return :file_created
else
return :file_changed
diff --git a/lib/puppet/type/pfile/create.rb b/lib/puppet/type/pfile/ensure.rb
index 4b7ee1e15..ab5639937 100755
--- a/lib/puppet/type/pfile/create.rb
+++ b/lib/puppet/type/pfile/ensure.rb
@@ -1,40 +1,108 @@
module Puppet
- Puppet.type(:file).newstate(:create) do
+ Puppet.type(:file).ensurable do
require 'etc'
desc "Whether to create files that don't currently exist.
- **false**/*true*/*file*/*directory*"
-
- @event = :file_created
-
- munge do |value|
- # default to just about anything meaning 'true'
- case value
- when "false", false, nil:
- false
- when "true", true, "file", "plain", /^f/:
- "file"
- when "directory", /^d/:
- "directory"
- when :notfound:
- # this is where a creation is being rolled back
- :notfound
- else
- raise Puppet::Error, "Cannot create files of type %s" % value
+ Possible values are *absent*, *present* (equivalent to *file*),
+ **file**/*directory*. Specifying 'absent' will delete the file,
+ although currently this will not recursively delete directories.
+
+ This is the only element with an *ensure* state that does not have
+ a default value."
+
+ # Most 'ensure' states have a default, but with files we, um, don't.
+ nodefault
+
+ #newvalue(:false) do
+ # # If they say "false" here, we just don't do anything at all; either
+ # # the file is there or it's not.
+ #end
+
+ newvalue(:absent) do
+ File.unlink(@parent.name)
+ end
+
+ aliasvalue(:false, :absent)
+
+ newvalue(:file) do
+ mode = @parent.should(:mode)
+ Puppet::Util.asuser(asuser(), @parent.should(:group)) {
+ f = nil
+ if mode
+ f = File.open(@parent[:path],"w", mode)
+ else
+ f = File.open(@parent[:path],"w")
+ end
+
+ if @parent[:content]
+ f.print @parent.should(:content)
+ end
+ f.flush
+ f.close
+ }
+ return :file_created
+ end
+
+ aliasvalue(:present, :file)
+
+ newvalue(:directory) do
+ mode = @parent.should(:mode)
+ Puppet::Util.asuser(asuser()) {
+ if mode
+ Dir.mkdir(@parent.name,mode)
+ else
+ Dir.mkdir(@parent.name)
+ end
+ }
+ return :directory_created
+ end
+
+ def asuser
+ if @parent.should(:owner) and ! @parent.should(:owner).is_a?(Symbol)
+ writeable = Puppet::Util.asuser(@parent.should(:owner)) {
+ FileTest.writable?(File.dirname(@parent[:path]))
+ }
+
+ # If the parent directory is writeable, then we execute
+ # as the user in question. Otherwise we'll rely on
+ # the 'owner' state to do things.
+ if writeable
+ asuser = @parent.should(:owner)
+ end
+ end
+
+ return asuser
+ end
+
+ def check
+ basedir = File.dirname(@parent.name)
+
+ if ! FileTest.exists?(basedir)
+ raise Puppet::Error,
+ "Can not create %s; parent directory does not exist" %
+ @parent.name
+ elsif ! FileTest.directory?(basedir)
+ raise Puppet::Error,
+ "Can not create %s; %s is not a directory" %
+ [@parent.name, dirname]
end
end
def retrieve
if stat = @parent.stat(true)
- @is = stat.ftype
+ @is = stat.ftype.intern
else
- @is = :notfound
+ if self.should == :false
+ @is = :false
+ else
+ @is = :absent
+ end
end
#self.debug "'exists' state is %s" % self.is
end
- def sync
+ def disabled_sync
event = nil
basedir = File.dirname(@parent.name)
@@ -94,7 +162,7 @@ module Puppet
end
}
event = :directory_created
- when :notfound:
+ when :absent:
# this is where the file should be deleted...
# This value is only valid when we're rolling back a creation,
diff --git a/lib/puppet/type/pfile/group.rb b/lib/puppet/type/pfile/group.rb
index 5bb297fa2..c523f612e 100755
--- a/lib/puppet/type/pfile/group.rb
+++ b/lib/puppet/type/pfile/group.rb
@@ -4,7 +4,7 @@ module Puppet
require 'etc'
desc "Which group should own the file. Argument can be either group
name or group ID."
- @event = :inode_changed
+ @event = :file_changed
def id2name(id)
begin
@@ -95,11 +95,11 @@ module Puppet
# we'll just let it fail, but we should probably set things up so
# that users get warned if they try to change to an unacceptable group.
def sync
- if @is == :notfound
+ if @is == :absent
@parent.stat(true)
self.retrieve
- if @is == :notfound
+ if @is == :absent
self.err "File '%s' does not exist; cannot chgrp" %
@parent[:path]
return nil
@@ -118,7 +118,7 @@ module Puppet
[@parent[:path], self.should, detail.message])
raise error
end
- return :inode_changed
+ return :file_changed
end
end
end
diff --git a/lib/puppet/type/pfile/mode.rb b/lib/puppet/type/pfile/mode.rb
index 297e5cb1c..31d1a264a 100755
--- a/lib/puppet/type/pfile/mode.rb
+++ b/lib/puppet/type/pfile/mode.rb
@@ -6,7 +6,7 @@ module Puppet
require 'etc'
desc "Mode the file should be. Currently relatively limited:
you must specify the exact mode the file should be."
- @event = :inode_changed
+ @event = :file_changed
# Our modes are octal, so make sure they print correctly. Other
# valid values are symbols, basically
@@ -83,18 +83,18 @@ module Puppet
end
end
else
- self.is = :notfound
+ self.is = :absent
end
#self.debug "chmod state is %o" % self.is
end
def sync
- if @is == :notfound
+ if @is == :absent
@parent.stat(true)
self.retrieve
#self.debug "%s: after refresh, is '%s'" % [self.class.name,@is]
- if @is == :notfound
+ if @is == :absent
self.info "File does not exist; cannot set mode" %
@parent.name
return nil
@@ -108,7 +108,7 @@ module Puppet
mode = self.should
- if mode == :notfound
+ if mode == :absent
# This is really only valid for create states...
return nil
end
@@ -120,7 +120,7 @@ module Puppet
[@parent.name, detail.message])
raise error
end
- return :inode_changed
+ return :file_changed
end
end
end
diff --git a/lib/puppet/type/pfile/source.rb b/lib/puppet/type/pfile/source.rb
index b8f6e3045..d6a11dd7a 100755
--- a/lib/puppet/type/pfile/source.rb
+++ b/lib/puppet/type/pfile/source.rb
@@ -1,6 +1,5 @@
module Puppet
-
- # Copy files from a local or remote source.
+ # Copy files from a local or remote source.
Puppet.type(:file).newstate(:source) do
PINPARAMS = [:mode, :type, :owner, :group, :checksum]
@@ -8,7 +7,26 @@ module Puppet
desc "Copy a file over the current file. Uses `checksum` to
determine when a file should be copied. Valid values are either
fully qualified paths to files, or URIs. Currently supported URI
- types are *puppet* and *file*."
+ types are *puppet* and *file*.
+
+ This is one of the primary mechanisms for getting content into
+ applications that Puppet does not directly support and is very
+ useful for those configuration files that don't change much across
+ sytems. For instance::
+
+ class sendmail {
+ file { \"/etc/mail/sendmail.cf\":
+ source => \"puppet://server/module/sendmail.cf\"
+ }
+ }
+
+ See the `fileserver docs`_ for information on how to configure
+ and use file services within Puppet.
+
+
+ .. _fileserver docs: /projects/puppet/documentation/fsconfigref
+
+ "
# Ask the file server to describe our file.
def describe(source)
@@ -98,41 +116,41 @@ module Puppet
when "file":
if sum = @parent.state(:checksum)
if sum.is
- if sum.is == :notfound
+ if sum.is == :absent
sum.retrieve
end
@is = sum.is
else
- @is = :notfound
+ @is = :absent
end
else
self.info "File does not have checksum"
- @is = :notfound
+ @is = :absent
end
@should = [@stats[:checksum]]
- if state = @parent.state(:create)
- unless state.should == "file"
- self.notice(
- "File %s had both create and source enabled" %
- @parent.name
- )
- @parent.delete(:create)
- end
- end
+ #if state = @parent.state(:ensure)
+ # unless state.should == "file"
+ # self.notice(
+ # "File %s had both create and source enabled" %
+ # @parent.name
+ # )
+ # @parent.delete(:ensure)
+ # end
+ #end
# If we're a directory, then do not copy anything, and instead just
# create the directory using the 'create' state.
when "directory":
- if state = @parent.state(:create)
+ if state = @parent.state(:ensure)
unless state.should == "directory"
state.should = "directory"
end
else
- @parent[:create] = "directory"
- @parent.state(:create).retrieve
+ @parent[:ensure] = "directory"
+ @parent.state(:ensure).retrieve
end
- # we'll let the :create state do our work
+ # we'll let the :ensure state do our work
@should.clear
@is = true
# FIXME We should at least support symlinks, I would think...
@@ -223,12 +241,13 @@ module Puppet
# try to create it with the correct modes to start
# we should also be changing our effective uid/gid, but...
- if @parent.should(:mode) and @parent.should(:mode) != :notfound
+ if @parent.should(:mode) and @parent.should(:mode) != :absent
args.push @parent.should(:mode)
end
# FIXME we should also change our effective user and group id
+ exists = File.exists?(@parent.name)
begin
File.open(*args) { |f|
f.print contents
@@ -256,7 +275,11 @@ module Puppet
[@parent.name, detail]
end
- return :file_changed
+ if exists
+ return :file_changed
+ else
+ return :file_created
+ end
end
end
end
diff --git a/lib/puppet/type/pfile/type.rb b/lib/puppet/type/pfile/type.rb
index 7d761c40b..0ea548c26 100755
--- a/lib/puppet/type/pfile/type.rb
+++ b/lib/puppet/type/pfile/type.rb
@@ -11,7 +11,7 @@ module Puppet
if stat = @parent.stat(true)
@is = stat.ftype
else
- @is = :notfound
+ @is = :absent
end
# so this state is never marked out of sync
diff --git a/lib/puppet/type/pfile/uid.rb b/lib/puppet/type/pfile/uid.rb
index 3f1add774..fc9129669 100755
--- a/lib/puppet/type/pfile/uid.rb
+++ b/lib/puppet/type/pfile/uid.rb
@@ -3,7 +3,7 @@ module Puppet
require 'etc'
desc "To whom the file should belong. Argument can be user name or
user ID."
- @event = :inode_changed
+ @event = :file_changed
def id2name(id)
if id.is_a?(Symbol)
@@ -81,7 +81,7 @@ module Puppet
def retrieve
unless stat = @parent.stat(true)
- @is = :notfound
+ @is = :absent
return
end
@@ -92,7 +92,7 @@ module Puppet
# it's an OS X bug, since it shows up in perl, too.
if @is > 120000
self.warning "current state is silly: %s" % @is
- @is = :notfound
+ @is = :absent
end
end
@@ -135,10 +135,10 @@ module Puppet
end
end
- if @is == :notfound
+ if @is == :absent
@parent.stat(true)
self.retrieve
- if @is == :notfound
+ if @is == :absent
self.info "File does not exist; cannot set owner"
return nil
end
@@ -155,7 +155,7 @@ module Puppet
[user, detail]
end
- return :inode_changed
+ return :file_changed
end
end
end
diff --git a/lib/puppet/type/pfilebucket.rb b/lib/puppet/type/pfilebucket.rb
index d17f681af..dfe1bd4db 100755
--- a/lib/puppet/type/pfilebucket.rb
+++ b/lib/puppet/type/pfilebucket.rb
@@ -10,7 +10,13 @@ module Puppet
for backing up. It stores files and returns the MD5 sum, which
can later be used to retrieve the file if restoration becomes
necessary. A filebucket does not do any work itself; instead,
- it can be specified as the value of *backup* in a **file** object."
+ it can be specified as the value of *backup* in a **file** object.
+
+ Currently, filebuckets are only useful for manual retrieval of
+ accidentally removed files (e.g., you look in the log for the md5
+ sum and retrieve the file with that sum from the filebucket), but
+ when transactions are fully supported filebuckets will be used to
+ undo transactions."
@states = []
diff --git a/lib/puppet/type/pprocess.rb b/lib/puppet/type/pprocess.rb
deleted file mode 100644
index dad39cd2c..000000000
--- a/lib/puppet/type/pprocess.rb
+++ /dev/null
@@ -1,95 +0,0 @@
-# DISABLED
-# I'm only working on services, not processes, right now
-
-module Puppet
- class State
- class PProcessRunning < State
- @doc = "Whether a process should be running. **true**/*false*"
- def retrieve
- running = 0
- regex = Regexp.new(@params[:pattern])
- begin
- # this ps is only tested on Solaris
- # XXX yeah, this definitely needs to be fixed...
- %x{ps -ef -U #{@params[:user]}}.split("\n").each { |process|
- if regex.match(process)
- running += 1
- end
- }
- rescue
- # this isn't correct, but what the hell
- Puppet::Message.new(
- :level => :error,
- :source => self.parent,
- :message => "Failed to run ps"
- )
- end
-
- self.state = running
- debug "there are #{running} #{self.parent} processes for start"
- end
-
- def <=>(other)
- self.state < 1
- end
-
- def fix
- require 'etc'
- # ruby is really cool
- uid = 0
- if @params[:user].is_a? Integer
- uid = @params[:user]
- else
- uid = Etc.getpwnam(@params[:user]).uid
- end
- Kernel.fork {
- PProcess.uid = uid
- PProcess.euid = uid
- string = @params[:binary] + (@params[:arguments] || "")
- Puppet::Message.new(
- :level => :notice,
- :source => self.parent,
- :message => "starting"
- )
- Kernel.exec(string)
- }
- end
- end
- end
- class Type
- class PProcess < Type
- attr_reader :stat, :path
- @parameters = [:start, :stop, :user, :pattern, :binary, :arguments]
- @name = :process
-
- @paramdoc[:start] = "How to start the process. Must be a fully
- qualified path."
- @paramdoc[:stop] = "How to stop the process. Must be a fully
- qualified path."
- @paramdoc[:user] = "Which user to run the proces as."
- @paramdoc[:pattern] = "The search pattern to use to determine
- whether the process is currently running."
- @paramdoc[:binary] = "The binary to actually execute."
- @paramdoc[:arguments] = "The arguments to pass the binary."
-
- @doc = "**Disabled. Use `service` instead.** Manage running
- processes."
-
- @namevar = :pattern
-
- Puppet::Relation.new(self, Puppet::Operation::Start, {
- :user => :user,
- :pattern => :pattern,
- :binary => :binary,
- :arguments => :arguments
- })
-
- Puppet::Relation.new(self, Puppet::Operation::Stop, {
- :user => :user,
- :pattern => :pattern
- })
-
- end # Puppet.type(:pprocess)
- end # Puppet::Type
-
-end
diff --git a/lib/puppet/type/service.rb b/lib/puppet/type/service.rb
index b526aae33..464da9b8d 100644
--- a/lib/puppet/type/service.rb
+++ b/lib/puppet/type/service.rb
@@ -7,12 +7,16 @@
module Puppet
newtype(:service) do
- @doc = "Manage running services. Rather than supporting managing
- individual processes, puppet uses init scripts to simplify
- specification of how to start, stop, or test processes. The
- `path` parameter is provided to enable creation of multiple
- init script directories, including supporting them for normal
- users."
+ @doc = "Manage running services. Service support unfortunately varies
+ widely by platform -- some platforms have very little if any
+ concept of a running service, and some have a very codified and
+ powerful concept. Puppet's service support will generally be able
+ to make up for any inherent shortcomings (e.g., if there is no
+ 'status' command, then Puppet will look in the process table for a
+ command matching the service name), but the more information you
+ can provide the better behaviour you will get. Or, you can just
+ use a platform that has very good service support."
+
attr_reader :stat
# newstate(:enabled) do
@@ -101,7 +105,9 @@ module Puppet
end
newparam(:type) do
- desc "The service type"
+ desc "The service type. For most platforms, it does not make
+ sense to change set this parameter, as the default is based on
+ the builtin service facilities."
defaultto { @parent.class.defaulttype }
@@ -119,23 +125,30 @@ module Puppet
end
newparam(:binary) do
desc "The path to the daemon. This is only used for
- systems that do not support init scripts."
+ systems that do not support init scripts. This binary will be
+ used to start the service if no ``start`` parameter is
+ provided."
end
newparam(:hasstatus) do
desc "Declare the the service's init script has a
- functional status command. This is assumed to be default for
- most systems, although there might be platforms on which this is
- assumed to be true."
+ functional status command. Based on testing, it was found
+ that a large number of init scripts on different platforms do
+ not support any kind of status command; thus, you must specify
+ manually whether the service you are running has such a
+ command (or you can specify a specific command using the
+ ``status`` parameter).
+
+ If you do not specify anything, then the service name will be
+ looked for in the process table."
end
newparam(:name) do
desc "The name of the service to run. This name
- is used to find the init script in the search path."
+ is used to find the service in whatever service subsystem it
+ is in."
isnamevar
end
newparam(:path) do
- desc "The search path for finding init scripts.
- There is currently no default, but hopefully soon there will
- be a reasonable default for all platforms."
+ desc "The search path for finding init scripts."
munge do |value|
paths = []
@@ -168,25 +181,32 @@ module Puppet
This is used for stopping services on platforms that do not
support init scripts, and is also used for determining service
status on those service whose init scripts do not include a status
- command."
+ command.
+
+ If this is left unspecified and is needed to check the status
+ of a service, then the service name will be used instead.
+
+ The pattern can be a simple string or any legal Ruby pattern."
defaultto { @parent.name }
end
newparam(:restart) do
desc "Specify a *restart* command manually. If left
- unspecified, the restart method will be determined automatically."
+ unspecified, the service will be stopped and then started."
end
newparam(:start) do
- desc "Specify a *start* command manually. If left
- unspecified, the start method will be determined automatically."
+ desc "Specify a *start* command manually. Most service subsystems
+ support a ``start`` command, so this will not need to be
+ specified."
end
newparam(:status) do
desc "Specify a *status* command manually. If left
- unspecified, the status method will be determined automatically."
+ unspecified, the status method will be determined
+ automatically, usually by looking for the service int he
+ process table."
end
newparam(:stop) do
- desc "Specify a *stop* command manually. If left
- unspecified, the stop method will be determined automatically."
+ desc "Specify a *stop* command manually."
end
# Create new subtypes of service management.
diff --git a/lib/puppet/type/state.rb b/lib/puppet/type/state.rb
index 6dff82765..bad42ec74 100644
--- a/lib/puppet/type/state.rb
+++ b/lib/puppet/type/state.rb
@@ -40,10 +40,39 @@ class State < Puppet::Parameter
define_method("set_" + name.to_s, &block)
end
+ def self.aliasvalue(name, other)
+ @statevalues ||= {}
+ unless @statevalues.include?(other)
+ raise Puppet::DevError, "Cannot alias nonexistent value %s" % other
+ end
+
+ @aliasvalues ||= {}
+ @aliasvalues[name] = other
+ end
+
+ def self.alias(name)
+ @aliasvalues[name]
+ end
+
+ def self.defaultvalues
+ newvalue(:present) do
+ @parent.create
+ end
+
+ newvalue(:absent) do
+ @parent.destroy
+ end
+
+ # This doc will probably get overridden
+ @doc ||= "The basic state that the object should be in."
+ end
+
# Return the list of valid values.
def self.values
@statevalues ||= {}
+ @aliasvalues ||= {}
+ #[@aliasvalues.keys, @statevalues.keys].flatten
@statevalues.keys
end
@@ -75,7 +104,6 @@ class State < Puppet::Parameter
end
if event and event.is_a?(Symbol)
- self.log "got event back %s" % event
return event
else
# Return the appropriate event.
@@ -86,6 +114,9 @@ class State < Puppet::Parameter
(@parent.class.name.to_s + "_changed").intern
end
+ #self.log "made event %s because 'should' is %s, 'is' is %s" %
+ # [event, self.should.inspect, self.is.inspect]
+
return event
end
end
@@ -232,6 +263,12 @@ class State < Puppet::Parameter
# The default 'sync' method only selects among a list of registered
# values.
def sync
+ if self.insync?
+ self.info "already in sync"
+ return nil
+ else
+ self.info "%s vs %s" % [self.is.inspect, self.should.inspect]
+ end
unless self.class.values
raise Puppet::DevError, "No values defined for %s" %
self.class.name
@@ -241,6 +278,24 @@ class State < Puppet::Parameter
self.set
end
+ munge do |value|
+ if self.class.values.empty?
+ # This state isn't using defined values to do its work.
+ return value
+ end
+ intern = value.to_s.intern
+ # If it's a valid value, always return it as a symbol.
+ if self.class.values.include?(intern)
+ retval = intern
+ elsif other = self.class.alias(intern)
+ self.info "returning alias %s for %s" % [other, intern]
+ retval = other
+ else
+ retval = value
+ end
+ retval
+ end
+
# Verify that the passed value is valid.
validate do |value|
if self.class.values.empty?
@@ -250,7 +305,7 @@ class State < Puppet::Parameter
unless value.is_a?(Symbol)
value = value.to_s.intern
end
- unless self.class.values.include?(value)
+ unless self.class.values.include?(value) or self.class.alias(value)
raise Puppet::Error,
"Invalid '%s' value '%s'. Valid values are '%s'" %
[self.class.name, value, self.class.values.join(", ")]
@@ -302,17 +357,24 @@ class State < Puppet::Parameter
def self.inherited(sub)
# Add in the two states that everyone will have.
sub.class_eval do
- newvalue(:present) do
- @parent.create
- end
+ end
+ end
- newvalue(:absent) do
- @parent.destroy
+ def change_to_s
+ begin
+ if @is == :absent
+ return "created"
+ elsif self.should == :absent
+ return "removed"
+ else
+ return "%s changed '%s' to '%s'" %
+ [self.name, self.is_to_s, self.should_to_s]
end
-
- # This doc will probably get overridden
- @doc = "The fundamental states that the object can be in. Allowed
- values are %s." % self.values.join(", ")
+ rescue Puppet::Error, Puppet::DevError
+ raise
+ rescue => detail
+ raise Puppet::DevError, "Could not convert change %s to string: %s" %
+ [self.name, detail]
end
end
diff --git a/lib/puppet/type/symlink.rb b/lib/puppet/type/symlink.rb
index 2be33cb1d..37e60d6f6 100755
--- a/lib/puppet/type/symlink.rb
+++ b/lib/puppet/type/symlink.rb
@@ -91,7 +91,18 @@ module Puppet
newparam(:recurse) do
desc "If target is a directory, recursively create
directories (using `file`'s `source` parameter) and link all
- contained files."
+ contained files. For instance::
+
+ # The Solaris Blastwave repository installs everything
+ # in /opt/csw; link it into /usr/local
+ symlink { \"/usr/local\":
+ target => \"/opt/csw\",
+ recurse => 1
+ }
+
+
+ Note that this does not link directories -- any directories
+ are created in the destination, and any files are linked over."
munge do |value|
@stat = nil
diff --git a/lib/puppet/type/tidy.rb b/lib/puppet/type/tidy.rb
index 61df0a80f..235d26e95 100755
--- a/lib/puppet/type/tidy.rb
+++ b/lib/puppet/type/tidy.rb
@@ -8,7 +8,8 @@ module Puppet
@doc = "Remove unwanted files based on specific criteria."
newparam(:path) do
- desc "The path to the file to manage. Must be fully qualified."
+ desc "The path to the file or directory to manage. Must be fully
+ qualified."
isnamevar
end
@@ -62,8 +63,8 @@ module Puppet
end
newparam(:type) do
- desc "Set the mechanism for determining age. Access
- time is the default mechanism, but modification."
+ desc "Set the mechanism for determining age.
+ **atime**/*mtime*/*ctime*."
munge do |type|
case type
@@ -81,7 +82,8 @@ module Puppet
end
newparam(:rmdirs) do
- desc "Tidy directories in addition to files."
+ desc "Tidy directories in addition to files; that is, remove
+ directories whose age is older than the specified criteria."
end
newstate(:tidyup) do
diff --git a/lib/puppet/type/user.rb b/lib/puppet/type/user.rb
index 3b342f785..317d86422 100755
--- a/lib/puppet/type/user.rb
+++ b/lib/puppet/type/user.rb
@@ -155,7 +155,15 @@ module Puppet
cannot delete them. Theoretically all of the parameters are
optional, but if no parameters are specified the comment will
be set to the user name in order to make the internals work out
- correctly."
+ correctly.
+
+ This element type uses the prescribed native tools for creating
+ groups and generally uses POSIX APIs for retrieving information
+ about them. It does not directly modify /etc/passwd or anything.
+
+ For most platforms, the tools used are ``useradd`` and its ilk;
+ for Mac OS X, NetInfo is used. This is currently unconfigurable,
+ but if you desperately need it to be so, please contact us."
@netinfodir = "users"
diff --git a/test/executables/puppetmodule.rb b/test/executables/puppetmodule.rb
index c0020779d..56173c4b6 100755
--- a/test/executables/puppetmodule.rb
+++ b/test/executables/puppetmodule.rb
@@ -25,7 +25,7 @@ class TestPuppetModule < Test::Unit::TestCase
createdfile = tempfile()
File.open(file, "w") { |f|
- f.puts "class yaytest { file { \"#{createdfile}\": create => true } }"
+ f.puts "class yaytest { file { \"#{createdfile}\": ensure => file } }"
}
output = nil
diff --git a/test/language/interpreter.rb b/test/language/interpreter.rb
index 9dbf8dc99..a9d448a67 100755
--- a/test/language/interpreter.rb
+++ b/test/language/interpreter.rb
@@ -22,7 +22,7 @@ class TestInterpreter < Test::Unit::TestCase
createdfile = tempfile()
File.open(file, "w") { |f|
- f.puts "node %s { file { \"%s\": create => true, mode => 755 } }\n" %
+ f.puts "node %s { file { \"%s\": ensure => file, mode => 755 } }\n" %
[node, createdfile]
}
diff --git a/test/other/events.rb b/test/other/events.rb
index f57fd3272..be319724c 100755
--- a/test/other/events.rb
+++ b/test/other/events.rb
@@ -21,7 +21,7 @@ class TestEvents < Test::Unit::TestCase
name = tempfile()
file = Puppet.type(:file).create(
:name => name,
- :create => true
+ :ensure => "file"
)
exec = Puppet.type(:exec).create(
:name => "echo true",
@@ -41,7 +41,7 @@ class TestEvents < Test::Unit::TestCase
name = tempfile()
file = Puppet.type(:file).create(
:name => name,
- :create => true
+ :ensure => "file"
)
exec = Puppet.type(:exec).create(
:name => "echo true",
@@ -76,7 +76,7 @@ class TestEvents < Test::Unit::TestCase
name = tempfile() + l.to_s
objects[l] = Puppet.type(:file).create(
:name => name,
- :create => true
+ :ensure => "file"
)
@@tmpfiles << name
when :b
diff --git a/test/other/log.rb b/test/other/log.rb
index 0bc2656ea..16f458193 100644
--- a/test/other/log.rb
+++ b/test/other/log.rb
@@ -182,7 +182,7 @@ class TestLog < Test::Unit::TestCase
path = tempfile()
file = Puppet.type(:file).create(
:path => path,
- :create => true
+ :ensure => "file"
)
assert_nothing_raised {
diff --git a/test/other/storage.rb b/test/other/storage.rb
index 0a52196d6..64f08cdc7 100755
--- a/test/other/storage.rb
+++ b/test/other/storage.rb
@@ -62,6 +62,16 @@ class TestParsedFile < Test::Unit::TestCase
}
threads.each { |th| th.join }
end
+
+ def test_emptyrestore
+ Puppet::Storage.load
+ Puppet::Storage.store
+ Puppet::Storage.clear
+ Puppet::Storage.load
+ state = Puppet::Storage.state('newstate')
+ assert_same Hash, state.class
+ assert_equal 0, state.size
+ end
end
# $Id$
diff --git a/test/other/transactions.rb b/test/other/transactions.rb
index 5a00fbe09..ed6843104 100644
--- a/test/other/transactions.rb
+++ b/test/other/transactions.rb
@@ -123,9 +123,9 @@ class TestTransactions < Test::Unit::TestCase
file[:mode] = "755"
}
- trans = assert_events([:inode_changed, :inode_changed], component)
+ trans = assert_events([:file_changed, :file_changed], component)
- assert_rollback_events(trans, [:inode_changed, :inode_changed], "file")
+ assert_rollback_events(trans, [:file_changed, :file_changed], "file")
assert_nothing_raised() {
file.retrieve
@@ -188,7 +188,7 @@ class TestTransactions < Test::Unit::TestCase
file[:mode] = "755"
}
- trans = assert_events( [:inode_changed], component)
+ trans = assert_events( [:file_changed], component)
assert(FileTest.exists?(execfile), "Execfile does not exist")
File.unlink(execfile)
@@ -196,7 +196,7 @@ class TestTransactions < Test::Unit::TestCase
file[:group] = @groups[1]
}
- trans = assert_events([:inode_changed], component)
+ trans = assert_events([:file_changed], component)
assert(FileTest.exists?(execfile), "Execfile does not exist")
end
@@ -227,7 +227,7 @@ class TestTransactions < Test::Unit::TestCase
file[:mode] = "755"
}
- trans = assert_events([:inode_changed, :inode_changed], component)
+ trans = assert_events([:file_changed, :file_changed], component)
end
diff --git a/test/parser/parser.rb b/test/parser/parser.rb
index 4752ce35e..68209a0d2 100644
--- a/test/parser/parser.rb
+++ b/test/parser/parser.rb
@@ -66,7 +66,7 @@ class TestParser < Test::Unit::TestCase
@@tmpfiles << name
File.open(file, "w") { |f|
- f.puts "file { \"%s\": create => true, mode => 755 }\n" %
+ f.puts "file { \"%s\": ensure => file, mode => 755 }\n" %
name
}
end
diff --git a/test/puppettest.rb b/test/puppettest.rb
index fd966f930..34d48ff52 100644
--- a/test/puppettest.rb
+++ b/test/puppettest.rb
@@ -289,7 +289,7 @@ module ServerTest
@createdfile = File.join(tmpdir(), self.class.to_s + "servermanifesttesting")
File.open(file, "w") { |f|
- f.puts "file { \"%s\": create => true, mode => 755 }\n" % @createdfile
+ f.puts "file { \"%s\": ensure => file, mode => 755 }\n" % @createdfile
}
@@tmpfiles << @createdfile
diff --git a/test/server/master.rb b/test/server/master.rb
index 3ccd176f8..a300a18a4 100644
--- a/test/server/master.rb
+++ b/test/server/master.rb
@@ -134,7 +134,7 @@ class TestMaster < Test::Unit::TestCase
Puppet::Type.allclear
File.open(manifest, "w") { |f|
- f.puts "file { \"%s\": create => true }\n" % file2
+ f.puts "file { \"%s\": ensure => file }\n" % file2
}
assert_nothing_raised {
client.getconfig
diff --git a/test/types/basic.rb b/test/types/basic.rb
index edc6bc66d..082a8342f 100644
--- a/test/types/basic.rb
+++ b/test/types/basic.rb
@@ -33,7 +33,7 @@ class TestBasic < Test::Unit::TestCase
@@tmpfiles << @filepath
@configfile = Puppet.type(:file).create(
:path => @filepath,
- :create => true,
+ :ensure => "file",
:checksum => "md5"
)
}
diff --git a/test/types/exec.rb b/test/types/exec.rb
index 370fe380f..7ecf8a26d 100755
--- a/test/types/exec.rb
+++ b/test/types/exec.rb
@@ -171,7 +171,7 @@ class TestExec < Test::Unit::TestCase
# verify that only the file_changed event was kicked off, not the
# command_executed
assert_equal(
- [:file_modified],
+ [:file_changed],
events
)
end
@@ -213,7 +213,7 @@ class TestExec < Test::Unit::TestCase
comp = newcomp("Testing", file, exec)
- assert_events([:file_changed, :executed_command], comp)
+ assert_events([:file_created, :executed_command], comp)
end
# Verify that we auto-require any managed scripts.
diff --git a/test/types/file.rb b/test/types/file.rb
index 65d1560cd..b9e85839e 100644
--- a/test/types/file.rb
+++ b/test/types/file.rb
@@ -124,7 +124,7 @@ class TestFile < Test::Unit::TestCase
file = Puppet.type(:file).create(
:path => path,
:owner => user.name,
- :create => true,
+ :ensure => "file",
:mode => "755"
)
}
@@ -221,7 +221,7 @@ class TestFile < Test::Unit::TestCase
assert_nothing_raised() {
file = Puppet.type(:file).create(
:name => path,
- :create => true
+ :ensure => "file"
)
}
assert_events([:file_created], file)
@@ -240,7 +240,7 @@ class TestFile < Test::Unit::TestCase
assert_nothing_raised() {
file = Puppet.type(:file).create(
:name => path,
- :create => "directory"
+ :ensure => "directory"
)
}
assert(! FileTest.directory?(path), "Directory %s already exists" %
@@ -261,7 +261,7 @@ class TestFile < Test::Unit::TestCase
assert_nothing_raised() {
file[:mode] = mode
}
- assert_events([:inode_changed], file)
+ assert_events([:file_changed], file)
assert_events([], file)
assert(file.insync?())
@@ -283,15 +283,13 @@ class TestFile < Test::Unit::TestCase
# try it both with files that exist and ones that don't
files = [exists, nonexists]
initstorage
- File.open(exists,"w") { |of|
- 10.times {
- of.puts rand(100)
- }
+ File.open(exists,File::CREAT|File::TRUNC|File::WRONLY) { |of|
+ of.puts "initial text"
}
types.each { |type|
files.each { |path|
if Puppet[:debug]
- Puppet.info "Testing %s on %s" % [type,path]
+ Puppet.warning "Testing %s on %s" % [type,path]
end
file = nil
events = nil
@@ -299,12 +297,12 @@ class TestFile < Test::Unit::TestCase
assert_nothing_raised() {
file = Puppet.type(:file).create(
:name => path,
- :create => true,
+ :ensure => "file",
:checksum => type
)
}
comp = Puppet.type(:component).create(
- :name => "componentfile"
+ :name => "checksum %s" % type
)
comp.push file
trans = nil
@@ -324,16 +322,19 @@ class TestFile < Test::Unit::TestCase
# we don't want to kick off an event the first time we
# come across a file
assert(
- ! events.include?(:file_modified)
+ ! events.include?(:file_changed)
)
assert_nothing_raised() {
- File.open(path,"w") { |of|
- of.puts rand(100)
+ File.open(path,File::CREAT|File::TRUNC|File::WRONLY) { |of|
+ of.puts "some more text, yo"
}
}
Puppet.type(:file).clear
Puppet.type(:component).clear
- sleep 1
+
+ # We have to sleep because the time resolution of the time-based
+ # mechanisms is greater than one second
+ sleep 1.1
# now recreate the file
assert_nothing_raised() {
@@ -343,17 +344,41 @@ class TestFile < Test::Unit::TestCase
)
}
comp = Puppet.type(:component).create(
- :name => "componentfile"
+ :name => "checksum, take 2, %s" % type
)
comp.push file
trans = nil
- assert_events([:file_modified], comp)
+
+ # If the file was missing, it should not generate an event
+ # when it gets created.
+ if path =~ /nonexists/e
+ assert_events([], comp)
+ else
+ assert_events([:file_changed], comp)
+ end
+ assert_nothing_raised() {
+ File.unlink(path)
+ File.open(path,File::CREAT|File::TRUNC|File::WRONLY) { |of|
+ # We have to put a certain amount of text in here or
+ # the md5-lite test fails
+ 2.times {
+ of.puts rand(100)
+ }
+ of.flush
+ }
+ }
+ #assert_apply(comp)
+ assert_events([:file_changed], comp)
# verify that we're actually getting notified when a file changes
assert_nothing_raised() {
Puppet.type(:file).clear
Puppet.type(:component).clear
}
+
+ if path =~ /nonexists/
+ File.unlink(path)
+ end
}
}
end
@@ -444,7 +469,7 @@ class TestFile < Test::Unit::TestCase
file = mkfile(
:name => path,
:recurse => true,
- :create => true
+ :ensure => "file"
)
}
@@ -483,7 +508,7 @@ class TestFile < Test::Unit::TestCase
assert_nothing_raised {
file = Puppet.type(:file).create(
:name => tempfile(),
- :create => true
+ :ensure => "file"
)
}
@@ -577,12 +602,12 @@ class TestFile < Test::Unit::TestCase
baseobj = Puppet.type(:file).create(
:name => basedir,
- :create => "directory"
+ :ensure => "directory"
)
subobj = Puppet.type(:file).create(
:name => subfile,
- :create => "file"
+ :ensure => "file"
)
Puppet::Type.finalize
@@ -640,7 +665,7 @@ class TestFile < Test::Unit::TestCase
assert_nothing_raised {
file = Puppet.type(:file).create(
:name => subpath,
- :create => "directory",
+ :ensure => "directory",
:recurse => true
)
}
diff --git a/test/types/filesources.rb b/test/types/filesources.rb
index 5ae728c81..ba401b446 100755
--- a/test/types/filesources.rb
+++ b/test/types/filesources.rb
@@ -565,7 +565,7 @@ class TestFileSources < Test::Unit::TestCase
}
comp = newcomp(file)
- assert_events([:file_changed], comp)
+ assert_events([:file_created], comp)
assert(File.exists?(to), "File does not exist")
diff --git a/test/types/package.rb b/test/types/package.rb
index 1723f973d..36da3c0cd 100644
--- a/test/types/package.rb
+++ b/test/types/package.rb
@@ -167,6 +167,7 @@ class TestPackages < Test::Unit::TestCase
comp = newcomp("package", pkg)
+ Puppet.err :mark
assert_events([:package_created], comp, "package")
# then uninstall it
@@ -177,6 +178,8 @@ class TestPackages < Test::Unit::TestCase
pkg.retrieve
+ p pkg
+
assert(! pkg.insync?, "Package is in sync")
assert_events([:package_removed], comp, "package")
diff --git a/test/types/type.rb b/test/types/type.rb
index 5426ec669..7d087b30b 100644
--- a/test/types/type.rb
+++ b/test/types/type.rb
@@ -59,7 +59,7 @@ class TestType < Test::Unit::TestCase
system("rm -f %s" % path)
file = Puppet.type(:file).create(
:path => path,
- :create => true,
+ :ensure => "file",
:recurse => true,
:checksum => "md5"
)
@@ -75,7 +75,7 @@ class TestType < Test::Unit::TestCase
system("rm -f %s" % path)
file = Puppet.type(:file).create(
"path" => path,
- "create" => true,
+ "ensure" => "file",
"recurse" => true,
"checksum" => "md5"
)
@@ -144,7 +144,7 @@ class TestType < Test::Unit::TestCase
assert_nothing_raised {
baseobj = Puppet.type(:file).create(
:name => file,
- :create => true,
+ :ensure => "file",
:alias => ["funtest"]
)
}