puppet 2.7.9 → 2.7.11
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 +413 -0
- data/README_DEVELOPER.md +28 -0
- data/conf/redhat/puppet.spec +10 -1
- data/conf/solaris/pkginfo +1 -1
- data/conf/suse/puppet.spec +7 -4
- data/ext/envpuppet.bat +13 -0
- data/ext/rack/files/apache2.conf +4 -0
- data/install.rb +4 -8
- data/lib/puppet.rb +1 -1
- data/lib/puppet/agent.rb +7 -0
- data/lib/puppet/agent/disabler.rb +27 -0
- data/lib/puppet/agent/locker.rb +0 -10
- data/lib/puppet/application.rb +3 -0
- data/lib/puppet/application/agent.rb +13 -3
- data/lib/puppet/application/apply.rb +6 -6
- data/lib/puppet/application/cert.rb +5 -5
- data/lib/puppet/application/instrumentation_data.rb +4 -0
- data/lib/puppet/application/instrumentation_listener.rb +4 -0
- data/lib/puppet/application/instrumentation_probe.rb +4 -0
- data/lib/puppet/configurer.rb +3 -1
- data/lib/puppet/configurer/downloader.rb +4 -2
- data/lib/puppet/configurer/fact_handler.rb +0 -21
- data/lib/puppet/daemon.rb +3 -4
- data/lib/puppet/defaults.rb +2 -2
- data/lib/puppet/face/instrumentation_data.rb +28 -0
- data/lib/puppet/face/instrumentation_listener.rb +96 -0
- data/lib/puppet/face/instrumentation_probe.rb +77 -0
- data/lib/puppet/face/module/list.rb +64 -0
- data/lib/puppet/face/module/uninstall.rb +50 -0
- data/lib/puppet/face/node/clean.rb +1 -4
- data/lib/puppet/feature/base.rb +1 -0
- data/lib/puppet/file_serving/content.rb +1 -1
- data/lib/puppet/indirector/facts/facter.rb +20 -7
- data/lib/puppet/indirector/facts/inventory_active_record.rb +14 -11
- data/lib/puppet/indirector/indirection.rb +7 -0
- data/lib/puppet/indirector/instrumentation_data.rb +3 -0
- data/lib/puppet/indirector/instrumentation_data/local.rb +19 -0
- data/lib/puppet/indirector/instrumentation_data/rest.rb +5 -0
- data/lib/puppet/indirector/instrumentation_listener.rb +3 -0
- data/lib/puppet/indirector/instrumentation_listener/local.rb +23 -0
- data/lib/puppet/indirector/instrumentation_listener/rest.rb +5 -0
- data/lib/puppet/indirector/instrumentation_probe.rb +3 -0
- data/lib/puppet/indirector/instrumentation_probe/local.rb +24 -0
- data/lib/puppet/indirector/instrumentation_probe/rest.rb +5 -0
- data/lib/puppet/indirector/rest.rb +1 -1
- data/lib/puppet/module.rb +13 -17
- data/lib/puppet/module_tool/applications.rb +1 -0
- data/lib/puppet/module_tool/applications/uninstaller.rb +33 -0
- data/lib/puppet/module_tool/contents_description.rb +1 -1
- data/lib/puppet/network/server.rb +2 -3
- data/lib/puppet/node/environment.rb +16 -3
- data/lib/puppet/parser/ast/leaf.rb +1 -1
- data/lib/puppet/parser/functions/create_resources.rb +1 -1
- data/lib/puppet/parser/type_loader.rb +1 -1
- data/lib/puppet/property.rb +46 -14
- data/lib/puppet/provider.rb +13 -4
- data/lib/puppet/provider/augeas/augeas.rb +6 -4
- data/lib/puppet/provider/group/pw.rb +24 -10
- data/lib/puppet/provider/nameservice/directoryservice.rb +146 -37
- data/lib/puppet/provider/package/pip.rb +1 -1
- data/lib/puppet/provider/package/yum.rb +1 -2
- data/lib/puppet/provider/service/debian.rb +14 -0
- data/lib/puppet/provider/service/launchd.rb +1 -1
- data/lib/puppet/provider/service/smf.rb +2 -2
- data/lib/puppet/provider/user/pw.rb +56 -2
- data/lib/puppet/provider/user/user_role_add.rb +32 -22
- data/lib/puppet/provider/user/windows_adsi.rb +1 -0
- data/lib/puppet/rails/benchmark.rb +1 -1
- data/lib/puppet/reports/store.rb +8 -1
- data/lib/puppet/resource/catalog.rb +5 -1
- data/lib/puppet/simple_graph.rb +11 -14
- data/lib/puppet/transaction.rb +10 -4
- data/lib/puppet/transaction/report.rb +9 -3
- data/lib/puppet/type.rb +19 -7
- data/lib/puppet/type/exec.rb +1 -1
- data/lib/puppet/type/file.rb +4 -1
- data/lib/puppet/type/file/ensure.rb +5 -1
- data/lib/puppet/type/file/mode.rb +45 -10
- data/lib/puppet/type/file/source.rb +4 -0
- data/lib/puppet/type/host.rb +17 -3
- data/lib/puppet/type/k5login.rb +3 -2
- data/lib/puppet/type/schedule.rb +3 -2
- data/lib/puppet/util.rb +83 -27
- data/lib/puppet/util/anonymous_filelock.rb +36 -0
- data/lib/puppet/util/docs.rb +18 -2
- data/lib/puppet/util/instrumentation.rb +173 -0
- data/lib/puppet/util/instrumentation/data.rb +34 -0
- data/lib/puppet/util/instrumentation/indirection_probe.rb +29 -0
- data/lib/puppet/util/instrumentation/instrumentable.rb +143 -0
- data/lib/puppet/util/instrumentation/listener.rb +60 -0
- data/lib/puppet/util/instrumentation/listeners/log.rb +29 -0
- data/lib/puppet/util/instrumentation/listeners/performance.rb +30 -0
- data/lib/puppet/util/monkey_patches.rb +8 -0
- data/lib/puppet/util/pidlock.rb +21 -25
- data/lib/puppet/util/rdoc/parser.rb +2 -2
- data/lib/puppet/util/reference.rb +8 -23
- data/lib/puppet/util/retryaction.rb +48 -0
- data/lib/puppet/util/suidmanager.rb +70 -39
- data/lib/puppet/util/symbolic_file_mode.rb +140 -0
- data/spec/integration/configurer_spec.rb +5 -0
- data/spec/integration/indirector/direct_file_server_spec.rb +1 -1
- data/spec/integration/indirector/file_content/file_server_spec.rb +7 -7
- data/spec/integration/provider/package_spec.rb +7 -0
- data/spec/unit/agent/disabler_spec.rb +60 -0
- data/spec/unit/agent/locker_spec.rb +0 -12
- data/spec/unit/agent_spec.rb +8 -0
- data/spec/unit/application/agent_spec.rb +38 -1
- data/spec/unit/application/apply_spec.rb +34 -40
- data/spec/unit/application/cert_spec.rb +1 -1
- data/spec/unit/application_spec.rb +6 -0
- data/spec/unit/configurer/downloader_spec.rb +29 -10
- data/spec/unit/configurer/fact_handler_spec.rb +5 -29
- data/spec/unit/configurer_spec.rb +8 -8
- data/spec/unit/daemon_spec.rb +12 -26
- data/spec/unit/face/instrumentation_data.rb +7 -0
- data/spec/unit/face/instrumentation_listener.rb +38 -0
- data/spec/unit/face/instrumentation_probe.rb +21 -0
- data/spec/unit/face/node_spec.rb +111 -111
- data/spec/unit/file_serving/content_spec.rb +2 -2
- data/spec/unit/indirector/facts/facter_spec.rb +25 -3
- data/spec/unit/indirector/facts/inventory_active_record_spec.rb +14 -4
- data/spec/unit/indirector/instrumentation_data/local_spec.rb +52 -0
- data/spec/unit/indirector/instrumentation_data/rest_spec.rb +11 -0
- data/spec/unit/indirector/instrumentation_listener/local_spec.rb +65 -0
- data/spec/unit/indirector/instrumentation_listener/rest_spec.rb +11 -0
- data/spec/unit/indirector/instrumentation_probe/local_spec.rb +65 -0
- data/spec/unit/indirector/instrumentation_probe/rest_spec.rb +11 -0
- data/spec/unit/module_spec.rb +39 -125
- data/spec/unit/module_tool/uninstaller_spec.rb +44 -0
- data/spec/unit/network/server_spec.rb +2 -20
- data/spec/unit/node/environment_spec.rb +76 -58
- data/spec/unit/parser/ast/asthash_spec.rb +1 -2
- data/spec/unit/parser/ast/leaf_spec.rb +16 -0
- data/spec/unit/property/keyvalue_spec.rb +5 -2
- data/spec/unit/property_spec.rb +260 -159
- data/spec/unit/provider/augeas/augeas_spec.rb +2 -2
- data/spec/unit/provider/group/pw_spec.rb +81 -0
- data/spec/unit/provider/nameservice/directoryservice_spec.rb +102 -0
- data/spec/unit/provider/package/pip_spec.rb +7 -0
- data/spec/unit/provider/package/yum_spec.rb +45 -1
- data/spec/unit/provider/service/debian_spec.rb +15 -0
- data/spec/unit/provider/service/launchd_spec.rb +48 -43
- data/spec/unit/provider/service/smf_spec.rb +3 -3
- data/spec/unit/provider/user/pw_spec.rb +183 -0
- data/spec/unit/provider/user/user_role_add_spec.rb +46 -39
- data/spec/unit/provider/user/windows_adsi_spec.rb +1 -0
- data/spec/unit/provider_spec.rb +32 -0
- data/spec/unit/reports/store_spec.rb +19 -1
- data/spec/unit/simple_graph_spec.rb +34 -19
- data/spec/unit/ssl/certificate_factory_spec.rb +3 -3
- data/spec/unit/transaction/report_spec.rb +29 -1
- data/spec/unit/transaction_spec.rb +32 -46
- data/spec/unit/type/file/mode_spec.rb +1 -1
- data/spec/unit/type/file/source_spec.rb +28 -3
- data/spec/unit/type/file_spec.rb +17 -16
- data/spec/unit/type/host_spec.rb +527 -0
- data/spec/unit/type/k5login_spec.rb +115 -0
- data/spec/unit/type/schedule_spec.rb +6 -6
- data/spec/unit/type_spec.rb +51 -0
- data/spec/unit/util/anonymous_filelock_spec.rb +78 -0
- data/spec/unit/util/execution_stub_spec.rb +2 -1
- data/spec/unit/util/instrumentation/data_spec.rb +44 -0
- data/spec/unit/util/instrumentation/indirection_probe_spec.rb +19 -0
- data/spec/unit/util/instrumentation/instrumentable_spec.rb +186 -0
- data/spec/unit/util/instrumentation/listener_spec.rb +100 -0
- data/spec/unit/util/instrumentation/listeners/log_spec.rb +34 -0
- data/spec/unit/util/instrumentation/listeners/performance_spec.rb +36 -0
- data/spec/unit/util/instrumentation_spec.rb +181 -0
- data/spec/unit/util/pidlock_spec.rb +208 -0
- data/spec/unit/util/rdoc/parser_spec.rb +1 -1
- data/spec/unit/util/reference_spec.rb +16 -6
- data/spec/unit/util/retryaction_spec.rb +62 -0
- data/spec/unit/util/suidmanager_spec.rb +101 -83
- data/spec/unit/util/symbolic_file_mode_spec.rb +182 -0
- data/spec/unit/util_spec.rb +126 -0
- data/tasks/rake/apple.rake +176 -0
- data/tasks/rake/templates/prototype.plist.erb +38 -0
- metadata +61 -13
- data/lib/puppet/application/module.rb +0 -3
- data/lib/puppet/face/module.rb +0 -12
- data/spec/unit/face/module/build_spec.rb +0 -30
- data/spec/unit/face/module/changes_spec.rb +0 -30
- data/spec/unit/face/module/clean_spec.rb +0 -30
- data/spec/unit/face/module/generate_spec.rb +0 -30
- data/spec/unit/face/module/install_spec.rb +0 -75
- data/spec/unit/face/module/search_spec.rb +0 -40
- data/test/util/pidlock.rb +0 -126
@@ -0,0 +1,48 @@
|
|
1
|
+
module Puppet::Util::RetryAction
|
2
|
+
class RetryException < Exception; end
|
3
|
+
class RetryException::NoBlockGiven < RetryException; end
|
4
|
+
class RetryException::NoRetriesGiven < RetryException;end
|
5
|
+
class RetryException::RetriesExceeded < RetryException; end
|
6
|
+
|
7
|
+
def self.retry_action( parameters = { :retry_exceptions => nil, :retries => nil } )
|
8
|
+
# Retry actions for a specified amount of time. This method will allow the final
|
9
|
+
# retry to complete even if that extends beyond the timeout period.
|
10
|
+
unless block_given?
|
11
|
+
raise RetryException::NoBlockGiven
|
12
|
+
end
|
13
|
+
|
14
|
+
raise RetryException::NoRetriesGiven if parameters[:retries].nil?
|
15
|
+
parameters[:retry_exceptions] ||= Hash.new
|
16
|
+
|
17
|
+
start = Time.now
|
18
|
+
failures = 0
|
19
|
+
|
20
|
+
begin
|
21
|
+
yield
|
22
|
+
rescue Exception => e
|
23
|
+
# If we were giving exceptions to catch,
|
24
|
+
# catch the excptions we care about and retry.
|
25
|
+
# All others fail hard
|
26
|
+
|
27
|
+
raise RetryException::RetriesExceeded if parameters[:retries] == 0
|
28
|
+
|
29
|
+
if (not parameters[:retry_exceptions].keys.empty?) and parameters[:retry_exceptions].keys.include?(e.class)
|
30
|
+
Puppet.info("Caught exception #{e.class}:#{e}")
|
31
|
+
Puppet.info(parameters[:retry_exceptions][e.class])
|
32
|
+
elsif (not parameters[:retry_exceptions].keys.empty?)
|
33
|
+
# If the exceptions is not in the list of retry_exceptions re-raise.
|
34
|
+
raise e
|
35
|
+
end
|
36
|
+
|
37
|
+
failures += 1
|
38
|
+
parameters[:retries] -= 1
|
39
|
+
|
40
|
+
# Increase the amount of time that we sleep after every
|
41
|
+
# failed retry attempt.
|
42
|
+
sleep (((2 ** failures) -1) * 0.1)
|
43
|
+
|
44
|
+
retry
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -1,11 +1,13 @@
|
|
1
1
|
require 'puppet/util/warnings'
|
2
2
|
require 'forwardable'
|
3
|
+
require 'etc'
|
3
4
|
|
4
5
|
module Puppet::Util::SUIDManager
|
5
6
|
include Puppet::Util::Warnings
|
6
7
|
extend Forwardable
|
7
8
|
|
8
|
-
# Note groups= is handled specially due to a bug in OS X 10.6
|
9
|
+
# Note groups= is handled specially due to a bug in OS X 10.6, 10.7,
|
10
|
+
# and probably upcoming releases...
|
9
11
|
to_delegate_to_process = [ :euid=, :euid, :egid=, :egid, :uid=, :uid, :gid=, :gid, :groups ]
|
10
12
|
|
11
13
|
to_delegate_to_process.each do |method|
|
@@ -28,10 +30,25 @@ module Puppet::Util::SUIDManager
|
|
28
30
|
module_function :osx_maj_ver
|
29
31
|
|
30
32
|
def groups=(grouplist)
|
31
|
-
|
32
|
-
return true
|
33
|
-
else
|
33
|
+
begin
|
34
34
|
return Process.groups = grouplist
|
35
|
+
rescue Errno::EINVAL => e
|
36
|
+
#We catch Errno::EINVAL as some operating systems (OS X in particular) can
|
37
|
+
# cause troubles when using Process#groups= to change *this* user / process
|
38
|
+
# list of supplementary groups membership. This is done via Ruby's function
|
39
|
+
# "static VALUE proc_setgroups(VALUE obj, VALUE ary)" which is effectively
|
40
|
+
# a wrapper for "int setgroups(size_t size, const gid_t *list)" (part of SVr4
|
41
|
+
# and 4.3BSD but not in POSIX.1-2001) that fails and sets errno to EINVAL.
|
42
|
+
#
|
43
|
+
# This does not appear to be a problem with Ruby but rather an issue on the
|
44
|
+
# operating system side. Therefore we catch the exception and look whether
|
45
|
+
# we run under OS X or not -- if so, then we acknowledge the problem and
|
46
|
+
# re-throw the exception otherwise.
|
47
|
+
if osx_maj_ver and not osx_maj_ver.empty?
|
48
|
+
return true
|
49
|
+
else
|
50
|
+
raise e
|
51
|
+
end
|
35
52
|
end
|
36
53
|
end
|
37
54
|
module_function :groups=
|
@@ -53,55 +70,76 @@ module Puppet::Util::SUIDManager
|
|
53
70
|
group and group.members.index(Sys::Admin.get_login) != nil
|
54
71
|
end
|
55
72
|
|
56
|
-
#
|
73
|
+
# Methods to handle changing uid/gid of the running process. In general,
|
74
|
+
# these will noop or fail on Windows, and require root to change to anything
|
75
|
+
# but the current uid/gid (which is a noop).
|
76
|
+
|
77
|
+
# Runs block setting euid and egid if provided then restoring original ids.
|
78
|
+
# If running on Windows or without root, the block will be run with the
|
79
|
+
# current euid/egid.
|
57
80
|
def asuser(new_uid=nil, new_gid=nil)
|
58
|
-
return yield if Puppet.features.microsoft_windows?
|
81
|
+
return yield if Puppet.features.microsoft_windows?
|
82
|
+
return yield unless root?
|
83
|
+
return yield unless new_uid or new_gid
|
59
84
|
|
60
85
|
old_euid, old_egid = self.euid, self.egid
|
61
86
|
begin
|
62
|
-
|
63
|
-
change_user(new_uid) if new_uid
|
87
|
+
change_privileges(new_uid, new_gid, false)
|
64
88
|
|
65
89
|
yield
|
66
90
|
ensure
|
67
|
-
|
68
|
-
change_user(old_euid)
|
91
|
+
change_privileges(new_uid ? old_euid : nil, old_egid, false)
|
69
92
|
end
|
70
93
|
end
|
71
94
|
module_function :asuser
|
72
95
|
|
96
|
+
# If `permanently` is set, will permanently change the uid/gid of the
|
97
|
+
# process. If not, it will only set the euid/egid. If only uid is supplied,
|
98
|
+
# the primary group of the supplied gid will be used. If only gid is
|
99
|
+
# supplied, only gid will be changed. This method will fail if used on
|
100
|
+
# Windows.
|
101
|
+
def change_privileges(uid=nil, gid=nil, permanently=false)
|
102
|
+
return unless uid or gid
|
103
|
+
|
104
|
+
unless gid
|
105
|
+
uid = convert_xid(:uid, uid)
|
106
|
+
gid = Etc.getpwuid(uid).gid
|
107
|
+
end
|
108
|
+
|
109
|
+
change_group(gid, permanently)
|
110
|
+
change_user(uid, permanently) if uid
|
111
|
+
end
|
112
|
+
module_function :change_privileges
|
113
|
+
|
114
|
+
# Changes the egid of the process if `permanently` is not set, otherwise
|
115
|
+
# changes gid. This method will fail if used on Windows, or attempting to
|
116
|
+
# change to a different gid without root.
|
73
117
|
def change_group(group, permanently=false)
|
74
118
|
gid = convert_xid(:gid, group)
|
75
119
|
raise Puppet::Error, "No such group #{group}" unless gid
|
76
120
|
|
77
121
|
if permanently
|
78
|
-
|
79
|
-
Process::GID.change_privilege(gid)
|
80
|
-
rescue NotImplementedError
|
81
|
-
Process.egid = gid
|
82
|
-
Process.gid = gid
|
83
|
-
end
|
122
|
+
Process::GID.change_privilege(gid)
|
84
123
|
else
|
85
124
|
Process.egid = gid
|
86
125
|
end
|
87
126
|
end
|
88
127
|
module_function :change_group
|
89
128
|
|
129
|
+
# As change_group, but operates on uids. If changing user permanently,
|
130
|
+
# supplementary groups will be set the to default groups for the new uid.
|
90
131
|
def change_user(user, permanently=false)
|
91
132
|
uid = convert_xid(:uid, user)
|
92
133
|
raise Puppet::Error, "No such user #{user}" unless uid
|
93
134
|
|
94
135
|
if permanently
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
initgroups(uid)
|
100
|
-
Process.euid = uid
|
101
|
-
Process.uid = uid
|
102
|
-
end
|
136
|
+
# If changing uid, we must be root. So initgroups first here.
|
137
|
+
initgroups(uid)
|
138
|
+
|
139
|
+
Process::UID.change_privilege(uid)
|
103
140
|
else
|
104
|
-
#
|
141
|
+
# We must be root to initgroups, so initgroups before dropping euid if
|
142
|
+
# we're root, otherwise elevate euid before initgroups.
|
105
143
|
# change euid (to root) first.
|
106
144
|
if Process.euid == 0
|
107
145
|
initgroups(uid)
|
@@ -126,10 +164,13 @@ module Puppet::Util::SUIDManager
|
|
126
164
|
end
|
127
165
|
module_function :convert_xid
|
128
166
|
|
129
|
-
# Initialize
|
130
|
-
|
131
|
-
|
132
|
-
|
167
|
+
# Initialize primary and supplemental groups to those of the target user. We
|
168
|
+
# take the UID and manually look up their details in the system database,
|
169
|
+
# including username and primary group. This method will fail on Windows, or
|
170
|
+
# if used without root to initgroups of another user.
|
171
|
+
def initgroups(uid)
|
172
|
+
pwent = Etc.getpwuid(uid)
|
173
|
+
Process.initgroups(pwent.name, pwent.gid)
|
133
174
|
end
|
134
175
|
|
135
176
|
module_function :initgroups
|
@@ -139,14 +180,4 @@ module Puppet::Util::SUIDManager
|
|
139
180
|
[output, $CHILD_STATUS.dup]
|
140
181
|
end
|
141
182
|
module_function :run_and_capture
|
142
|
-
|
143
|
-
def system(command, new_uid=nil, new_gid=nil)
|
144
|
-
status = nil
|
145
|
-
asuser(new_uid, new_gid) do
|
146
|
-
Kernel.system(command)
|
147
|
-
status = $CHILD_STATUS.dup
|
148
|
-
end
|
149
|
-
status
|
150
|
-
end
|
151
|
-
module_function :system
|
152
183
|
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'puppet/util'
|
2
|
+
|
3
|
+
module Puppet::Util::SymbolicFileMode
|
4
|
+
SetUIDBit = ReadBit = 4
|
5
|
+
SetGIDBit = WriteBit = 2
|
6
|
+
StickyBit = ExecBit = 1
|
7
|
+
SymbolicMode = { 'x' => ExecBit, 'w' => WriteBit, 'r' => ReadBit }
|
8
|
+
SymbolicSpecialToBit = {
|
9
|
+
't' => { 'u' => StickyBit, 'g' => StickyBit, 'o' => StickyBit },
|
10
|
+
's' => { 'u' => SetUIDBit, 'g' => SetGIDBit, 'o' => StickyBit }
|
11
|
+
}
|
12
|
+
|
13
|
+
def valid_symbolic_mode?(value)
|
14
|
+
value = normalize_symbolic_mode(value)
|
15
|
+
return true if value =~ /^0?[0-7]{1,4}$/
|
16
|
+
return true if value =~ /^([ugoa]*[-=+][-=+rstwxXugo]*)(,[ugoa]*[-=+][-=+rstwxXugo]*)*$/
|
17
|
+
return false
|
18
|
+
end
|
19
|
+
|
20
|
+
def normalize_symbolic_mode(value)
|
21
|
+
return nil if value.nil?
|
22
|
+
|
23
|
+
# We need to treat integers as octal numbers.
|
24
|
+
if value.is_a? Numeric then
|
25
|
+
return value.to_s(8)
|
26
|
+
elsif value =~ /^0?[0-7]{1,4}$/ then
|
27
|
+
return value.to_i(8).to_s(8)
|
28
|
+
else
|
29
|
+
return value
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def symbolic_mode_to_int(modification, to_mode = 0, is_a_directory = false)
|
34
|
+
if modification.nil? or modification == '' then
|
35
|
+
raise Puppet::Error, "An empty mode string is illegal"
|
36
|
+
end
|
37
|
+
if modification =~ /^[0-7]+$/ then return modification.to_i(8) end
|
38
|
+
if modification =~ /^\d+$/ then
|
39
|
+
raise Puppet::Error, "Numeric modes must be in octal, not decimal!"
|
40
|
+
end
|
41
|
+
|
42
|
+
fail "non-numeric current mode (#{to_mode.inspect})" unless to_mode.is_a?(Numeric)
|
43
|
+
|
44
|
+
original_mode = {
|
45
|
+
's' => (to_mode & 07000) >> 9,
|
46
|
+
'u' => (to_mode & 00700) >> 6,
|
47
|
+
'g' => (to_mode & 00070) >> 3,
|
48
|
+
'o' => (to_mode & 00007) >> 0,
|
49
|
+
# Are there any execute bits set in the original mode?
|
50
|
+
'any x?' => (to_mode & 00111) != 0
|
51
|
+
}
|
52
|
+
final_mode = {
|
53
|
+
's' => original_mode['s'],
|
54
|
+
'u' => original_mode['u'],
|
55
|
+
'g' => original_mode['g'],
|
56
|
+
'o' => original_mode['o'],
|
57
|
+
}
|
58
|
+
|
59
|
+
modification.split(/\s*,\s*/).each do |part|
|
60
|
+
begin
|
61
|
+
_, to, dsl = /^([ugoa]*)([-+=].*)$/.match(part).to_a
|
62
|
+
if dsl.nil? then raise Puppet::Error, 'Missing action' end
|
63
|
+
to = "a" unless to and to.length > 0
|
64
|
+
|
65
|
+
# We want a snapshot of the mode before we start messing with it to
|
66
|
+
# make actions like 'a-g' atomic. Various parts of the DSL refer to
|
67
|
+
# the original mode, the final mode, or the current snapshot of the
|
68
|
+
# mode, for added fun.
|
69
|
+
snapshot_mode = {}
|
70
|
+
final_mode.each {|k,v| snapshot_mode[k] = v }
|
71
|
+
|
72
|
+
to.gsub('a', 'ugo').split('').uniq.each do |who|
|
73
|
+
value = snapshot_mode[who]
|
74
|
+
|
75
|
+
action = '!'
|
76
|
+
actions = {
|
77
|
+
'!' => lambda {|_,_| raise Puppet::Error, 'Missing operation (-, =, or +)' },
|
78
|
+
'=' => lambda {|m,v| m | v },
|
79
|
+
'+' => lambda {|m,v| m | v },
|
80
|
+
'-' => lambda {|m,v| m & ~v },
|
81
|
+
}
|
82
|
+
|
83
|
+
dsl.split('').each do |op|
|
84
|
+
case op
|
85
|
+
when /[-+=]/ then
|
86
|
+
action = op
|
87
|
+
# Clear all bits, if this is assignment
|
88
|
+
value = 0 if op == '='
|
89
|
+
|
90
|
+
when /[ugo]/ then
|
91
|
+
value = actions[action].call(value, snapshot_mode[op])
|
92
|
+
|
93
|
+
when /[rwx]/ then
|
94
|
+
value = actions[action].call(value, SymbolicMode[op])
|
95
|
+
|
96
|
+
when 'X' then
|
97
|
+
# Only meaningful in combination with "set" actions.
|
98
|
+
if action != '+' then
|
99
|
+
raise Puppet::Error, "X only works with the '+' operator"
|
100
|
+
end
|
101
|
+
|
102
|
+
# As per the BSD manual page, set if this is a directory, or if
|
103
|
+
# any execute bit is set on the original (unmodified) mode.
|
104
|
+
# Ignored otherwise; it is "add if", not "add or clear".
|
105
|
+
if is_a_directory or original_mode['any x?'] then
|
106
|
+
value = actions[action].call(value, ExecBit)
|
107
|
+
end
|
108
|
+
|
109
|
+
when /[st]/ then
|
110
|
+
bit = SymbolicSpecialToBit[op][who] or fail "internal error"
|
111
|
+
final_mode['s'] = actions[action].call(final_mode['s'], bit)
|
112
|
+
|
113
|
+
else
|
114
|
+
raise Puppet::Error, 'Unknown operation'
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Now, assign back the value.
|
119
|
+
final_mode[who] = value
|
120
|
+
end
|
121
|
+
|
122
|
+
rescue Puppet::Error => e
|
123
|
+
if part.inspect != modification.inspect then
|
124
|
+
rest = " at #{part.inspect}"
|
125
|
+
else
|
126
|
+
rest = ''
|
127
|
+
end
|
128
|
+
|
129
|
+
raise Puppet::Error, "#{e}#{rest} in symbolic mode #{modification.inspect}"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
result =
|
134
|
+
final_mode['s'] << 9 |
|
135
|
+
final_mode['u'] << 6 |
|
136
|
+
final_mode['g'] << 3 |
|
137
|
+
final_mode['o'] << 0
|
138
|
+
return result
|
139
|
+
end
|
140
|
+
end
|
@@ -47,6 +47,7 @@ describe Puppet::Configurer do
|
|
47
47
|
Puppet::Transaction::Report.indirection.stubs(:save)
|
48
48
|
|
49
49
|
Puppet[:lastrunfile] = tmpfile("lastrunfile")
|
50
|
+
Puppet.settings.setting(:lastrunfile).mode = 0666
|
50
51
|
Puppet[:report] = true
|
51
52
|
|
52
53
|
# We only record integer seconds in the timestamp, and truncate
|
@@ -56,6 +57,10 @@ describe Puppet::Configurer do
|
|
56
57
|
@configurer.run :catalog => @catalog, :report => report
|
57
58
|
t2 = Time.now.tv_sec
|
58
59
|
|
60
|
+
file_mode = Puppet.features.microsoft_windows? ? '100644' : '100666'
|
61
|
+
|
62
|
+
File.stat(Puppet[:lastrunfile]).mode.to_s(8).should == file_mode
|
63
|
+
|
59
64
|
summary = nil
|
60
65
|
File.open(Puppet[:lastrunfile], "r") do |fd|
|
61
66
|
summary = YAML.load(fd.read)
|
@@ -22,7 +22,7 @@ describe Puppet::Indirector::DirectFileServer, " when interacting with the files
|
|
22
22
|
it "should return an instance capable of returning its content" do
|
23
23
|
FileTest.expects(:exists?).with(@filepath).returns(true)
|
24
24
|
File.stubs(:lstat).with(@filepath).returns(stub("stat", :ftype => "file"))
|
25
|
-
|
25
|
+
Puppet::Util.expects(:binread).with(@filepath).returns("my content")
|
26
26
|
|
27
27
|
instance = @terminus.find(@terminus.indirection.request(:find, "file://host#{@filepath}"))
|
28
28
|
|
@@ -24,7 +24,7 @@ describe Puppet::Indirector::FileContent::FileServer, " when finding files" do
|
|
24
24
|
modpath = File.join(path, "mod")
|
25
25
|
FileUtils.mkdir_p(File.join(modpath, "lib"))
|
26
26
|
file = File.join(modpath, "lib", "file.rb")
|
27
|
-
File.open(file, "
|
27
|
+
File.open(file, "wb") { |f| f.write "1\r\n" }
|
28
28
|
|
29
29
|
Puppet.settings[:modulepath] = "/no/such/file"
|
30
30
|
|
@@ -35,8 +35,8 @@ describe Puppet::Indirector::FileContent::FileServer, " when finding files" do
|
|
35
35
|
|
36
36
|
result.should_not be_nil
|
37
37
|
result.length.should == 2
|
38
|
-
result
|
39
|
-
result
|
38
|
+
result.map {|x| x.should be_instance_of(Puppet::FileServing::Content) }
|
39
|
+
result.find {|x| x.relative_path == 'file.rb' }.content.should == "1\r\n"
|
40
40
|
end
|
41
41
|
|
42
42
|
it "should find file content in modules" do
|
@@ -47,7 +47,7 @@ describe Puppet::Indirector::FileContent::FileServer, " when finding files" do
|
|
47
47
|
modpath = File.join(path, "mymod")
|
48
48
|
FileUtils.mkdir_p(File.join(modpath, "files"))
|
49
49
|
file = File.join(modpath, "files", "myfile")
|
50
|
-
File.open(file, "
|
50
|
+
File.open(file, "wb") { |f| f.write "1\r\n" }
|
51
51
|
|
52
52
|
Puppet.settings[:modulepath] = path
|
53
53
|
|
@@ -55,7 +55,7 @@ describe Puppet::Indirector::FileContent::FileServer, " when finding files" do
|
|
55
55
|
|
56
56
|
result.should_not be_nil
|
57
57
|
result.should be_instance_of(Puppet::FileServing::Content)
|
58
|
-
result.content.should == "1\n"
|
58
|
+
result.content.should == "1\r\n"
|
59
59
|
end
|
60
60
|
|
61
61
|
it "should find file content in files when node name expansions are used" do
|
@@ -67,7 +67,7 @@ describe Puppet::Indirector::FileContent::FileServer, " when finding files" do
|
|
67
67
|
Dir.mkdir(@path)
|
68
68
|
subdir = File.join(@path, "mynode")
|
69
69
|
Dir.mkdir(subdir)
|
70
|
-
File.open(File.join(subdir, "myfile"), "
|
70
|
+
File.open(File.join(subdir, "myfile"), "wb") { |f| f.write "1\r\n" }
|
71
71
|
|
72
72
|
# Use a real mount, so the integration is a bit deeper.
|
73
73
|
@mount1 = Puppet::FileServing::Configuration::Mount::File.new("one")
|
@@ -85,6 +85,6 @@ describe Puppet::Indirector::FileContent::FileServer, " when finding files" do
|
|
85
85
|
|
86
86
|
result.should_not be_nil
|
87
87
|
result.should be_instance_of(Puppet::FileServing::Content)
|
88
|
-
result.content.should == "1\n"
|
88
|
+
result.content.should == "1\r\n"
|
89
89
|
end
|
90
90
|
end
|
@@ -27,6 +27,13 @@ describe "Package provider", :'fails_on_ruby_1.9.2' => true do
|
|
27
27
|
Puppet[:vardir] = tmpdir('msi_package_var_dir')
|
28
28
|
end
|
29
29
|
|
30
|
+
# the instances method requires root priviledges on gentoo
|
31
|
+
# if the eix cache is outdated (to run eix-update) so make
|
32
|
+
# sure we dont actually run eix-update
|
33
|
+
if provider.name == :portage
|
34
|
+
provider.stubs(:update_eix).returns('Database contains 15240 packages in 155 categories')
|
35
|
+
end
|
36
|
+
|
30
37
|
provider.instances.each do |package|
|
31
38
|
package.should be_instance_of(provider)
|
32
39
|
package.properties[:provider].should == provider.name
|