puppet 0.13.6 → 0.16.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puppet might be problematic. Click here for more details.
- data/CHANGELOG +57 -0
- data/Rakefile +38 -410
- data/bin/puppet +14 -12
- data/bin/puppetca +1 -3
- data/bin/puppetd +25 -7
- data/bin/puppetdoc +161 -104
- data/bin/puppetmasterd +4 -4
- data/conf/epm.list +8 -0
- data/conf/redhat/client.init +6 -1
- data/conf/redhat/no-chuser-0.15.1.patch +38 -0
- data/conf/redhat/puppet.spec +20 -5
- data/conf/redhat/puppetd.conf +1 -1
- data/conf/redhat/puppetmasterd.conf +1 -1
- data/conf/redhat/server.init +2 -4
- data/examples/code/snippets/{casestatement → casestatement.pp} +12 -1
- data/examples/code/snippets/selectorvalues.pp +15 -0
- data/examples/code/snippets/singleselector.pp +22 -0
- data/examples/code/snippets/tag.pp +9 -0
- data/ext/module_puppet +1 -1
- data/install.rb +303 -303
- data/lib/puppet.rb +7 -9
- data/lib/puppet/client.rb +18 -5
- data/lib/puppet/client/dipper.rb +12 -10
- data/lib/puppet/client/master.rb +113 -41
- data/lib/puppet/client/pelement.rb +20 -0
- data/lib/puppet/config.rb +113 -6
- data/lib/puppet/element.rb +1 -3
- data/lib/puppet/event.rb +12 -23
- data/lib/puppet/filetype.rb +93 -5
- data/lib/puppet/inifile.rb +201 -0
- data/lib/puppet/log.rb +18 -6
- data/lib/puppet/parameter.rb +80 -29
- data/lib/puppet/parser/ast.rb +6 -4
- data/lib/puppet/parser/ast/caseopt.rb +13 -4
- data/lib/puppet/parser/ast/casestatement.rb +2 -2
- data/lib/puppet/parser/ast/component.rb +4 -14
- data/lib/puppet/parser/ast/hostclass.rb +1 -1
- data/lib/puppet/parser/ast/leaf.rb +12 -0
- data/lib/puppet/parser/ast/node.rb +4 -4
- data/lib/puppet/parser/ast/objectdef.rb +5 -51
- data/lib/puppet/parser/ast/selector.rb +2 -0
- data/lib/puppet/parser/ast/tag.rb +26 -0
- data/lib/puppet/parser/interpreter.rb +89 -74
- data/lib/puppet/parser/lexer.rb +4 -3
- data/lib/puppet/parser/parser.rb +440 -378
- data/lib/puppet/parser/scope.rb +844 -887
- data/lib/puppet/server.rb +12 -1
- data/lib/puppet/server/authconfig.rb +166 -0
- data/lib/puppet/server/authstore.rb +8 -6
- data/lib/puppet/server/ca.rb +23 -26
- data/lib/puppet/server/filebucket.rb +24 -23
- data/lib/puppet/server/fileserver.rb +116 -47
- data/lib/puppet/server/master.rb +58 -19
- data/lib/puppet/server/pelement.rb +176 -0
- data/lib/puppet/server/rights.rb +78 -0
- data/lib/puppet/server/servlet.rb +19 -6
- data/lib/puppet/sslcertificates.rb +4 -2
- data/lib/puppet/sslcertificates/ca.rb +66 -34
- data/lib/puppet/storage.rb +20 -26
- data/lib/puppet/transaction.rb +49 -92
- data/lib/puppet/type.rb +142 -35
- data/lib/puppet/type/cron.rb +29 -14
- data/lib/puppet/type/exec.rb +92 -35
- data/lib/puppet/type/group.rb +29 -11
- data/lib/puppet/type/nameservice.rb +50 -1
- data/lib/puppet/type/nameservice/netinfo.rb +68 -1
- data/lib/puppet/type/nameservice/objectadd.rb +1 -0
- data/lib/puppet/type/package.rb +150 -109
- data/lib/puppet/type/package/apple.rb +27 -0
- data/lib/puppet/type/package/apt.rb +1 -0
- data/lib/puppet/type/package/darwinport.rb +97 -0
- data/lib/puppet/type/package/dpkg.rb +10 -2
- data/lib/puppet/type/package/freebsd.rb +19 -0
- data/lib/puppet/type/package/{bsd.rb → openbsd.rb} +36 -7
- data/lib/puppet/type/package/ports.rb +98 -0
- data/lib/puppet/type/package/rpm.rb +43 -7
- data/lib/puppet/type/package/sun.rb +53 -36
- data/lib/puppet/type/package/yum.rb +5 -16
- data/lib/puppet/type/parsedtype.rb +41 -29
- data/lib/puppet/type/parsedtype/host.rb +13 -5
- data/lib/puppet/type/parsedtype/mount.rb +250 -0
- data/lib/puppet/type/parsedtype/port.rb +8 -6
- data/lib/puppet/type/pfile.rb +284 -30
- data/lib/puppet/type/pfile/checksum.rb +96 -68
- data/lib/puppet/type/pfile/content.rb +16 -13
- data/lib/puppet/type/pfile/ensure.rb +64 -126
- data/lib/puppet/type/pfile/group.rb +12 -5
- data/lib/puppet/type/pfile/mode.rb +16 -4
- data/lib/puppet/type/pfile/source.rb +47 -73
- data/lib/puppet/type/pfile/target.rb +81 -0
- data/lib/puppet/type/pfile/uid.rb +10 -3
- data/lib/puppet/type/pfilebucket.rb +12 -3
- data/lib/puppet/type/schedule.rb +5 -1
- data/lib/puppet/type/service.rb +138 -66
- data/lib/puppet/type/service/debian.rb +9 -3
- data/lib/puppet/type/service/init.rb +51 -56
- data/lib/puppet/type/service/smf.rb +16 -6
- data/lib/puppet/type/state.rb +71 -32
- data/lib/puppet/type/symlink.rb +12 -7
- data/lib/puppet/type/tidy.rb +5 -1
- data/lib/puppet/type/user.rb +116 -20
- data/lib/puppet/type/yumrepo.rb +314 -0
- data/lib/puppet/util.rb +84 -14
- data/test/client/client.rb +41 -18
- data/test/client/master.rb +50 -4
- data/test/executables/puppetbin.rb +31 -4
- data/test/executables/puppetca.rb +18 -2
- data/test/language/ast.rb +201 -31
- data/test/language/interpreter.rb +8 -2
- data/test/{parser → language}/lexer.rb +1 -1
- data/test/language/node.rb +84 -0
- data/test/{parser → language}/parser.rb +1 -1
- data/test/language/scope.rb +101 -2
- data/test/language/snippets.rb +23 -2
- data/test/other/config.rb +99 -1
- data/test/other/filetype.rb +95 -0
- data/test/other/inifile.rb +114 -0
- data/test/other/log.rb +3 -2
- data/test/other/transactions.rb +55 -10
- data/test/puppet/utiltest.rb +25 -1
- data/test/puppettest.rb +140 -46
- data/test/server/authconfig.rb +56 -0
- data/test/server/bucket.rb +32 -18
- data/test/server/fileserver.rb +75 -30
- data/test/server/master.rb +27 -4
- data/test/server/pelement.rb +298 -0
- data/test/server/rights.rb +41 -0
- data/test/server/server.rb +2 -2
- data/test/tagging/tagging.rb +100 -1
- data/test/types/basic.rb +3 -3
- data/test/types/cron.rb +24 -1
- data/test/types/exec.rb +99 -1
- data/test/types/file.rb +298 -2
- data/test/types/filebucket.rb +4 -15
- data/test/types/filesources.rb +43 -14
- data/test/types/group.rb +1 -13
- data/test/types/mount.rb +277 -0
- data/test/types/package.rb +164 -33
- data/test/types/parameter.rb +107 -0
- data/test/types/port.rb +2 -1
- data/test/types/service.rb +37 -2
- data/test/types/state.rb +92 -0
- data/test/types/symlink.rb +30 -2
- data/test/types/tidy.rb +2 -14
- data/test/types/type.rb +35 -1
- data/test/types/user.rb +110 -1
- data/test/types/yumrepo.rb +95 -0
- metadata +316 -290
- data/test/types/filetype.rb +0 -160
data/lib/puppet/server.rb
CHANGED
@@ -27,6 +27,16 @@ module Puppet
|
|
27
27
|
class Server < WEBrick::HTTPServer
|
28
28
|
include Puppet::Daemon
|
29
29
|
|
30
|
+
# Create our config object if necessary. This works even if
|
31
|
+
# there's no configuration file.
|
32
|
+
def authconfig
|
33
|
+
unless defined? @authconfig
|
34
|
+
@authconfig = Puppet::Server::AuthConfig.new()
|
35
|
+
end
|
36
|
+
|
37
|
+
@authconfig
|
38
|
+
end
|
39
|
+
|
30
40
|
def initialize(hash = {})
|
31
41
|
Puppet.info "Starting server for Puppet version %s" % Puppet.version
|
32
42
|
daemonize = nil
|
@@ -158,6 +168,7 @@ module Puppet
|
|
158
168
|
end
|
159
169
|
|
160
170
|
require 'puppet/server/authstore'
|
171
|
+
require 'puppet/server/authconfig'
|
161
172
|
require 'puppet/server/servlet'
|
162
173
|
require 'puppet/server/master'
|
163
174
|
require 'puppet/server/ca'
|
@@ -166,4 +177,4 @@ require 'puppet/server/filebucket'
|
|
166
177
|
require 'puppet/server/logger'
|
167
178
|
require 'puppet/client'
|
168
179
|
|
169
|
-
# $Id: server.rb
|
180
|
+
# $Id: server.rb 1129 2006-04-21 19:14:59Z luke $
|
@@ -0,0 +1,166 @@
|
|
1
|
+
require 'puppet/parsedfile'
|
2
|
+
require 'puppet/server/rights'
|
3
|
+
|
4
|
+
module Puppet
|
5
|
+
class Server
|
6
|
+
|
7
|
+
class ConfigurationError < Puppet::Error; end
|
8
|
+
|
9
|
+
class AuthConfig < Puppet::ParsedFile
|
10
|
+
Puppet.config.setdefaults(:puppet,
|
11
|
+
:authconfig => [ "$confdir/namespaceauth.conf",
|
12
|
+
"The configuration file that defines the rights to the different
|
13
|
+
namespaces and methods. This can be used as a coarse-grained
|
14
|
+
authorization system for both ``puppetd`` and ``puppetmasterd``."
|
15
|
+
]
|
16
|
+
)
|
17
|
+
|
18
|
+
# Just proxy the setting methods to our rights stuff
|
19
|
+
[:allow, :deny].each do |method|
|
20
|
+
define_method(method) do |*args|
|
21
|
+
@rights.send(method, *args)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Here we add a little bit of semantics. They can set auth on a whole namespace
|
26
|
+
# or on just a single method in the namespace.
|
27
|
+
def allowed?(name, host, ip)
|
28
|
+
namespace, method = name.to_s.split(".")
|
29
|
+
unless namespace and method
|
30
|
+
raise ArgumentError, "Invalid method name %s" % name
|
31
|
+
end
|
32
|
+
|
33
|
+
name = name.intern if name.is_a? String
|
34
|
+
namespace = namespace.intern
|
35
|
+
method = method.intern
|
36
|
+
|
37
|
+
if @rights.include?(name)
|
38
|
+
return @rights[name].allowed?(host, ip)
|
39
|
+
elsif @rights.include?(namespace)
|
40
|
+
return @rights[namespace].allowed?(host, ip)
|
41
|
+
else
|
42
|
+
return false
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Does the file exist? Puppetmasterd does not require it, but
|
47
|
+
# puppetd does.
|
48
|
+
def exists?
|
49
|
+
FileTest.exists?(@file)
|
50
|
+
end
|
51
|
+
|
52
|
+
def initialize(file = nil, parsenow = true)
|
53
|
+
@file ||= Puppet[:authconfig]
|
54
|
+
return unless self.exists?
|
55
|
+
super(file)
|
56
|
+
@rights = Rights.new
|
57
|
+
@configstamp = @configtimeout = @configstatted = nil
|
58
|
+
|
59
|
+
if parsenow
|
60
|
+
read()
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Read the configuration file.
|
65
|
+
def read
|
66
|
+
return unless FileTest.exists?(@file)
|
67
|
+
|
68
|
+
if @configstamp
|
69
|
+
if @configtimeout and @configstatted
|
70
|
+
if Time.now - @configstatted > @configtimeout
|
71
|
+
@configstatted = Time.now
|
72
|
+
tmp = File.stat(@file).ctime
|
73
|
+
|
74
|
+
if tmp == @configstamp
|
75
|
+
return
|
76
|
+
end
|
77
|
+
else
|
78
|
+
return
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
parse()
|
84
|
+
|
85
|
+
@configstamp = File.stat(@file).ctime
|
86
|
+
@configstatted = Time.now
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def parse
|
92
|
+
newrights = Puppet::Server::Rights.new
|
93
|
+
begin
|
94
|
+
File.open(@file) { |f|
|
95
|
+
right = nil
|
96
|
+
count = 1
|
97
|
+
f.each { |line|
|
98
|
+
case line
|
99
|
+
when /^\s*#/: next # skip comments
|
100
|
+
when /^\s*$/: next # skip blank lines
|
101
|
+
when /\[([\w.]+)\]/: # "namespace" or "namespace.method"
|
102
|
+
name = $1
|
103
|
+
if newrights.include?(name)
|
104
|
+
raise FileServerError, "%s is already set at %s" %
|
105
|
+
[newrights[name], name]
|
106
|
+
end
|
107
|
+
newrights.newright(name)
|
108
|
+
right = newrights[name]
|
109
|
+
when /^\s*(\w+)\s+(.+)$/:
|
110
|
+
var = $1
|
111
|
+
value = $2
|
112
|
+
case var
|
113
|
+
when "allow":
|
114
|
+
value.split(/\s*,\s*/).each { |val|
|
115
|
+
begin
|
116
|
+
right.info "allowing %s access" % val
|
117
|
+
right.allow(val)
|
118
|
+
rescue AuthStoreError => detail
|
119
|
+
raise ConfigurationError, "%s at line %s of %s" %
|
120
|
+
[detail.to_s, count, @config]
|
121
|
+
end
|
122
|
+
}
|
123
|
+
when "deny":
|
124
|
+
value.split(/\s*,\s*/).each { |val|
|
125
|
+
begin
|
126
|
+
right.info "denying %s access" % val
|
127
|
+
right.deny(val)
|
128
|
+
rescue AuthStoreError => detail
|
129
|
+
raise ConfigurationError, "%s at line %s of %s" %
|
130
|
+
[detail.to_s, count, @config]
|
131
|
+
end
|
132
|
+
}
|
133
|
+
else
|
134
|
+
raise ConfigurationError,
|
135
|
+
"Invalid argument '%s' at line %s" % [var, count]
|
136
|
+
end
|
137
|
+
else
|
138
|
+
raise ConfigurationError, "Invalid line %s: %s" % [count, line]
|
139
|
+
end
|
140
|
+
count += 1
|
141
|
+
}
|
142
|
+
}
|
143
|
+
rescue Errno::EACCES => detail
|
144
|
+
Puppet.err "Configuration error: Cannot read %s; cannot serve" % @file
|
145
|
+
#raise Puppet::Error, "Cannot read %s" % @config
|
146
|
+
rescue Errno::ENOENT => detail
|
147
|
+
Puppet.err "Configuration error: '%s' does not exit; cannot serve" %
|
148
|
+
@file
|
149
|
+
#raise Puppet::Error, "%s does not exit" % @config
|
150
|
+
#rescue FileServerError => detail
|
151
|
+
# Puppet.err "FileServer error: %s" % detail
|
152
|
+
end
|
153
|
+
|
154
|
+
# Verify each of the rights are valid.
|
155
|
+
# We let the check raise an error, so that it can raise an error
|
156
|
+
# pointing to the specific problem.
|
157
|
+
newrights.each { |name, right|
|
158
|
+
right.valid?
|
159
|
+
}
|
160
|
+
@rights = newrights
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
# $Id: authconfig.rb 1129 2006-04-21 19:14:59Z luke $
|
@@ -9,12 +9,13 @@ class Server
|
|
9
9
|
class AuthorizationError < Puppet::Error; end
|
10
10
|
|
11
11
|
class AuthStore
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
# This has to be an array, not a hash, else it loses its ordering.
|
13
|
+
ORDER = [
|
14
|
+
[:ip, [:ip]],
|
15
|
+
[:name, [:hostname, :domain]]
|
16
|
+
]
|
16
17
|
|
17
|
-
Puppet::Util.logmethods(self,
|
18
|
+
Puppet::Util.logmethods(self, true)
|
18
19
|
|
19
20
|
def allow(pattern)
|
20
21
|
# a simple way to allow anyone at all to connect
|
@@ -49,6 +50,7 @@ class Server
|
|
49
50
|
value = name.split(".").reverse
|
50
51
|
end
|
51
52
|
|
53
|
+
|
52
54
|
array.each { |type|
|
53
55
|
[[@deny, false], [@allow, true]].each { |ary|
|
54
56
|
hash, retval = ary
|
@@ -221,4 +223,4 @@ class Server
|
|
221
223
|
end
|
222
224
|
end
|
223
225
|
#
|
224
|
-
# $Id: authstore.rb
|
226
|
+
# $Id: authstore.rb 1129 2006-04-21 19:14:59Z luke $
|
data/lib/puppet/server/ca.rb
CHANGED
@@ -79,35 +79,12 @@ class Server
|
|
79
79
|
return ""
|
80
80
|
end
|
81
81
|
|
82
|
-
#
|
83
|
-
#
|
84
|
-
|
85
|
-
#unless FileTest.directory?(Puppet[:publickeydir])
|
86
|
-
# Puppet.recmkdir(Puppet[:publickeydir])
|
87
|
-
#end
|
88
|
-
pkeyfile = File.join(Puppet[:publickeydir], [hostname, "pem"].join('.'))
|
82
|
+
# We used to save the public key, but it's basically unnecessary
|
83
|
+
# and it mucks with the permissions requirements.
|
84
|
+
# save_pk(hostname, csr.public_key)
|
89
85
|
|
90
|
-
if FileTest.exists?(pkeyfile)
|
91
|
-
currentkey = File.open(pkeyfile) { |k| k.read }
|
92
|
-
unless currentkey == public_key.to_s
|
93
|
-
raise Puppet::Error, "public keys for %s differ" % hostname
|
94
|
-
end
|
95
|
-
else
|
96
|
-
File.open(pkeyfile, "w", 0644) { |f|
|
97
|
-
f.print public_key.to_s
|
98
|
-
}
|
99
|
-
end
|
100
|
-
#unless FileTest.directory?(Puppet[:certdir])
|
101
|
-
# Puppet.recmkdir(Puppet[:certdir], 0770)
|
102
|
-
#end
|
103
86
|
certfile = File.join(Puppet[:certdir], [hostname, "pem"].join("."))
|
104
87
|
|
105
|
-
#puts hostname
|
106
|
-
#puts certfile
|
107
|
-
|
108
|
-
#unless FileTest.directory?(Puppet[:csrdir])
|
109
|
-
# Puppet.recmkdir(Puppet[:csrdir], 0770)
|
110
|
-
#end
|
111
88
|
# first check to see if we already have a signed cert for the host
|
112
89
|
cert, cacert = ca.getclientcert(hostname)
|
113
90
|
if cert and cacert
|
@@ -139,6 +116,26 @@ class Server
|
|
139
116
|
raise "huh?"
|
140
117
|
end
|
141
118
|
end
|
119
|
+
|
120
|
+
private
|
121
|
+
|
122
|
+
# Save the public key.
|
123
|
+
def save_pk(hostname, public_key)
|
124
|
+
pkeyfile = File.join(Puppet[:publickeydir], [hostname, "pem"].join('.'))
|
125
|
+
|
126
|
+
if FileTest.exists?(pkeyfile)
|
127
|
+
currentkey = File.open(pkeyfile) { |k| k.read }
|
128
|
+
unless currentkey == public_key.to_s
|
129
|
+
raise Puppet::Error, "public keys for %s differ" % hostname
|
130
|
+
end
|
131
|
+
else
|
132
|
+
File.open(pkeyfile, "w", 0644) { |f|
|
133
|
+
f.print public_key.to_s
|
134
|
+
}
|
135
|
+
end
|
136
|
+
end
|
142
137
|
end
|
143
138
|
end
|
144
139
|
end
|
140
|
+
|
141
|
+
# $Id: ca.rb 1053 2006-04-02 23:39:02Z luke $
|
@@ -3,10 +3,8 @@
|
|
3
3
|
|
4
4
|
|
5
5
|
require 'webrick'
|
6
|
-
#require 'webrick/https'
|
7
6
|
require 'xmlrpc/server'
|
8
7
|
require 'xmlrpc/client'
|
9
|
-
#require 'webrick/httpstatus'
|
10
8
|
require 'facter'
|
11
9
|
require 'digest/md5'
|
12
10
|
require 'puppet/base64'
|
@@ -29,6 +27,9 @@ class Server
|
|
29
27
|
iface.add_method("string getfile(string)")
|
30
28
|
}
|
31
29
|
|
30
|
+
Puppet::Util.logmethods(self, true)
|
31
|
+
attr_reader :name
|
32
|
+
|
32
33
|
# this doesn't work for relative paths
|
33
34
|
def FileBucket.paths(base,md5)
|
34
35
|
return [
|
@@ -39,8 +40,6 @@ class Server
|
|
39
40
|
end
|
40
41
|
|
41
42
|
def initialize(hash)
|
42
|
-
# build our AST
|
43
|
-
|
44
43
|
if hash.include?(:ConflictCheck)
|
45
44
|
@conflictchk = hash[:ConflictCheck]
|
46
45
|
hash.delete(:ConflictCheck)
|
@@ -59,28 +58,27 @@ class Server
|
|
59
58
|
end
|
60
59
|
end
|
61
60
|
|
62
|
-
Puppet.
|
61
|
+
Puppet.config.use(:filebucket)
|
62
|
+
|
63
|
+
@name = "filebucket[#{Puppet[:bucketdir]}]"
|
63
64
|
end
|
64
65
|
|
65
66
|
# accept a file from a client
|
66
67
|
def addfile(string,path, client = nil, clientip = nil)
|
67
|
-
#puts "entering addfile"
|
68
68
|
contents = Base64.decode64(string)
|
69
|
-
#puts "string is decoded"
|
70
|
-
|
71
69
|
md5 = Digest::MD5.hexdigest(contents)
|
72
|
-
#puts "md5 is made"
|
73
70
|
|
74
71
|
bpath, bfile, pathpath = FileBucket.paths(@bucket,md5)
|
75
72
|
|
76
73
|
# if it's a new directory...
|
77
74
|
if Puppet.recmkdir(bpath)
|
75
|
+
msg = "Adding %s(%s)" % [path, md5]
|
76
|
+
msg += " from #{client}" if client
|
77
|
+
self.info msg
|
78
78
|
# ...then just create the file
|
79
|
-
|
80
|
-
File.open(bfile, File::WRONLY|File::CREAT) { |of|
|
79
|
+
File.open(bfile, File::WRONLY|File::CREAT, 0440) { |of|
|
81
80
|
of.print contents
|
82
81
|
}
|
83
|
-
#puts "File is created"
|
84
82
|
else # if the dir already existed...
|
85
83
|
# ...we need to verify that the contents match the existing file
|
86
84
|
if @conflictchk
|
@@ -89,21 +87,23 @@ class Server
|
|
89
87
|
"No file at %s for sum %s" % [bfile,md5], caller)
|
90
88
|
end
|
91
89
|
|
92
|
-
curfile =
|
93
|
-
File.open(bfile) { |of|
|
94
|
-
curfile = of.read
|
95
|
-
}
|
90
|
+
curfile = File.read(bfile)
|
96
91
|
|
97
|
-
#
|
98
|
-
#
|
92
|
+
# If the contents don't match, then we've found a conflict.
|
93
|
+
# Unlikely, but quite bad.
|
99
94
|
if curfile != contents
|
100
95
|
raise(BucketError,
|
101
96
|
"Got passed new contents for sum %s" % md5, caller)
|
97
|
+
else
|
98
|
+
msg = "Got duplicate %s(%s)" % [path, md5]
|
99
|
+
msg += " from #{client}" if client
|
100
|
+
self.info msg
|
102
101
|
end
|
103
102
|
end
|
104
|
-
#puts "Conflict check is done"
|
105
103
|
end
|
106
104
|
|
105
|
+
contents = ""
|
106
|
+
|
107
107
|
# in either case, add the passed path to the list of paths
|
108
108
|
paths = nil
|
109
109
|
addpath = false
|
@@ -119,14 +119,12 @@ class Server
|
|
119
119
|
else
|
120
120
|
addpath = true
|
121
121
|
end
|
122
|
-
#puts "Path is checked"
|
123
122
|
|
124
123
|
# if it's a new file, or if our path isn't in the file yet, add it
|
125
124
|
if addpath
|
126
125
|
File.open(pathpath, File::WRONLY|File::CREAT|File::APPEND) { |of|
|
127
126
|
of.puts path
|
128
127
|
}
|
129
|
-
#puts "Path is added"
|
130
128
|
end
|
131
129
|
|
132
130
|
return md5
|
@@ -146,9 +144,12 @@ class Server
|
|
146
144
|
|
147
145
|
return Base64.encode64(contents)
|
148
146
|
end
|
149
|
-
|
147
|
+
|
148
|
+
def to_s
|
149
|
+
self.name
|
150
|
+
end
|
150
151
|
end
|
151
152
|
end
|
152
153
|
end
|
153
154
|
#
|
154
|
-
# $Id: filebucket.rb
|
155
|
+
# $Id: filebucket.rb 1113 2006-04-17 16:15:33Z luke $
|
@@ -3,8 +3,8 @@ require 'webrick/httpstatus'
|
|
3
3
|
require 'cgi'
|
4
4
|
|
5
5
|
module Puppet
|
6
|
+
class FileServerError < Puppet::Error; end
|
6
7
|
class Server
|
7
|
-
class FileServerError < Puppet::Error; end
|
8
8
|
class FileServer < Handler
|
9
9
|
attr_accessor :local
|
10
10
|
|
@@ -16,53 +16,36 @@ class Server
|
|
16
16
|
CHECKPARAMS = [:mode, :type, :owner, :group, :checksum]
|
17
17
|
|
18
18
|
@interface = XMLRPC::Service::Interface.new("fileserver") { |iface|
|
19
|
-
iface.add_method("string describe(string)")
|
20
|
-
iface.add_method("string list(string, boolean, array)")
|
21
|
-
iface.add_method("string retrieve(string)")
|
19
|
+
iface.add_method("string describe(string, string)")
|
20
|
+
iface.add_method("string list(string, string, boolean, array)")
|
21
|
+
iface.add_method("string retrieve(string, string)")
|
22
22
|
}
|
23
23
|
|
24
24
|
def authcheck(file, mount, client, clientip)
|
25
25
|
unless mount.allowed?(client, clientip)
|
26
|
-
|
27
|
-
[client,
|
26
|
+
mount.warning "%s cannot access %s" %
|
27
|
+
[client, file]
|
28
28
|
raise Puppet::Server::AuthorizationError, "Cannot access %s" % mount
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
# Run 'retrieve' on a file. This gets the actual parameters, so
|
33
|
-
# we can pass them to the client.
|
34
|
-
def check(dir)
|
35
|
-
unless FileTest.exists?(dir)
|
36
|
-
Puppet.notice "File source %s does not exist" % dir
|
37
|
-
return nil
|
38
|
-
end
|
39
|
-
|
40
|
-
obj = nil
|
41
|
-
unless obj = Puppet.type(:file)[dir]
|
42
|
-
obj = Puppet.type(:file).create(
|
43
|
-
:name => dir,
|
44
|
-
:check => CHECKPARAMS
|
45
|
-
)
|
46
|
-
end
|
47
|
-
# we should really have a timeout here -- we don't
|
48
|
-
# want to actually check on every connection, maybe no more
|
49
|
-
# than every 60 seconds or something
|
50
|
-
#@files[mount].evaluate
|
51
|
-
obj.evaluate
|
52
|
-
|
53
|
-
return obj
|
54
|
-
end
|
55
|
-
|
56
32
|
# Describe a given file. This returns all of the manageable aspects
|
57
33
|
# of that file.
|
58
|
-
def describe(file, client = nil, clientip = nil)
|
34
|
+
def describe(file, links = :ignore, client = nil, clientip = nil)
|
59
35
|
readconfig
|
36
|
+
|
37
|
+
links = links.intern if links.is_a? String
|
38
|
+
|
39
|
+
if links == :manage
|
40
|
+
raise Puppet::FileServerError, "Cannot currently copy links"
|
41
|
+
end
|
42
|
+
|
60
43
|
mount, path = splitpath(file)
|
61
44
|
|
62
45
|
authcheck(file, mount, client, clientip)
|
63
46
|
|
64
47
|
if client
|
65
|
-
|
48
|
+
mount.debug "Describing %s for %s" % [file, client]
|
66
49
|
end
|
67
50
|
|
68
51
|
sdir = nil
|
@@ -73,15 +56,20 @@ class Server
|
|
73
56
|
end
|
74
57
|
|
75
58
|
obj = nil
|
76
|
-
unless obj =
|
59
|
+
unless obj = mount.check(sdir, links)
|
77
60
|
return ""
|
78
61
|
end
|
79
62
|
|
63
|
+
#if links == :ignore and obj[:type] == "link"
|
64
|
+
# mount.info "Ignoring link %s" % obj.name
|
65
|
+
# return ""
|
66
|
+
#end
|
67
|
+
|
80
68
|
desc = []
|
81
69
|
CHECKPARAMS.each { |check|
|
82
70
|
if state = obj.state(check)
|
83
71
|
unless state.is
|
84
|
-
mount.
|
72
|
+
mount.debug "Manually retrieving info for %s" % check
|
85
73
|
state.retrieve
|
86
74
|
end
|
87
75
|
desc << state.is
|
@@ -148,14 +136,14 @@ class Server
|
|
148
136
|
end
|
149
137
|
|
150
138
|
# List a specific directory's contents.
|
151
|
-
def list(dir, recurse = false, ignore = false, client = nil, clientip = nil)
|
139
|
+
def list(dir, links = :ignore, recurse = false, ignore = false, client = nil, clientip = nil)
|
152
140
|
readconfig
|
153
141
|
mount, path = splitpath(dir)
|
154
142
|
|
155
143
|
authcheck(dir, mount, client, clientip)
|
156
144
|
|
157
145
|
if client
|
158
|
-
|
146
|
+
mount.debug "Listing %s for %s" % [dir, client]
|
159
147
|
end
|
160
148
|
|
161
149
|
subdir = nil
|
@@ -199,7 +187,7 @@ class Server
|
|
199
187
|
if FileTest.directory?(path)
|
200
188
|
if FileTest.readable?(path)
|
201
189
|
@mounts[name] = Mount.new(name, path)
|
202
|
-
@mounts[name].info "Mounted"
|
190
|
+
@mounts[name].info "Mounted %s" % path
|
203
191
|
else
|
204
192
|
raise FileServerError, "%s is not readable" % path
|
205
193
|
end
|
@@ -311,14 +299,15 @@ class Server
|
|
311
299
|
|
312
300
|
# Retrieve a file from the local disk and pass it to the remote
|
313
301
|
# client.
|
314
|
-
def retrieve(file, client = nil, clientip = nil)
|
302
|
+
def retrieve(file, links = :ignore, client = nil, clientip = nil)
|
315
303
|
readconfig
|
304
|
+
links = links.intern if links.is_a? String
|
316
305
|
mount, path = splitpath(file)
|
317
306
|
|
318
307
|
authcheck(file, mount, client, clientip)
|
319
308
|
|
320
309
|
if client
|
321
|
-
|
310
|
+
mount.info "Sending %s to %s" % [file, client]
|
322
311
|
end
|
323
312
|
|
324
313
|
fpath = nil
|
@@ -332,7 +321,18 @@ class Server
|
|
332
321
|
return ""
|
333
322
|
end
|
334
323
|
|
335
|
-
|
324
|
+
links = links.intern if links.is_a? String
|
325
|
+
|
326
|
+
if links == :ignore and FileTest.symlink?(fpath)
|
327
|
+
return ""
|
328
|
+
end
|
329
|
+
|
330
|
+
str = nil
|
331
|
+
if links == :manage
|
332
|
+
raise Puppet::Error, "Cannot copy links yet."
|
333
|
+
else
|
334
|
+
str = File.read(fpath)
|
335
|
+
end
|
336
336
|
|
337
337
|
if @local
|
338
338
|
return str
|
@@ -353,7 +353,8 @@ class Server
|
|
353
353
|
)
|
354
354
|
end
|
355
355
|
|
356
|
-
# Recursively list the directory.
|
356
|
+
# Recursively list the directory. FIXME This should be using
|
357
|
+
# puppet objects, not directly listing.
|
357
358
|
def reclist(mount, root, path, recurse, ignore)
|
358
359
|
# Take out the root of the path.
|
359
360
|
name = path.sub(root, '')
|
@@ -441,6 +442,10 @@ class Server
|
|
441
442
|
dirname
|
442
443
|
end
|
443
444
|
|
445
|
+
def to_s
|
446
|
+
"fileserver"
|
447
|
+
end
|
448
|
+
|
444
449
|
# A simple class for wrapping mount points. Instances of this class
|
445
450
|
# don't know about the enclosing object; they're mainly just used for
|
446
451
|
# authorization.
|
@@ -449,6 +454,31 @@ class Server
|
|
449
454
|
|
450
455
|
Puppet::Util.logmethods(self, true)
|
451
456
|
|
457
|
+
# Run 'retrieve' on a file. This gets the actual parameters, so
|
458
|
+
# we can pass them to the client.
|
459
|
+
def check(dir, links)
|
460
|
+
unless FileTest.exists?(dir)
|
461
|
+
self.notice "File source %s does not exist" % dir
|
462
|
+
return nil
|
463
|
+
end
|
464
|
+
|
465
|
+
obj = fileobj(dir, links)
|
466
|
+
|
467
|
+
# FIXME we should really have a timeout here -- we don't
|
468
|
+
# want to actually check on every connection, maybe no more
|
469
|
+
# than every 60 seconds or something. It'd be nice if we
|
470
|
+
# could use the builtin scheduling to do this.
|
471
|
+
|
472
|
+
# Retrieval is enough here, because we don't want to cache
|
473
|
+
# any information in the state file, and we don't want to generate
|
474
|
+
# any state changes or anything. We don't even need to sync
|
475
|
+
# the checksum, because we're always going to hit the disk
|
476
|
+
# directly.
|
477
|
+
obj.retrieve
|
478
|
+
|
479
|
+
return obj
|
480
|
+
end
|
481
|
+
|
452
482
|
# Create out orbject. It must have a name.
|
453
483
|
def initialize(name, path = nil)
|
454
484
|
unless name =~ %r{^\w+$}
|
@@ -462,9 +492,44 @@ class Server
|
|
462
492
|
@path = nil
|
463
493
|
end
|
464
494
|
|
495
|
+
@comp = Puppet.type(:component).create(
|
496
|
+
:name => "mount[#{name}]"
|
497
|
+
)
|
498
|
+
#@comp.type = "mount"
|
499
|
+
#@comp.name = name
|
500
|
+
|
465
501
|
super()
|
466
502
|
end
|
467
503
|
|
504
|
+
def fileobj(path, links)
|
505
|
+
obj = nil
|
506
|
+
if obj = Puppet.type(:file)[path]
|
507
|
+
# This can only happen in local fileserving, but it's an
|
508
|
+
# important one. It'd be nice if we didn't just set
|
509
|
+
# the check params every time, but I'm not sure it's worth
|
510
|
+
# the effort.
|
511
|
+
obj[:check] = CHECKPARAMS
|
512
|
+
else
|
513
|
+
obj = Puppet.type(:file).create(
|
514
|
+
:name => path,
|
515
|
+
:check => CHECKPARAMS
|
516
|
+
)
|
517
|
+
|
518
|
+
@comp.push(obj)
|
519
|
+
end
|
520
|
+
|
521
|
+
if links == :manage
|
522
|
+
links = :follow
|
523
|
+
end
|
524
|
+
|
525
|
+
# This, ah, might be completely redundant
|
526
|
+
unless obj[:links] == links
|
527
|
+
obj[:links] = links
|
528
|
+
end
|
529
|
+
|
530
|
+
return obj
|
531
|
+
end
|
532
|
+
|
468
533
|
# Set the path.
|
469
534
|
def path=(path)
|
470
535
|
unless FileTest.exists?(path)
|
@@ -474,11 +539,15 @@ class Server
|
|
474
539
|
end
|
475
540
|
|
476
541
|
def to_s
|
477
|
-
if @path
|
478
|
-
|
479
|
-
else
|
480
|
-
|
481
|
-
end
|
542
|
+
#if @path
|
543
|
+
# "mount[#{@name}]" + ":" + @path
|
544
|
+
#else
|
545
|
+
# "mount[#{@name}]"
|
546
|
+
#end
|
547
|
+
"mount[#{@name}]"
|
548
|
+
end
|
549
|
+
|
550
|
+
def type?(file)
|
482
551
|
end
|
483
552
|
|
484
553
|
# Verify our configuration is valid. This should really check to
|
@@ -493,4 +562,4 @@ class Server
|
|
493
562
|
end
|
494
563
|
end
|
495
564
|
|
496
|
-
# $Id: fileserver.rb
|
565
|
+
# $Id: fileserver.rb 989 2006-03-06 21:19:34Z luke $
|