plist4r 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/.nojekyll +0 -0
- data/.yardopts +1 -0
- data/README.rdoc +18 -23
- data/Rakefile +16 -7
- data/VERSION +1 -1
- data/bin/plist4r +8 -0
- data/lib/plist4r.rb +35 -7
- data/lib/plist4r/application.rb +19 -0
- data/lib/plist4r/backend.rb +23 -2
- data/lib/plist4r/backend/example.rb +45 -4
- data/lib/plist4r/backend/haml.rb +1 -0
- data/lib/plist4r/backend/libxml4r.rb +3 -2
- data/lib/plist4r/backend/plutil.rb +4 -1
- data/lib/plist4r/backend/ruby_cocoa.rb +10 -3
- data/lib/plist4r/commands.rb +61 -0
- data/lib/plist4r/config.rb +21 -1
- data/lib/plist4r/mixin/data_methods.rb +23 -3
- data/lib/plist4r/mixin/mixlib_cli.rb +199 -0
- data/lib/plist4r/mixin/mixlib_config.rb +158 -152
- data/lib/plist4r/mixin/ordered_hash.rb +143 -135
- data/lib/plist4r/mixin/popen4.rb +25 -5
- data/lib/plist4r/mixin/ruby_stdlib.rb +13 -1
- data/lib/plist4r/options.rb +44 -0
- data/lib/plist4r/plist.rb +156 -13
- data/lib/plist4r/plist_type.rb +25 -4
- data/lib/plist4r/plist_type/launchd.rb +377 -263
- data/plist4r.gemspec +56 -48
- data/test.rb +2 -2
- metadata +13 -7
- data/lib/plist4r/mixin/class_attributes.rb +0 -128
data/lib/plist4r/plist_type.rb
CHANGED
@@ -12,12 +12,12 @@ module Plist4r
|
|
12
12
|
|
13
13
|
def hash hash=nil
|
14
14
|
case hash
|
15
|
-
when ::
|
15
|
+
when ::Plist4r::OrderedHash
|
16
16
|
@hash = @orig = hash
|
17
17
|
when nil
|
18
18
|
@hash
|
19
19
|
else
|
20
|
-
raise "Must hash be an ::
|
20
|
+
raise "Must hash be an ::Plist4r::OrderedHash"
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
@@ -25,6 +25,27 @@ module Plist4r
|
|
25
25
|
raise "Method not implemented #{method_name.to_sym.inspect}, for class #{self.inspect}"
|
26
26
|
end
|
27
27
|
|
28
|
+
# A Hash Array of the supported plist keys for this type. These are only those plist keys
|
29
|
+
# recognized as belonging to a specific plist datatype. Used in validation, part of DataMethods.
|
30
|
+
# We usually overload this method in subclasses of {Plist4r::PlistType}.
|
31
|
+
# @example
|
32
|
+
# class Plist4r::PlistType::MyPlistType < PlistType
|
33
|
+
# def self.valid_keys
|
34
|
+
# {
|
35
|
+
# :string => %w[PlistKeyS1 PlistKeyS2 ...],
|
36
|
+
# :bool => %w[PlistKeyB1 PlistKeyB2 ...],
|
37
|
+
# :integer => %w[PlistKeyI1 PlistKeyI2 ...],
|
38
|
+
# :method_defined => %w[CustomPlistKey1 CustomPlistKey2 ...]
|
39
|
+
# }
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# plist.plist_type :my_plist_type
|
44
|
+
# plist.plist_key_s1 "some string"
|
45
|
+
# plist.plist_key_b1 true
|
46
|
+
# plist.plist_key_i1 08
|
47
|
+
# plist.custom_plist_key1 MyClass.new(opts)
|
48
|
+
#
|
28
49
|
def valid_keys
|
29
50
|
self.class.valid_keys
|
30
51
|
end
|
@@ -60,7 +81,7 @@ module Plist4r
|
|
60
81
|
# puts "@enclosing_block = #{@enclosing_block}"
|
61
82
|
|
62
83
|
@block = blk
|
63
|
-
@hash = ::
|
84
|
+
@hash = ::Plist4r::OrderedHash.new
|
64
85
|
# puts "@hash = #{@hash}"
|
65
86
|
|
66
87
|
instance_eval(&@block) if @block
|
@@ -84,7 +105,7 @@ module Plist4r
|
|
84
105
|
end
|
85
106
|
|
86
107
|
def unselect_all
|
87
|
-
@hash = ::
|
108
|
+
@hash = ::Plist4r::OrderedHash.new
|
88
109
|
end
|
89
110
|
|
90
111
|
def select_all
|
@@ -4,6 +4,9 @@ require 'plist4r/plist_type'
|
|
4
4
|
module Plist4r
|
5
5
|
class PlistType::Launchd < PlistType
|
6
6
|
|
7
|
+
# A Hash Array of the supported plist keys for this type. These are the plist keys are recognized to belong to a Launchd plist.
|
8
|
+
# Used in validation, categorized by the value's DataType.
|
9
|
+
# @see Plist4r::DataMethods
|
7
10
|
def self.valid_keys
|
8
11
|
{
|
9
12
|
:string => %w[Label UserName GroupName LimitLoadToSessionType Program RootDirectory WorkingDirectory StandardInPath StandardOutPath StandardErrorPath],
|
@@ -14,16 +17,21 @@ module Plist4r
|
|
14
17
|
}
|
15
18
|
end
|
16
19
|
|
17
|
-
#
|
18
|
-
#
|
19
|
-
# inetdCompatibility -> hash or nil
|
20
|
-
#
|
21
|
-
# inetd_compatibility <hash>
|
20
|
+
# Set or return the plist key "inetdCompatibility"
|
21
|
+
# @param [Hash <true,false>] value the
|
22
22
|
# The presence of this key specifies that the daemon expects to be run as if it were launched from inetd.
|
23
23
|
#
|
24
|
-
#
|
24
|
+
# @option value [true,false] :wait (nil)
|
25
25
|
# This flag corresponds to the "wait" or "nowait" option of inetd. If true, then the listening socket is passed via the standard in/out/error file descriptors.
|
26
26
|
# If false, then accept(2) is called on behalf of the job, and the result is passed via the standard in/out/error descriptors.
|
27
|
+
#
|
28
|
+
# @example
|
29
|
+
# # set inetdCompatibility
|
30
|
+
# launchd_plist.inetdCompatibility({:wait => true})
|
31
|
+
#
|
32
|
+
# # return inetdCompatibility
|
33
|
+
# launchd_plist.inetdCompatibility => hash or nil
|
34
|
+
#
|
27
35
|
def inetd_compatibility value=nil
|
28
36
|
key = "inetdCompatibility"
|
29
37
|
case value
|
@@ -39,7 +47,7 @@ module Plist4r
|
|
39
47
|
raise "Invalid value: #{method_name} #{value.inspect}. Should be: #{method_name} :wait => true|false"
|
40
48
|
end
|
41
49
|
end
|
42
|
-
|
50
|
+
|
43
51
|
class KeepAlive < ArrayDict
|
44
52
|
def valid_keys
|
45
53
|
{
|
@@ -49,47 +57,52 @@ module Plist4r
|
|
49
57
|
end
|
50
58
|
end
|
51
59
|
|
52
|
-
#
|
53
|
-
# keep_alive(true)
|
54
|
-
# keep_alive(false)
|
55
|
-
# keep_alive { block_of_keys }
|
56
|
-
# keep_alive => true, false, Hash, or nil
|
60
|
+
# Set or return the plist key "KeepAlive"
|
57
61
|
#
|
58
|
-
#
|
62
|
+
# @param [true, false, Hash] value
|
59
63
|
# This optional key is used to control whether your job is to be kept continuously running or to let demand and conditions control the invocation. The default is
|
60
64
|
# false and therefore only demand will start the job. The value may be set to true to unconditionally keep the job alive. Alternatively, a dictionary of conditions
|
61
65
|
# may be specified to selectively control whether launchd keeps a job alive or not. If multiple keys are provided, launchd ORs them, thus providing maximum flexibil-
|
62
66
|
# ity to the job to refine the logic and stall if necessary. If launchd finds no reason to restart the job, it falls back on demand based invocation. Jobs that exit
|
63
67
|
# quickly and frequently when configured to be kept alive will be throttled to converve system resources.
|
64
68
|
#
|
65
|
-
#
|
66
|
-
#
|
67
|
-
# successful_exit <boolean>
|
69
|
+
# @option value [true,false] :successful_exit (nil)
|
68
70
|
# If true, the job will be restarted as long as the program exits and with an exit status of zero. If false, the job will be restarted in the inverse condi-
|
69
71
|
# tion. This key implies that "RunAtLoad" is set to true, since the job needs to run at least once before we can get an exit status.
|
70
72
|
#
|
71
|
-
#
|
73
|
+
# @option value [true,false] :network_state (nil)
|
72
74
|
# If true, the job will be kept alive as long as the network is up, where up is defined as at least one non-loopback interface being up and having IPv4 or IPv6
|
73
75
|
# addresses assigned to them. If false, the job will be kept alive in the inverse condition.
|
74
76
|
#
|
77
|
+
# @option value [Hash <true,false>] :path_state (nil)
|
75
78
|
# path_state <hash of booleans>
|
76
79
|
# Each key in this dictionary is a file-system path. If the value of the key is true, then the job will be kept alive as long as the path exists. If false, the
|
77
80
|
# job will be kept alive in the inverse condition. The intent of this feature is that two or more jobs may create semaphores in the file-system namespace.
|
78
81
|
#
|
82
|
+
# @option value [Hash <true,false>] :other_job_enabled (nil)
|
79
83
|
# other_job_enabled <hash of booleans>
|
80
84
|
# Each key in this dictionary is the label of another job. If the value of the key is true, then this job is kept alive as long as that other job is enabled.
|
81
85
|
# Otherwise, if the value is false, then this job is kept alive as long as the other job is disabled. This feature should not be considered a substitute for
|
82
86
|
# the use of IPC.
|
83
87
|
#
|
84
|
-
#
|
88
|
+
# @example
|
89
|
+
# # set KeepAlive (boolean)
|
90
|
+
#
|
91
|
+
# launchd_plist.keep_alive(true)
|
92
|
+
# launchd_plist.keep_alive(false)
|
85
93
|
#
|
86
|
-
#
|
94
|
+
# # return KeepAlive
|
95
|
+
# launchd_plist.keep_alive => true, false, Hash, or nil
|
87
96
|
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
# network_state false
|
91
|
-
# end
|
97
|
+
# @example
|
98
|
+
# # set KeepAlive (hash of values)
|
92
99
|
#
|
100
|
+
# launchd_plist.keep_alive do
|
101
|
+
# successful_exit true
|
102
|
+
# network_state false
|
103
|
+
# path_state { "/path1" => true, "/path2" => false }
|
104
|
+
# other_job_enabled { "notifyd" => true, "syslogd" => true }
|
105
|
+
# end
|
93
106
|
def keep_alive value=nil, &blk
|
94
107
|
key = "KeepAlive"
|
95
108
|
|
@@ -98,7 +111,7 @@ module Plist4r
|
|
98
111
|
@hash[key] = value
|
99
112
|
when nil
|
100
113
|
if blk
|
101
|
-
@hash[key] ||= ::
|
114
|
+
@hash[key] ||= ::Plist4r::OrderedHash.new
|
102
115
|
@hash[key] = ::LaunchdPlistStructs::KeepAlive.new(@hash[key],&blk).hash
|
103
116
|
else
|
104
117
|
@hash[key]
|
@@ -108,11 +121,16 @@ module Plist4r
|
|
108
121
|
end
|
109
122
|
end
|
110
123
|
|
111
|
-
#
|
112
|
-
#
|
113
|
-
#
|
124
|
+
# Set or return the plist key "EnvironmentVariables"
|
125
|
+
#
|
126
|
+
# @example
|
127
|
+
# # Set environment variables
|
128
|
+
# launchd_plist.environment_variables({ "VAR1" => "VAL1", "VAR2" => "VAL2" })
|
114
129
|
#
|
115
|
-
#
|
130
|
+
# # Return environment variables
|
131
|
+
# launchd_plist.environment_variables => { "VAR1" => "VAL1", "VAR2" => "VAL2" }
|
132
|
+
#
|
133
|
+
# @param [Hash <String>] value
|
116
134
|
# This optional key is used to specify additional environmental variables to be set before running the job.
|
117
135
|
def environment_variables value=nil, &blk
|
118
136
|
key = "EnvironmentVariables"
|
@@ -140,47 +158,55 @@ module Plist4r
|
|
140
158
|
end
|
141
159
|
end
|
142
160
|
|
143
|
-
#
|
144
|
-
#
|
145
|
-
# start_calendar_interval -> array or nil
|
146
|
-
#
|
147
|
-
# start_calendar_interval <array_index=nil> <block of keys>
|
161
|
+
# Set or return the plist key "StartCalendarInterval"
|
162
|
+
#
|
148
163
|
# This optional key causes the job to be started every calendar interval as specified. Missing arguments are considered to be wildcard. The semantics are much like
|
149
164
|
# crontab(5). Unlike cron which skips job invocations when the computer is asleep, launchd will start the job the next time the computer wakes up. If multiple
|
150
165
|
# intervals transpire before the computer is woken, those events will be coalesced into one event upon wake from sleep.
|
166
|
+
#
|
167
|
+
# @example Reference
|
168
|
+
# start_calendar_interval index=nil do
|
169
|
+
# minute <integer>
|
170
|
+
# # The minute on which this job will be run.
|
171
|
+
#
|
172
|
+
# hour <integer>
|
173
|
+
# # The hour on which this job will be run.
|
174
|
+
#
|
175
|
+
# day <integer>
|
176
|
+
# # The day on which this job will be run.
|
177
|
+
#
|
178
|
+
# weekday <integer>
|
179
|
+
# # The weekday on which this job will be run (0 and 7 are Sunday).
|
180
|
+
#
|
181
|
+
# month <integer>
|
182
|
+
# # The month on which this job will be run.
|
183
|
+
# end
|
184
|
+
#
|
185
|
+
# @example Example
|
186
|
+
# # Set start calendar interval
|
151
187
|
#
|
152
|
-
#
|
153
|
-
#
|
154
|
-
#
|
155
|
-
#
|
156
|
-
#
|
157
|
-
#
|
158
|
-
#
|
159
|
-
#
|
160
|
-
#
|
161
|
-
#
|
162
|
-
#
|
163
|
-
# Weekday <integer>
|
164
|
-
# The weekday on which this job will be run (0 and 7 are Sunday).
|
165
|
-
#
|
166
|
-
# Month <integer>
|
167
|
-
# The month on which this job will be run.
|
168
|
-
#
|
169
|
-
# end
|
188
|
+
# launchd_plist.start_calendar_interval 0 do
|
189
|
+
# hour 02
|
190
|
+
# minute 05
|
191
|
+
# day 06
|
192
|
+
# end
|
193
|
+
#
|
194
|
+
# launchd_plist.start_calendar_interval 1 do
|
195
|
+
# hour 10
|
196
|
+
# minute 30
|
197
|
+
# end
|
170
198
|
#
|
171
|
-
#
|
199
|
+
# launchd_plist.start_calendar_interval do
|
200
|
+
# month 3
|
201
|
+
# end
|
172
202
|
#
|
173
|
-
#
|
174
|
-
#
|
175
|
-
#
|
176
|
-
# day 06
|
177
|
-
# end
|
203
|
+
# # Return start calendar interval
|
204
|
+
# launchd_plist.start_calendar_interval[1] => { "Hour" => 10, "Minute" => 30 }
|
205
|
+
# launchd_plist.start_calendar_interval.last => { "Month" => 3 }
|
178
206
|
#
|
179
|
-
#
|
180
|
-
#
|
181
|
-
#
|
182
|
-
# day 06
|
183
|
-
# end
|
207
|
+
# @param [Fixnum] index The array index for this calendar entry
|
208
|
+
# @param [Block] blk A block setting the specific start calendar intervals.
|
209
|
+
# Appends a new entry to the end of the array if no index specified.
|
184
210
|
#
|
185
211
|
def start_calendar_interval index=nil, &blk
|
186
212
|
key = "StartCalendarInterval"
|
@@ -206,118 +232,130 @@ module Plist4r
|
|
206
232
|
end
|
207
233
|
end
|
208
234
|
|
209
|
-
#
|
210
|
-
# soft_resource_limits { block_of_keys }
|
211
|
-
# soft_resource_limits -> hash or nil
|
212
|
-
#
|
213
|
-
# soft_resource_limits <block of keys>
|
214
|
-
# Resource limits to be imposed on the job. These adjust variables set with setrlimit(2). The following keys apply:
|
215
|
-
#
|
216
|
-
# soft_resource_limits do
|
217
|
-
#
|
218
|
-
# Core <integer>
|
219
|
-
# The largest size (in bytes) core file that may be created.
|
220
|
-
#
|
221
|
-
# CPU <integer>
|
222
|
-
# The maximum amount of cpu time (in seconds) to be used by each process.
|
235
|
+
# Set or return the plist key "SoftResourceLimits"
|
223
236
|
#
|
224
|
-
#
|
225
|
-
# The maximum size (in bytes) of the data segment for a process; this defines how far a program may extend its break with the sbrk(2) system call.
|
226
|
-
#
|
227
|
-
# FileSize <integer>
|
228
|
-
# The largest size (in bytes) file that may be created.
|
229
|
-
#
|
230
|
-
# MemoryLock <integer>
|
231
|
-
# The maximum size (in bytes) which a process may lock into memory using the mlock(2) function.
|
232
|
-
#
|
233
|
-
# NumberOfFiles <integer>
|
234
|
-
# The maximum number of open files for this process. Setting this value in a system wide daemon will set the sysctl(3) kern.maxfiles (SoftResourceLimits) or
|
235
|
-
# kern.maxfilesperproc (HardResourceLimits) value in addition to the setrlimit(2) values.
|
236
|
-
#
|
237
|
-
# NumberOfProcesses <integer>
|
238
|
-
# The maximum number of simultaneous processes for this user id. Setting this value in a system wide daemon will set the sysctl(3) kern.maxproc (SoftResource-
|
239
|
-
# Limits) or kern.maxprocperuid (HardResourceLimits) value in addition to the setrlimit(2) values.
|
240
|
-
#
|
241
|
-
# ResidentSetSize <integer>
|
242
|
-
# The maximum size (in bytes) to which a process's resident set size may grow. This imposes a limit on the amount of physical memory to be given to a process;
|
243
|
-
# if memory is tight, the system will prefer to take memory from processes that are exceeding their declared resident set size.
|
244
|
-
#
|
245
|
-
# Stack <integer>
|
246
|
-
# The maximum size (in bytes) of the stack segment for a process; this defines how far a program's stack segment may be extended. Stack extension is performed
|
247
|
-
# automatically by the system.
|
237
|
+
# Resource limits to be imposed on the job. These adjust variables set with setrlimit(2). The following keys apply:
|
248
238
|
#
|
249
|
-
#
|
239
|
+
# @example Reference
|
240
|
+
# soft_resource_limits do
|
241
|
+
# core <integer>
|
242
|
+
# # The largest size (in bytes) core file that may be created.
|
243
|
+
#
|
244
|
+
# cpu <integer>
|
245
|
+
# # The maximum amount of cpu time (in seconds) to be used by each process.
|
246
|
+
#
|
247
|
+
# data <integer>
|
248
|
+
# # The maximum size (in bytes) of the data segment for a process; this defines how far a
|
249
|
+
# # program may extend its break with the sbrk(2) system call.
|
250
|
+
#
|
251
|
+
# file_size <integer>
|
252
|
+
# # The largest size (in bytes) file that may be created.
|
253
|
+
#
|
254
|
+
# memory_lock <integer>
|
255
|
+
# # The maximum size (in bytes) which a process may lock into memory using the mlock(2) function.
|
256
|
+
#
|
257
|
+
# number_of_files <integer>
|
258
|
+
# # The maximum number of open files for this process. Setting this value in a system wide
|
259
|
+
# # daemon will set the sysctl(3) kern.maxfiles (SoftResourceLimits) or kern.maxfilesperproc
|
260
|
+
# # (HardResourceLimits) value in addition to the setrlimit(2) values.
|
261
|
+
#
|
262
|
+
# number_of_processes <integer>
|
263
|
+
# # The maximum number of simultaneous processes for this user id. Setting this value in a
|
264
|
+
# # system wide daemon will set the sysctl(3) kern.maxproc (SoftResource-Limits) or
|
265
|
+
# # kern.maxprocperuid (HardResourceLimits) value in addition to the setrlimit(2) values.
|
266
|
+
#
|
267
|
+
# resident_set_size <integer>
|
268
|
+
# # The maximum size (in bytes) to which a process's resident set size may grow. This imposes
|
269
|
+
# # a limit on the amount of physical memory to be given to a process; if memory is tight, the
|
270
|
+
# # system will prefer to take memory from processes that are exceeding their declared resident
|
271
|
+
# # set size.
|
272
|
+
#
|
273
|
+
# stack <integer>
|
274
|
+
# # The maximum size (in bytes) of the stack segment for a process; this defines how far a
|
275
|
+
# # program's stack segment may be extended. Stack extension is performed automatically
|
276
|
+
# # by the system.
|
277
|
+
# end
|
250
278
|
#
|
251
|
-
# Example
|
279
|
+
# @example Example
|
280
|
+
#
|
281
|
+
# # Set soft resource limits
|
282
|
+
# soft_resource_limits do
|
283
|
+
# NumberOfProcesses 4
|
284
|
+
# NumberOfFiles 512
|
285
|
+
# end
|
252
286
|
#
|
253
|
-
#
|
254
|
-
#
|
255
|
-
# NumberOfFiles 512
|
256
|
-
# end
|
287
|
+
# # Return soft resource limits
|
288
|
+
# soft_resource_limits => { "NumberOfProcesses" => 4, "NumberOfFiles" => 512 }
|
257
289
|
#
|
258
290
|
def soft_resource_limits value=nil, &blk
|
259
291
|
key = "SoftResourceLimits"
|
260
292
|
if blk
|
261
|
-
@hash[key] ||= ::
|
293
|
+
@hash[key] ||= ::Plist4r::OrderedHash.new
|
262
294
|
@hash[key] = ::LaunchdPlistStructs::ResourceLimits.new(@hash[key],&blk).hash
|
263
295
|
else
|
264
296
|
@hash[key]
|
265
297
|
end
|
266
298
|
end
|
267
299
|
|
268
|
-
#
|
269
|
-
# hard_resource_limits { block_of_keys }
|
270
|
-
# hard_resource_limits -> hash or nil
|
271
|
-
#
|
272
|
-
# hard_resource_limits <block of keys>
|
273
|
-
# Resource limits to be imposed on the job. These adjust variables set with setrlimit(2). The following keys apply:
|
274
|
-
#
|
275
|
-
# hard_resource_limits do
|
276
|
-
#
|
277
|
-
# Core <integer>
|
278
|
-
# The largest size (in bytes) core file that may be created.
|
279
|
-
#
|
280
|
-
# CPU <integer>
|
281
|
-
# The maximum amount of cpu time (in seconds) to be used by each process.
|
300
|
+
# Set or return the plist key "HardResourceLimits"
|
282
301
|
#
|
283
|
-
#
|
284
|
-
# The maximum size (in bytes) of the data segment for a process; this defines how far a program may extend its break with the sbrk(2) system call.
|
285
|
-
#
|
286
|
-
# FileSize <integer>
|
287
|
-
# The largest size (in bytes) file that may be created.
|
288
|
-
#
|
289
|
-
# MemoryLock <integer>
|
290
|
-
# The maximum size (in bytes) which a process may lock into memory using the mlock(2) function.
|
291
|
-
#
|
292
|
-
# NumberOfFiles <integer>
|
293
|
-
# The maximum number of open files for this process. Setting this value in a system wide daemon will set the sysctl(3) kern.maxfiles (SoftResourceLimits) or
|
294
|
-
# kern.maxfilesperproc (HardResourceLimits) value in addition to the setrlimit(2) values.
|
295
|
-
#
|
296
|
-
# NumberOfProcesses <integer>
|
297
|
-
# The maximum number of simultaneous processes for this user id. Setting this value in a system wide daemon will set the sysctl(3) kern.maxproc (SoftResource-
|
298
|
-
# Limits) or kern.maxprocperuid (HardResourceLimits) value in addition to the setrlimit(2) values.
|
299
|
-
#
|
300
|
-
# ResidentSetSize <integer>
|
301
|
-
# The maximum size (in bytes) to which a process's resident set size may grow. This imposes a limit on the amount of physical memory to be given to a process;
|
302
|
-
# if memory is tight, the system will prefer to take memory from processes that are exceeding their declared resident set size.
|
303
|
-
#
|
304
|
-
# Stack <integer>
|
305
|
-
# The maximum size (in bytes) of the stack segment for a process; this defines how far a program's stack segment may be extended. Stack extension is performed
|
306
|
-
# automatically by the system.
|
307
|
-
#
|
308
|
-
# end
|
302
|
+
# Resource limits to be imposed on the job. These adjust variables set with setrlimit(2). The following keys apply:
|
309
303
|
#
|
310
|
-
#
|
304
|
+
# @example Reference
|
305
|
+
# hard_resource_limits do
|
306
|
+
# core <integer>
|
307
|
+
# # The largest size (in bytes) core file that may be created.
|
308
|
+
#
|
309
|
+
# cpu <integer>
|
310
|
+
# # The maximum amount of cpu time (in seconds) to be used by each process.
|
311
|
+
#
|
312
|
+
# data <integer>
|
313
|
+
# # The maximum size (in bytes) of the data segment for a process; this defines how far a
|
314
|
+
# # program may extend its break with the sbrk(2) system call.
|
315
|
+
#
|
316
|
+
# file_size <integer>
|
317
|
+
# # The largest size (in bytes) file that may be created.
|
318
|
+
#
|
319
|
+
# memory_lock <integer>
|
320
|
+
# # The maximum size (in bytes) which a process may lock into memory using the mlock(2) function.
|
321
|
+
#
|
322
|
+
# number_of_files <integer>
|
323
|
+
# # The maximum number of open files for this process. Setting this value in a system wide
|
324
|
+
# # daemon will set the sysctl(3) kern.maxfiles (SoftResourceLimits) or kern.maxfilesperproc
|
325
|
+
# # (HardResourceLimits) value in addition to the setrlimit(2) values.
|
326
|
+
#
|
327
|
+
# number_of_processes <integer>
|
328
|
+
# # The maximum number of simultaneous processes for this user id. Setting this value in a
|
329
|
+
# # system wide daemon will set the sysctl(3) kern.maxproc (SoftResource-Limits) or
|
330
|
+
# # kern.maxprocperuid (HardResourceLimits) value in addition to the setrlimit(2) values.
|
331
|
+
#
|
332
|
+
# resident_set_size <integer>
|
333
|
+
# # The maximum size (in bytes) to which a process's resident set size may grow. This imposes
|
334
|
+
# # a limit on the amount of physical memory to be given to a process; if memory is tight, the
|
335
|
+
# # system will prefer to take memory from processes that are exceeding their declared resident
|
336
|
+
# # set size.
|
337
|
+
#
|
338
|
+
# stack <integer>
|
339
|
+
# # The maximum size (in bytes) of the stack segment for a process; this defines how far a
|
340
|
+
# # program's stack segment may be extended. Stack extension is performed automatically
|
341
|
+
# # by the system.
|
342
|
+
# end
|
311
343
|
#
|
312
|
-
#
|
313
|
-
#
|
314
|
-
#
|
315
|
-
#
|
344
|
+
# @example Example
|
345
|
+
#
|
346
|
+
# # Set hard resource limits
|
347
|
+
# hard_resource_limits do
|
348
|
+
# NumberOfProcesses 4
|
349
|
+
# NumberOfFiles 512
|
350
|
+
# end
|
316
351
|
#
|
352
|
+
# # Return hard resource limits
|
353
|
+
# hard_resource_limits => { "NumberOfProcesses" => 4, "NumberOfFiles" => 512 }
|
354
|
+
#
|
317
355
|
def hard_resource_limits value=nil, &blk
|
318
356
|
key = "HardResourceLimits"
|
319
357
|
if blk
|
320
|
-
@hash[key] ||= ::
|
358
|
+
@hash[key] ||= ::Plist4r::OrderedHash.new
|
321
359
|
@hash[key] = ::LaunchdPlistStructs::ResourceLimits.new(@hash[key],&blk).hash
|
322
360
|
else
|
323
361
|
@hash[key]
|
@@ -336,7 +374,7 @@ module Plist4r
|
|
336
374
|
@hash[service] = value
|
337
375
|
set_or_return :bool, service, value
|
338
376
|
elsif blk
|
339
|
-
@hash[service] = ::
|
377
|
+
@hash[service] = ::Plist4r::OrderedHash.new
|
340
378
|
@hash[service] = ::LaunchdPlistStructs::MachServices::MachService.new(@hash[service],&blk).hash
|
341
379
|
else
|
342
380
|
@orig
|
@@ -344,42 +382,49 @@ module Plist4r
|
|
344
382
|
end
|
345
383
|
end
|
346
384
|
|
347
|
-
#
|
348
|
-
# mach_services { block }
|
349
|
-
# mach_services -> hash or nil
|
385
|
+
# Set or return the plist key "MachServices"
|
350
386
|
#
|
351
|
-
#
|
387
|
+
# Structure: "A dictionary of booleans" or a "dictionary of dictionaries"
|
388
|
+
#
|
352
389
|
# This optional key is used to specify Mach services to be registered with the Mach bootstrap sub-system. Each key in this dictionary should be the name of service
|
353
390
|
# to be advertised. The value of the key must be a boolean and set to true. Alternatively, a dictionary can be used instead of a simple true value.
|
354
391
|
#
|
355
|
-
# ResetAtClose <boolean>
|
356
|
-
# If this boolean is false, the port is recycled, thus leaving clients to remain oblivious to the demand nature of job. If the value is set to true, clients
|
357
|
-
# receive port death notifications when the job lets go of the receive right. The port will be recreated atomically with respect to bootstrap_look_up() calls,
|
358
|
-
# so that clients can trust that after receiving a port death notification, the new port will have already been recreated. Setting the value to true should be
|
359
|
-
# done with care. Not all clients may be able to handle this behavior. The default value is false.
|
360
|
-
#
|
361
|
-
# HideUntilCheckIn <boolean>
|
362
|
-
# Reserve the name in the namespace, but cause bootstrap_look_up() to fail until the job has checked in with launchd.
|
363
|
-
#
|
364
392
|
# Finally, for the job itself, the values will be replaced with Mach ports at the time of check-in with launchd.
|
365
393
|
#
|
366
|
-
#
|
394
|
+
# @example Reference
|
395
|
+
# mach_services do
|
396
|
+
# reset_at_close <boolean>
|
397
|
+
# # If this boolean is false, the port is recycled, thus leaving clients to remain oblivious
|
398
|
+
# # to the demand nature of job. If the value is set to true, clients receive port death
|
399
|
+
# # notifications when the job lets go of the receive right. The port will be recreated
|
400
|
+
# # atomically with respect to bootstrap_look_up() calls, so that clients can trust that
|
401
|
+
# # after receiving a port death notification, the new port will have already been recreated.
|
402
|
+
# # Setting the value to true should be done with care. Not all clients may be able to handle
|
403
|
+
# # this behavior. The default value is false.
|
404
|
+
#
|
405
|
+
# hide_until_check_in <boolean>
|
406
|
+
# # Reserve the name in the namespace, but cause bootstrap_look_up() to fail until the job
|
407
|
+
# # has checked in with launchd.
|
408
|
+
# end
|
367
409
|
#
|
368
|
-
#
|
369
|
-
# add "com.apple.afpfs_checkafp", true
|
370
|
-
# end
|
410
|
+
# @example Example
|
371
411
|
#
|
372
|
-
#
|
373
|
-
#
|
374
|
-
#
|
375
|
-
#
|
376
|
-
#
|
377
|
-
#
|
412
|
+
# # Set mach services
|
413
|
+
# mach_services do
|
414
|
+
# add "com.apple.afpfs_checkafp", true
|
415
|
+
# end
|
416
|
+
#
|
417
|
+
# mach_services do
|
418
|
+
# add "com.apple.AppleFileServer" do
|
419
|
+
# hide_until_check_in true
|
420
|
+
# reset_at_close false
|
421
|
+
# end
|
422
|
+
# end
|
378
423
|
#
|
379
424
|
def mach_services value=nil, &blk
|
380
425
|
key = "MachServices"
|
381
426
|
if blk
|
382
|
-
@hash[key] ||= ::
|
427
|
+
@hash[key] ||= ::Plist4r::OrderedHash.new
|
383
428
|
@hash[key] = ::LaunchdPlistStructs::MachServices.new(@hash[key],&blk).hash
|
384
429
|
else
|
385
430
|
@hash[key]
|
@@ -425,122 +470,191 @@ module Plist4r
|
|
425
470
|
end
|
426
471
|
end
|
427
472
|
|
428
|
-
#
|
429
|
-
# sockets(socket_key="Listeners") { block_of_keys }
|
430
|
-
# sockets(socket_key="Listeners", socket_index) { block_of_keys }
|
431
|
-
# sockets -> hash or nil
|
432
|
-
#
|
433
|
-
# socket <array_index=nil> <block of keys>
|
434
|
-
# socket <dictionary... OR dictionary + array index...>
|
473
|
+
# Set or return the plist key "Sockets"
|
435
474
|
#
|
436
|
-
#
|
437
|
-
# for more information about how to properly use the Sockets feature
|
475
|
+
# Structure: "dictionary of dictionaries... OR dictionary of array of dictionaries..."
|
438
476
|
#
|
439
|
-
#
|
440
|
-
#
|
441
|
-
# use to differentiate which descriptors correspond to which application level protocols (e.g. http vs. ftp vs. DNS...). At check-in time, the value of each Sockets
|
442
|
-
# dictionary key will be an array of descriptors. Daemon/Agent writers should consider all descriptors of a given key to be to be effectively equivalent, even though
|
443
|
-
# each file descriptor likely represents a different networking protocol which conforms to the criteria specified in the job configuration file.
|
444
|
-
# The parameters below are used as inputs to call getaddrinfo(3).
|
477
|
+
# Please see http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPSystemStartup/Articles/LaunchOnDemandDaemons.html
|
478
|
+
# for more information about how to properly use the Sockets feature.
|
445
479
|
#
|
446
|
-
#
|
480
|
+
# NOTE:
|
447
481
|
#
|
448
|
-
#
|
449
|
-
#
|
450
|
-
#
|
482
|
+
# Sockets will work only if a special Sockets callback method is implemented within the daemon which
|
483
|
+
# launchd is attempting to start. (this is not commonly the case for most OSS eg apache, mysql, etc).
|
484
|
+
# If writing / modifying a deamon is not an option, it may be more worthwhile to consider if the
|
485
|
+
# Launchd WatchPaths feature is applicable instead of Sockets.
|
451
486
|
#
|
452
|
-
#
|
453
|
-
# This optional key specifies whether listen(2) or connect(2) should be called on the created file descriptor. The default is true ("to listen").
|
487
|
+
# Heres 2 example deamons which implement the necessary sockets callbacks.
|
454
488
|
#
|
455
|
-
#
|
456
|
-
# This optional key specifies the node to connect(2) or bind(2) to.
|
489
|
+
# Examples:
|
457
490
|
#
|
458
|
-
#
|
459
|
-
# This optional key specifies the service on the node to connect(2) or bind(2) to.
|
491
|
+
# http://developer.apple.com/mac/library/samplecode/BetterAuthorizationSample/Introduction/Intro.html
|
460
492
|
#
|
461
|
-
#
|
462
|
-
# This optional key can be used to specifically request that "IPv4" or "IPv6" socket(s) be created.
|
493
|
+
# http://bitbucket.org/mikemccracken/py-launchd/wiki/Home
|
463
494
|
#
|
464
|
-
#
|
465
|
-
#
|
495
|
+
# The remainder of this section simply describes how to declare Sockets definitions within a launchd plist file.
|
496
|
+
# It does not explain how to implement the sockets feature in a deamon. (For that, please see the above links)
|
466
497
|
#
|
467
|
-
#
|
468
|
-
#
|
498
|
+
# This optional key is used to specify launch on demand sockets that can be used to let launchd know when to run the job. The job must check-in to get a copy of the
|
499
|
+
# file descriptors using APIs outlined in launch(3). The keys of the top level Sockets dictionary can be anything. They are meant for the application developer to
|
500
|
+
# use to differentiate which descriptors correspond to which application level protocols (e.g. http vs. ftp vs. DNS...). At check-in time, the value of each Sockets
|
501
|
+
# dictionary key will be an array of descriptors. Daemon/Agent writers should consider all descriptors of a given key to be to be effectively equivalent, even though
|
502
|
+
# each file descriptor likely represents a different networking protocol which conforms to the criteria specified in the job configuration file.
|
503
|
+
# The parameters below are used as inputs to call getaddrinfo(3).
|
469
504
|
#
|
470
|
-
#
|
471
|
-
#
|
472
|
-
#
|
505
|
+
# @example Reference
|
506
|
+
# socket "socket_key" do
|
507
|
+
# sock_type <string>
|
508
|
+
# # This optional key tells launchctl what type of socket to create. The default is "stream"
|
509
|
+
# # and other valid values for this key are "dgram" and "seqpacket" respectively.
|
510
|
+
#
|
511
|
+
# sock_passive <boolean>
|
512
|
+
# # This optional key specifies whether listen(2) or connect(2) should be called on the
|
513
|
+
# # created file descriptor. The default is true ("to listen").
|
514
|
+
#
|
515
|
+
# sock_node_name <string>
|
516
|
+
# # This optional key specifies the node to connect(2) or bind(2) to.
|
517
|
+
#
|
518
|
+
# sock_service_name <string>
|
519
|
+
# # This optional key specifies the service on the node to connect(2) or bind(2) to.
|
520
|
+
#
|
521
|
+
# sock_family <string>
|
522
|
+
# # This optional key can be used to specifically request that "IPv4" or "IPv6" socket(s) be
|
523
|
+
# # created.
|
524
|
+
#
|
525
|
+
# sock_protocol <string>
|
526
|
+
# # This optional key specifies the protocol to be passed to socket(2). The only value
|
527
|
+
# # understood by this key at the moment is "TCP".
|
528
|
+
#
|
529
|
+
# sock_path_name <string>
|
530
|
+
# # This optional key implies SockFamily is set to "Unix". It specifies the path to
|
531
|
+
# # connect(2) or bind(2) to.
|
532
|
+
#
|
533
|
+
# secure_socket_with_key <string>
|
534
|
+
# # This optional key is a variant of SockPathName. Instead of binding to a known path,
|
535
|
+
# # a securely generated socket is created and the path is assigned to the environment
|
536
|
+
# # variable that is inherited by all jobs spawned by launchd.
|
537
|
+
#
|
538
|
+
# sock_path_mode <integer>
|
539
|
+
# # This optional key specifies the mode of the socket. Known bug: Property lists don't
|
540
|
+
# # support octal, so please convert the value to decimal.
|
541
|
+
#
|
542
|
+
# bonjour <boolean or string or array of strings>
|
543
|
+
# # This optional key can be used to request that the service be registered with the
|
544
|
+
# # mDNSResponder(8). If the value is boolean, the service name is inferred from
|
545
|
+
# # the SockServiceName.
|
546
|
+
#
|
547
|
+
# multicast_group <string>
|
548
|
+
# # This optional key can be used to request that the datagram socket join a multicast
|
549
|
+
# # group. If the value is a hostname, then getaddrinfo(3) will be used to join the
|
550
|
+
# # correct multicast address for a given socket family. If an explicit IPv4 or IPv6
|
551
|
+
# # address is given, it is required that the SockFamily family also be set, otherwise
|
552
|
+
# # the results are undefined.
|
553
|
+
# end
|
473
554
|
#
|
474
|
-
#
|
475
|
-
# This optional key specifies the mode of the socket. Known bug: Property lists don't support octal, so please convert the value to decimal.
|
555
|
+
# @example Example
|
476
556
|
#
|
477
|
-
#
|
478
|
-
#
|
479
|
-
#
|
557
|
+
# # Method construct
|
558
|
+
# socket(socket_key="Listeners") { block_of_keys }
|
559
|
+
# socket(socket_key="Listeners", socket_index) { block_of_keys }
|
560
|
+
# socket -> hash or nil
|
480
561
|
#
|
481
|
-
#
|
482
|
-
#
|
483
|
-
#
|
484
|
-
#
|
562
|
+
# # Write this socket to index [0]. Creates an *array* of sockets
|
563
|
+
# # This array is held within the default sockets key name, "Listeners"
|
564
|
+
# launchd_plist.socket 0 do
|
565
|
+
# sock_service_name "netbios-ssn"
|
566
|
+
# end
|
567
|
+
#
|
568
|
+
# # Add a new socket called "netbios". Creates a *dictionary* of sockets
|
569
|
+
# launchd_plist.socket "netbios" do
|
570
|
+
# sock_service_name "netbios"
|
571
|
+
# bonjour ['smb']
|
572
|
+
# end
|
485
573
|
#
|
486
|
-
#
|
574
|
+
# # Inspect all the sockets structure afterward (recommended)
|
575
|
+
# puts launchd_plist.socket.inspect
|
487
576
|
#
|
488
|
-
#
|
489
|
-
# Sockets is a complex structure. If you are manupilating an existing Sockets entry, then you must fully specify the key you want to modify.
|
490
|
-
# so `socket do` should be written as `socket "Listeners" do`, (and in the case of an array of sockets) `socket 0 do` should be written as `socket "Listeners" 0 do`
|
577
|
+
# @example Correct Usage, and Erroneous usage
|
491
578
|
#
|
492
|
-
#
|
579
|
+
# # scenario 1:
|
580
|
+
# socket do
|
581
|
+
# sock_service_name "netbios-ssn"
|
582
|
+
# end
|
583
|
+
# # => Result: Ok. The default "Listeners" toplevel key is generated implicitly.
|
584
|
+
#
|
585
|
+
# # scenario 2:
|
586
|
+
# socket do
|
587
|
+
# sock_service_name "netbios-ssn"
|
588
|
+
# end
|
589
|
+
# socket do
|
590
|
+
# sock_service_name "netbios"
|
591
|
+
# bonjour ['smb']
|
592
|
+
# end
|
593
|
+
# # => Result: Exception error is raise the second time because the "Listeners" key already
|
594
|
+
# # exists. We can forcefully overwrite this existing sockets key with `socket "Listeners" do`.
|
595
|
+
#
|
596
|
+
# # scenario 3:
|
597
|
+
# socket "netbios-ssn" do
|
598
|
+
# sock_service_name "netbios-ssn"
|
599
|
+
# end
|
600
|
+
# socket "netbios" do
|
601
|
+
# sock_service_name "netbios"
|
602
|
+
# bonjour ['smb']
|
603
|
+
# end
|
604
|
+
# => Result: Ok. Each Sockets entry has a unique key.
|
605
|
+
#
|
606
|
+
# # scenario 4:
|
607
|
+
# socket 0 do
|
608
|
+
# sock_service_name "netbios-ssn"
|
609
|
+
# end
|
610
|
+
# socket 1 do
|
611
|
+
# sock_service_name "netbios"
|
612
|
+
# bonjour ['smb']
|
613
|
+
# end
|
614
|
+
# # => Result: Ok. Each Sockets entry has a unique array index. The array of all these sockets
|
615
|
+
# # is held within the default "Listeners" key (implicit array or sockets).
|
616
|
+
#
|
617
|
+
# # scenario 5:
|
618
|
+
# socket do
|
619
|
+
# sock_service_name "netbios-ssn"
|
620
|
+
# end
|
621
|
+
# socket[0] do
|
622
|
+
# sock_service_name "netbios"
|
623
|
+
# bonjour ['smb']
|
624
|
+
# end
|
625
|
+
# # => Result: Exception error. because we cant mix and match types with the implicit
|
626
|
+
# # "Listeners" key. If in doubt then avoid using the arrays.
|
493
627
|
#
|
494
|
-
#
|
495
|
-
# socket do
|
496
|
-
# sock_service_name "netbios-ssn"
|
497
|
-
# end
|
498
|
-
# # => Result: Ok. The default "Listeners" toplevel key is generated implicitly.
|
628
|
+
# @example NOTE: Accessing the default sockets
|
499
629
|
#
|
500
|
-
#
|
501
|
-
#
|
502
|
-
#
|
503
|
-
#
|
630
|
+
# # Sockets is a complex structure. When manupilating an existing Sockets entry, (the second
|
631
|
+
# # time around), we must fully specify the key to modify. This is usually achieved simply
|
632
|
+
# # specifying the implicit "Listeners" key name.
|
633
|
+
#
|
634
|
+
# # For example, if we created a socket with
|
504
635
|
# socket do
|
505
|
-
#
|
506
|
-
# bonjour ['smb']
|
636
|
+
# # ...
|
507
637
|
# end
|
508
|
-
# # => Result: Exception error is raise the second time because the "Listeners" key already exists. We can forcefully overwrite this existing sockets key with `socket "Listeners" do`.
|
509
638
|
#
|
510
|
-
#
|
511
|
-
# socket "
|
512
|
-
#
|
513
|
-
# end
|
514
|
-
# socket "netbios" do
|
515
|
-
# sock_service_name "netbios"
|
516
|
-
# bonjour ['smb']
|
639
|
+
# # is accessed as
|
640
|
+
# socket "Listeners" do
|
641
|
+
# # ...
|
517
642
|
# end
|
518
|
-
# => Result: Ok. Each Sockets entry has a unique key.
|
519
643
|
#
|
520
|
-
#
|
644
|
+
# # or if an array of sockets
|
521
645
|
# socket 0 do
|
522
|
-
#
|
523
|
-
# end
|
524
|
-
# socket 1 do
|
525
|
-
# sock_service_name "netbios"
|
526
|
-
# bonjour ['smb']
|
646
|
+
# # ...
|
527
647
|
# end
|
528
|
-
#
|
529
|
-
#
|
530
|
-
#
|
531
|
-
#
|
532
|
-
# sock_service_name "netbios-ssn"
|
533
|
-
# end
|
534
|
-
# socket[0] do
|
535
|
-
# sock_service_name "netbios"
|
536
|
-
# bonjour ['smb']
|
648
|
+
#
|
649
|
+
# # in reality becomes
|
650
|
+
# socket "Listeners" 0 do
|
651
|
+
# # ...
|
537
652
|
# end
|
538
|
-
# # => Result: Exception error. because we cant mix and match types with the implicit "Listeners" key. If in doubt then avoid using the arrays.
|
539
653
|
#
|
540
654
|
def socket index_or_key=nil, index=nil, &blk
|
541
655
|
key = "Sockets"
|
542
656
|
if blk
|
543
|
-
@hash[key] ||= ::
|
657
|
+
@hash[key] ||= ::Plist4r::OrderedHash.new
|
544
658
|
sockets = ::LaunchdPlistStructs::Sockets.new(@hash[key]).hash
|
545
659
|
|
546
660
|
case index_or_key
|