puppet 0.13.1 → 0.13.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of puppet might be problematic. Click here for more details.
- data/CHANGELOG +4 -0
- data/Rakefile +2 -2
- data/bin/puppet +29 -0
- data/bin/puppetd +35 -1
- data/conf/redhat/puppet.spec +1 -1
- data/lib/puppet.rb +1 -1
- data/lib/puppet/client/master.rb +34 -3
- data/lib/puppet/filetype.rb +6 -2
- data/lib/puppet/networkclient.rb +4 -1
- data/lib/puppet/parameter.rb +35 -38
- data/lib/puppet/parser/ast/node.rb +1 -0
- data/lib/puppet/parser/interpreter.rb +129 -2
- data/lib/puppet/parser/scope.rb +44 -6
- data/lib/puppet/type.rb +47 -37
- data/lib/puppet/type/cron.rb +25 -10
- data/lib/puppet/type/exec.rb +165 -71
- data/lib/puppet/type/nameservice.rb +2 -17
- data/lib/puppet/type/package.rb +31 -7
- data/lib/puppet/type/package/sun.rb +11 -6
- data/lib/puppet/type/parsedtype.rb +94 -60
- data/lib/puppet/type/parsedtype/host.rb +5 -12
- data/lib/puppet/type/parsedtype/port.rb +53 -32
- data/lib/puppet/type/parsedtype/sshkey.rb +8 -4
- data/lib/puppet/type/pfile.rb +6 -4
- data/lib/puppet/type/pfile/ensure.rb +1 -6
- data/lib/puppet/type/state.rb +34 -74
- data/lib/puppet/type/symlink.rb +30 -19
- data/lib/puppet/type/user.rb +63 -11
- data/lib/puppet/util.rb +54 -60
- data/test/client/master.rb +72 -0
- data/test/language/interpreter.rb +94 -0
- data/test/other/log.rb +8 -1
- data/test/puppet/utiltest.rb +101 -1
- data/test/test +12 -5
- data/test/types/cron.rb +21 -1
- data/test/types/exec.rb +46 -2
- data/test/types/group.rb +15 -3
- data/test/types/host.rb +43 -4
- data/test/types/port.rb +67 -6
- data/test/types/sshkey.rb +45 -4
- data/test/types/symlink.rb +4 -4
- data/test/types/type.rb +41 -3
- data/test/types/user.rb +23 -2
- metadata +3 -2
data/lib/puppet/util.rb
CHANGED
@@ -21,7 +21,11 @@ module Util
|
|
21
21
|
# The gid has to be changed first, because, well, otherwise we won't
|
22
22
|
# be able to
|
23
23
|
if group
|
24
|
-
|
24
|
+
if group.is_a? Integer
|
25
|
+
gid = group
|
26
|
+
else
|
27
|
+
gid = self.gid(group)
|
28
|
+
end
|
25
29
|
|
26
30
|
if Process.gid != gid
|
27
31
|
oldgid = Process.gid
|
@@ -34,6 +38,11 @@ module Util
|
|
34
38
|
end
|
35
39
|
|
36
40
|
if user
|
41
|
+
if user.is_a? Integer
|
42
|
+
uid = user
|
43
|
+
else
|
44
|
+
uid = self.uid(user)
|
45
|
+
end
|
37
46
|
uid = self.uid(user)
|
38
47
|
# Now change the uid
|
39
48
|
if Process.uid != uid
|
@@ -126,22 +135,40 @@ module Util
|
|
126
135
|
if group =~ /^\d+$/
|
127
136
|
group = Integer(group)
|
128
137
|
end
|
138
|
+
unless group
|
139
|
+
raise Puppet::DevError, "Invalid group %s" % group.inspect
|
140
|
+
end
|
129
141
|
gid = nil
|
130
|
-
|
131
|
-
|
142
|
+
obj = nil
|
143
|
+
|
144
|
+
# We want to look the group up either way
|
145
|
+
if group.is_a?(Integer)
|
146
|
+
# If this doesn't find anything
|
147
|
+
obj = Puppet.type(:group).find { |gobj|
|
148
|
+
gobj.should(:gid) == group ||
|
149
|
+
gobj.is(:gid) == group
|
150
|
+
}
|
151
|
+
|
152
|
+
unless obj
|
153
|
+
begin
|
154
|
+
gobj = Etc.getgrgid(group)
|
155
|
+
gid = gobj.gid
|
156
|
+
rescue ArgumentError => detail
|
157
|
+
# ignore it; we couldn't find the group
|
158
|
+
end
|
159
|
+
end
|
132
160
|
else
|
133
161
|
unless obj = Puppet.type(:group)[group]
|
134
162
|
obj = Puppet.type(:group).create(
|
135
163
|
:name => group,
|
136
164
|
:check => [:gid]
|
137
165
|
)
|
138
|
-
|
139
|
-
obj.retrieve
|
140
|
-
gid = obj.is(:gid)
|
141
|
-
unless gid.is_a?(Integer)
|
142
|
-
raise Puppet::Error, "Could not find group %s" % group
|
166
|
+
obj.retrieve
|
143
167
|
end
|
144
168
|
end
|
169
|
+
if obj
|
170
|
+
gid = obj.should(:gid) || obj.is(:gid)
|
171
|
+
end
|
145
172
|
|
146
173
|
return gid
|
147
174
|
end
|
@@ -152,8 +179,22 @@ module Util
|
|
152
179
|
if user =~ /^\d+$/
|
153
180
|
user = Integer(user)
|
154
181
|
end
|
182
|
+
|
155
183
|
if user.is_a?(Integer)
|
156
|
-
|
184
|
+
# If this doesn't find anything
|
185
|
+
obj = Puppet.type(:user).find { |uobj|
|
186
|
+
uobj.should(:uid) == user ||
|
187
|
+
uobj.is(:uid) == user
|
188
|
+
}
|
189
|
+
|
190
|
+
unless obj
|
191
|
+
begin
|
192
|
+
uobj = Etc.getpwuid(user)
|
193
|
+
uid = uobj.uid
|
194
|
+
rescue ArgumentError => detail
|
195
|
+
# ignore it; we couldn't find the user
|
196
|
+
end
|
197
|
+
end
|
157
198
|
else
|
158
199
|
unless obj = Puppet.type(:user)[user]
|
159
200
|
obj = Puppet.type(:user).create(
|
@@ -161,63 +202,16 @@ module Util
|
|
161
202
|
:check => [:uid, :gid]
|
162
203
|
)
|
163
204
|
end
|
205
|
+
end
|
206
|
+
|
207
|
+
if obj
|
164
208
|
obj.retrieve
|
165
209
|
uid = obj.is(:uid)
|
166
|
-
unless uid.is_a?(Integer)
|
167
|
-
raise Puppet::Error, "Could not find user %s" % user
|
168
|
-
end
|
169
210
|
end
|
170
211
|
|
171
212
|
return uid
|
172
213
|
end
|
173
214
|
|
174
|
-
# Create a lock file while something is happening
|
175
|
-
def self.disabledlock(*opts)
|
176
|
-
lock = opts[0] + ".lock"
|
177
|
-
while File.exists?(lock)
|
178
|
-
stamp = File.stat(lock).mtime.to_i
|
179
|
-
if Time.now.to_i - stamp > 5
|
180
|
-
Puppet.notice "Lock file %s is %s seconds old; removing" %
|
181
|
-
[lock, Time.now.to_i - stamp]
|
182
|
-
File.delete(lock)
|
183
|
-
break
|
184
|
-
else
|
185
|
-
sleep 0.1
|
186
|
-
end
|
187
|
-
#Puppet.debug "%s is locked" % opts[0]
|
188
|
-
end
|
189
|
-
File.open(lock, "w") { |f| f.print " "; f.flush }
|
190
|
-
writing = false
|
191
|
-
if opts[1] == "w"
|
192
|
-
writing = true
|
193
|
-
tmp = opts[0] + ".tmp"
|
194
|
-
orig = opts[0]
|
195
|
-
opts[0] = tmp
|
196
|
-
end
|
197
|
-
begin
|
198
|
-
File.open(*opts) { |file| yield file }
|
199
|
-
begin
|
200
|
-
if writing
|
201
|
-
Puppet.warning "opts were %s" % opts.inspect
|
202
|
-
system("ls -l %s 2>/dev/null" % tmp)
|
203
|
-
system("ls -l %s 2>/dev/null" % orig)
|
204
|
-
File.rename(tmp, orig)
|
205
|
-
end
|
206
|
-
rescue => detail
|
207
|
-
Puppet.err "Could not replace %s: %s" % [orig, detail]
|
208
|
-
File.unlink(tmp)
|
209
|
-
end
|
210
|
-
rescue => detail
|
211
|
-
Puppet.err "Storage error: %s" % detail
|
212
|
-
raise
|
213
|
-
ensure
|
214
|
-
# I don't really understand how the lock file could disappear,
|
215
|
-
# but just in case...
|
216
|
-
if FileTest.exists?(lock)
|
217
|
-
File.delete(lock)
|
218
|
-
end
|
219
|
-
end
|
220
|
-
end
|
221
215
|
|
222
216
|
# Create instance methods for each of the log levels. This allows
|
223
217
|
# the messages to be a little richer. Most classes will be calling this
|
@@ -278,4 +272,4 @@ module Util
|
|
278
272
|
end
|
279
273
|
end
|
280
274
|
|
281
|
-
# $Id: util.rb
|
275
|
+
# $Id: util.rb 914 2006-02-15 21:04:14Z luke $
|
@@ -0,0 +1,72 @@
|
|
1
|
+
if __FILE__ == $0
|
2
|
+
$:.unshift '..'
|
3
|
+
$:.unshift '../../lib'
|
4
|
+
$puppetbase = "../.."
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'puppet'
|
8
|
+
require 'puppet/client'
|
9
|
+
require 'puppet/server'
|
10
|
+
require 'test/unit'
|
11
|
+
require 'puppettest.rb'
|
12
|
+
|
13
|
+
# $Id: master.rb 908 2006-02-14 00:14:56Z luke $
|
14
|
+
|
15
|
+
class TestMasterClient < Test::Unit::TestCase
|
16
|
+
include ServerTest
|
17
|
+
|
18
|
+
def mkmaster(file)
|
19
|
+
master = nil
|
20
|
+
# create our master
|
21
|
+
assert_nothing_raised() {
|
22
|
+
# this is the default server setup
|
23
|
+
master = Puppet::Server::Master.new(
|
24
|
+
:File => file,
|
25
|
+
:UseNodes => false,
|
26
|
+
:Local => true
|
27
|
+
)
|
28
|
+
}
|
29
|
+
return master
|
30
|
+
end
|
31
|
+
|
32
|
+
def mkclient(master)
|
33
|
+
client = nil
|
34
|
+
assert_nothing_raised() {
|
35
|
+
client = Puppet::Client::MasterClient.new(
|
36
|
+
:Master => master
|
37
|
+
)
|
38
|
+
}
|
39
|
+
|
40
|
+
return client
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_disable
|
44
|
+
manifest = mktestmanifest
|
45
|
+
|
46
|
+
master = mkmaster(manifest)
|
47
|
+
|
48
|
+
client = mkclient(master)
|
49
|
+
|
50
|
+
assert(! FileTest.exists?(@createdfile))
|
51
|
+
|
52
|
+
assert_nothing_raised {
|
53
|
+
client.disable
|
54
|
+
}
|
55
|
+
|
56
|
+
assert_nothing_raised {
|
57
|
+
client.run
|
58
|
+
}
|
59
|
+
|
60
|
+
assert(! FileTest.exists?(@createdfile), "Disabled client ran")
|
61
|
+
|
62
|
+
assert_nothing_raised {
|
63
|
+
client.enable
|
64
|
+
}
|
65
|
+
|
66
|
+
assert_nothing_raised {
|
67
|
+
client.run
|
68
|
+
}
|
69
|
+
|
70
|
+
assert(FileTest.exists?(@createdfile), "Enabled client did not run")
|
71
|
+
end
|
72
|
+
end
|
@@ -68,4 +68,98 @@ class TestInterpreter < Test::Unit::TestCase
|
|
68
68
|
|
69
69
|
assert(config != newconfig, "Configs are somehow the same")
|
70
70
|
end
|
71
|
+
|
72
|
+
# Only test ldap stuff on luke's network, since that's the only place we
|
73
|
+
# have data for.
|
74
|
+
if Facter["domain"].value == "madstop.com"
|
75
|
+
begin
|
76
|
+
require 'ldap'
|
77
|
+
$haveldap = true
|
78
|
+
rescue LoadError
|
79
|
+
$stderr.puts "Missing ldap; skipping ldap source tests"
|
80
|
+
$haveldap = false
|
81
|
+
end
|
82
|
+
if $haveldap
|
83
|
+
def ldapconnect
|
84
|
+
|
85
|
+
@ldap = LDAP::Conn.new("ldap", 389)
|
86
|
+
@ldap.set_option( LDAP::LDAP_OPT_PROTOCOL_VERSION, 3 )
|
87
|
+
@ldap.simple_bind("", "")
|
88
|
+
|
89
|
+
return @ldap
|
90
|
+
end
|
91
|
+
|
92
|
+
def ldaphost(node)
|
93
|
+
parent = nil
|
94
|
+
classes = nil
|
95
|
+
@ldap.search( "ou=hosts, dc=madstop, dc=com", 2,
|
96
|
+
"(&(objectclass=puppetclient)(cn=%s))" % node
|
97
|
+
) do |entry|
|
98
|
+
parent = entry.vals("parentnode").shift
|
99
|
+
classes = entry.vals("puppetclass")
|
100
|
+
end
|
101
|
+
|
102
|
+
return parent, classes
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_ldapnodes
|
106
|
+
Puppet[:ldapbase] = "ou=hosts, dc=madstop, dc=com"
|
107
|
+
|
108
|
+
ldapconnect()
|
109
|
+
file = tempfile()
|
110
|
+
files = []
|
111
|
+
parentfile = tempfile() + "-parent"
|
112
|
+
files << parentfile
|
113
|
+
hostname = Facter["hostname"].value
|
114
|
+
lparent, lclasses = ldaphost(Facter["hostname"].value)
|
115
|
+
File.open(file, "w") { |f|
|
116
|
+
f.puts "node #{lparent} {
|
117
|
+
file { \"#{parentfile}\": ensure => file }
|
118
|
+
}"
|
119
|
+
|
120
|
+
lclasses.each { |klass|
|
121
|
+
kfile = tempfile() + "-klass"
|
122
|
+
files << kfile
|
123
|
+
f.puts "class #{klass} { file { \"#{kfile}\": ensure => file } }"
|
124
|
+
}
|
125
|
+
}
|
126
|
+
interp = nil
|
127
|
+
assert_nothing_raised {
|
128
|
+
interp = Puppet::Parser::Interpreter.new(
|
129
|
+
:Manifest => file,
|
130
|
+
:NodeSources => [:ldap]
|
131
|
+
)
|
132
|
+
}
|
133
|
+
|
134
|
+
assert_nothing_raised {
|
135
|
+
interp.setup_ldap
|
136
|
+
}
|
137
|
+
|
138
|
+
parent = nil
|
139
|
+
classes = nil
|
140
|
+
assert_nothing_raised {
|
141
|
+
parent, classes = interp.nodesearch_ldap(hostname)
|
142
|
+
}
|
143
|
+
|
144
|
+
assert_equal(lparent, parent, "Parent node did not match")
|
145
|
+
assert_equal(lclasses, classes, "Class list did not match")
|
146
|
+
|
147
|
+
objects = nil
|
148
|
+
assert_nothing_raised {
|
149
|
+
objects = interp.run(hostname, Puppet::Client::MasterClient.facts)
|
150
|
+
}
|
151
|
+
|
152
|
+
comp = nil
|
153
|
+
assert_nothing_raised {
|
154
|
+
comp = objects.to_type
|
155
|
+
}
|
156
|
+
|
157
|
+
assert_apply(comp)
|
158
|
+
files.each { |cfile|
|
159
|
+
@@tmpfiles << cfile
|
160
|
+
assert(FileTest.exists?(cfile), "Did not make %s" % cfile)
|
161
|
+
}
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
71
165
|
end
|
data/test/other/log.rb
CHANGED
@@ -9,14 +9,20 @@ require 'puppet'
|
|
9
9
|
require 'puppettest'
|
10
10
|
require 'test/unit'
|
11
11
|
|
12
|
-
# $Id: log.rb
|
12
|
+
# $Id: log.rb 914 2006-02-15 21:04:14Z luke $
|
13
13
|
|
14
14
|
class TestLog < Test::Unit::TestCase
|
15
15
|
include TestPuppet
|
16
16
|
|
17
|
+
def setup
|
18
|
+
super
|
19
|
+
@oldloglevel = Puppet::Log.level
|
20
|
+
end
|
21
|
+
|
17
22
|
def teardown
|
18
23
|
super
|
19
24
|
Puppet::Log.close
|
25
|
+
Puppet::Log.level = @oldloglevel
|
20
26
|
end
|
21
27
|
|
22
28
|
def getlevels
|
@@ -44,6 +50,7 @@ class TestLog < Test::Unit::TestCase
|
|
44
50
|
def test_logfile
|
45
51
|
fact = nil
|
46
52
|
levels = nil
|
53
|
+
oldlevel = Puppet::Log.level
|
47
54
|
Puppet::Log.level = :debug
|
48
55
|
levels = getlevels
|
49
56
|
logfile = tempfile()
|
data/test/puppet/utiltest.rb
CHANGED
@@ -43,6 +43,106 @@ class TestPuppetUtil < Test::Unit::TestCase
|
|
43
43
|
threads.each { |th| th.join }
|
44
44
|
end
|
45
45
|
|
46
|
+
# First verify we can convert a known user
|
47
|
+
def test_gidbyname
|
48
|
+
%x{groups}.split(" ").each { |group|
|
49
|
+
gid = nil
|
50
|
+
assert_nothing_raised {
|
51
|
+
gid = Puppet::Util.gid(group)
|
52
|
+
}
|
53
|
+
|
54
|
+
assert(gid, "Could not retrieve gid for %s" % group)
|
55
|
+
|
56
|
+
assert(Puppet.type(:group)[group], "Util did not create %s" % group)
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
# Then verify we can retrieve a known group by gid
|
61
|
+
def test_gidbyid
|
62
|
+
%x{groups}.split(" ").each { |group|
|
63
|
+
obj = Puppet.type(:group).create(
|
64
|
+
:name => group,
|
65
|
+
:check => [:gid]
|
66
|
+
)
|
67
|
+
obj.retrieve
|
68
|
+
id = obj.is(:gid)
|
69
|
+
gid = nil
|
70
|
+
assert_nothing_raised {
|
71
|
+
gid = Puppet::Util.gid(id)
|
72
|
+
}
|
73
|
+
|
74
|
+
assert(gid, "Could not retrieve gid for %s" % group)
|
75
|
+
assert_equal(id, gid, "Got mismatched ids")
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
# Finally, verify that we can find groups by id even if we don't
|
80
|
+
# know them
|
81
|
+
def test_gidbyunknownid
|
82
|
+
gid = nil
|
83
|
+
group = Process.gid
|
84
|
+
assert_nothing_raised {
|
85
|
+
gid = Puppet::Util.gid(group)
|
86
|
+
}
|
87
|
+
|
88
|
+
assert(gid, "Could not retrieve gid for %s" % group)
|
89
|
+
assert_equal(group, gid, "Got mismatched ids")
|
90
|
+
end
|
91
|
+
|
92
|
+
def user
|
93
|
+
require 'etc'
|
94
|
+
unless defined? @user
|
95
|
+
obj = Etc.getpwuid(Process.uid)
|
96
|
+
@user = obj.name
|
97
|
+
end
|
98
|
+
return @user
|
99
|
+
end
|
100
|
+
|
101
|
+
# And do it all over again for users
|
102
|
+
# First verify we can convert a known user
|
103
|
+
def test_uidbyname
|
104
|
+
user = user()
|
105
|
+
uid = nil
|
106
|
+
assert_nothing_raised {
|
107
|
+
uid = Puppet::Util.uid(user)
|
108
|
+
}
|
109
|
+
|
110
|
+
assert(uid, "Could not retrieve uid for %s" % user)
|
111
|
+
assert_equal(Process.uid, uid, "UIDs did not match")
|
112
|
+
assert(Puppet.type(:user)[user], "Util did not create %s" % user)
|
113
|
+
end
|
114
|
+
|
115
|
+
# Then verify we can retrieve a known user by uid
|
116
|
+
def test_uidbyid
|
117
|
+
user = user()
|
118
|
+
obj = Puppet.type(:user).create(
|
119
|
+
:name => user,
|
120
|
+
:check => [:uid]
|
121
|
+
)
|
122
|
+
obj.retrieve
|
123
|
+
id = obj.is(:uid)
|
124
|
+
uid = nil
|
125
|
+
assert_nothing_raised {
|
126
|
+
uid = Puppet::Util.uid(id)
|
127
|
+
}
|
128
|
+
|
129
|
+
assert(uid, "Could not retrieve uid for %s" % user)
|
130
|
+
assert_equal(id, uid, "Got mismatched ids")
|
131
|
+
end
|
132
|
+
|
133
|
+
# Finally, verify that we can find users by id even if we don't
|
134
|
+
# know them
|
135
|
+
def test_uidbyunknownid
|
136
|
+
uid = nil
|
137
|
+
user = Process.uid
|
138
|
+
assert_nothing_raised {
|
139
|
+
uid = Puppet::Util.uid(user)
|
140
|
+
}
|
141
|
+
|
142
|
+
assert(uid, "Could not retrieve uid for %s" % user)
|
143
|
+
assert_equal(user, uid, "Got mismatched ids")
|
144
|
+
end
|
145
|
+
|
46
146
|
unless Process.uid == 0
|
47
147
|
$stderr.puts "Run as root to perform Utility tests"
|
48
148
|
def test_nothing
|
@@ -153,4 +253,4 @@ class TestPuppetUtil < Test::Unit::TestCase
|
|
153
253
|
end
|
154
254
|
end
|
155
255
|
|
156
|
-
# $Id: utiltest.rb
|
256
|
+
# $Id: utiltest.rb 914 2006-02-15 21:04:14Z luke $
|