1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 """
40 Provides configuration-related objects.
41
42 Summary
43 =======
44
45 Cedar Backup stores all of its configuration in an XML document typically
46 called C{cback.conf}. The standard location for this document is in
47 C{/etc}, but users can specify a different location if they want to.
48
49 The C{Config} class is a Python object representation of a Cedar Backup XML
50 configuration file. The representation is two-way: XML data can be used to
51 create a C{Config} object, and then changes to the object can be propogated
52 back to disk. A C{Config} object can even be used to create a configuration
53 file from scratch programmatically.
54
55 The C{Config} class is intended to be the only Python-language interface to
56 Cedar Backup configuration on disk. Cedar Backup will use the class as its
57 internal representation of configuration, and applications external to Cedar
58 Backup itself (such as a hypothetical third-party configuration tool written
59 in Python or a third party extension module) should also use the class when
60 they need to read and write configuration files.
61
62 Backwards Compatibility
63 =======================
64
65 The configuration file format has changed between Cedar Backup 1.x and Cedar
66 Backup 2.x. Any Cedar Backup 1.x configuration file is also a valid Cedar
67 Backup 2.x configuration file. However, it doesn't work to go the other
68 direction, as the 2.x configuration files contains additional configuration
69 is not accepted by older versions of the software.
70
71 XML Configuration Structure
72 ===========================
73
74 A C{Config} object can either be created "empty", or can be created based on
75 XML input (either in the form of a string or read in from a file on disk).
76 Generally speaking, the XML input I{must} result in a C{Config} object which
77 passes the validations laid out below in the I{Validation} section.
78
79 An XML configuration file is composed of seven sections:
80
81 - I{reference}: specifies reference information about the file (author, revision, etc)
82 - I{extensions}: specifies mappings to Cedar Backup extensions (external code)
83 - I{options}: specifies global configuration options
84 - I{peers}: specifies the set of peers in a master's backup pool
85 - I{collect}: specifies configuration related to the collect action
86 - I{stage}: specifies configuration related to the stage action
87 - I{store}: specifies configuration related to the store action
88 - I{purge}: specifies configuration related to the purge action
89
90 Each section is represented by an class in this module, and then the overall
91 C{Config} class is a composition of the various other classes.
92
93 Any configuration section that is missing in the XML document (or has not
94 been filled into an "empty" document) will just be set to C{None} in the
95 object representation. The same goes for individual fields within each
96 configuration section. Keep in mind that the document might not be
97 completely valid if some sections or fields aren't filled in - but that
98 won't matter until validation takes place (see the I{Validation} section
99 below).
100
101 Unicode vs. String Data
102 =======================
103
104 By default, all string data that comes out of XML documents in Python is
105 unicode data (i.e. C{u"whatever"}). This is fine for many things, but when
106 it comes to filesystem paths, it can cause us some problems. We really want
107 strings to be encoded in the filesystem encoding rather than being unicode.
108 So, most elements in configuration which represent filesystem paths are
109 coverted to plain strings using L{util.encodePath}. The main exception is
110 the various C{absoluteExcludePath} and C{relativeExcludePath} lists. These
111 are I{not} converted, because they are generally only used for filtering,
112 not for filesystem operations.
113
114 Validation
115 ==========
116
117 There are two main levels of validation in the C{Config} class and its
118 children. The first is field-level validation. Field-level validation
119 comes into play when a given field in an object is assigned to or updated.
120 We use Python's C{property} functionality to enforce specific validations on
121 field values, and in some places we even use customized list classes to
122 enforce validations on list members. You should expect to catch a
123 C{ValueError} exception when making assignments to configuration class
124 fields.
125
126 The second level of validation is post-completion validation. Certain
127 validations don't make sense until a document is fully "complete". We don't
128 want these validations to apply all of the time, because it would make
129 building up a document from scratch a real pain. For instance, we might
130 have to do things in the right order to keep from throwing exceptions, etc.
131
132 All of these post-completion validations are encapsulated in the
133 L{Config.validate} method. This method can be called at any time by a
134 client, and will always be called immediately after creating a C{Config}
135 object from XML data and before exporting a C{Config} object to XML. This
136 way, we get decent ease-of-use but we also don't accept or emit invalid
137 configuration files.
138
139 The L{Config.validate} implementation actually takes two passes to
140 completely validate a configuration document. The first pass at validation
141 is to ensure that the proper sections are filled into the document. There
142 are default requirements, but the caller has the opportunity to override
143 these defaults.
144
145 The second pass at validation ensures that any filled-in section contains
146 valid data. Any section which is not set to C{None} is validated according
147 to the rules for that section (see below).
148
149 I{Reference Validations}
150
151 No validations.
152
153 I{Extensions Validations}
154
155 The list of actions may be either C{None} or an empty list C{[]} if desired.
156 Each extended action must include a name, a module and a function. Then, an
157 extended action must include either an index or dependency information.
158 Which one is required depends on which order mode is configured.
159
160 I{Options Validations}
161
162 All fields must be filled in except the rsh command. The rcp and rsh
163 commands are used as default values for all remote peers. Remote peers can
164 also rely on the backup user as the default remote user name if they choose.
165
166 I{Peers Validations}
167
168 Local peers must be completely filled in, including both name and collect
169 directory. Remote peers must also fill in the name and collect directory,
170 but can leave the remote user and rcp command unset. In this case, the
171 remote user is assumed to match the backup user from the options section and
172 rcp command is taken directly from the options section.
173
174 I{Collect Validations}
175
176 The target directory must be filled in. The collect mode, archive mode and
177 ignore file are all optional. The list of absolute paths to exclude and
178 patterns to exclude may be either C{None} or an empty list C{[]} if desired.
179
180 Each collect directory entry must contain an absolute path to collect, and
181 then must either be able to take collect mode, archive mode and ignore file
182 configuration from the parent C{CollectConfig} object, or must set each
183 value on its own. The list of absolute paths to exclude, relative paths to
184 exclude and patterns to exclude may be either C{None} or an empty list C{[]}
185 if desired. Any list of absolute paths to exclude or patterns to exclude
186 will be combined with the same list in the C{CollectConfig} object to make
187 the complete list for a given directory.
188
189 I{Stage Validations}
190
191 The target directory must be filled in. There must be at least one peer
192 (remote or local) between the two lists of peers. A list with no entries
193 can be either C{None} or an empty list C{[]} if desired.
194
195 If a set of peers is provided, this configuration completely overrides
196 configuration in the peers configuration section, and the same validations
197 apply.
198
199 I{Store Validations}
200
201 The device type and drive speed are optional, and all other values are
202 required (missing booleans will be set to defaults, which is OK).
203
204 The image writer functionality in the C{writer} module is supposed to be
205 able to handle a device speed of C{None}. Any caller which needs a "real"
206 (non-C{None}) value for the device type can use C{DEFAULT_DEVICE_TYPE},
207 which is guaranteed to be sensible.
208
209 I{Purge Validations}
210
211 The list of purge directories may be either C{None} or an empty list C{[]}
212 if desired. All purge directories must contain a path and a retain days
213 value.
214
215 @sort: ActionDependencies, ActionHook, PreActionHook, PostActionHook,
216 ExtendedAction, CommandOverride, CollectFile, CollectDir, PurgeDir, LocalPeer,
217 RemotePeer, ReferenceConfig, ExtensionsConfig, OptionsConfig, PeersConfig,
218 CollectConfig, StageConfig, StoreConfig, PurgeConfig, Config,
219 DEFAULT_DEVICE_TYPE, DEFAULT_MEDIA_TYPE,
220 VALID_DEVICE_TYPES, VALID_MEDIA_TYPES,
221 VALID_COLLECT_MODES, VALID_ARCHIVE_MODES,
222 VALID_ORDER_MODES
223
224 @var DEFAULT_DEVICE_TYPE: The default device type.
225 @var DEFAULT_MEDIA_TYPE: The default media type.
226 @var VALID_DEVICE_TYPES: List of valid device types.
227 @var VALID_MEDIA_TYPES: List of valid media types.
228 @var VALID_COLLECT_MODES: List of valid collect modes.
229 @var VALID_COMPRESS_MODES: List of valid compress modes.
230 @var VALID_ARCHIVE_MODES: List of valid archive modes.
231 @var VALID_ORDER_MODES: List of valid extension order modes.
232
233 @author: Kenneth J. Pronovici <pronovic@ieee.org>
234 """
235
236
237
238
239
240
241 import os
242 import re
243 import logging
244
245
246 from CedarBackup2.writers.util import validateScsiId, validateDriveSpeed
247 from CedarBackup2.util import UnorderedList, AbsolutePathList, ObjectTypeList
248 from CedarBackup2.util import RegexMatchList, RegexList, encodePath
249 from CedarBackup2.util import convertSize, UNIT_BYTES, UNIT_KBYTES, UNIT_MBYTES, UNIT_GBYTES
250 from CedarBackup2.xmlutil import isElement, readChildren, readFirstChild
251 from CedarBackup2.xmlutil import readStringList, readString, readInteger, readBoolean
252 from CedarBackup2.xmlutil import addContainerNode, addStringNode, addIntegerNode, addBooleanNode
253 from CedarBackup2.xmlutil import createInputDom, createOutputDom, serializeDom
254
255
256
257
258
259
260 logger = logging.getLogger("CedarBackup2.log.config")
261
262 DEFAULT_DEVICE_TYPE = "cdwriter"
263 DEFAULT_MEDIA_TYPE = "cdrw-74"
264
265 VALID_DEVICE_TYPES = [ "cdwriter", "dvdwriter", ]
266 VALID_CD_MEDIA_TYPES = [ "cdr-74", "cdrw-74", "cdr-80", "cdrw-80", ]
267 VALID_DVD_MEDIA_TYPES = [ "dvd+r", "dvd+rw", ]
268 VALID_MEDIA_TYPES = VALID_CD_MEDIA_TYPES + VALID_DVD_MEDIA_TYPES
269 VALID_COLLECT_MODES = [ "daily", "weekly", "incr", ]
270 VALID_ARCHIVE_MODES = [ "tar", "targz", "tarbz2", ]
271 VALID_COMPRESS_MODES = [ "none", "gzip", "bzip2", ]
272 VALID_ORDER_MODES = [ "index", "dependency", ]
273 VALID_BLANK_MODES = [ "daily", "weekly", ]
274 VALID_BYTE_UNITS = [ UNIT_BYTES, UNIT_KBYTES, UNIT_MBYTES, UNIT_GBYTES, ]
275 VALID_FAILURE_MODES = [ "none", "all", "daily", "weekly", ]
276
277 REWRITABLE_MEDIA_TYPES = [ "cdrw-74", "cdrw-80", "dvd+rw", ]
278
279 ACTION_NAME_REGEX = r"^[a-z0-9]*$"
280
281
282
283
284
285
287
288 """
289 Class representing a byte quantity.
290
291 A byte quantity has both a quantity and a byte-related unit. Units are
292 maintained using the constants from util.py.
293
294 The quantity is maintained internally as a string so that issues of
295 precision can be avoided. It really isn't possible to store a floating
296 point number here while being able to losslessly translate back and forth
297 between XML and object representations. (Perhaps the Python 2.4 Decimal
298 class would have been an option, but I want to stay compatible with Python
299 2.3.)
300
301 Even though the quantity is maintained as a string, the string must be in a
302 valid floating point positive number. Technically, any floating point
303 string format supported by Python is allowble. However, it does not make
304 sense to have a negative quantity of bytes in this context.
305
306 @sort: __init__, __repr__, __str__, __cmp__, quantity, units
307 """
308
309 - def __init__(self, quantity=None, units=None):
310 """
311 Constructor for the C{ByteQuantity} class.
312
313 @param quantity: Quantity of bytes, as string ("1.25")
314 @param units: Unit of bytes, one of VALID_BYTE_UNITS
315
316 @raise ValueError: If one of the values is invalid.
317 """
318 self._quantity = None
319 self._units = None
320 self.quantity = quantity
321 self.units = units
322
324 """
325 Official string representation for class instance.
326 """
327 return "ByteQuantity(%s, %s)" % (self.quantity, self.units)
328
330 """
331 Informal string representation for class instance.
332 """
333 return self.__repr__()
334
336 """
337 Definition of equals operator for this class.
338 Lists within this class are "unordered" for equality comparisons.
339 @param other: Other object to compare to.
340 @return: -1/0/1 depending on whether self is C{<}, C{=} or C{>} other.
341 """
342 if other is None:
343 return 1
344 if self._quantity != other._quantity:
345 if self._quantity < other._quantity:
346 return -1
347 else:
348 return 1
349 if self._units != other._units:
350 if self._units < other._units:
351 return -1
352 else:
353 return 1
354 return 0
355
357 """
358 Property target used to set the quantity
359 The value must be a non-empty string if it is not C{None}.
360 @raise ValueError: If the value is an empty string.
361 @raise ValueError: If the value is not a valid floating point number
362 @raise ValueError: If the value is less than zero
363 """
364 if value is not None:
365 if len(value) < 1:
366 raise ValueError("Quantity must be a non-empty string.")
367 floatValue = float(value)
368 if floatValue < 0.0:
369 raise ValueError("Quantity cannot be negative.")
370 self._quantity = value
371
373 """
374 Property target used to get the quantity.
375 """
376 return self._quantity
377
379 """
380 Property target used to set the units value.
381 If not C{None}, the units value must be one of the values in L{VALID_BYTE_UNITS}.
382 @raise ValueError: If the value is not valid.
383 """
384 if value is not None:
385 if value not in VALID_BYTE_UNITS:
386 raise ValueError("Units value must be one of %s." % VALID_BYTE_UNITS)
387 self._units = value
388
390 """
391 Property target used to get the units value.
392 """
393 return self._units
394
396 """
397 Property target used to return the byte quantity as a floating point number.
398 If there is no quantity set, then a value of 0.0 is returned.
399 """
400 if self.quantity is not None and self.units is not None:
401 return convertSize(self.quantity, self.units, UNIT_BYTES)
402 return 0.0
403
404 quantity = property(_getQuantity, _setQuantity, None, doc="Byte quantity, as a string")
405 units = property(_getUnits, _setUnits, None, doc="Units for byte quantity, for instance UNIT_BYTES")
406 bytes = property(_getBytes, None, None, doc="Byte quantity, as a floating point number.")
407
408
409
410
411
412
414
415 """
416 Class representing dependencies associated with an extended action.
417
418 Execution ordering for extended actions is done in one of two ways: either by using
419 index values (lower index gets run first) or by having the extended action specify
420 dependencies in terms of other named actions. This class encapsulates the dependency
421 information for an extended action.
422
423 As with all of the other classes that represent configuration sections, all
424 of these values are optional. It is up to some higher-level construct to
425 decide whether everything they need is filled in. Some validation is done
426 on non-C{None} assignments through the use of the Python C{property()}
427 construct.
428
429 The following restrictions exist on data in this class:
430
431 - Any action name must be a non-empty string matching C{ACTION_NAME_REGEX}
432
433 @sort: __init__, __repr__, __str__, __cmp__, beforeList, afterList
434 """
435
436 - def __init__(self, beforeList=None, afterList=None):
437 """
438 Constructor for the C{ActionDependencies} class.
439
440 @param beforeList: List of named actions that this action must be run before
441 @param afterList: List of named actions that this action must be run after
442
443 @raise ValueError: If one of the values is invalid.
444 """
445 self._beforeList = None
446 self._afterList = None
447 self.beforeList = beforeList
448 self.afterList = afterList
449
451 """
452 Official string representation for class instance.
453 """
454 return "ActionDependencies(%s, %s)" % (self.beforeList, self.afterList)
455
457 """
458 Informal string representation for class instance.
459 """
460 return self.__repr__()
461
463 """
464 Definition of equals operator for this class.
465 @param other: Other object to compare to.
466 @return: -1/0/1 depending on whether self is C{<}, C{=} or C{>} other.
467 """
468 if other is None:
469 return 1
470 if self._beforeList != other._beforeList:
471 if self._beforeList < other._beforeList:
472 return -1
473 else:
474 return 1
475 if self._afterList != other._afterList:
476 if self._afterList < other._afterList:
477 return -1
478 else:
479 return 1
480 return 0
481
483 """
484 Property target used to set the "run before" list.
485 Either the value must be C{None} or each element must be a string matching ACTION_NAME_REGEX.
486 @raise ValueError: If the value does not match the regular expression.
487 """
488 if value is None:
489 self._beforeList = None
490 else:
491 try:
492 saved = self._beforeList
493 self._beforeList = RegexMatchList(ACTION_NAME_REGEX, emptyAllowed=False, prefix="Action name")
494 self._beforeList.extend(value)
495 except Exception, e:
496 self._beforeList = saved
497 raise e
498
500 """
501 Property target used to get the "run before" list.
502 """
503 return self._beforeList
504
506 """
507 Property target used to set the "run after" list.
508 Either the value must be C{None} or each element must be a string matching ACTION_NAME_REGEX.
509 @raise ValueError: If the value does not match the regular expression.
510 """
511 if value is None:
512 self._afterList = None
513 else:
514 try:
515 saved = self._afterList
516 self._afterList = RegexMatchList(ACTION_NAME_REGEX, emptyAllowed=False, prefix="Action name")
517 self._afterList.extend(value)
518 except Exception, e:
519 self._afterList = saved
520 raise e
521
523 """
524 Property target used to get the "run after" list.
525 """
526 return self._afterList
527
528 beforeList = property(_getBeforeList, _setBeforeList, None, "List of named actions that this action must be run before.")
529 afterList = property(_getAfterList, _setAfterList, None, "List of named actions that this action must be run after.")
530
531
532
533
534
535
537
538 """
539 Class representing a hook associated with an action.
540
541 A hook associated with an action is a shell command to be executed either
542 before or after a named action is executed.
543
544 As with all of the other classes that represent configuration sections, all
545 of these values are optional. It is up to some higher-level construct to
546 decide whether everything they need is filled in. Some validation is done
547 on non-C{None} assignments through the use of the Python C{property()}
548 construct.
549
550 The following restrictions exist on data in this class:
551
552 - The action name must be a non-empty string matching C{ACTION_NAME_REGEX}
553 - The shell command must be a non-empty string.
554
555 The internal C{before} and C{after} instance variables are always set to
556 False in this parent class.
557
558 @sort: __init__, __repr__, __str__, __cmp__, action, command, before, after
559 """
560
561 - def __init__(self, action=None, command=None):
562 """
563 Constructor for the C{ActionHook} class.
564
565 @param action: Action this hook is associated with
566 @param command: Shell command to execute
567
568 @raise ValueError: If one of the values is invalid.
569 """
570 self._action = None
571 self._command = None
572 self._before = False
573 self._after = False
574 self.action = action
575 self.command = command
576
578 """
579 Official string representation for class instance.
580 """
581 return "ActionHook(%s, %s, %s, %s)" % (self.action, self.command, self.before, self.after)
582
584 """
585 Informal string representation for class instance.
586 """
587 return self.__repr__()
588
590 """
591 Definition of equals operator for this class.
592 @param other: Other object to compare to.
593 @return: -1/0/1 depending on whether self is C{<}, C{=} or C{>} other.
594 """
595 if other is None:
596 return 1
597 if self._action != other._action:
598 if self._action < other._action:
599 return -1
600 else:
601 return 1
602 if self._command != other._command:
603 if self._command < other._command:
604 return -1
605 else:
606 return 1
607 if self._before != other._before:
608 if self._before < other._before:
609 return -1
610 else:
611 return 1
612 if self._after != other._after:
613 if self._after < other._after:
614 return -1
615 else:
616 return 1
617 return 0
618
620 """
621 Property target used to set the action name.
622 The value must be a non-empty string if it is not C{None}.
623 It must also consist only of lower-case letters and digits.
624 @raise ValueError: If the value is an empty string.
625 """
626 pattern = re.compile(ACTION_NAME_REGEX)
627 if value is not None:
628 if len(value) < 1:
629 raise ValueError("The action name must be a non-empty string.")
630 if not pattern.search(value):
631 raise ValueError("The action name must consist of only lower-case letters and digits.")
632 self._action = value
633
635 """
636 Property target used to get the action name.
637 """
638 return self._action
639
641 """
642 Property target used to set the command.
643 The value must be a non-empty string if it is not C{None}.
644 @raise ValueError: If the value is an empty string.
645 """
646 if value is not None:
647 if len(value) < 1:
648 raise ValueError("The command must be a non-empty string.")
649 self._command = value
650
652 """
653 Property target used to get the command.
654 """
655 return self._command
656
658 """
659 Property target used to get the before flag.
660 """
661 return self._before
662
664 """
665 Property target used to get the after flag.
666 """
667 return self._after
668
669 action = property(_getAction, _setAction, None, "Action this hook is associated with.")
670 command = property(_getCommand, _setCommand, None, "Shell command to execute.")
671 before = property(_getBefore, None, None, "Indicates whether command should be executed before action.")
672 after = property(_getAfter, None, None, "Indicates whether command should be executed after action.")
673
675
676 """
677 Class representing a pre-action hook associated with an action.
678
679 A hook associated with an action is a shell command to be executed either
680 before or after a named action is executed. In this case, a pre-action hook
681 is executed before the named action.
682
683 As with all of the other classes that represent configuration sections, all
684 of these values are optional. It is up to some higher-level construct to
685 decide whether everything they need is filled in. Some validation is done
686 on non-C{None} assignments through the use of the Python C{property()}
687 construct.
688
689 The following restrictions exist on data in this class:
690
691 - The action name must be a non-empty string consisting of lower-case letters and digits.
692 - The shell command must be a non-empty string.
693
694 The internal C{before} instance variable is always set to True in this
695 class.
696
697 @sort: __init__, __repr__, __str__, __cmp__, action, command, before, after
698 """
699
700 - def __init__(self, action=None, command=None):
701 """
702 Constructor for the C{PreActionHook} class.
703
704 @param action: Action this hook is associated with
705 @param command: Shell command to execute
706
707 @raise ValueError: If one of the values is invalid.
708 """
709 ActionHook.__init__(self, action, command)
710 self._before = True
711
713 """
714 Official string representation for class instance.
715 """
716 return "PreActionHook(%s, %s, %s, %s)" % (self.action, self.command, self.before, self.after)
717
718 -class PostActionHook(ActionHook):
719
720 """
721 Class representing a pre-action hook associated with an action.
722
723 A hook associated with an action is a shell command to be executed either
724 before or after a named action is executed. In this case, a post-action hook
725 is executed after the named action.
726
727 As with all of the other classes that represent configuration sections, all
728 of these values are optional. It is up to some higher-level construct to
729 decide whether everything they need is filled in. Some validation is done
730 on non-C{None} assignments through the use of the Python C{property()}
731 construct.
732
733 The following restrictions exist on data in this class:
734
735 - The action name must be a non-empty string consisting of lower-case letters and digits.
736 - The shell command must be a non-empty string.
737
738 The internal C{before} instance variable is always set to True in this
739 class.
740
741 @sort: __init__, __repr__, __str__, __cmp__, action, command, before, after
742 """
743
744 - def __init__(self, action=None, command=None):
745 """
746 Constructor for the C{PostActionHook} class.
747
748 @param action: Action this hook is associated with
749 @param command: Shell command to execute
750
751 @raise ValueError: If one of the values is invalid.
752 """
753 ActionHook.__init__(self, action, command)
754 self._after = True
755
756 - def __repr__(self):
757 """
758 Official string representation for class instance.
759 """
760 return "PostActionHook(%s, %s, %s, %s)" % (self.action, self.command, self.before, self.after)
761
762
763
764
765
766
768
769 """
770 Class representing optimized store-action media blanking behavior.
771
772 As with all of the other classes that represent configuration sections, all
773 of these values are optional. It is up to some higher-level construct to
774 decide whether everything they need is filled in. Some validation is done
775 on non-C{None} assignments through the use of the Python C{property()}
776 construct.
777
778 The following restrictions exist on data in this class:
779
780 - The blanking mode must be a one of the values in L{VALID_BLANK_MODES}
781 - The blanking factor must be a positive floating point number
782
783 @sort: __init__, __repr__, __str__, __cmp__, blankMode, blankFactor
784 """
785
786 - def __init__(self, blankMode=None, blankFactor=None):
787 """
788 Constructor for the C{BlankBehavior} class.
789
790 @param blankMode: Blanking mode
791 @param blankFactor: Blanking factor
792
793 @raise ValueError: If one of the values is invalid.
794 """
795 self._blankMode = None
796 self._blankFactor = None
797 self.blankMode = blankMode
798 self.blankFactor = blankFactor
799
801 """
802 Official string representation for class instance.
803 """
804 return "BlankBehavior(%s, %s)" % (self.blankMode, self.blankFactor)
805
807 """
808 Informal string representation for class instance.
809 """
810 return self.__repr__()
811
813 """
814 Definition of equals operator for this class.
815 @param other: Other object to compare to.
816 @return: -1/0/1 depending on whether self is C{<}, C{=} or C{>} other.
817 """
818 if other is None:
819 return 1
820 if self._blankMode != other._blankMode:
821 if self._blankMode < other._blankMode:
822 return -1
823 else:
824 return 1
825 if self._blankFactor != other._blankFactor:
826 if self._blankFactor < other._blankFactor:
827 return -1
828 else:
829 return 1
830 return 0
831
833 """
834 Property target used to set the blanking mode.
835 The value must be one of L{VALID_BLANK_MODES}.
836 @raise ValueError: If the value is not valid.
837 """
838 if value is not None:
839 if value not in VALID_BLANK_MODES:
840 raise ValueError("Blanking mode must be one of %s." % VALID_BLANK_MODES)
841 self._blankMode = value
842
844 """
845 Property target used to get the blanking mode.
846 """
847 return self._blankMode
848
850 """
851 Property target used to set the blanking factor.
852 The value must be a non-empty string if it is not C{None}.
853 @raise ValueError: If the value is an empty string.
854 @raise ValueError: If the value is not a valid floating point number
855 @raise ValueError: If the value is less than zero
856 """
857 if value is not None:
858 if len(value) < 1:
859 raise ValueError("Blanking factor must be a non-empty string.")
860 floatValue = float(value)
861 if floatValue < 0.0:
862 raise ValueError("Blanking factor cannot be negative.")
863 self._blankFactor = value
864
866 """
867 Property target used to get the blanking factor.
868 """
869 return self._blankFactor
870
871 blankMode = property(_getBlankMode, _setBlankMode, None, "Blanking mode")
872 blankFactor = property(_getBlankFactor, _setBlankFactor, None, "Blanking factor")
873
874
875
876
877
878
880
881 """
882 Class representing an extended action.
883
884 As with all of the other classes that represent configuration sections, all
885 of these values are optional. It is up to some higher-level construct to
886 decide whether everything they need is filled in. Some validation is done
887 on non-C{None} assignments through the use of the Python C{property()}
888 construct.
889
890 Essentially, an extended action needs to allow the following to happen::
891
892 exec("from %s import %s" % (module, function))
893 exec("%s(action, configPath")" % function)
894
895 The following restrictions exist on data in this class:
896
897 - The action name must be a non-empty string consisting of lower-case letters and digits.
898 - The module must be a non-empty string and a valid Python identifier.
899 - The function must be an on-empty string and a valid Python identifier.
900 - If set, the index must be a positive integer.
901 - If set, the dependencies attribute must be an C{ActionDependencies} object.
902
903 @sort: __init__, __repr__, __str__, __cmp__, name, module, function, index, dependencies
904 """
905
906 - def __init__(self, name=None, module=None, function=None, index=None, dependencies=None):
907 """
908 Constructor for the C{ExtendedAction} class.
909
910 @param name: Name of the extended action
911 @param module: Name of the module containing the extended action function
912 @param function: Name of the extended action function
913 @param index: Index of action, used for execution ordering
914 @param dependencies: Dependencies for action, used for execution ordering
915
916 @raise ValueError: If one of the values is invalid.
917 """
918 self._name = None
919 self._module = None
920 self._function = None
921 self._index = None
922 self._dependencies = None
923 self.name = name
924 self.module = module
925 self.function = function
926 self.index = index
927 self.dependencies = dependencies
928
930 """
931 Official string representation for class instance.
932 """
933 return "ExtendedAction(%s, %s, %s, %s, %s)" % (self.name, self.module, self.function, self.index, self.dependencies)
934
936 """
937 Informal string representation for class instance.
938 """
939 return self.__repr__()
940
942 """
943 Definition of equals operator for this class.
944 @param other: Other object to compare to.
945 @return: -1/0/1 depending on whether self is C{<}, C{=} or C{>} other.
946 """
947 if other is None:
948 return 1
949 if self._name != other._name:
950 if self._name < other._name:
951 return -1
952 else:
953 return 1
954 if self._module != other._module:
955 if self._module < other._module:
956 return -1
957 else:
958 return 1
959 if self._function != other._function:
960 if self._function < other._function:
961 return -1
962 else:
963 return 1
964 if self._index != other._index:
965 if self._index < other._index:
966 return -1
967 else:
968 return 1
969 if self._dependencies != other._dependencies:
970 if self._dependencies < other._dependencies:
971 return -1
972 else:
973 return 1
974 return 0
975
977 """
978 Property target used to set the action name.
979 The value must be a non-empty string if it is not C{None}.
980 It must also consist only of lower-case letters and digits.
981 @raise ValueError: If the value is an empty string.
982 """
983 pattern = re.compile(ACTION_NAME_REGEX)
984 if value is not None:
985 if len(value) < 1:
986 raise ValueError("The action name must be a non-empty string.")
987 if not pattern.search(value):
988 raise ValueError("The action name must consist of only lower-case letters and digits.")
989 self._name = value
990
992 """
993 Property target used to get the action name.
994 """
995 return self._name
996
998 """
999 Property target used to set the module name.
1000 The value must be a non-empty string if it is not C{None}.
1001 It must also be a valid Python identifier.
1002 @raise ValueError: If the value is an empty string.
1003 """
1004 pattern = re.compile(r"^([A-Za-z_][A-Za-z0-9_]*)(\.[A-Za-z_][A-Za-z0-9_]*)*$")
1005 if value is not None:
1006 if len(value) < 1:
1007 raise ValueError("The module name must be a non-empty string.")
1008 if not pattern.search(value):
1009 raise ValueError("The module name must be a valid Python identifier.")
1010 self._module = value
1011
1013 """
1014 Property target used to get the module name.
1015 """
1016 return self._module
1017
1019 """
1020 Property target used to set the function name.
1021 The value must be a non-empty string if it is not C{None}.
1022 It must also be a valid Python identifier.
1023 @raise ValueError: If the value is an empty string.
1024 """
1025 pattern = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*$")
1026 if value is not None:
1027 if len(value) < 1:
1028 raise ValueError("The function name must be a non-empty string.")
1029 if not pattern.search(value):
1030 raise ValueError("The function name must be a valid Python identifier.")
1031 self._function = value
1032
1034 """
1035 Property target used to get the function name.
1036 """
1037 return self._function
1038
1040 """
1041 Property target used to set the action index.
1042 The value must be an integer >= 0.
1043 @raise ValueError: If the value is not valid.
1044 """
1045 if value is None:
1046 self._index = None
1047 else:
1048 try:
1049 value = int(value)
1050 except TypeError:
1051 raise ValueError("Action index value must be an integer >= 0.")
1052 if value < 0:
1053 raise ValueError("Action index value must be an integer >= 0.")
1054 self._index = value
1055
1057 """
1058 Property target used to get the action index.
1059 """
1060 return self._index
1061
1063 """
1064 Property target used to set the action dependencies information.
1065 If not C{None}, the value must be a C{ActionDependecies} object.
1066 @raise ValueError: If the value is not a C{ActionDependencies} object.
1067 """
1068 if value is None:
1069 self._dependencies = None
1070 else:
1071 if not isinstance(value, ActionDependencies):
1072 raise ValueError("Value must be a C{ActionDependencies} object.")
1073 self._dependencies = value
1074
1076 """
1077 Property target used to get action dependencies information.
1078 """
1079 return self._dependencies
1080
1081 name = property(_getName, _setName, None, "Name of the extended action.")
1082 module = property(_getModule, _setModule, None, "Name of the module containing the extended action function.")
1083 function = property(_getFunction, _setFunction, None, "Name of the extended action function.")
1084 index = property(_getIndex, _setIndex, None, "Index of action, used for execution ordering.")
1085 dependencies = property(_getDependencies, _setDependencies, None, "Dependencies for action, used for execution ordering.")
1086
1087
1088
1089
1090
1091
1093
1094 """
1095 Class representing a piece of Cedar Backup command override configuration.
1096
1097 As with all of the other classes that represent configuration sections, all
1098 of these values are optional. It is up to some higher-level construct to
1099 decide whether everything they need is filled in. Some validation is done
1100 on non-C{None} assignments through the use of the Python C{property()}
1101 construct.
1102
1103 The following restrictions exist on data in this class:
1104
1105 - The absolute path must be absolute
1106
1107 @note: Lists within this class are "unordered" for equality comparisons.
1108
1109 @sort: __init__, __repr__, __str__, __cmp__, command, absolutePath
1110 """
1111
1112 - def __init__(self, command=None, absolutePath=None):
1113 """
1114 Constructor for the C{CommandOverride} class.
1115
1116 @param command: Name of command to be overridden.
1117 @param absolutePath: Absolute path of the overrridden command.
1118
1119 @raise ValueError: If one of the values is invalid.
1120 """
1121 self._command = None
1122 self._absolutePath = None
1123 self.command = command
1124 self.absolutePath = absolutePath
1125
1127 """
1128 Official string representation for class instance.
1129 """
1130 return "CommandOverride(%s, %s)" % (self.command, self.absolutePath)
1131
1133 """
1134 Informal string representation for class instance.
1135 """
1136 return self.__repr__()
1137
1139 """
1140 Definition of equals operator for this class.
1141 @param other: Other object to compare to.
1142 @return: -1/0/1 depending on whether self is C{<}, C{=} or C{>} other.
1143 """
1144 if other is None:
1145 return 1
1146 if self._command != other._command:
1147 if self._command < other.command:
1148 return -1
1149 else:
1150 return 1
1151 if self._absolutePath != other._absolutePath:
1152 if self._absolutePath < other.absolutePath:
1153 return -1
1154 else:
1155 return 1
1156 return 0
1157
1159 """
1160 Property target used to set the command.
1161 The value must be a non-empty string if it is not C{None}.
1162 @raise ValueError: If the value is an empty string.
1163 """
1164 if value is not None:
1165 if len(value) < 1:
1166 raise ValueError("The command must be a non-empty string.")
1167 self._command = value
1168
1170 """
1171 Property target used to get the command.
1172 """
1173 return self._command
1174
1176 """
1177 Property target used to set the absolute path.
1178 The value must be an absolute path if it is not C{None}.
1179 It does not have to exist on disk at the time of assignment.
1180 @raise ValueError: If the value is not an absolute path.
1181 @raise ValueError: If the value cannot be encoded properly.
1182 """
1183 if value is not None:
1184 if not os.path.isabs(value):
1185 raise ValueError("Not an absolute path: [%s]" % value)
1186 self._absolutePath = encodePath(value)
1187
1189 """
1190 Property target used to get the absolute path.
1191 """
1192 return self._absolutePath
1193
1194 command = property(_getCommand, _setCommand, None, doc="Name of command to be overridden.")
1195 absolutePath = property(_getAbsolutePath, _setAbsolutePath, None, doc="Absolute path of the overrridden command.")
1196
1197
1198
1199
1200
1201
1203
1204 """
1205 Class representing a Cedar Backup collect file.
1206
1207 As with all of the other classes that represent configuration sections, all
1208 of these values are optional. It is up to some higher-level construct to
1209 decide whether everything they need is filled in. Some validation is done
1210 on non-C{None} assignments through the use of the Python C{property()}
1211 construct.
1212
1213 The following restrictions exist on data in this class:
1214
1215 - Absolute paths must be absolute
1216 - The collect mode must be one of the values in L{VALID_COLLECT_MODES}.
1217 - The archive mode must be one of the values in L{VALID_ARCHIVE_MODES}.
1218
1219 @sort: __init__, __repr__, __str__, __cmp__, absolutePath, collectMode, archiveMode
1220 """
1221
1222 - def __init__(self, absolutePath=None, collectMode=None, archiveMode=None):
1223 """
1224 Constructor for the C{CollectFile} class.
1225
1226 @param absolutePath: Absolute path of the file to collect.
1227 @param collectMode: Overridden collect mode for this file.
1228 @param archiveMode: Overridden archive mode for this file.
1229
1230 @raise ValueError: If one of the values is invalid.
1231 """
1232 self._absolutePath = None
1233 self._collectMode = None
1234 self._archiveMode = None
1235 self.absolutePath = absolutePath
1236 self.collectMode = collectMode
1237 self.archiveMode = archiveMode
1238
1244
1246 """
1247 Informal string representation for class instance.
1248 """
1249 return self.__repr__()
1250
1252 """
1253 Definition of equals operator for this class.
1254 @param other: Other object to compare to.
1255 @return: -1/0/1 depending on whether self is C{<}, C{=} or C{>} other.
1256 """
1257 if other is None:
1258 return 1
1259 if self._absolutePath != other._absolutePath:
1260 if self._absolutePath < other.absolutePath:
1261 return -1
1262 else:
1263 return 1
1264 if self._collectMode != other._collectMode:
1265 if self._collectMode < other._collectMode:
1266 return -1
1267 else:
1268 return 1
1269 if self._archiveMode != other._archiveMode:
1270 if self._archiveMode < other._archiveMode:
1271 return -1
1272 else:
1273 return 1
1274 return 0
1275
1277 """
1278 Property target used to set the absolute path.
1279 The value must be an absolute path if it is not C{None}.
1280 It does not have to exist on disk at the time of assignment.
1281 @raise ValueError: If the value is not an absolute path.
1282 @raise ValueError: If the value cannot be encoded properly.
1283 """
1284 if value is not None:
1285 if not os.path.isabs(value):
1286 raise ValueError("Not an absolute path: [%s]" % value)
1287 self._absolutePath = encodePath(value)
1288
1290 """
1291 Property target used to get the absolute path.
1292 """
1293 return self._absolutePath
1294
1296 """
1297 Property target used to set the collect mode.
1298 If not C{None}, the mode must be one of the values in L{VALID_COLLECT_MODES}.
1299 @raise ValueError: If the value is not valid.
1300 """
1301 if value is not None:
1302 if value not in VALID_COLLECT_MODES:
1303 raise ValueError("Collect mode must be one of %s." % VALID_COLLECT_MODES)
1304 self._collectMode = value
1305
1307 """
1308 Property target used to get the collect mode.
1309 """
1310 return self._collectMode
1311
1313 """
1314 Property target used to set the archive mode.
1315 If not C{None}, the mode must be one of the values in L{VALID_ARCHIVE_MODES}.
1316 @raise ValueError: If the value is not valid.
1317 """
1318 if value is not None:
1319 if value not in VALID_ARCHIVE_MODES:
1320 raise ValueError("Archive mode must be one of %s." % VALID_ARCHIVE_MODES)
1321 self._archiveMode = value
1322
1324 """
1325 Property target used to get the archive mode.
1326 """
1327 return self._archiveMode
1328
1329 absolutePath = property(_getAbsolutePath, _setAbsolutePath, None, doc="Absolute path of the file to collect.")
1330 collectMode = property(_getCollectMode, _setCollectMode, None, doc="Overridden collect mode for this file.")
1331 archiveMode = property(_getArchiveMode, _setArchiveMode, None, doc="Overridden archive mode for this file.")
1332
1333
1334
1335
1336
1337
1339
1340 """
1341 Class representing a Cedar Backup collect directory.
1342
1343 As with all of the other classes that represent configuration sections, all
1344 of these values are optional. It is up to some higher-level construct to
1345 decide whether everything they need is filled in. Some validation is done
1346 on non-C{None} assignments through the use of the Python C{property()}
1347 construct.
1348
1349 The following restrictions exist on data in this class:
1350
1351 - Absolute paths must be absolute
1352 - The collect mode must be one of the values in L{VALID_COLLECT_MODES}.
1353 - The archive mode must be one of the values in L{VALID_ARCHIVE_MODES}.
1354 - The ignore file must be a non-empty string.
1355
1356 For the C{absoluteExcludePaths} list, validation is accomplished through the
1357 L{util.AbsolutePathList} list implementation that overrides common list
1358 methods and transparently does the absolute path validation for us.
1359
1360 @note: Lists within this class are "unordered" for equality comparisons.
1361
1362 @sort: __init__, __repr__, __str__, __cmp__, absolutePath, collectMode,
1363 archiveMode, ignoreFile, linkDepth, dereference, absoluteExcludePaths,
1364 relativeExcludePaths, excludePatterns
1365 """
1366
1367 - def __init__(self, absolutePath=None, collectMode=None, archiveMode=None, ignoreFile=None,
1368 absoluteExcludePaths=None, relativeExcludePaths=None, excludePatterns=None,
1369 linkDepth=None, dereference=False):
1370 """
1371 Constructor for the C{CollectDir} class.
1372
1373 @param absolutePath: Absolute path of the directory to collect.
1374 @param collectMode: Overridden collect mode for this directory.
1375 @param archiveMode: Overridden archive mode for this directory.
1376 @param ignoreFile: Overidden ignore file name for this directory.
1377 @param linkDepth: Maximum at which soft links should be followed.
1378 @param dereference: Whether to dereference links that are followed.
1379 @param absoluteExcludePaths: List of absolute paths to exclude.
1380 @param relativeExcludePaths: List of relative paths to exclude.
1381 @param excludePatterns: List of regular expression patterns to exclude.
1382
1383 @raise ValueError: If one of the values is invalid.
1384 """
1385 self._absolutePath = None
1386 self._collectMode = None
1387 self._archiveMode = None
1388 self._ignoreFile = None
1389 self._linkDepth = None
1390 self._deference = None
1391 self._absoluteExcludePaths = None
1392 self._relativeExcludePaths = None
1393 self._excludePatterns = None
1394 self.absolutePath = absolutePath
1395 self.collectMode = collectMode
1396 self.archiveMode = archiveMode
1397 self.ignoreFile = ignoreFile
1398 self.linkDepth = linkDepth
1399 self.dereference = dereference
1400 self.absoluteExcludePaths = absoluteExcludePaths
1401 self.relativeExcludePaths = relativeExcludePaths
1402 self.excludePatterns = excludePatterns
1403
1405 """
1406 Official string representation for class instance.
1407 """
1408 return "CollectDir(%s, %s, %s, %s, %s, %s, %s, %s, %s)" % (self.absolutePath, self.collectMode,
1409 self.archiveMode, self.ignoreFile,
1410 self.absoluteExcludePaths,
1411 self.relativeExcludePaths,
1412 self.excludePatterns,
1413 self.linkDepth, self.dereference)
1414
1416 """
1417 Informal string representation for class instance.
1418 """
1419 return self.__repr__()
1420
1422 """
1423 Definition of equals operator for this class.
1424 Lists within this class are "unordered" for equality comparisons.
1425 @param other: Other object to compare to.
1426 @return: -1/0/1 depending on whether self is C{<}, C{=} or C{>} other.
1427 """
1428 if other is None:
1429 return 1
1430 if self._absolutePath != other._absolutePath:
1431 if self._absolutePath < other.absolutePath:
1432 return -1
1433 else:
1434 return 1
1435 if self._collectMode != other._collectMode:
1436 if self._collectMode < other._collectMode:
1437 return -1
1438 else:
1439 return 1
1440 if self._archiveMode != other._archiveMode:
1441 if self._archiveMode < other._archiveMode:
1442 return -1
1443 else:
1444 return 1
1445 if self._ignoreFile != other._ignoreFile:
1446 if self._ignoreFile < other._ignoreFile:
1447 return -1
1448 else:
1449 return 1
1450 if self._linkDepth != other._linkDepth:
1451 if self._linkDepth < other._linkDepth:
1452 return -1
1453 else:
1454 return 1
1455 if self._dereference != other._dereference:
1456 if self._dereference < other._dereference:
1457 return -1
1458 else:
1459 return 1
1460 if self._absoluteExcludePaths != other._absoluteExcludePaths:
1461 if self._absoluteExcludePaths < other._absoluteExcludePaths:
1462 return -1
1463 else:
1464 return 1
1465 if self._relativeExcludePaths != other._relativeExcludePaths:
1466 if self._relativeExcludePaths < other._relativeExcludePaths:
1467 return -1
1468 else:
1469 return 1
1470 if self._excludePatterns != other._excludePatterns:
1471 if self._excludePatterns < other._excludePatterns:
1472 return -1
1473 else:
1474 return 1
1475 return 0
1476
1478 """
1479 Property target used to set the absolute path.
1480 The value must be an absolute path if it is not C{None}.
1481 It does not have to exist on disk at the time of assignment.
1482 @raise ValueError: If the value is not an absolute path.
1483 @raise ValueError: If the value cannot be encoded properly.
1484 """
1485 if value is not None:
1486 if not os.path.isabs(value):
1487 raise ValueError("Not an absolute path: [%s]" % value)
1488 self._absolutePath = encodePath(value)
1489
1491 """
1492 Property target used to get the absolute path.
1493 """
1494 return self._absolutePath
1495
1497 """
1498 Property target used to set the collect mode.
1499 If not C{None}, the mode must be one of the values in L{VALID_COLLECT_MODES}.
1500 @raise ValueError: If the value is not valid.
1501 """
1502 if value is not None:
1503 if value not in VALID_COLLECT_MODES:
1504 raise ValueError("Collect mode must be one of %s." % VALID_COLLECT_MODES)
1505 self._collectMode = value
1506
1508 """
1509 Property target used to get the collect mode.
1510 """
1511 return self._collectMode
1512
1514 """
1515 Property target used to set the archive mode.
1516 If not C{None}, the mode must be one of the values in L{VALID_ARCHIVE_MODES}.
1517 @raise ValueError: If the value is not valid.
1518 """
1519 if value is not None:
1520 if value not in VALID_ARCHIVE_MODES:
1521 raise ValueError("Archive mode must be one of %s." % VALID_ARCHIVE_MODES)
1522 self._archiveMode = value
1523
1525 """
1526 Property target used to get the archive mode.
1527 """
1528 return self._archiveMode
1529
1531 """
1532 Property target used to set the ignore file.
1533 The value must be a non-empty string if it is not C{None}.
1534 @raise ValueError: If the value is an empty string.
1535 """
1536 if value is not None:
1537 if len(value) < 1:
1538 raise ValueError("The ignore file must be a non-empty string.")
1539 self._ignoreFile = value
1540
1542 """
1543 Property target used to get the ignore file.
1544 """
1545 return self._ignoreFile
1546
1548 """
1549 Property target used to set the link depth.
1550 The value must be an integer >= 0.
1551 @raise ValueError: If the value is not valid.
1552 """
1553 if value is None:
1554 self._linkDepth = None
1555 else:
1556 try:
1557 value = int(value)
1558 except TypeError:
1559 raise ValueError("Link depth value must be an integer >= 0.")
1560 if value < 0:
1561 raise ValueError("Link depth value must be an integer >= 0.")
1562 self._linkDepth = value
1563
1565 """
1566 Property target used to get the action linkDepth.
1567 """
1568 return self._linkDepth
1569
1571 """
1572 Property target used to set the dereference flag.
1573 No validations, but we normalize the value to C{True} or C{False}.
1574 """
1575 if value:
1576 self._dereference = True
1577 else:
1578 self._dereference = False
1579
1581 """
1582 Property target used to get the dereference flag.
1583 """
1584 return self._dereference
1585
1587 """
1588 Property target used to set the absolute exclude paths list.
1589 Either the value must be C{None} or each element must be an absolute path.
1590 Elements do not have to exist on disk at the time of assignment.
1591 @raise ValueError: If the value is not an absolute path.
1592 """
1593 if value is None:
1594 self._absoluteExcludePaths = None
1595 else:
1596 try:
1597 saved = self._absoluteExcludePaths
1598 self._absoluteExcludePaths = AbsolutePathList()
1599 self._absoluteExcludePaths.extend(value)
1600 except Exception, e:
1601 self._absoluteExcludePaths = saved
1602 raise e
1603
1605 """
1606 Property target used to get the absolute exclude paths list.
1607 """
1608 return self._absoluteExcludePaths
1609
1611 """
1612 Property target used to set the relative exclude paths list.
1613 Elements do not have to exist on disk at the time of assignment.
1614 """
1615 if value is None:
1616 self._relativeExcludePaths = None
1617 else:
1618 try:
1619 saved = self._relativeExcludePaths
1620 self._relativeExcludePaths = UnorderedList()
1621 self._relativeExcludePaths.extend(value)
1622 except Exception, e:
1623 self._relativeExcludePaths = saved
1624 raise e
1625
1627 """
1628 Property target used to get the relative exclude paths list.
1629 """
1630 return self._relativeExcludePaths
1631
1633 """
1634 Property target used to set the exclude patterns list.
1635 """
1636 if value is None:
1637 self._excludePatterns = None
1638 else:
1639 try:
1640 saved = self._excludePatterns
1641 self._excludePatterns = RegexList()
1642 self._excludePatterns.extend(value)
1643 except Exception, e:
1644 self._excludePatterns = saved
1645 raise e
1646
1648 """
1649 Property target used to get the exclude patterns list.
1650 """
1651 return self._excludePatterns
1652
1653 absolutePath = property(_getAbsolutePath, _setAbsolutePath, None, doc="Absolute path of the directory to collect.")
1654 collectMode = property(_getCollectMode, _setCollectMode, None, doc="Overridden collect mode for this directory.")
1655 archiveMode = property(_getArchiveMode, _setArchiveMode, None, doc="Overridden archive mode for this directory.")
1656 ignoreFile = property(_getIgnoreFile, _setIgnoreFile, None, doc="Overridden ignore file name for this directory.")
1657 linkDepth = property(_getLinkDepth, _setLinkDepth, None, doc="Maximum at which soft links should be followed.")
1658 dereference = property(_getDereference, _setDereference, None, doc="Whether to dereference links that are followed.")
1659 absoluteExcludePaths = property(_getAbsoluteExcludePaths, _setAbsoluteExcludePaths, None, "List of absolute paths to exclude.")
1660 relativeExcludePaths = property(_getRelativeExcludePaths, _setRelativeExcludePaths, None, "List of relative paths to exclude.")
1661 excludePatterns = property(_getExcludePatterns, _setExcludePatterns, None, "List of regular expression patterns to exclude.")
1662
1663
1664
1665
1666
1667
1669
1670 """
1671 Class representing a Cedar Backup purge directory.
1672
1673 As with all of the other classes that represent configuration sections, all
1674 of these values are optional. It is up to some higher-level construct to
1675 decide whether everything they need is filled in. Some validation is done
1676 on non-C{None} assignments through the use of the Python C{property()}
1677 construct.
1678
1679 The following restrictions exist on data in this class:
1680
1681 - The absolute path must be an absolute path
1682 - The retain days value must be an integer >= 0.
1683
1684 @sort: __init__, __repr__, __str__, __cmp__, absolutePath, retainDays
1685 """
1686
1687 - def __init__(self, absolutePath=None, retainDays=None):
1688 """
1689 Constructor for the C{PurgeDir} class.
1690
1691 @param absolutePath: Absolute path of the directory to be purged.
1692 @param retainDays: Number of days content within directory should be retained.
1693
1694 @raise ValueError: If one of the values is invalid.
1695 """
1696 self._absolutePath = None
1697 self._retainDays = None
1698 self.absolutePath = absolutePath
1699 self.retainDays = retainDays
1700
1702 """
1703 Official string representation for class instance.
1704 """
1705 return "PurgeDir(%s, %s)" % (self.absolutePath, self.retainDays)
1706
1708 """
1709 Informal string representation for class instance.
1710 """
1711 return self.__repr__()
1712
1714 """
1715 Definition of equals operator for this class.
1716 @param other: Other object to compare to.
1717 @return: -1/0/1 depending on whether self is C{<}, C{=} or C{>} other.
1718 """
1719 if other is None:
1720 return 1
1721 if self._absolutePath != other._absolutePath:
1722 if self._absolutePath < other._absolutePath:
1723 return -1
1724 else:
1725 return 1
1726 if self._retainDays != other._retainDays:
1727 if self._retainDays < other._retainDays:
1728 return -1
1729 else:
1730 return 1
1731 return 0
1732
1734 """
1735 Property target used to set the absolute path.
1736 The value must be an absolute path if it is not C{None}.
1737 It does not have to exist on disk at the time of assignment.
1738 @raise ValueError: If the value is not an absolute path.
1739 @raise ValueError: If the value cannot be encoded properly.
1740 """
1741 if value is not None:
1742 if not os.path.isabs(value):
1743 raise ValueError("Absolute path must, er, be an absolute path.")
1744 self._absolutePath = encodePath(value)
1745
1747 """
1748 Property target used to get the absolute path.
1749 """
1750 return self._absolutePath
1751
1753 """
1754 Property target used to set the retain days value.
1755 The value must be an integer >= 0.
1756 @raise ValueError: If the value is not valid.
1757 """
1758 if value is None:
1759 self._retainDays = None
1760 else:
1761 try:
1762 value = int(value)
1763 except TypeError:
1764 raise ValueError("Retain days value must be an integer >= 0.")
1765 if value < 0:
1766 raise ValueError("Retain days value must be an integer >= 0.")
1767 self._retainDays = value
1768
1770 """
1771 Property target used to get the absolute path.
1772 """
1773 return self._retainDays
1774
1775 absolutePath = property(_getAbsolutePath, _setAbsolutePath, None, "Absolute path of directory to purge.")
1776 retainDays = property(_getRetainDays, _setRetainDays, None, "Number of days content within directory should be retained.")
1777
1778
1779
1780
1781
1782
1784
1785 """
1786 Class representing a Cedar Backup peer.
1787
1788 As with all of the other classes that represent configuration sections, all
1789 of these values are optional. It is up to some higher-level construct to
1790 decide whether everything they need is filled in. Some validation is done
1791 on non-C{None} assignments through the use of the Python C{property()}
1792 construct.
1793
1794 The following restrictions exist on data in this class:
1795
1796 - The peer name must be a non-empty string.
1797 - The collect directory must be an absolute path.
1798 - The ignore failure mode must be one of the values in L{VALID_FAILURE_MODES}.
1799
1800 @sort: __init__, __repr__, __str__, __cmp__, name, collectDir
1801 """
1802
1803 - def __init__(self, name=None, collectDir=None, ignoreFailureMode=None):
1804 """
1805 Constructor for the C{LocalPeer} class.
1806
1807 @param name: Name of the peer, typically a valid hostname.
1808 @param collectDir: Collect directory to stage files from on peer.
1809 @param ignoreFailureMode: Ignore failure mode for peer.
1810
1811 @raise ValueError: If one of the values is invalid.
1812 """
1813 self._name = None
1814 self._collectDir = None
1815 self._ignoreFailureMode = None
1816 self.name = name
1817 self.collectDir = collectDir
1818 self.ignoreFailureMode = ignoreFailureMode
1819
1821 """
1822 Official string representation for class instance.
1823 """
1824 return "LocalPeer(%s, %s, %s)" % (self.name, self.collectDir, self.ignoreFailureMode)
1825
1827 """
1828 Informal string representation for class instance.
1829 """
1830 return self.__repr__()
1831
1833 """
1834 Definition of equals operator for this class.
1835 @param other: Other object to compare to.
1836 @return: -1/0/1 depending on whether self is C{<}, C{=} or C{>} other.
1837 """
1838 if other is None:
1839 return 1
1840 if self._name != other._name:
1841 if self._name < other._name:
1842 return -1
1843 else:
1844 return 1
1845 if self._collectDir != other._collectDir:
1846 if self._collectDir < other._collectDir:
1847 return -1
1848 else:
1849 return 1
1850 if self._ignoreFailureMode != other._ignoreFailureMode:
1851 if self._ignoreFailureMode < other._ignoreFailureMode:
1852 return -1
1853 else:
1854 return 1
1855 return 0
1856
1858 """
1859 Property target used to set the peer name.
1860 The value must be a non-empty string if it is not C{None}.
1861 @raise ValueError: If the value is an empty string.
1862 """
1863 if value is not None:
1864 if len(value) < 1:
1865 raise ValueError("The peer name must be a non-empty string.")
1866 self._name = value
1867
1869 """
1870 Property target used to get the peer name.
1871 """
1872 return self._name
1873
1875 """
1876 Property target used to set the collect directory.
1877 The value must be an absolute path if it is not C{None}.
1878 It does not have to exist on disk at the time of assignment.
1879 @raise ValueError: If the value is not an absolute path.
1880 @raise ValueError: If the value cannot be encoded properly.
1881 """
1882 if value is not None:
1883 if not os.path.isabs(value):
1884 raise ValueError("Collect directory must be an absolute path.")
1885 self._collectDir = encodePath(value)
1886
1888 """
1889 Property target used to get the collect directory.
1890 """
1891 return self._collectDir
1892
1894 """
1895 Property target used to set the ignoreFailure mode.
1896 If not C{None}, the mode must be one of the values in L{VALID_FAILURE_MODES}.
1897 @raise ValueError: If the value is not valid.
1898 """
1899 if value is not None:
1900 if value not in VALID_FAILURE_MODES:
1901 raise ValueError("Ignore failure mode must be one of %s." % VALID_FAILURE_MODES)
1902 self._ignoreFailureMode = value
1903
1905 """
1906 Property target used to get the ignoreFailure mode.
1907 """
1908 return self._ignoreFailureMode
1909
1910 name = property(_getName, _setName, None, "Name of the peer, typically a valid hostname.")
1911 collectDir = property(_getCollectDir, _setCollectDir, None, "Collect directory to stage files from on peer.")
1912 ignoreFailureMode = property(_getIgnoreFailureMode, _setIgnoreFailureMode, None, "Ignore failure mode for peer.")
1913
1914
1915
1916
1917
1918
1920
1921 """
1922 Class representing a Cedar Backup peer.
1923
1924 As with all of the other classes that represent configuration sections, all
1925 of these values are optional. It is up to some higher-level construct to
1926 decide whether everything they need is filled in. Some validation is done
1927 on non-C{None} assignments through the use of the Python C{property()}
1928 construct.
1929
1930 The following restrictions exist on data in this class:
1931
1932 - The peer name must be a non-empty string.
1933 - The collect directory must be an absolute path.
1934 - The remote user must be a non-empty string.
1935 - The rcp command must be a non-empty string.
1936 - The rsh command must be a non-empty string.
1937 - The cback command must be a non-empty string.
1938 - Any managed action name must be a non-empty string matching C{ACTION_NAME_REGEX}
1939 - The ignore failure mode must be one of the values in L{VALID_FAILURE_MODES}.
1940
1941 @sort: __init__, __repr__, __str__, __cmp__, name, collectDir, remoteUser, rcpCommand
1942 """
1943
1944 - def __init__(self, name=None, collectDir=None, remoteUser=None,
1945 rcpCommand=None, rshCommand=None, cbackCommand=None,
1946 managed=False, managedActions=None, ignoreFailureMode=None):
1947 """
1948 Constructor for the C{RemotePeer} class.
1949
1950 @param name: Name of the peer, must be a valid hostname.
1951 @param collectDir: Collect directory to stage files from on peer.
1952 @param remoteUser: Name of backup user on remote peer.
1953 @param rcpCommand: Overridden rcp-compatible copy command for peer.
1954 @param rshCommand: Overridden rsh-compatible remote shell command for peer.
1955 @param cbackCommand: Overridden cback-compatible command to use on remote peer.
1956 @param managed: Indicates whether this is a managed peer.
1957 @param managedActions: Overridden set of actions that are managed on the peer.
1958 @param ignoreFailureMode: Ignore failure mode for peer.
1959
1960 @raise ValueError: If one of the values is invalid.
1961 """
1962 self._name = None
1963 self._collectDir = None
1964 self._remoteUser = None
1965 self._rcpCommand = None
1966 self._rshCommand = None
1967 self._cbackCommand = None
1968 self._managed = None
1969 self._managedActions = None
1970 self._ignoreFailureMode = None
1971 self.name = name
1972 self.collectDir = collectDir
1973 self.remoteUser = remoteUser
1974 self.rcpCommand = rcpCommand
1975 self.rshCommand = rshCommand
1976 self.cbackCommand = cbackCommand
1977 self.managed = managed
1978 self.managedActions = managedActions
1979 self.ignoreFailureMode = ignoreFailureMode
1980
1982 """
1983 Official string representation for class instance.
1984 """
1985 return "RemotePeer(%s, %s, %s, %s, %s, %s, %s, %s, %s)" % (self.name, self.collectDir, self.remoteUser,
1986 self.rcpCommand, self.rshCommand, self.cbackCommand,
1987 self.managed, self.managedActions, self.ignoreFailureMode)
1988
1990 """
1991 Informal string representation for class instance.
1992 """
1993 return self.__repr__()
1994
1996 """
1997 Definition of equals operator for this class.
1998 @param other: Other object to compare to.
1999 @return: -1/0/1 depending on whether self is C{<}, C{=} or C{>} other.
2000 """
2001 if other is None:
2002 return 1
2003 if self._name != other._name:
2004 if self._name < other._name:
2005 return -1
2006 else:
2007 return 1
2008 if self._collectDir != other._collectDir:
2009 if self._collectDir < other._collectDir:
2010 return -1
2011 else:
2012 return 1
2013 if self._remoteUser != other._remoteUser:
2014 if self._remoteUser < other._remoteUser:
2015 return -1
2016 else:
2017 return 1
2018 if self._rcpCommand != other._rcpCommand:
2019 if self._rcpCommand < other._rcpCommand:
2020 return -1
2021 else:
2022 return 1
2023 if self._rshCommand != other._rshCommand:
2024 if self._rshCommand < other._rshCommand:
2025 return -1
2026 else:
2027 return 1
2028 if self._cbackCommand != other._cbackCommand:
2029 if self._cbackCommand < other._cbackCommand:
2030 return -1
2031 else:
2032 return 1
2033 if self._managed != other._managed:
2034 if self._managed < other._managed:
2035 return -1
2036 else:
2037 return 1
2038 if self._managedActions != other._managedActions:
2039 if self._managedActions < other._managedActions:
2040 return -1
2041 else:
2042 return 1
2043 if self._ignoreFailureMode != other._ignoreFailureMode:
2044 if self._ignoreFailureMode < other._ignoreFailureMode:
2045 return -1
2046 else:
2047 return 1
2048 return 0
2049
2051 """
2052 Property target used to set the peer name.
2053 The value must be a non-empty string if it is not C{None}.
2054 @raise ValueError: If the value is an empty string.
2055 """
2056 if value is not None:
2057 if len(value) < 1:
2058 raise ValueError("The peer name must be a non-empty string.")
2059 self._name = value
2060
2062 """
2063 Property target used to get the peer name.
2064 """
2065 return self._name
2066
2068 """
2069 Property target used to set the collect directory.
2070 The value must be an absolute path if it is not C{None}.
2071 It does not have to exist on disk at the time of assignment.
2072 @raise ValueError: If the value is not an absolute path.
2073 @raise ValueError: If the value cannot be encoded properly.
2074 """
2075 if value is not None:
2076 if not os.path.isabs(value):
2077 raise ValueError("Collect directory must be an absolute path.")
2078 self._collectDir = encodePath(value)
2079
2081 """
2082 Property target used to get the collect directory.
2083 """
2084 return self._collectDir
2085
2087 """
2088 Property target used to set the remote user.
2089 The value must be a non-empty string if it is not C{None}.
2090 @raise ValueError: If the value is an empty string.
2091 """
2092 if value is not None:
2093 if len(value) < 1:
2094 raise ValueError("The remote user must be a non-empty string.")
2095 self._remoteUser = value
2096
2098 """
2099 Property target used to get the remote user.
2100 """
2101 return self._remoteUser
2102
2104 """
2105 Property target used to set the rcp command.
2106 The value must be a non-empty string if it is not C{None}.
2107 @raise ValueError: If the value is an empty string.
2108 """
2109 if value is not None:
2110 if len(value) < 1:
2111 raise ValueError("The rcp command must be a non-empty string.")
2112 self._rcpCommand = value
2113
2115 """
2116 Property target used to get the rcp command.
2117 """
2118 return self._rcpCommand
2119
2121 """
2122 Property target used to set the rsh command.
2123 The value must be a non-empty string if it is not C{None}.
2124 @raise ValueError: If the value is an empty string.
2125 """
2126 if value is not None:
2127 if len(value) < 1:
2128 raise ValueError("The rsh command must be a non-empty string.")
2129 self._rshCommand = value
2130
2132 """
2133 Property target used to get the rsh command.
2134 """
2135 return self._rshCommand
2136
2138 """
2139 Property target used to set the cback command.
2140 The value must be a non-empty string if it is not C{None}.
2141 @raise ValueError: If the value is an empty string.
2142 """
2143 if value is not None:
2144 if len(value) < 1:
2145 raise ValueError("The cback command must be a non-empty string.")
2146 self._cbackCommand = value
2147
2149 """
2150 Property target used to get the cback command.
2151 """
2152 return self._cbackCommand
2153
2155 """
2156 Property target used to set the managed flag.
2157 No validations, but we normalize the value to C{True} or C{False}.
2158 """
2159 if value:
2160 self._managed = True
2161 else:
2162 self._managed = False
2163
2165 """
2166 Property target used to get the managed flag.
2167 """
2168 return self._managed
2169
2171 """
2172 Property target used to set the managed actions list.
2173 Elements do not have to exist on disk at the time of assignment.
2174 """
2175 if value is None:
2176 self._managedActions = None
2177 else:
2178 try:
2179 saved = self._managedActions
2180 self._managedActions = RegexMatchList(ACTION_NAME_REGEX, emptyAllowed=False, prefix="Action name")
2181 self._managedActions.extend(value)
2182 except Exception, e:
2183 self._managedActions = saved
2184 raise e
2185
2187 """
2188 Property target used to get the managed actions list.
2189 """
2190 return self._managedActions
2191
2193 """
2194 Property target used to set the ignoreFailure mode.
2195 If not C{None}, the mode must be one of the values in L{VALID_FAILURE_MODES}.
2196 @raise ValueError: If the value is not valid.
2197 """
2198 if value is not None:
2199 if value not in VALID_FAILURE_MODES:
2200 raise ValueError("Ignore failure mode must be one of %s." % VALID_FAILURE_MODES)
2201 self._ignoreFailureMode = value
2202
2204 """
2205 Property target used to get the ignoreFailure mode.
2206 """
2207 return self._ignoreFailureMode
2208
2209 name = property(_getName, _setName, None, "Name of the peer, must be a valid hostname.")
2210 collectDir = property(_getCollectDir, _setCollectDir, None, "Collect directory to stage files from on peer.")
2211 remoteUser = property(_getRemoteUser, _setRemoteUser, None, "Name of backup user on remote peer.")
2212 rcpCommand = property(_getRcpCommand, _setRcpCommand, None, "Overridden rcp-compatible copy command for peer.")
2213 rshCommand = property(_getRshCommand, _setRshCommand, None, "Overridden rsh-compatible remote shell command for peer.")
2214 cbackCommand = property(_getCbackCommand, _setCbackCommand, None, "Overridden cback-compatible command to use on remote peer.")
2215 managed = property(_getManaged, _setManaged, None, "Indicates whether this is a managed peer.")
2216 managedActions = property(_getManagedActions, _setManagedActions, None, "Overridden set of actions that are managed on the peer.")
2217 ignoreFailureMode = property(_getIgnoreFailureMode, _setIgnoreFailureMode, None, "Ignore failure mode for peer.")
2218
2219
2220
2221
2222
2223
2225
2226 """
2227 Class representing a Cedar Backup reference configuration.
2228
2229 The reference information is just used for saving off metadata about
2230 configuration and exists mostly for backwards-compatibility with Cedar
2231 Backup 1.x.
2232
2233 As with all of the other classes that represent configuration sections, all
2234 of these values are optional. It is up to some higher-level construct to
2235 decide whether everything they need is filled in. We don't do any
2236 validation on the contents of any of the fields, although we generally
2237 expect them to be strings.
2238
2239 @sort: __init__, __repr__, __str__, __cmp__, author, revision, description, generator
2240 """
2241
2242 - def __init__(self, author=None, revision=None, description=None, generator=None):
2243 """
2244 Constructor for the C{ReferenceConfig} class.
2245
2246 @param author: Author of the configuration file.
2247 @param revision: Revision of the configuration file.
2248 @param description: Description of the configuration file.
2249 @param generator: Tool that generated the configuration file.
2250 """
2251 self._author = None
2252 self._revision = None
2253 self._description = None
2254 self._generator = None
2255 self.author = author
2256 self.revision = revision
2257 self.description = description
2258 self.generator = generator
2259
2261 """
2262 Official string representation for class instance.
2263 """
2264 return "ReferenceConfig(%s, %s, %s, %s)" % (self.author, self.revision, self.description, self.generator)
2265
2267 """
2268 Informal string representation for class instance.
2269 """
2270 return self.__repr__()
2271
2273 """
2274 Definition of equals operator for this class.
2275 @param other: Other object to compare to.
2276 @return: -1/0/1 depending on whether self is C{<}, C{=} or C{>} other.
2277 """
2278 if other is None:
2279 return 1
2280 if self._author != other._author:
2281 if self._author < other._author:
2282 return -1
2283 else:
2284 return 1
2285 if self._revision != other._revision:
2286 if self._revision < other._revision:
2287 return -1
2288 else:
2289 return 1
2290 if self._description != other._description:
2291 if self._description < other._description:
2292 return -1
2293 else:
2294 return 1
2295 if self._generator != other._generator:
2296 if self._generator < other._generator:
2297 return -1
2298 else:
2299 return 1
2300 return 0
2301
2303 """
2304 Property target used to set the author value.
2305 No validations.
2306 """
2307 self._author = value
2308
2310 """
2311 Property target used to get the author value.
2312 """
2313 return self._author
2314
2316 """
2317 Property target used to set the revision value.
2318 No validations.
2319 """
2320 self._revision = value
2321
2323 """
2324 Property target used to get the revision value.
2325 """
2326 return self._revision
2327
2329 """
2330 Property target used to set the description value.
2331 No validations.
2332 """
2333 self._description = value
2334
2336 """
2337 Property target used to get the description value.
2338 """
2339 return self._description
2340
2342 """
2343 Property target used to set the generator value.
2344 No validations.
2345 """
2346 self._generator = value
2347
2349 """
2350 Property target used to get the generator value.
2351 """
2352 return self._generator
2353
2354 author = property(_getAuthor, _setAuthor, None, "Author of the configuration file.")
2355 revision = property(_getRevision, _setRevision, None, "Revision of the configuration file.")
2356 description = property(_getDescription, _setDescription, None, "Description of the configuration file.")
2357 generator = property(_getGenerator, _setGenerator, None, "Tool that generated the configuration file.")
2358
2359
2360
2361
2362
2363
2365
2366 """
2367 Class representing Cedar Backup extensions configuration.
2368
2369 Extensions configuration is used to specify "extended actions" implemented
2370 by code external to Cedar Backup. For instance, a hypothetical third party
2371 might write extension code to collect database repository data. If they
2372 write a properly-formatted extension function, they can use the extension
2373 configuration to map a command-line Cedar Backup action (i.e. "database")
2374 to their function.
2375
2376 As with all of the other classes that represent configuration sections, all
2377 of these values are optional. It is up to some higher-level construct to
2378 decide whether everything they need is filled in. Some validation is done
2379 on non-C{None} assignments through the use of the Python C{property()}
2380 construct.
2381
2382 The following restrictions exist on data in this class:
2383
2384 - If set, the order mode must be one of the values in C{VALID_ORDER_MODES}
2385 - The actions list must be a list of C{ExtendedAction} objects.
2386
2387 @sort: __init__, __repr__, __str__, __cmp__, orderMode, actions
2388 """
2389
2390 - def __init__(self, actions=None, orderMode=None):
2391 """
2392 Constructor for the C{ExtensionsConfig} class.
2393 @param actions: List of extended actions
2394 """
2395 self._orderMode = None
2396 self._actions = None
2397 self.orderMode = orderMode
2398 self.actions = actions
2399
2401 """
2402 Official string representation for class instance.
2403 """
2404 return "ExtensionsConfig(%s, %s)" % (self.orderMode, self.actions)
2405
2407 """
2408 Informal string representation for class instance.
2409 """
2410 return self.__repr__()
2411
2413 """
2414 Definition of equals operator for this class.
2415 @param other: Other object to compare to.
2416 @return: -1/0/1 depending on whether self is C{<}, C{=} or C{>} other.
2417 """
2418 if other is None:
2419 return 1
2420 if self._orderMode != other._orderMode:
2421 if self._orderMode < other._orderMode:
2422 return -1
2423 else:
2424 return 1
2425 if self._actions != other._actions:
2426 if self._actions < other._actions:
2427 return -1
2428 else:
2429 return 1
2430 return 0
2431
2433 """
2434 Property target used to set the order mode.
2435 The value must be one of L{VALID_ORDER_MODES}.
2436 @raise ValueError: If the value is not valid.
2437 """
2438 if value is not None:
2439 if value not in VALID_ORDER_MODES:
2440 raise ValueError("Order mode must be one of %s." % VALID_ORDER_MODES)
2441 self._orderMode = value
2442
2444 """
2445 Property target used to get the order mode.
2446 """
2447 return self._orderMode
2448
2450 """
2451 Property target used to set the actions list.
2452 Either the value must be C{None} or each element must be an C{ExtendedAction}.
2453 @raise ValueError: If the value is not a C{ExtendedAction}
2454 """
2455 if value is None:
2456 self._actions = None
2457 else:
2458 try:
2459 saved = self._actions
2460 self._actions = ObjectTypeList(ExtendedAction, "ExtendedAction")
2461 self._actions.extend(value)
2462 except Exception, e:
2463 self._actions = saved
2464 raise e
2465
2467 """
2468 Property target used to get the actions list.
2469 """
2470 return self._actions
2471
2472 orderMode = property(_getOrderMode, _setOrderMode, None, "Order mode for extensions, to control execution ordering.")
2473 actions = property(_getActions, _setActions, None, "List of extended actions.")
2474
2475
2476
2477
2478
2479
2481
2482 """
2483 Class representing a Cedar Backup global options configuration.
2484
2485 The options section is used to store global configuration options and
2486 defaults that can be applied to other sections.
2487
2488 As with all of the other classes that represent configuration sections, all
2489 of these values are optional. It is up to some higher-level construct to
2490 decide whether everything they need is filled in. Some validation is done
2491 on non-C{None} assignments through the use of the Python C{property()}
2492 construct.
2493
2494 The following restrictions exist on data in this class:
2495
2496 - The working directory must be an absolute path.
2497 - The starting day must be a day of the week in English, i.e. C{"monday"}, C{"tuesday"}, etc.
2498 - All of the other values must be non-empty strings if they are set to something other than C{None}.
2499 - The overrides list must be a list of C{CommandOverride} objects.
2500 - The hooks list must be a list of C{ActionHook} objects.
2501 - The cback command must be a non-empty string.
2502 - Any managed action name must be a non-empty string matching C{ACTION_NAME_REGEX}
2503
2504 @sort: __init__, __repr__, __str__, __cmp__, startingDay, workingDir,
2505 backupUser, backupGroup, rcpCommand, rshCommand, overrides
2506 """
2507
2508 - def __init__(self, startingDay=None, workingDir=None, backupUser=None,
2509 backupGroup=None, rcpCommand=None, overrides=None,
2510 hooks=None, rshCommand=None, cbackCommand=None,
2511 managedActions=None):
2512 """
2513 Constructor for the C{OptionsConfig} class.
2514
2515 @param startingDay: Day that starts the week.
2516 @param workingDir: Working (temporary) directory to use for backups.
2517 @param backupUser: Effective user that backups should run as.
2518 @param backupGroup: Effective group that backups should run as.
2519 @param rcpCommand: Default rcp-compatible copy command for staging.
2520 @param rshCommand: Default rsh-compatible command to use for remote shells.
2521 @param cbackCommand: Default cback-compatible command to use on managed remote peers.
2522 @param overrides: List of configured command path overrides, if any.
2523 @param hooks: List of configured pre- and post-action hooks.
2524 @param managedActions: Default set of actions that are managed on remote peers.
2525
2526 @raise ValueError: If one of the values is invalid.
2527 """
2528 self._startingDay = None
2529 self._workingDir = None
2530 self._backupUser = None
2531 self._backupGroup = None
2532 self._rcpCommand = None
2533 self._rshCommand = None
2534 self._cbackCommand = None
2535 self._overrides = None
2536 self._hooks = None
2537 self._managedActions = None
2538 self.startingDay = startingDay
2539 self.workingDir = workingDir
2540 self.backupUser = backupUser
2541 self.backupGroup = backupGroup
2542 self.rcpCommand = rcpCommand
2543 self.rshCommand = rshCommand
2544 self.cbackCommand = cbackCommand
2545 self.overrides = overrides
2546 self.hooks = hooks
2547 self.managedActions = managedActions
2548
2550 """
2551 Official string representation for class instance.
2552 """
2553 return "OptionsConfig(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)" % (self.startingDay, self.workingDir,
2554 self.backupUser, self.backupGroup,
2555 self.rcpCommand, self.overrides,
2556 self.hooks, self.rshCommand,
2557 self.cbackCommand, self.managedActions)
2558
2560 """
2561 Informal string representation for class instance.
2562 """
2563 return self.__repr__()
2564
2566 """
2567 Definition of equals operator for this class.
2568 @param other: Other object to compare to.
2569 @return: -1/0/1 depending on whether self is C{<}, C{=} or C{>} other.
2570 """
2571 if other is None:
2572 return 1
2573 if self._startingDay != other._startingDay:
2574 if self._startingDay < other._startingDay:
2575 return -1
2576 else:
2577 return 1
2578 if self._workingDir != other._workingDir:
2579 if self._workingDir < other._workingDir:
2580 return -1
2581 else:
2582 return 1
2583 if self._backupUser != other._backupUser:
2584 if self._backupUser < other._backupUser:
2585 return -1
2586 else:
2587 return 1
2588 if self._backupGroup != other._backupGroup:
2589 if self._backupGroup < other._backupGroup:
2590 return -1
2591 else:
2592 return 1
2593 if self._rcpCommand != other._rcpCommand:
2594 if self._rcpCommand < other._rcpCommand:
2595 return -1
2596 else:
2597 return 1
2598 if self._rshCommand != other._rshCommand:
2599 if self._rshCommand < other._rshCommand:
2600 return -1
2601 else:
2602 return 1
2603 if self._cbackCommand != other._cbackCommand:
2604 if self._cbackCommand < other._cbackCommand:
2605 return -1
2606 else:
2607 return 1
2608 if self._overrides != other._overrides:
2609 if self._overrides < other._overrides:
2610 return -1
2611 else:
2612 return 1
2613 if self._hooks != other._hooks:
2614 if self._hooks < other._hooks:
2615 return -1
2616 else:
2617 return 1
2618 if self._managedActions != other._managedActions:
2619 if self._managedActions < other._managedActions:
2620 return -1
2621 else:
2622 return 1
2623 return 0
2624
2626 """
2627 If no override currently exists for the command, add one.
2628 @param command: Name of command to be overridden.
2629 @param absolutePath: Absolute path of the overrridden command.
2630 """
2631 override = CommandOverride(command, absolutePath)
2632 if self.overrides is None:
2633 self.overrides = [ override, ]
2634 else:
2635 exists = False
2636 for object in self.overrides:
2637 if object.command == override.command:
2638 exists = True
2639 break
2640 if not exists:
2641 self.overrides.append(override)
2642
2644 """
2645 If override currently exists for the command, replace it; otherwise add it.
2646 @param command: Name of command to be overridden.
2647 @param absolutePath: Absolute path of the overrridden command.
2648 """
2649 override = CommandOverride(command, absolutePath)
2650 if self.overrides is None:
2651 self.overrides = [ override, ]
2652 else:
2653 exists = False
2654 for object in self.overrides:
2655 if object.command == override.command:
2656 exists = True
2657 object.absolutePath = override.absolutePath
2658 break
2659 if not exists:
2660 self.overrides.append(override)
2661
2663 """
2664 Property target used to set the starting day.
2665 If it is not C{None}, the value must be a valid English day of the week,
2666 one of C{"monday"}, C{"tuesday"}, C{"wednesday"}, etc.
2667 @raise ValueError: If the value is not a valid day of the week.
2668 """
2669 if value is not None:
2670 if value not in ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday", ]:
2671 raise ValueError("Starting day must be an English day of the week, i.e. \"monday\".")
2672 self._startingDay = value
2673
2675 """
2676 Property target used to get the starting day.
2677 """
2678 return self._startingDay
2679
2681 """
2682 Property target used to set the working directory.
2683 The value must be an absolute path if it is not C{None}.
2684 It does not have to exist on disk at the time of assignment.
2685 @raise ValueError: If the value is not an absolute path.
2686 @raise ValueError: If the value cannot be encoded properly.
2687 """
2688 if value is not None:
2689 if not os.path.isabs(value):
2690 raise ValueError("Working directory must be an absolute path.")
2691 self._workingDir = encodePath(value)
2692
2694 """
2695 Property target used to get the working directory.
2696 """
2697 return self._workingDir
2698
2700 """
2701 Property target used to set the backup user.
2702 The value must be a non-empty string if it is not C{None}.
2703 @raise ValueError: If the value is an empty string.
2704 """
2705 if value is not None:
2706 if len(value) < 1:
2707 raise ValueError("Backup user must be a non-empty string.")
2708 self._backupUser = value
2709
2711 """
2712 Property target used to get the backup user.
2713 """
2714 return self._backupUser
2715
2717 """
2718 Property target used to set the backup group.
2719 The value must be a non-empty string if it is not C{None}.
2720 @raise ValueError: If the value is an empty string.
2721 """
2722 if value is not None:
2723 if len(value) < 1:
2724 raise ValueError("Backup group must be a non-empty string.")
2725 self._backupGroup = value
2726
2728 """
2729 Property target used to get the backup group.
2730 """
2731 return self._backupGroup
2732
2734 """
2735 Property target used to set the rcp command.
2736 The value must be a non-empty string if it is not C{None}.
2737 @raise ValueError: If the value is an empty string.
2738 """
2739 if value is not None:
2740 if len(value) < 1:
2741 raise ValueError("The rcp command must be a non-empty string.")
2742 self._rcpCommand = value
2743
2745 """
2746 Property target used to get the rcp command.
2747 """
2748 return self._rcpCommand
2749
2751 """
2752 Property target used to set the rsh command.
2753 The value must be a non-empty string if it is not C{None}.
2754 @raise ValueError: If the value is an empty string.
2755 """
2756 if value is not None:
2757 if len(value) < 1:
2758 raise ValueError("The rsh command must be a non-empty string.")
2759 self._rshCommand = value
2760
2762 """
2763 Property target used to get the rsh command.
2764 """
2765 return self._rshCommand
2766
2768 """
2769 Property target used to set the cback command.
2770 The value must be a non-empty string if it is not C{None}.
2771 @raise ValueError: If the value is an empty string.
2772 """
2773 if value is not None:
2774 if len(value) < 1:
2775 raise ValueError("The cback command must be a non-empty string.")
2776 self._cbackCommand = value
2777
2779 """
2780 Property target used to get the cback command.
2781 """
2782 return self._cbackCommand
2783
2785 """
2786 Property target used to set the command path overrides list.
2787 Either the value must be C{None} or each element must be a C{CommandOverride}.
2788 @raise ValueError: If the value is not a C{CommandOverride}
2789 """
2790 if value is None:
2791 self._overrides = None
2792 else:
2793 try:
2794 saved = self._overrides
2795 self._overrides = ObjectTypeList(CommandOverride, "CommandOverride")
2796 self._overrides.extend(value)
2797 except Exception, e:
2798 self._overrides = saved
2799 raise e
2800
2802 """
2803 Property target used to get the command path overrides list.
2804 """
2805 return self._overrides
2806
2808 """
2809 Property target used to set the pre- and post-action hooks list.
2810 Either the value must be C{None} or each element must be an C{ActionHook}.
2811 @raise ValueError: If the value is not a C{CommandOverride}
2812 """
2813 if value is None:
2814 self._hooks = None
2815 else:
2816 try:
2817 saved = self._hooks
2818 self._hooks = ObjectTypeList(ActionHook, "ActionHook")
2819 self._hooks.extend(value)
2820 except Exception, e:
2821 self._hooks = saved
2822 raise e
2823
2825 """
2826 Property target used to get the command path hooks list.
2827 """
2828 return self._hooks
2829
2831 """
2832 Property target used to set the managed actions list.
2833 Elements do not have to exist on disk at the time of assignment.
2834 """
2835 if value is None:
2836 self._managedActions = None
2837 else:
2838 try:
2839 saved = self._managedActions
2840 self._managedActions = RegexMatchList(ACTION_NAME_REGEX, emptyAllowed=False, prefix="Action name")
2841 self._managedActions.extend(value)
2842 except Exception, e:
2843 self._managedActions = saved
2844 raise e
2845
2847 """
2848 Property target used to get the managed actions list.
2849 """
2850 return self._managedActions
2851
2852 startingDay = property(_getStartingDay, _setStartingDay, None, "Day that starts the week.")
2853 workingDir = property(_getWorkingDir, _setWorkingDir, None, "Working (temporary) directory to use for backups.")
2854 backupUser = property(_getBackupUser, _setBackupUser, None, "Effective user that backups should run as.")
2855 backupGroup = property(_getBackupGroup, _setBackupGroup, None, "Effective group that backups should run as.")
2856 rcpCommand = property(_getRcpCommand, _setRcpCommand, None, "Default rcp-compatible copy command for staging.")
2857 rshCommand = property(_getRshCommand, _setRshCommand, None, "Default rsh-compatible command to use for remote shells.")
2858 cbackCommand = property(_getCbackCommand, _setCbackCommand, None, "Default cback-compatible command to use on managed remote peers.")
2859 overrides = property(_getOverrides, _setOverrides, None, "List of configured command path overrides, if any.")
2860 hooks = property(_getHooks, _setHooks, None, "List of configured pre- and post-action hooks.")
2861 managedActions = property(_getManagedActions, _setManagedActions, None, "Default set of actions that are managed on remote peers.")
2862
2863
2864
2865
2866
2867
2869
2870 """
2871 Class representing Cedar Backup global peer configuration.
2872
2873 This section contains a list of local and remote peers in a master's backup
2874 pool. The section is optional. If a master does not define this section,
2875 then all peers are unmanaged, and the stage configuration section must
2876 explicitly list any peer that is to be staged. If this section is
2877 configured, then peers may be managed or unmanaged, and the stage section
2878 peer configuration (if any) completely overrides this configuration.
2879
2880 As with all of the other classes that represent configuration sections, all
2881 of these values are optional. It is up to some higher-level construct to
2882 decide whether everything they need is filled in.
2883
2884 The following restrictions exist on data in this class:
2885
2886 - The list of local peers must contain only C{LocalPeer} objects
2887 - The list of remote peers must contain only C{RemotePeer} objects
2888
2889 @note: Lists within this class are "unordered" for equality comparisons.
2890
2891 @sort: __init__, __repr__, __str__, __cmp__, localPeers, remotePeers
2892 """
2893
2894 - def __init__(self, localPeers=None, remotePeers=None):
2895 """
2896 Constructor for the C{PeersConfig} class.
2897
2898 @param localPeers: List of local peers.
2899 @param remotePeers: List of remote peers.
2900
2901 @raise ValueError: If one of the values is invalid.
2902 """
2903 self._localPeers = None
2904 self._remotePeers = None
2905 self.localPeers = localPeers
2906 self.remotePeers = remotePeers
2907
2909 """
2910 Official string representation for class instance.
2911 """
2912 return "PeersConfig(%s, %s)" % (self.localPeers, self.remotePeers)
2913
2915 """
2916 Informal string representation for class instance.
2917 """
2918 return self.__repr__()
2919
2921 """
2922 Definition of equals operator for this class.
2923 Lists within this class are "unordered" for equality comparisons.
2924 @param other: Other object to compare to.
2925 @return: -1/0/1 depending on whether self is C{<}, C{=} or C{>} other.
2926 """
2927 if other is None:
2928 return 1
2929 if self._localPeers != other._localPeers:
2930 if self._localPeers < other._localPeers:
2931 return -1
2932 else:
2933 return 1
2934 if self._remotePeers != other._remotePeers:
2935 if self._remotePeers < other._remotePeers:
2936 return -1
2937 else:
2938 return 1
2939 return 0
2940
2942 """
2943 Indicates whether any peers are filled into this object.
2944 @return: Boolean true if any local or remote peers are filled in, false otherwise.
2945 """
2946 return ((self.localPeers is not None and len(self.localPeers) > 0) or
2947 (self.remotePeers is not None and len(self.remotePeers) > 0))
2948
2950 """
2951 Property target used to set the local peers list.
2952 Either the value must be C{None} or each element must be a C{LocalPeer}.
2953 @raise ValueError: If the value is not an absolute path.
2954 """
2955 if value is None:
2956 self._localPeers = None
2957 else:
2958 try:
2959 saved = self._localPeers
2960 self._localPeers = ObjectTypeList(LocalPeer, "LocalPeer")
2961 self._localPeers.extend(value)
2962 except Exception, e:
2963 self._localPeers = saved
2964 raise e
2965
2967 """
2968 Property target used to get the local peers list.
2969 """
2970 return self._localPeers
2971
2973 """
2974 Property target used to set the remote peers list.
2975 Either the value must be C{None} or each element must be a C{RemotePeer}.
2976 @raise ValueError: If the value is not a C{RemotePeer}
2977 """
2978 if value is None:
2979 self._remotePeers = None
2980 else:
2981 try:
2982 saved = self._remotePeers
2983 self._remotePeers = ObjectTypeList(RemotePeer, "RemotePeer")
2984 self._remotePeers.extend(value)
2985 except Exception, e:
2986 self._remotePeers = saved
2987 raise e
2988
2990 """
2991 Property target used to get the remote peers list.
2992 """
2993 return self._remotePeers
2994
2995 localPeers = property(_getLocalPeers, _setLocalPeers, None, "List of local peers.")
2996 remotePeers = property(_getRemotePeers, _setRemotePeers, None, "List of remote peers.")
2997
2998
2999
3000
3001
3002
3004
3005 """
3006 Class representing a Cedar Backup collect configuration.
3007
3008 As with all of the other classes that represent configuration sections, all
3009 of these values are optional. It is up to some higher-level construct to
3010 decide whether everything they need is filled in. Some validation is done
3011 on non-C{None} assignments through the use of the Python C{property()}
3012 construct.
3013
3014 The following restrictions exist on data in this class:
3015
3016 - The target directory must be an absolute path.
3017 - The collect mode must be one of the values in L{VALID_COLLECT_MODES}.
3018 - The archive mode must be one of the values in L{VALID_ARCHIVE_MODES}.
3019 - The ignore file must be a non-empty string.
3020 - Each of the paths in C{absoluteExcludePaths} must be an absolute path
3021 - The collect file list must be a list of C{CollectFile} objects.
3022 - The collect directory list must be a list of C{CollectDir} objects.
3023
3024 For the C{absoluteExcludePaths} list, validation is accomplished through the
3025 L{util.AbsolutePathList} list implementation that overrides common list
3026 methods and transparently does the absolute path validation for us.
3027
3028 For the C{collectFiles} and C{collectDirs} list, validation is accomplished
3029 through the L{util.ObjectTypeList} list implementation that overrides common
3030 list methods and transparently ensures that each element has an appropriate
3031 type.
3032
3033 @note: Lists within this class are "unordered" for equality comparisons.
3034
3035 @sort: __init__, __repr__, __str__, __cmp__, targetDir,
3036 collectMode, archiveMode, ignoreFile, absoluteExcludePaths,
3037 excludePatterns, collectFiles, collectDirs
3038 """
3039
3040 - def __init__(self, targetDir=None, collectMode=None, archiveMode=None, ignoreFile=None,
3041 absoluteExcludePaths=None, excludePatterns=None, collectFiles=None, collectDirs=None):
3042 """
3043 Constructor for the C{CollectConfig} class.
3044
3045 @param targetDir: Directory to collect files into.
3046 @param collectMode: Default collect mode.
3047 @param archiveMode: Default archive mode for collect files.
3048 @param ignoreFile: Default ignore file name.
3049 @param absoluteExcludePaths: List of absolute paths to exclude.
3050 @param excludePatterns: List of regular expression patterns to exclude.
3051 @param collectFiles: List of collect files.
3052 @param collectDirs: List of collect directories.
3053
3054 @raise ValueError: If one of the values is invalid.
3055 """
3056 self._targetDir = None
3057 self._collectMode = None
3058 self._archiveMode = None
3059 self._ignoreFile = None
3060 self._absoluteExcludePaths = None
3061 self._excludePatterns = None
3062 self._collectFiles = None
3063 self._collectDirs = None
3064 self.targetDir = targetDir
3065 self.collectMode = collectMode
3066 self.archiveMode = archiveMode
3067 self.ignoreFile = ignoreFile
3068 self.absoluteExcludePaths = absoluteExcludePaths
3069 self.excludePatterns = excludePatterns
3070 self.collectFiles = collectFiles
3071 self.collectDirs = collectDirs
3072
3074 """
3075 Official string representation for class instance.
3076 """
3077 return "CollectConfig(%s, %s, %s, %s, %s, %s, %s, %s)" % (self.targetDir, self.collectMode, self.archiveMode,
3078 self.ignoreFile, self.absoluteExcludePaths,
3079 self.excludePatterns, self.collectFiles, self.collectDirs)
3080
3082 """
3083 Informal string representation for class instance.
3084 """
3085 return self.__repr__()
3086
3088 """
3089 Definition of equals operator for this class.
3090 Lists within this class are "unordered" for equality comparisons.
3091 @param other: Other object to compare to.
3092 @return: -1/0/1 depending on whether self is C{<}, C{=} or C{>} other.
3093 """
3094 if other is None:
3095 return 1
3096 if self._targetDir != other._targetDir:
3097 if self._targetDir < other._targetDir:
3098 return -1
3099 else:
3100 return 1
3101 if self._collectMode != other._collectMode:
3102 if self._collectMode < other._collectMode:
3103 return -1
3104 else:
3105 return 1
3106 if self._archiveMode != other._archiveMode:
3107 if self._archiveMode < other._archiveMode:
3108 return -1
3109 else:
3110 return 1
3111 if self._ignoreFile != other._ignoreFile:
3112 if self._ignoreFile < other._ignoreFile:
3113 return -1
3114 else:
3115 return 1
3116 if self._absoluteExcludePaths != other._absoluteExcludePaths:
3117 if self._absoluteExcludePaths < other._absoluteExcludePaths:
3118 return -1
3119 else:
3120 return 1
3121 if self._excludePatterns != other._excludePatterns:
3122 if self._excludePatterns < other._excludePatterns:
3123 return -1
3124 else:
3125 return 1
3126 if self._collectFiles != other._collectFiles:
3127 if self._collectFiles < other._collectFiles:
3128 return -1
3129 else:
3130 return 1
3131 if self._collectDirs != other._collectDirs:
3132 if self._collectDirs < other._collectDirs:
3133 return -1
3134 else:
3135 return 1
3136 return 0
3137
3139 """
3140 Property target used to set the target directory.
3141 The value must be an absolute path if it is not C{None}.
3142 It does not have to exist on disk at the time of assignment.
3143 @raise ValueError: If the value is not an absolute path.
3144 @raise ValueError: If the value cannot be encoded properly.
3145 """
3146 if value is not None:
3147 if not os.path.isabs(value):
3148 raise ValueError("Target directory must be an absolute path.")
3149 self._targetDir = encodePath(value)
3150
3152 """
3153 Property target used to get the target directory.
3154 """
3155 return self._targetDir
3156
3158 """
3159 Property target used to set the collect mode.
3160 If not C{None}, the mode must be one of L{VALID_COLLECT_MODES}.
3161 @raise ValueError: If the value is not valid.
3162 """
3163 if value is not None:
3164 if value not in VALID_COLLECT_MODES:
3165 raise ValueError("Collect mode must be one of %s." % VALID_COLLECT_MODES)
3166 self._collectMode = value
3167
3169 """
3170 Property target used to get the collect mode.
3171 """
3172 return self._collectMode
3173
3175 """
3176 Property target used to set the archive mode.
3177 If not C{None}, the mode must be one of L{VALID_ARCHIVE_MODES}.
3178 @raise ValueError: If the value is not valid.
3179 """
3180 if value is not None:
3181 if value not in VALID_ARCHIVE_MODES:
3182 raise ValueError("Archive mode must be one of %s." % VALID_ARCHIVE_MODES)
3183 self._archiveMode = value
3184
3186 """
3187 Property target used to get the archive mode.
3188 """
3189 return self._archiveMode
3190
3192 """
3193 Property target used to set the ignore file.
3194 The value must be a non-empty string if it is not C{None}.
3195 @raise ValueError: If the value is an empty string.
3196 @raise ValueError: If the value cannot be encoded properly.
3197 """
3198 if value is not None:
3199 if len(value) < 1:
3200 raise ValueError("The ignore file must be a non-empty string.")
3201 self._ignoreFile = encodePath(value)
3202
3204 """
3205 Property target used to get the ignore file.
3206 """
3207 return self._ignoreFile
3208
3210 """
3211 Property target used to set the absolute exclude paths list.
3212 Either the value must be C{None} or each element must be an absolute path.
3213 Elements do not have to exist on disk at the time of assignment.
3214 @raise ValueError: If the value is not an absolute path.
3215 """
3216 if value is None:
3217 self._absoluteExcludePaths = None
3218 else:
3219 try:
3220 saved = self._absoluteExcludePaths
3221 self._absoluteExcludePaths = AbsolutePathList()
3222 self._absoluteExcludePaths.extend(value)
3223 except Exception, e:
3224 self._absoluteExcludePaths = saved
3225 raise e
3226
3228 """
3229 Property target used to get the absolute exclude paths list.
3230 """
3231 return self._absoluteExcludePaths
3232
3234 """
3235 Property target used to set the exclude patterns list.
3236 """
3237 if value is None:
3238 self._excludePatterns = None
3239 else:
3240 try:
3241 saved = self._excludePatterns
3242 self._excludePatterns = RegexList()
3243 self._excludePatterns.extend(value)
3244 except Exception, e:
3245 self._excludePatterns = saved
3246 raise e
3247
3249 """
3250 Property target used to get the exclude patterns list.
3251 """
3252 return self._excludePatterns
3253
3255 """
3256 Property target used to set the collect files list.
3257 Either the value must be C{None} or each element must be a C{CollectFile}.
3258 @raise ValueError: If the value is not a C{CollectFile}
3259 """
3260 if value is None:
3261 self._collectFiles = None
3262 else:
3263 try:
3264 saved = self._collectFiles
3265 self._collectFiles = ObjectTypeList(CollectFile, "CollectFile")
3266 self._collectFiles.extend(value)
3267 except Exception, e:
3268 self._collectFiles = saved
3269 raise e
3270
3272 """
3273 Property target used to get the collect files list.
3274 """
3275 return self._collectFiles
3276
3278 """
3279 Property target used to set the collect dirs list.
3280 Either the value must be C{None} or each element must be a C{CollectDir}.
3281 @raise ValueError: If the value is not a C{CollectDir}
3282 """
3283 if value is None:
3284 self._collectDirs = None
3285 else:
3286 try:
3287 saved = self._collectDirs
3288 self._collectDirs = ObjectTypeList(CollectDir, "CollectDir")
3289 self._collectDirs.extend(value)
3290 except Exception, e:
3291 self._collectDirs = saved
3292 raise e
3293
3295 """
3296 Property target used to get the collect dirs list.
3297 """
3298 return self._collectDirs
3299
3300 targetDir = property(_getTargetDir, _setTargetDir, None, "Directory to collect files into.")
3301 collectMode = property(_getCollectMode, _setCollectMode, None, "Default collect mode.")
3302 archiveMode = property(_getArchiveMode, _setArchiveMode, None, "Default archive mode for collect files.")
3303 ignoreFile = property(_getIgnoreFile, _setIgnoreFile, None, "Default ignore file name.")
3304 absoluteExcludePaths = property(_getAbsoluteExcludePaths, _setAbsoluteExcludePaths, None, "List of absolute paths to exclude.")
3305 excludePatterns = property(_getExcludePatterns, _setExcludePatterns, None, "List of regular expressions patterns to exclude.")
3306 collectFiles = property(_getCollectFiles, _setCollectFiles, None, "List of collect files.")
3307 collectDirs = property(_getCollectDirs, _setCollectDirs, None, "List of collect directories.")
3308
3309
3310
3311
3312
3313
3315
3316 """
3317 Class representing a Cedar Backup stage configuration.
3318
3319 As with all of the other classes that represent configuration sections, all
3320 of these values are optional. It is up to some higher-level construct to
3321 decide whether everything they need is filled in. Some validation is done
3322 on non-C{None} assignments through the use of the Python C{property()}
3323 construct.
3324
3325 The following restrictions exist on data in this class:
3326
3327 - The target directory must be an absolute path
3328 - The list of local peers must contain only C{LocalPeer} objects
3329 - The list of remote peers must contain only C{RemotePeer} objects
3330
3331 @note: Lists within this class are "unordered" for equality comparisons.
3332
3333 @sort: __init__, __repr__, __str__, __cmp__, targetDir, localPeers, remotePeers
3334 """
3335
3336 - def __init__(self, targetDir=None, localPeers=None, remotePeers=None):
3337 """
3338 Constructor for the C{StageConfig} class.
3339
3340 @param targetDir: Directory to stage files into, by peer name.
3341 @param localPeers: List of local peers.
3342 @param remotePeers: List of remote peers.
3343
3344 @raise ValueError: If one of the values is invalid.
3345 """
3346 self._targetDir = None
3347 self._localPeers = None
3348 self._remotePeers = None
3349 self.targetDir = targetDir
3350 self.localPeers = localPeers
3351 self.remotePeers = remotePeers
3352
3354 """
3355 Official string representation for class instance.
3356 """
3357 return "StageConfig(%s, %s, %s)" % (self.targetDir, self.localPeers, self.remotePeers)
3358
3360 """
3361 Informal string representation for class instance.
3362 """
3363 return self.__repr__()
3364
3366 """
3367 Definition of equals operator for this class.
3368 Lists within this class are "unordered" for equality comparisons.
3369 @param other: Other object to compare to.
3370 @return: -1/0/1 depending on whether self is C{<}, C{=} or C{>} other.
3371 """
3372 if other is None:
3373 return 1
3374 if self._targetDir != other._targetDir:
3375 if self._targetDir < other._targetDir:
3376 return -1
3377 else:
3378 return 1
3379 if self._localPeers != other._localPeers:
3380 if self._localPeers < other._localPeers:
3381 return -1
3382 else:
3383 return 1
3384 if self._remotePeers != other._remotePeers:
3385 if self._remotePeers < other._remotePeers:
3386 return -1
3387 else:
3388 return 1
3389 return 0
3390
3392 """
3393 Indicates whether any peers are filled into this object.
3394 @return: Boolean true if any local or remote peers are filled in, false otherwise.
3395 """
3396 return ((self.localPeers is not None and len(self.localPeers) > 0) or
3397 (self.remotePeers is not None and len(self.remotePeers) > 0))
3398
3400 """
3401 Property target used to set the target directory.
3402 The value must be an absolute path if it is not C{None}.
3403 It does not have to exist on disk at the time of assignment.
3404 @raise ValueError: If the value is not an absolute path.
3405 @raise ValueError: If the value cannot be encoded properly.
3406 """
3407 if value is not None:
3408 if not os.path.isabs(value):
3409 raise ValueError("Target directory must be an absolute path.")
3410 self._targetDir = encodePath(value)
3411
3413 """
3414 Property target used to get the target directory.
3415 """
3416 return self._targetDir
3417
3419 """
3420 Property target used to set the local peers list.
3421 Either the value must be C{None} or each element must be a C{LocalPeer}.
3422 @raise ValueError: If the value is not an absolute path.
3423 """
3424 if value is None:
3425 self._localPeers = None
3426 else:
3427 try:
3428 saved = self._localPeers
3429 self._localPeers = ObjectTypeList(LocalPeer, "LocalPeer")
3430 self._localPeers.extend(value)
3431 except Exception, e:
3432 self._localPeers = saved
3433 raise e
3434
3436 """
3437 Property target used to get the local peers list.
3438 """
3439 return self._localPeers
3440
3442 """
3443 Property target used to set the remote peers list.
3444 Either the value must be C{None} or each element must be a C{RemotePeer}.
3445 @raise ValueError: If the value is not a C{RemotePeer}
3446 """
3447 if value is None:
3448 self._remotePeers = None
3449 else:
3450 try:
3451 saved = self._remotePeers
3452 self._remotePeers = ObjectTypeList(RemotePeer, "RemotePeer")
3453 self._remotePeers.extend(value)
3454 except Exception, e:
3455 self._remotePeers = saved
3456 raise e
3457
3459 """
3460 Property target used to get the remote peers list.
3461 """
3462 return self._remotePeers
3463
3464 targetDir = property(_getTargetDir, _setTargetDir, None, "Directory to stage files into, by peer name.")
3465 localPeers = property(_getLocalPeers, _setLocalPeers, None, "List of local peers.")
3466 remotePeers = property(_getRemotePeers, _setRemotePeers, None, "List of remote peers.")
3467
3468
3469
3470
3471
3472
3474
3475 """
3476 Class representing a Cedar Backup store configuration.
3477
3478 As with all of the other classes that represent configuration sections, all
3479 of these values are optional. It is up to some higher-level construct to
3480 decide whether everything they need is filled in. Some validation is done
3481 on non-C{None} assignments through the use of the Python C{property()}
3482 construct.
3483
3484 The following restrictions exist on data in this class:
3485
3486 - The source directory must be an absolute path.
3487 - The media type must be one of the values in L{VALID_MEDIA_TYPES}.
3488 - The device type must be one of the values in L{VALID_DEVICE_TYPES}.
3489 - The device path must be an absolute path.
3490 - The SCSI id, if provided, must be in the form specified by L{validateScsiId}.
3491 - The drive speed must be an integer >= 1
3492 - The blanking behavior must be a C{BlankBehavior} object
3493 - The refresh media delay must be an integer >= 0
3494
3495 Note that although the blanking factor must be a positive floating point
3496 number, it is stored as a string. This is done so that we can losslessly go
3497 back and forth between XML and object representations of configuration.
3498
3499 @sort: __init__, __repr__, __str__, __cmp__, sourceDir,
3500 mediaType, deviceType, devicePath, deviceScsiId,
3501 driveSpeed, checkData, checkMedia, warnMidnite, noEject,
3502 blankBehavior, refreshMediaDelay
3503 """
3504
3505 - def __init__(self, sourceDir=None, mediaType=None, deviceType=None,
3506 devicePath=None, deviceScsiId=None, driveSpeed=None,
3507 checkData=False, warnMidnite=False, noEject=False,
3508 checkMedia=False, blankBehavior=None, refreshMediaDelay=None):
3509 """
3510 Constructor for the C{StoreConfig} class.
3511
3512 @param sourceDir: Directory whose contents should be written to media.
3513 @param mediaType: Type of the media (see notes above).
3514 @param deviceType: Type of the device (optional, see notes above).
3515 @param devicePath: Filesystem device name for writer device, i.e. C{/dev/cdrw}.
3516 @param deviceScsiId: SCSI id for writer device, i.e. C{[<method>:]scsibus,target,lun}.
3517 @param driveSpeed: Speed of the drive, i.e. C{2} for 2x drive, etc.
3518 @param checkData: Whether resulting image should be validated.
3519 @param checkMedia: Whether media should be checked before being written to.
3520 @param warnMidnite: Whether to generate warnings for crossing midnite.
3521 @param noEject: Indicates that the writer device should not be ejected.
3522 @param blankBehavior: Controls optimized blanking behavior.
3523 @param refreshMediaDelay: Delay, in seconds, to add after refreshing media
3524
3525 @raise ValueError: If one of the values is invalid.
3526 """
3527 self._sourceDir = None
3528 self._mediaType = None
3529 self._deviceType = None
3530 self._devicePath = None
3531 self._deviceScsiId = None
3532 self._driveSpeed = None
3533 self._checkData = None
3534 self._checkMedia = None
3535 self._warnMidnite = None
3536 self._noEject = None
3537 self._blankBehavior = None
3538 self._refreshMediaDelay = None
3539 self.sourceDir = sourceDir
3540 self.mediaType = mediaType
3541 self.deviceType = deviceType
3542 self.devicePath = devicePath
3543 self.deviceScsiId = deviceScsiId
3544 self.driveSpeed = driveSpeed
3545 self.checkData = checkData
3546 self.checkMedia = checkMedia
3547 self.warnMidnite = warnMidnite
3548 self.noEject = noEject
3549 self.blankBehavior = blankBehavior
3550 self.refreshMediaDelay = refreshMediaDelay
3551
3553 """
3554 Official string representation for class instance.
3555 """
3556 return "StoreConfig(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)" % (self.sourceDir, self.mediaType, self.deviceType,
3557 self.devicePath, self.deviceScsiId, self.driveSpeed,
3558 self.checkData, self.warnMidnite, self.noEject,
3559 self.checkMedia, self.blankBehavior, self.refreshMediaDelay)
3560
3562 """
3563 Informal string representation for class instance.
3564 """
3565 return self.__repr__()
3566
3568 """
3569 Definition of equals operator for this class.
3570 @param other: Other object to compare to.
3571 @return: -1/0/1 depending on whether self is C{<}, C{=} or C{>} other.
3572 """
3573 if other is None:
3574 return 1
3575 if self._sourceDir != other._sourceDir:
3576 if self._sourceDir < other._sourceDir:
3577 return -1
3578 else:
3579 return 1
3580 if self._mediaType != other._mediaType:
3581 if self._mediaType < other._mediaType:
3582 return -1
3583 else:
3584 return 1
3585 if self._deviceType != other._deviceType:
3586 if self._deviceType < other._deviceType:
3587 return -1
3588 else:
3589 return 1
3590 if self._devicePath != other._devicePath:
3591 if self._devicePath < other._devicePath:
3592 return -1
3593 else:
3594 return 1
3595 if self._deviceScsiId != other._deviceScsiId:
3596 if self._deviceScsiId < other._deviceScsiId:
3597 return -1
3598 else:
3599 return 1
3600 if self._driveSpeed != other._driveSpeed:
3601 if self._driveSpeed < other._driveSpeed:
3602 return -1
3603 else:
3604 return 1
3605 if self._checkData != other._checkData:
3606 if self._checkData < other._checkData:
3607 return -1
3608 else:
3609 return 1
3610 if self._checkMedia != other._checkMedia:
3611 if self._checkMedia < other._checkMedia:
3612 return -1
3613 else:
3614 return 1
3615 if self._warnMidnite != other._warnMidnite:
3616 if self._warnMidnite < other._warnMidnite:
3617 return -1
3618 else:
3619 return 1
3620 if self._noEject != other._noEject:
3621 if self._noEject < other._noEject:
3622 return -1
3623 else:
3624 return 1
3625 if self._blankBehavior != other._blankBehavior:
3626 if self._blankBehavior < other._blankBehavior:
3627 return -1
3628 else:
3629 return 1
3630 if self._refreshMediaDelay != other._refreshMediaDelay:
3631 if self._refreshMediaDelay < other._refreshMediaDelay:
3632 return -1
3633 else:
3634 return 1
3635 return 0
3636
3638 """
3639 Property target used to set the source directory.
3640 The value must be an absolute path if it is not C{None}.
3641 It does not have to exist on disk at the time of assignment.
3642 @raise ValueError: If the value is not an absolute path.
3643 @raise ValueError: If the value cannot be encoded properly.
3644 """
3645 if value is not None:
3646 if not os.path.isabs(value):
3647 raise ValueError("Source directory must be an absolute path.")
3648 self._sourceDir = encodePath(value)
3649
3651 """
3652 Property target used to get the source directory.
3653 """
3654 return self._sourceDir
3655
3666
3672
3674 """
3675 Property target used to set the device type.
3676 The value must be one of L{VALID_DEVICE_TYPES}.
3677 @raise ValueError: If the value is not valid.
3678 """
3679 if value is not None:
3680 if value not in VALID_DEVICE_TYPES:
3681 raise ValueError("Device type must be one of %s." % VALID_DEVICE_TYPES)
3682 self._deviceType = value
3683
3685 """
3686 Property target used to get the device type.
3687 """
3688 return self._deviceType
3689
3691 """
3692 Property target used to set the device path.
3693 The value must be an absolute path if it is not C{None}.
3694 It does not have to exist on disk at the time of assignment.
3695 @raise ValueError: If the value is not an absolute path.
3696 @raise ValueError: If the value cannot be encoded properly.
3697 """
3698 if value is not None:
3699 if not os.path.isabs(value):
3700 raise ValueError("Device path must be an absolute path.")
3701 self._devicePath = encodePath(value)
3702
3704 """
3705 Property target used to get the device path.
3706 """
3707 return self._devicePath
3708
3710 """
3711 Property target used to set the SCSI id
3712 The SCSI id must be valid per L{validateScsiId}.
3713 @raise ValueError: If the value is not valid.
3714 """
3715 if value is None:
3716 self._deviceScsiId = None
3717 else:
3718 self._deviceScsiId = validateScsiId(value)
3719
3721 """
3722 Property target used to get the SCSI id.
3723 """
3724 return self._deviceScsiId
3725
3727 """
3728 Property target used to set the drive speed.
3729 The drive speed must be valid per L{validateDriveSpeed}.
3730 @raise ValueError: If the value is not valid.
3731 """
3732 self._driveSpeed = validateDriveSpeed(value)
3733
3735 """
3736 Property target used to get the drive speed.
3737 """
3738 return self._driveSpeed
3739
3741 """
3742 Property target used to set the check data flag.
3743 No validations, but we normalize the value to C{True} or C{False}.
3744 """
3745 if value:
3746 self._checkData = True
3747 else:
3748 self._checkData = False
3749
3751 """
3752 Property target used to get the check data flag.
3753 """
3754 return self._checkData
3755
3765
3771
3773 """
3774 Property target used to set the midnite warning flag.
3775 No validations, but we normalize the value to C{True} or C{False}.
3776 """
3777 if value:
3778 self._warnMidnite = True
3779 else:
3780 self._warnMidnite = False
3781
3783 """
3784 Property target used to get the midnite warning flag.
3785 """
3786 return self._warnMidnite
3787
3789 """
3790 Property target used to set the no-eject flag.
3791 No validations, but we normalize the value to C{True} or C{False}.
3792 """
3793 if value:
3794 self._noEject = True
3795 else:
3796 self._noEject = False
3797
3799 """
3800 Property target used to get the no-eject flag.
3801 """
3802 return self._noEject
3803
3805 """
3806 Property target used to set blanking behavior configuration.
3807 If not C{None}, the value must be a C{BlankBehavior} object.
3808 @raise ValueError: If the value is not a C{BlankBehavior}
3809 """
3810 if value is None:
3811 self._blankBehavior = None
3812 else:
3813 if not isinstance(value, BlankBehavior):
3814 raise ValueError("Value must be a C{BlankBehavior} object.")
3815 self._blankBehavior = value
3816
3818 """
3819 Property target used to get the blanking behavior configuration.
3820 """
3821 return self._blankBehavior
3822
3841
3847
3848 sourceDir = property(_getSourceDir, _setSourceDir, None, "Directory whose contents should be written to media.")
3849 mediaType = property(_getMediaType, _setMediaType, None, "Type of the media (see notes above).")
3850 deviceType = property(_getDeviceType, _setDeviceType, None, "Type of the device (optional, see notes above).")
3851 devicePath = property(_getDevicePath, _setDevicePath, None, "Filesystem device name for writer device.")
3852 deviceScsiId = property(_getDeviceScsiId, _setDeviceScsiId, None, "SCSI id for writer device (optional, see notes above).")
3853 driveSpeed = property(_getDriveSpeed, _setDriveSpeed, None, "Speed of the drive.")
3854 checkData = property(_getCheckData, _setCheckData, None, "Whether resulting image should be validated.")
3855 checkMedia = property(_getCheckMedia, _setCheckMedia, None, "Whether media should be checked before being written to.")
3856 warnMidnite = property(_getWarnMidnite, _setWarnMidnite, None, "Whether to generate warnings for crossing midnite.")
3857 noEject = property(_getNoEject, _setNoEject, None, "Indicates that the writer device should not be ejected.")
3858 blankBehavior = property(_getBlankBehavior, _setBlankBehavior, None, "Controls optimized blanking behavior.")
3859 refreshMediaDelay = property(_getRefreshMediaDelay, _setRefreshMediaDelay, None, "Delay, in seconds, to add after refreshing media.")
3860
3861
3862
3863
3864
3865
3867
3868 """
3869 Class representing a Cedar Backup purge configuration.
3870
3871 As with all of the other classes that represent configuration sections, all
3872 of these values are optional. It is up to some higher-level construct to
3873 decide whether everything they need is filled in. Some validation is done
3874 on non-C{None} assignments through the use of the Python C{property()}
3875 construct.
3876
3877 The following restrictions exist on data in this class:
3878
3879 - The purge directory list must be a list of C{PurgeDir} objects.
3880
3881 For the C{purgeDirs} list, validation is accomplished through the
3882 L{util.ObjectTypeList} list implementation that overrides common list
3883 methods and transparently ensures that each element is a C{PurgeDir}.
3884
3885 @note: Lists within this class are "unordered" for equality comparisons.
3886
3887 @sort: __init__, __repr__, __str__, __cmp__, purgeDirs
3888 """
3889
3891 """
3892 Constructor for the C{Purge} class.
3893 @param purgeDirs: List of purge directories.
3894 @raise ValueError: If one of the values is invalid.
3895 """
3896 self._purgeDirs = None
3897 self.purgeDirs = purgeDirs
3898
3900 """
3901 Official string representation for class instance.
3902 """
3903 return "PurgeConfig(%s)" % self.purgeDirs
3904
3906 """
3907 Informal string representation for class instance.
3908 """
3909 return self.__repr__()
3910
3912 """
3913 Definition of equals operator for this class.
3914 Lists within this class are "unordered" for equality comparisons.
3915 @param other: Other object to compare to.
3916 @return: -1/0/1 depending on whether self is C{<}, C{=} or C{>} other.
3917 """
3918 if other is None:
3919 return 1
3920 if self._purgeDirs != other._purgeDirs:
3921 if self._purgeDirs < other._purgeDirs:
3922 return -1
3923 else:
3924 return 1
3925 return 0
3926
3928 """
3929 Property target used to set the purge dirs list.
3930 Either the value must be C{None} or each element must be a C{PurgeDir}.
3931 @raise ValueError: If the value is not a C{PurgeDir}
3932 """
3933 if value is None:
3934 self._purgeDirs = None
3935 else:
3936 try:
3937 saved = self._purgeDirs
3938 self._purgeDirs = ObjectTypeList(PurgeDir, "PurgeDir")
3939 self._purgeDirs.extend(value)
3940 except Exception, e:
3941 self._purgeDirs = saved
3942 raise e
3943
3945 """
3946 Property target used to get the purge dirs list.
3947 """
3948 return self._purgeDirs
3949
3950 purgeDirs = property(_getPurgeDirs, _setPurgeDirs, None, "List of directories to purge.")
3951
3952
3953
3954
3955
3956
3958
3959
3960
3961
3962
3963 """
3964 Class representing a Cedar Backup XML configuration document.
3965
3966 The C{Config} class is a Python object representation of a Cedar Backup XML
3967 configuration file. It is intended to be the only Python-language interface
3968 to Cedar Backup configuration on disk for both Cedar Backup itself and for
3969 external applications.
3970
3971 The object representation is two-way: XML data can be used to create a
3972 C{Config} object, and then changes to the object can be propogated back to
3973 disk. A C{Config} object can even be used to create a configuration file
3974 from scratch programmatically.
3975
3976 This class and the classes it is composed from often use Python's
3977 C{property} construct to validate input and limit access to values. Some
3978 validations can only be done once a document is considered "complete"
3979 (see module notes for more details).
3980
3981 Assignments to the various instance variables must match the expected
3982 type, i.e. C{reference} must be a C{ReferenceConfig}. The internal check
3983 uses the built-in C{isinstance} function, so it should be OK to use
3984 subclasses if you want to.
3985
3986 If an instance variable is not set, its value will be C{None}. When an
3987 object is initialized without using an XML document, all of the values
3988 will be C{None}. Even when an object is initialized using XML, some of
3989 the values might be C{None} because not every section is required.
3990
3991 @note: Lists within this class are "unordered" for equality comparisons.
3992
3993 @sort: __init__, __repr__, __str__, __cmp__, extractXml, validate,
3994 reference, extensions, options, collect, stage, store, purge,
3995 _getReference, _setReference, _getExtensions, _setExtensions,
3996 _getOptions, _setOptions, _getPeers, _setPeers, _getCollect,
3997 _setCollect, _getStage, _setStage, _getStore, _setStore,
3998 _getPurge, _setPurge
3999 """
4000
4001
4002
4003
4004
4005 - def __init__(self, xmlData=None, xmlPath=None, validate=True):
4006 """
4007 Initializes a configuration object.
4008
4009 If you initialize the object without passing either C{xmlData} or
4010 C{xmlPath}, then configuration will be empty and will be invalid until it
4011 is filled in properly.
4012
4013 No reference to the original XML data or original path is saved off by
4014 this class. Once the data has been parsed (successfully or not) this
4015 original information is discarded.
4016
4017 Unless the C{validate} argument is C{False}, the L{Config.validate}
4018 method will be called (with its default arguments) against configuration
4019 after successfully parsing any passed-in XML. Keep in mind that even if
4020 C{validate} is C{False}, it might not be possible to parse the passed-in
4021 XML document if lower-level validations fail.
4022
4023 @note: It is strongly suggested that the C{validate} option always be set
4024 to C{True} (the default) unless there is a specific need to read in
4025 invalid configuration from disk.
4026
4027 @param xmlData: XML data representing configuration.
4028 @type xmlData: String data.
4029
4030 @param xmlPath: Path to an XML file on disk.
4031 @type xmlPath: Absolute path to a file on disk.
4032
4033 @param validate: Validate the document after parsing it.
4034 @type validate: Boolean true/false.
4035
4036 @raise ValueError: If both C{xmlData} and C{xmlPath} are passed-in.
4037 @raise ValueError: If the XML data in C{xmlData} or C{xmlPath} cannot be parsed.
4038 @raise ValueError: If the parsed configuration document is not valid.
4039 """
4040 self._reference = None
4041 self._extensions = None
4042 self._options = None
4043 self._peers = None
4044 self._collect = None
4045 self._stage = None
4046 self._store = None
4047 self._purge = None
4048 self.reference = None
4049 self.extensions = None
4050 self.options = None
4051 self.peers = None
4052 self.collect = None
4053 self.stage = None
4054 self.store = None
4055 self.purge = None
4056 if xmlData is not None and xmlPath is not None:
4057 raise ValueError("Use either xmlData or xmlPath, but not both.")
4058 if xmlData is not None:
4059 self._parseXmlData(xmlData)
4060 if validate:
4061 self.validate()
4062 elif xmlPath is not None:
4063 xmlData = open(xmlPath).read()
4064 self._parseXmlData(xmlData)
4065 if validate:
4066 self.validate()
4067
4068
4069
4070
4071
4072
4074 """
4075 Official string representation for class instance.
4076 """
4077 return "Config(%s, %s, %s, %s, %s, %s, %s, %s)" % (self.reference, self.extensions, self.options,
4078 self.peers, self.collect, self.stage, self.store,
4079 self.purge)
4080
4082 """
4083 Informal string representation for class instance.
4084 """
4085 return self.__repr__()
4086
4087
4088
4089
4090
4091
4093 """
4094 Definition of equals operator for this class.
4095 Lists within this class are "unordered" for equality comparisons.
4096 @param other: Other object to compare to.
4097 @return: -1/0/1 depending on whether self is C{<}, C{=} or C{>} other.
4098 """
4099 if other is None:
4100 return 1
4101 if self._reference != other._reference:
4102 if self._reference < other._reference:
4103 return -1
4104 else:
4105 return 1
4106 if self._extensions != other._extensions:
4107 if self._extensions < other._extensions:
4108 return -1
4109 else:
4110 return 1
4111 if self._options != other._options:
4112 if self._options < other._options:
4113 return -1
4114 else:
4115 return 1
4116 if self._peers != other._peers:
4117 if self._peers < other._peers:
4118 return -1
4119 else:
4120 return 1
4121 if self._collect != other._collect:
4122 if self._collect < other._collect:
4123 return -1
4124 else:
4125 return 1
4126 if self._stage != other._stage:
4127 if self._stage < other._stage:
4128 return -1
4129 else:
4130 return 1
4131 if self._store != other._store:
4132 if self._store < other._store:
4133 return -1
4134 else:
4135 return 1
4136 if self._purge != other._purge:
4137 if self._purge < other._purge:
4138 return -1
4139 else:
4140 return 1
4141 return 0
4142
4143
4144
4145
4146
4147
4149 """
4150 Property target used to set the reference configuration value.
4151 If not C{None}, the value must be a C{ReferenceConfig} object.
4152 @raise ValueError: If the value is not a C{ReferenceConfig}
4153 """
4154 if value is None:
4155 self._reference = None
4156 else:
4157 if not isinstance(value, ReferenceConfig):
4158 raise ValueError("Value must be a C{ReferenceConfig} object.")
4159 self._reference = value
4160
4162 """
4163 Property target used to get the reference configuration value.
4164 """
4165 return self._reference
4166
4167 - def _setExtensions(self, value):
4168 """
4169 Property target used to set the extensions configuration value.
4170 If not C{None}, the value must be a C{ExtensionsConfig} object.
4171 @raise ValueError: If the value is not a C{ExtensionsConfig}
4172 """
4173 if value is None:
4174 self._extensions = None
4175 else:
4176 if not isinstance(value, ExtensionsConfig):
4177 raise ValueError("Value must be a C{ExtensionsConfig} object.")
4178 self._extensions = value
4179
4180 - def _getExtensions(self):
4181 """
4182 Property target used to get the extensions configuration value.
4183 """
4184 return self._extensions
4185
4187 """
4188 Property target used to set the options configuration value.
4189 If not C{None}, the value must be an C{OptionsConfig} object.
4190 @raise ValueError: If the value is not a C{OptionsConfig}
4191 """
4192 if value is None:
4193 self._options = None
4194 else:
4195 if not isinstance(value, OptionsConfig):
4196 raise ValueError("Value must be a C{OptionsConfig} object.")
4197 self._options = value
4198
4200 """
4201 Property target used to get the options configuration value.
4202 """
4203 return self._options
4204
4206 """
4207 Property target used to set the peers configuration value.
4208 If not C{None}, the value must be an C{PeersConfig} object.
4209 @raise ValueError: If the value is not a C{PeersConfig}
4210 """
4211 if value is None:
4212 self._peers = None
4213 else:
4214 if not isinstance(value, PeersConfig):
4215 raise ValueError("Value must be a C{PeersConfig} object.")
4216 self._peers = value
4217
4219 """
4220 Property target used to get the peers configuration value.
4221 """
4222 return self._peers
4223
4225 """
4226 Property target used to set the collect configuration value.
4227 If not C{None}, the value must be a C{CollectConfig} object.
4228 @raise ValueError: If the value is not a C{CollectConfig}
4229 """
4230 if value is None:
4231 self._collect = None
4232 else:
4233 if not isinstance(value, CollectConfig):
4234 raise ValueError("Value must be a C{CollectConfig} object.")
4235 self._collect = value
4236
4238 """
4239 Property target used to get the collect configuration value.
4240 """
4241 return self._collect
4242
4244 """
4245 Property target used to set the stage configuration value.
4246 If not C{None}, the value must be a C{StageConfig} object.
4247 @raise ValueError: If the value is not a C{StageConfig}
4248 """
4249 if value is None:
4250 self._stage = None
4251 else:
4252 if not isinstance(value, StageConfig):
4253 raise ValueError("Value must be a C{StageConfig} object.")
4254 self._stage = value
4255
4257 """
4258 Property target used to get the stage configuration value.
4259 """
4260 return self._stage
4261
4263 """
4264 Property target used to set the store configuration value.
4265 If not C{None}, the value must be a C{StoreConfig} object.
4266 @raise ValueError: If the value is not a C{StoreConfig}
4267 """
4268 if value is None:
4269 self._store = None
4270 else:
4271 if not isinstance(value, StoreConfig):
4272 raise ValueError("Value must be a C{StoreConfig} object.")
4273 self._store = value
4274
4276 """
4277 Property target used to get the store configuration value.
4278 """
4279 return self._store
4280
4282 """
4283 Property target used to set the purge configuration value.
4284 If not C{None}, the value must be a C{PurgeConfig} object.
4285 @raise ValueError: If the value is not a C{PurgeConfig}
4286 """
4287 if value is None:
4288 self._purge = None
4289 else:
4290 if not isinstance(value, PurgeConfig):
4291 raise ValueError("Value must be a C{PurgeConfig} object.")
4292 self._purge = value
4293
4295 """
4296 Property target used to get the purge configuration value.
4297 """
4298 return self._purge
4299
4300 reference = property(_getReference, _setReference, None, "Reference configuration in terms of a C{ReferenceConfig} object.")
4301 extensions = property(_getExtensions, _setExtensions, None, "Extensions configuration in terms of a C{ExtensionsConfig} object.")
4302 options = property(_getOptions, _setOptions, None, "Options configuration in terms of a C{OptionsConfig} object.")
4303 peers = property(_getPeers, _setPeers, None, "Peers configuration in terms of a C{PeersConfig} object.")
4304 collect = property(_getCollect, _setCollect, None, "Collect configuration in terms of a C{CollectConfig} object.")
4305 stage = property(_getStage, _setStage, None, "Stage configuration in terms of a C{StageConfig} object.")
4306 store = property(_getStore, _setStore, None, "Store configuration in terms of a C{StoreConfig} object.")
4307 purge = property(_getPurge, _setPurge, None, "Purge configuration in terms of a C{PurgeConfig} object.")
4308
4309
4310
4311
4312
4313
4315 """
4316 Extracts configuration into an XML document.
4317
4318 If C{xmlPath} is not provided, then the XML document will be returned as
4319 a string. If C{xmlPath} is provided, then the XML document will be written
4320 to the file and C{None} will be returned.
4321
4322 Unless the C{validate} parameter is C{False}, the L{Config.validate}
4323 method will be called (with its default arguments) against the
4324 configuration before extracting the XML. If configuration is not valid,
4325 then an XML document will not be extracted.
4326
4327 @note: It is strongly suggested that the C{validate} option always be set
4328 to C{True} (the default) unless there is a specific need to write an
4329 invalid configuration file to disk.
4330
4331 @param xmlPath: Path to an XML file to create on disk.
4332 @type xmlPath: Absolute path to a file.
4333
4334 @param validate: Validate the document before extracting it.
4335 @type validate: Boolean true/false.
4336
4337 @return: XML string data or C{None} as described above.
4338
4339 @raise ValueError: If configuration within the object is not valid.
4340 @raise IOError: If there is an error writing to the file.
4341 @raise OSError: If there is an error writing to the file.
4342 """
4343 if validate:
4344 self.validate()
4345 xmlData = self._extractXml()
4346 if xmlPath is not None:
4347 open(xmlPath, "w").write(xmlData)
4348 return None
4349 else:
4350 return xmlData
4351
4352 - def validate(self, requireOneAction=True, requireReference=False, requireExtensions=False, requireOptions=True,
4353 requireCollect=False, requireStage=False, requireStore=False, requirePurge=False, requirePeers=False):
4354 """
4355 Validates configuration represented by the object.
4356
4357 This method encapsulates all of the validations that should apply to a
4358 fully "complete" document but are not already taken care of by earlier
4359 validations. It also provides some extra convenience functionality which
4360 might be useful to some people. The process of validation is laid out in
4361 the I{Validation} section in the class notes (above).
4362
4363 @param requireOneAction: Require at least one of the collect, stage, store or purge sections.
4364 @param requireReference: Require the reference section.
4365 @param requireExtensions: Require the extensions section.
4366 @param requireOptions: Require the options section.
4367 @param requirePeers: Require the peers section.
4368 @param requireCollect: Require the collect section.
4369 @param requireStage: Require the stage section.
4370 @param requireStore: Require the store section.
4371 @param requirePurge: Require the purge section.
4372
4373 @raise ValueError: If one of the validations fails.
4374 """
4375 if requireOneAction and (self.collect, self.stage, self.store, self.purge) == (None, None, None, None):
4376 raise ValueError("At least one of the collect, stage, store and purge sections is required.")
4377 if requireReference and self.reference is None:
4378 raise ValueError("The reference is section is required.")
4379 if requireExtensions and self.extensions is None:
4380 raise ValueError("The extensions is section is required.")
4381 if requireOptions and self.options is None:
4382 raise ValueError("The options is section is required.")
4383 if requirePeers and self.peers is None:
4384 raise ValueError("The peers is section is required.")
4385 if requireCollect and self.collect is None:
4386 raise ValueError("The collect is section is required.")
4387 if requireStage and self.stage is None:
4388 raise ValueError("The stage is section is required.")
4389 if requireStore and self.store is None:
4390 raise ValueError("The store is section is required.")
4391 if requirePurge and self.purge is None:
4392 raise ValueError("The purge is section is required.")
4393 self._validateContents()
4394
4395
4396
4397
4398
4399
4401 """
4402 Internal method to parse an XML string into the object.
4403
4404 This method parses the XML document into a DOM tree (C{xmlDom}) and then
4405 calls individual static methods to parse each of the individual
4406 configuration sections.
4407
4408 Most of the validation we do here has to do with whether the document can
4409 be parsed and whether any values which exist are valid. We don't do much
4410 validation as to whether required elements actually exist unless we have
4411 to to make sense of the document (instead, that's the job of the
4412 L{validate} method).
4413
4414 @param xmlData: XML data to be parsed
4415 @type xmlData: String data
4416
4417 @raise ValueError: If the XML cannot be successfully parsed.
4418 """
4419 (xmlDom, parentNode) = createInputDom(xmlData)
4420 self._reference = Config._parseReference(parentNode)
4421 self._extensions = Config._parseExtensions(parentNode)
4422 self._options = Config._parseOptions(parentNode)
4423 self._peers = Config._parsePeers(parentNode)
4424 self._collect = Config._parseCollect(parentNode)
4425 self._stage = Config._parseStage(parentNode)
4426 self._store = Config._parseStore(parentNode)
4427 self._purge = Config._parsePurge(parentNode)
4428
4430 """
4431 Parses a reference configuration section.
4432
4433 We read the following fields::
4434
4435 author //cb_config/reference/author
4436 revision //cb_config/reference/revision
4437 description //cb_config/reference/description
4438 generator //cb_config/reference/generator
4439
4440 @param parentNode: Parent node to search beneath.
4441
4442 @return: C{ReferenceConfig} object or C{None} if the section does not exist.
4443 @raise ValueError: If some filled-in value is invalid.
4444 """
4445 reference = None
4446 sectionNode = readFirstChild(parentNode, "reference")
4447 if sectionNode is not None:
4448 reference = ReferenceConfig()
4449 reference.author = readString(sectionNode, "author")
4450 reference.revision = readString(sectionNode, "revision")
4451 reference.description = readString(sectionNode, "description")
4452 reference.generator = readString(sectionNode, "generator")
4453 return reference
4454 _parseReference = staticmethod(_parseReference)
4455
4457 """
4458 Parses an extensions configuration section.
4459
4460 We read the following fields::
4461
4462 orderMode //cb_config/extensions/order_mode
4463
4464 We also read groups of the following items, one list element per item::
4465
4466 name //cb_config/extensions/action/name
4467 module //cb_config/extensions/action/module
4468 function //cb_config/extensions/action/function
4469 index //cb_config/extensions/action/index
4470 dependencies //cb_config/extensions/action/depends
4471
4472 The extended actions are parsed by L{_parseExtendedActions}.
4473
4474 @param parentNode: Parent node to search beneath.
4475
4476 @return: C{ExtensionsConfig} object or C{None} if the section does not exist.
4477 @raise ValueError: If some filled-in value is invalid.
4478 """
4479 extensions = None
4480 sectionNode = readFirstChild(parentNode, "extensions")
4481 if sectionNode is not None:
4482 extensions = ExtensionsConfig()
4483 extensions.orderMode = readString(sectionNode, "order_mode")
4484 extensions.actions = Config._parseExtendedActions(sectionNode)
4485 return extensions
4486 _parseExtensions = staticmethod(_parseExtensions)
4487
4489 """
4490 Parses a options configuration section.
4491
4492 We read the following fields::
4493
4494 startingDay //cb_config/options/starting_day
4495 workingDir //cb_config/options/working_dir
4496 backupUser //cb_config/options/backup_user
4497 backupGroup //cb_config/options/backup_group
4498 rcpCommand //cb_config/options/rcp_command
4499 rshCommand //cb_config/options/rsh_command
4500 cbackCommand //cb_config/options/cback_command
4501 managedActions //cb_config/options/managed_actions
4502
4503 The list of managed actions is a comma-separated list of action names.
4504
4505 We also read groups of the following items, one list element per
4506 item::
4507
4508 overrides //cb_config/options/override
4509 hooks //cb_config/options/hook
4510
4511 The overrides are parsed by L{_parseOverrides} and the hooks are parsed
4512 by L{_parseHooks}.
4513
4514 @param parentNode: Parent node to search beneath.
4515
4516 @return: C{OptionsConfig} object or C{None} if the section does not exist.
4517 @raise ValueError: If some filled-in value is invalid.
4518 """
4519 options = None
4520 sectionNode = readFirstChild(parentNode, "options")
4521 if sectionNode is not None:
4522 options = OptionsConfig()
4523 options.startingDay = readString(sectionNode, "starting_day")
4524 options.workingDir = readString(sectionNode, "working_dir")
4525 options.backupUser = readString(sectionNode, "backup_user")
4526 options.backupGroup = readString(sectionNode, "backup_group")
4527 options.rcpCommand = readString(sectionNode, "rcp_command")
4528 options.rshCommand = readString(sectionNode, "rsh_command")
4529 options.cbackCommand = readString(sectionNode, "cback_command")
4530 options.overrides = Config._parseOverrides(sectionNode)
4531 options.hooks = Config._parseHooks(sectionNode)
4532 managedActions = readString(sectionNode, "managed_actions")
4533 options.managedActions = Config._parseCommaSeparatedString(managedActions)
4534 return options
4535 _parseOptions = staticmethod(_parseOptions)
4536
4538 """
4539 Parses a peers configuration section.
4540
4541 We read groups of the following items, one list element per
4542 item::
4543
4544 localPeers //cb_config/stage/peer
4545 remotePeers //cb_config/stage/peer
4546
4547 The individual peer entries are parsed by L{_parsePeerList}.
4548
4549 @param parentNode: Parent node to search beneath.
4550
4551 @return: C{StageConfig} object or C{None} if the section does not exist.
4552 @raise ValueError: If some filled-in value is invalid.
4553 """
4554 peers = None
4555 sectionNode = readFirstChild(parentNode, "peers")
4556 if sectionNode is not None:
4557 peers = PeersConfig()
4558 (peers.localPeers, peers.remotePeers) = Config._parsePeerList(sectionNode)
4559 return peers
4560 _parsePeers = staticmethod(_parsePeers)
4561
4563 """
4564 Parses a collect configuration section.
4565
4566 We read the following individual fields::
4567
4568 targetDir //cb_config/collect/collect_dir
4569 collectMode //cb_config/collect/collect_mode
4570 archiveMode //cb_config/collect/archive_mode
4571 ignoreFile //cb_config/collect/ignore_file
4572
4573 We also read groups of the following items, one list element per
4574 item::
4575
4576 absoluteExcludePaths //cb_config/collect/exclude/abs_path
4577 excludePatterns //cb_config/collect/exclude/pattern
4578 collectFiles //cb_config/collect/file
4579 collectDirs //cb_config/collect/dir
4580
4581 The exclusions are parsed by L{_parseExclusions}, the collect files are
4582 parsed by L{_parseCollectFiles}, and the directories are parsed by
4583 L{_parseCollectDirs}.
4584
4585 @param parentNode: Parent node to search beneath.
4586
4587 @return: C{CollectConfig} object or C{None} if the section does not exist.
4588 @raise ValueError: If some filled-in value is invalid.
4589 """
4590 collect = None
4591 sectionNode = readFirstChild(parentNode, "collect")
4592 if sectionNode is not None:
4593 collect = CollectConfig()
4594 collect.targetDir = readString(sectionNode, "collect_dir")
4595 collect.collectMode = readString(sectionNode, "collect_mode")
4596 collect.archiveMode = readString(sectionNode, "archive_mode")
4597 collect.ignoreFile = readString(sectionNode, "ignore_file")
4598 (collect.absoluteExcludePaths, unused, collect.excludePatterns) = Config._parseExclusions(sectionNode)
4599 collect.collectFiles = Config._parseCollectFiles(sectionNode)
4600 collect.collectDirs = Config._parseCollectDirs(sectionNode)
4601 return collect
4602 _parseCollect = staticmethod(_parseCollect)
4603
4605 """
4606 Parses a stage configuration section.
4607
4608 We read the following individual fields::
4609
4610 targetDir //cb_config/stage/staging_dir
4611
4612 We also read groups of the following items, one list element per
4613 item::
4614
4615 localPeers //cb_config/stage/peer
4616 remotePeers //cb_config/stage/peer
4617
4618 The individual peer entries are parsed by L{_parsePeerList}.
4619
4620 @param parentNode: Parent node to search beneath.
4621
4622 @return: C{StageConfig} object or C{None} if the section does not exist.
4623 @raise ValueError: If some filled-in value is invalid.
4624 """
4625 stage = None
4626 sectionNode = readFirstChild(parentNode, "stage")
4627 if sectionNode is not None:
4628 stage = StageConfig()
4629 stage.targetDir = readString(sectionNode, "staging_dir")
4630 (stage.localPeers, stage.remotePeers) = Config._parsePeerList(sectionNode)
4631 return stage
4632 _parseStage = staticmethod(_parseStage)
4633
4635 """
4636 Parses a store configuration section.
4637
4638 We read the following fields::
4639
4640 sourceDir //cb_config/store/source_dir
4641 mediaType //cb_config/store/media_type
4642 deviceType //cb_config/store/device_type
4643 devicePath //cb_config/store/target_device
4644 deviceScsiId //cb_config/store/target_scsi_id
4645 driveSpeed //cb_config/store/drive_speed
4646 checkData //cb_config/store/check_data
4647 checkMedia //cb_config/store/check_media
4648 warnMidnite //cb_config/store/warn_midnite
4649 noEject //cb_config/store/no_eject
4650
4651 Blanking behavior configuration is parsed by the C{_parseBlankBehavior}
4652 method.
4653
4654 @param parentNode: Parent node to search beneath.
4655
4656 @return: C{StoreConfig} object or C{None} if the section does not exist.
4657 @raise ValueError: If some filled-in value is invalid.
4658 """
4659 store = None
4660 sectionNode = readFirstChild(parentNode, "store")
4661 if sectionNode is not None:
4662 store = StoreConfig()
4663 store.sourceDir = readString(sectionNode, "source_dir")
4664 store.mediaType = readString(sectionNode, "media_type")
4665 store.deviceType = readString(sectionNode, "device_type")
4666 store.devicePath = readString(sectionNode, "target_device")
4667 store.deviceScsiId = readString(sectionNode, "target_scsi_id")
4668 store.driveSpeed = readInteger(sectionNode, "drive_speed")
4669 store.checkData = readBoolean(sectionNode, "check_data")
4670 store.checkMedia = readBoolean(sectionNode, "check_media")
4671 store.warnMidnite = readBoolean(sectionNode, "warn_midnite")
4672 store.noEject = readBoolean(sectionNode, "no_eject")
4673 store.blankBehavior = Config._parseBlankBehavior(sectionNode)
4674 store.refreshMediaDelay = readInteger(sectionNode, "refresh_media_delay")
4675 return store
4676 _parseStore = staticmethod(_parseStore)
4677
4679 """
4680 Parses a purge configuration section.
4681
4682 We read groups of the following items, one list element per
4683 item::
4684
4685 purgeDirs //cb_config/purge/dir
4686
4687 The individual directory entries are parsed by L{_parsePurgeDirs}.
4688
4689 @param parentNode: Parent node to search beneath.
4690
4691 @return: C{PurgeConfig} object or C{None} if the section does not exist.
4692 @raise ValueError: If some filled-in value is invalid.
4693 """
4694 purge = None
4695 sectionNode = readFirstChild(parentNode, "purge")
4696 if sectionNode is not None:
4697 purge = PurgeConfig()
4698 purge.purgeDirs = Config._parsePurgeDirs(sectionNode)
4699 return purge
4700 _parsePurge = staticmethod(_parsePurge)
4701
4703 """
4704 Reads extended actions data from immediately beneath the parent.
4705
4706 We read the following individual fields from each extended action::
4707
4708 name name
4709 module module
4710 function function
4711 index index
4712 dependencies depends
4713
4714 Dependency information is parsed by the C{_parseDependencies} method.
4715
4716 @param parentNode: Parent node to search beneath.
4717
4718 @return: List of extended actions.
4719 @raise ValueError: If the data at the location can't be read
4720 """
4721 lst = []
4722 for entry in readChildren(parentNode, "action"):
4723 if isElement(entry):
4724 action = ExtendedAction()
4725 action.name = readString(entry, "name")
4726 action.module = readString(entry, "module")
4727 action.function = readString(entry, "function")
4728 action.index = readInteger(entry, "index")
4729 action.dependencies = Config._parseDependencies(entry)
4730 lst.append(action);
4731 if lst == []:
4732 lst = None
4733 return lst
4734 _parseExtendedActions = staticmethod(_parseExtendedActions)
4735
4737 """
4738 Reads exclusions data from immediately beneath the parent.
4739
4740 We read groups of the following items, one list element per item::
4741
4742 absolute exclude/abs_path
4743 relative exclude/rel_path
4744 patterns exclude/pattern
4745
4746 If there are none of some pattern (i.e. no relative path items) then
4747 C{None} will be returned for that item in the tuple.
4748
4749 This method can be used to parse exclusions on both the collect
4750 configuration level and on the collect directory level within collect
4751 configuration.
4752
4753 @param parentNode: Parent node to search beneath.
4754
4755 @return: Tuple of (absolute, relative, patterns) exclusions.
4756 """
4757 sectionNode = readFirstChild(parentNode, "exclude")
4758 if sectionNode is None:
4759 return (None, None, None)
4760 else:
4761 absolute = readStringList(sectionNode, "abs_path")
4762 relative = readStringList(sectionNode, "rel_path")
4763 patterns = readStringList(sectionNode, "pattern")
4764 return (absolute, relative, patterns)
4765 _parseExclusions = staticmethod(_parseExclusions)
4766
4768 """
4769 Reads a list of C{CommandOverride} objects from immediately beneath the parent.
4770
4771 We read the following individual fields::
4772
4773 command command
4774 absolutePath abs_path
4775
4776 @param parentNode: Parent node to search beneath.
4777
4778 @return: List of C{CommandOverride} objects or C{None} if none are found.
4779 @raise ValueError: If some filled-in value is invalid.
4780 """
4781 lst = []
4782 for entry in readChildren(parentNode, "override"):
4783 if isElement(entry):
4784 override = CommandOverride()
4785 override.command = readString(entry, "command")
4786 override.absolutePath = readString(entry, "abs_path")
4787 lst.append(override)
4788 if lst == []:
4789 lst = None
4790 return lst
4791 _parseOverrides = staticmethod(_parseOverrides)
4792
4794 """
4795 Reads a list of C{ActionHook} objects from immediately beneath the parent.
4796
4797 We read the following individual fields::
4798
4799 action action
4800 command command
4801
4802 @param parentNode: Parent node to search beneath.
4803
4804 @return: List of C{ActionHook} objects or C{None} if none are found.
4805 @raise ValueError: If some filled-in value is invalid.
4806 """
4807 lst = []
4808 for entry in readChildren(parentNode, "pre_action_hook"):
4809 if isElement(entry):
4810 hook = PreActionHook()
4811 hook.action = readString(entry, "action")
4812 hook.command = readString(entry, "command")
4813 lst.append(hook)
4814 for entry in readChildren(parentNode, "post_action_hook"):
4815 if isElement(entry):
4816 hook = PostActionHook()
4817 hook.action = readString(entry, "action")
4818 hook.command = readString(entry, "command")
4819 lst.append(hook)
4820 if lst == []:
4821 lst = None
4822 return lst
4823 _parseHooks = staticmethod(_parseHooks)
4824
4826 """
4827 Reads a list of C{CollectFile} objects from immediately beneath the parent.
4828
4829 We read the following individual fields::
4830
4831 absolutePath abs_path
4832 collectMode mode I{or} collect_mode
4833 archiveMode archive_mode
4834
4835 The collect mode is a special case. Just a C{mode} tag is accepted, but
4836 we prefer C{collect_mode} for consistency with the rest of the config
4837 file and to avoid confusion with the archive mode. If both are provided,
4838 only C{mode} will be used.
4839
4840 @param parentNode: Parent node to search beneath.
4841
4842 @return: List of C{CollectFile} objects or C{None} if none are found.
4843 @raise ValueError: If some filled-in value is invalid.
4844 """
4845 lst = []
4846 for entry in readChildren(parentNode, "file"):
4847 if isElement(entry):
4848 cfile = CollectFile()
4849 cfile.absolutePath = readString(entry, "abs_path")
4850 cfile.collectMode = readString(entry, "mode")
4851 if cfile.collectMode is None:
4852 cfile.collectMode = readString(entry, "collect_mode")
4853 cfile.archiveMode = readString(entry, "archive_mode")
4854 lst.append(cfile)
4855 if lst == []:
4856 lst = None
4857 return lst
4858 _parseCollectFiles = staticmethod(_parseCollectFiles)
4859
4861 """
4862 Reads a list of C{CollectDir} objects from immediately beneath the parent.
4863
4864 We read the following individual fields::
4865
4866 absolutePath abs_path
4867 collectMode mode I{or} collect_mode
4868 archiveMode archive_mode
4869 ignoreFile ignore_file
4870 linkDepth link_depth
4871 dereference dereference
4872
4873 The collect mode is a special case. Just a C{mode} tag is accepted for
4874 backwards compatibility, but we prefer C{collect_mode} for consistency
4875 with the rest of the config file and to avoid confusion with the archive
4876 mode. If both are provided, only C{mode} will be used.
4877
4878 We also read groups of the following items, one list element per
4879 item::
4880
4881 absoluteExcludePaths exclude/abs_path
4882 relativeExcludePaths exclude/rel_path
4883 excludePatterns exclude/pattern
4884
4885 The exclusions are parsed by L{_parseExclusions}.
4886
4887 @param parentNode: Parent node to search beneath.
4888
4889 @return: List of C{CollectDir} objects or C{None} if none are found.
4890 @raise ValueError: If some filled-in value is invalid.
4891 """
4892 lst = []
4893 for entry in readChildren(parentNode, "dir"):
4894 if isElement(entry):
4895 cdir = CollectDir()
4896 cdir.absolutePath = readString(entry, "abs_path")
4897 cdir.collectMode = readString(entry, "mode")
4898 if cdir.collectMode is None:
4899 cdir.collectMode = readString(entry, "collect_mode")
4900 cdir.archiveMode = readString(entry, "archive_mode")
4901 cdir.ignoreFile = readString(entry, "ignore_file")
4902 cdir.linkDepth = readInteger(entry, "link_depth")
4903 cdir.dereference = readBoolean(entry, "dereference")
4904 (cdir.absoluteExcludePaths, cdir.relativeExcludePaths, cdir.excludePatterns) = Config._parseExclusions(entry)
4905 lst.append(cdir)
4906 if lst == []:
4907 lst = None
4908 return lst
4909 _parseCollectDirs = staticmethod(_parseCollectDirs)
4910
4912 """
4913 Reads a list of C{PurgeDir} objects from immediately beneath the parent.
4914
4915 We read the following individual fields::
4916
4917 absolutePath <baseExpr>/abs_path
4918 retainDays <baseExpr>/retain_days
4919
4920 @param parentNode: Parent node to search beneath.
4921
4922 @return: List of C{PurgeDir} objects or C{None} if none are found.
4923 @raise ValueError: If the data at the location can't be read
4924 """
4925 lst = []
4926 for entry in readChildren(parentNode, "dir"):
4927 if isElement(entry):
4928 cdir = PurgeDir()
4929 cdir.absolutePath = readString(entry, "abs_path")
4930 cdir.retainDays = readInteger(entry, "retain_days")
4931 lst.append(cdir)
4932 if lst == []:
4933 lst = None
4934 return lst
4935 _parsePurgeDirs = staticmethod(_parsePurgeDirs)
4936
4938 """
4939 Reads remote and local peer data from immediately beneath the parent.
4940
4941 We read the following individual fields for both remote
4942 and local peers::
4943
4944 name name
4945 collectDir collect_dir
4946
4947 We also read the following individual fields for remote peers
4948 only::
4949
4950 remoteUser backup_user
4951 rcpCommand rcp_command
4952 rshCommand rsh_command
4953 cbackCommand cback_command
4954 managed managed
4955 managedActions managed_actions
4956
4957 Additionally, the value in the C{type} field is used to determine whether
4958 this entry is a remote peer. If the type is C{"remote"}, it's a remote
4959 peer, and if the type is C{"local"}, it's a remote peer.
4960
4961 If there are none of one type of peer (i.e. no local peers) then C{None}
4962 will be returned for that item in the tuple.
4963
4964 @param parentNode: Parent node to search beneath.
4965
4966 @return: Tuple of (local, remote) peer lists.
4967 @raise ValueError: If the data at the location can't be read
4968 """
4969 localPeers = []
4970 remotePeers = []
4971 for entry in readChildren(parentNode, "peer"):
4972 if isElement(entry):
4973 peerType = readString(entry, "type")
4974 if peerType == "local":
4975 localPeer = LocalPeer()
4976 localPeer.name = readString(entry, "name")
4977 localPeer.collectDir = readString(entry, "collect_dir")
4978 localPeer.ignoreFailureMode = readString(entry, "ignore_failures")
4979 localPeers.append(localPeer)
4980 elif peerType == "remote":
4981 remotePeer = RemotePeer()
4982 remotePeer.name = readString(entry, "name")
4983 remotePeer.collectDir = readString(entry, "collect_dir")
4984 remotePeer.remoteUser = readString(entry, "backup_user")
4985 remotePeer.rcpCommand = readString(entry, "rcp_command")
4986 remotePeer.rshCommand = readString(entry, "rsh_command")
4987 remotePeer.cbackCommand = readString(entry, "cback_command")
4988 remotePeer.ignoreFailureMode = readString(entry, "ignore_failures")
4989 remotePeer.managed = readBoolean(entry, "managed")
4990 managedActions = readString(entry, "managed_actions")
4991 remotePeer.managedActions = Config._parseCommaSeparatedString(managedActions)
4992 remotePeers.append(remotePeer)
4993 if localPeers == []:
4994 localPeers = None
4995 if remotePeers == []:
4996 remotePeers = None
4997 return (localPeers, remotePeers)
4998 _parsePeerList = staticmethod(_parsePeerList)
4999
5001 """
5002 Reads extended action dependency information from a parent node.
5003
5004 We read the following individual fields::
5005
5006 runBefore depends/run_before
5007 runAfter depends/run_after
5008
5009 Each of these fields is a comma-separated list of action names.
5010
5011 The result is placed into an C{ActionDependencies} object.
5012
5013 If the dependencies parent node does not exist, C{None} will be returned.
5014 Otherwise, an C{ActionDependencies} object will always be created, even
5015 if it does not contain any actual dependencies in it.
5016
5017 @param parentNode: Parent node to search beneath.
5018
5019 @return: C{ActionDependencies} object or C{None}.
5020 @raise ValueError: If the data at the location can't be read
5021 """
5022 sectionNode = readFirstChild(parentNode, "depends")
5023 if sectionNode is None:
5024 return None
5025 else:
5026 runBefore = readString(sectionNode, "run_before")
5027 runAfter = readString(sectionNode, "run_after")
5028 beforeList = Config._parseCommaSeparatedString(runBefore)
5029 afterList = Config._parseCommaSeparatedString(runAfter)
5030 return ActionDependencies(beforeList, afterList)
5031 _parseDependencies = staticmethod(_parseDependencies)
5032
5034 """
5035 Parses a list of values out of a comma-separated string.
5036
5037 The items in the list are split by comma, and then have whitespace
5038 stripped. As a special case, if C{commaString} is C{None}, then C{None}
5039 will be returned.
5040
5041 @param commaString: List of values in comma-separated string format.
5042 @return: Values from commaString split into a list, or C{None}.
5043 """
5044 if commaString is None:
5045 return None
5046 else:
5047 pass1 = commaString.split(",")
5048 pass2 = []
5049 for item in pass1:
5050 item = item.strip()
5051 if len(item) > 0:
5052 pass2.append(item)
5053 return pass2
5054 _parseCommaSeparatedString = staticmethod(_parseCommaSeparatedString)
5055
5057 """
5058 Reads a single C{BlankBehavior} object from immediately beneath the parent.
5059
5060 We read the following individual fields::
5061
5062 blankMode blank_behavior/mode
5063 blankFactor blank_behavior/factor
5064
5065 @param parentNode: Parent node to search beneath.
5066
5067 @return: C{BlankBehavior} object or C{None} if none if the section is not found
5068 @raise ValueError: If some filled-in value is invalid.
5069 """
5070 blankBehavior = None
5071 sectionNode = readFirstChild(parentNode, "blank_behavior")
5072 if sectionNode is not None:
5073 blankBehavior = BlankBehavior()
5074 blankBehavior.blankMode = readString(sectionNode, "mode")
5075 blankBehavior.blankFactor = readString(sectionNode, "factor")
5076 return blankBehavior
5077 _parseBlankBehavior = staticmethod(_parseBlankBehavior)
5078
5079
5080
5081
5082
5083
5085 """
5086 Internal method to extract configuration into an XML string.
5087
5088 This method assumes that the internal L{validate} method has been called
5089 prior to extracting the XML, if the caller cares. No validation will be
5090 done internally.
5091
5092 As a general rule, fields that are set to C{None} will be extracted into
5093 the document as empty tags. The same goes for container tags that are
5094 filled based on lists - if the list is empty or C{None}, the container
5095 tag will be empty.
5096 """
5097 (xmlDom, parentNode) = createOutputDom()
5098 Config._addReference(xmlDom, parentNode, self.reference)
5099 Config._addExtensions(xmlDom, parentNode, self.extensions)
5100 Config._addOptions(xmlDom, parentNode, self.options)
5101 Config._addPeers(xmlDom, parentNode, self.peers)
5102 Config._addCollect(xmlDom, parentNode, self.collect)
5103 Config._addStage(xmlDom, parentNode, self.stage)
5104 Config._addStore(xmlDom, parentNode, self.store)
5105 Config._addPurge(xmlDom, parentNode, self.purge)
5106 xmlData = serializeDom(xmlDom)
5107 xmlDom.unlink()
5108 return xmlData
5109
5111 """
5112 Adds a <reference> configuration section as the next child of a parent.
5113
5114 We add the following fields to the document::
5115
5116 author //cb_config/reference/author
5117 revision //cb_config/reference/revision
5118 description //cb_config/reference/description
5119 generator //cb_config/reference/generator
5120
5121 If C{referenceConfig} is C{None}, then no container will be added.
5122
5123 @param xmlDom: DOM tree as from L{createOutputDom}.
5124 @param parentNode: Parent that the section should be appended to.
5125 @param referenceConfig: Reference configuration section to be added to the document.
5126 """
5127 if referenceConfig is not None:
5128 sectionNode = addContainerNode(xmlDom, parentNode, "reference")
5129 addStringNode(xmlDom, sectionNode, "author", referenceConfig.author)
5130 addStringNode(xmlDom, sectionNode, "revision", referenceConfig.revision)
5131 addStringNode(xmlDom, sectionNode, "description", referenceConfig.description)
5132 addStringNode(xmlDom, sectionNode, "generator", referenceConfig.generator)
5133 _addReference = staticmethod(_addReference)
5134
5136 """
5137 Adds an <extensions> configuration section as the next child of a parent.
5138
5139 We add the following fields to the document::
5140
5141 order_mode //cb_config/extensions/order_mode
5142
5143 We also add groups of the following items, one list element per item::
5144
5145 actions //cb_config/extensions/action
5146
5147 The extended action entries are added by L{_addExtendedAction}.
5148
5149 If C{extensionsConfig} is C{None}, then no container will be added.
5150
5151 @param xmlDom: DOM tree as from L{createOutputDom}.
5152 @param parentNode: Parent that the section should be appended to.
5153 @param extensionsConfig: Extensions configuration section to be added to the document.
5154 """
5155 if extensionsConfig is not None:
5156 sectionNode = addContainerNode(xmlDom, parentNode, "extensions")
5157 addStringNode(xmlDom, sectionNode, "order_mode", extensionsConfig.orderMode)
5158 if extensionsConfig.actions is not None:
5159 for action in extensionsConfig.actions:
5160 Config._addExtendedAction(xmlDom, sectionNode, action)
5161 _addExtensions = staticmethod(_addExtensions)
5162
5164 """
5165 Adds a <options> configuration section as the next child of a parent.
5166
5167 We add the following fields to the document::
5168
5169 startingDay //cb_config/options/starting_day
5170 workingDir //cb_config/options/working_dir
5171 backupUser //cb_config/options/backup_user
5172 backupGroup //cb_config/options/backup_group
5173 rcpCommand //cb_config/options/rcp_command
5174 rshCommand //cb_config/options/rsh_command
5175 cbackCommand //cb_config/options/cback_command
5176 managedActions //cb_config/options/managed_actions
5177
5178 We also add groups of the following items, one list element per
5179 item::
5180
5181 overrides //cb_config/options/override
5182 hooks //cb_config/options/pre_action_hook
5183 hooks //cb_config/options/post_action_hook
5184
5185 The individual override items are added by L{_addOverride}. The
5186 individual hook items are added by L{_addHook}.
5187
5188 If C{optionsConfig} is C{None}, then no container will be added.
5189
5190 @param xmlDom: DOM tree as from L{createOutputDom}.
5191 @param parentNode: Parent that the section should be appended to.
5192 @param optionsConfig: Options configuration section to be added to the document.
5193 """
5194 if optionsConfig is not None:
5195 sectionNode = addContainerNode(xmlDom, parentNode, "options")
5196 addStringNode(xmlDom, sectionNode, "starting_day", optionsConfig.startingDay)
5197 addStringNode(xmlDom, sectionNode, "working_dir", optionsConfig.workingDir)
5198 addStringNode(xmlDom, sectionNode, "backup_user", optionsConfig.backupUser)
5199 addStringNode(xmlDom, sectionNode, "backup_group", optionsConfig.backupGroup)
5200 addStringNode(xmlDom, sectionNode, "rcp_command", optionsConfig.rcpCommand)
5201 addStringNode(xmlDom, sectionNode, "rsh_command", optionsConfig.rshCommand)
5202 addStringNode(xmlDom, sectionNode, "cback_command", optionsConfig.cbackCommand)
5203 managedActions = Config._buildCommaSeparatedString(optionsConfig.managedActions)
5204 addStringNode(xmlDom, sectionNode, "managed_actions", managedActions)
5205 if optionsConfig.overrides is not None:
5206 for override in optionsConfig.overrides:
5207 Config._addOverride(xmlDom, sectionNode, override)
5208 if optionsConfig.hooks is not None:
5209 for hook in optionsConfig.hooks:
5210 Config._addHook(xmlDom, sectionNode, hook)
5211 _addOptions = staticmethod(_addOptions)
5212
5213 - def _addPeers(xmlDom, parentNode, peersConfig):
5214 """
5215 Adds a <peers> configuration section as the next child of a parent.
5216
5217 We add groups of the following items, one list element per
5218 item::
5219
5220 localPeers //cb_config/peers/peer
5221 remotePeers //cb_config/peers/peer
5222
5223 The individual local and remote peer entries are added by
5224 L{_addLocalPeer} and L{_addRemotePeer}, respectively.
5225
5226 If C{peersConfig} is C{None}, then no container will be added.
5227
5228 @param xmlDom: DOM tree as from L{createOutputDom}.
5229 @param parentNode: Parent that the section should be appended to.
5230 @param peersConfig: Peers configuration section to be added to the document.
5231 """
5232 if peersConfig is not None:
5233 sectionNode = addContainerNode(xmlDom, parentNode, "peers")
5234 if peersConfig.localPeers is not None:
5235 for localPeer in peersConfig.localPeers:
5236 Config._addLocalPeer(xmlDom, sectionNode, localPeer)
5237 if peersConfig.remotePeers is not None:
5238 for remotePeer in peersConfig.remotePeers:
5239 Config._addRemotePeer(xmlDom, sectionNode, remotePeer)
5240 _addPeers = staticmethod(_addPeers)
5241
5243 """
5244 Adds a <collect> configuration section as the next child of a parent.
5245
5246 We add the following fields to the document::
5247
5248 targetDir //cb_config/collect/collect_dir
5249 collectMode //cb_config/collect/collect_mode
5250 archiveMode //cb_config/collect/archive_mode
5251 ignoreFile //cb_config/collect/ignore_file
5252
5253 We also add groups of the following items, one list element per
5254 item::
5255
5256 absoluteExcludePaths //cb_config/collect/exclude/abs_path
5257 excludePatterns //cb_config/collect/exclude/pattern
5258 collectFiles //cb_config/collect/file
5259 collectDirs //cb_config/collect/dir
5260
5261 The individual collect files are added by L{_addCollectFile} and
5262 individual collect directories are added by L{_addCollectDir}.
5263
5264 If C{collectConfig} is C{None}, then no container will be added.
5265
5266 @param xmlDom: DOM tree as from L{createOutputDom}.
5267 @param parentNode: Parent that the section should be appended to.
5268 @param collectConfig: Collect configuration section to be added to the document.
5269 """
5270 if collectConfig is not None:
5271 sectionNode = addContainerNode(xmlDom, parentNode, "collect")
5272 addStringNode(xmlDom, sectionNode, "collect_dir", collectConfig.targetDir)
5273 addStringNode(xmlDom, sectionNode, "collect_mode", collectConfig.collectMode)
5274 addStringNode(xmlDom, sectionNode, "archive_mode", collectConfig.archiveMode)
5275 addStringNode(xmlDom, sectionNode, "ignore_file", collectConfig.ignoreFile)
5276 if ((collectConfig.absoluteExcludePaths is not None and collectConfig.absoluteExcludePaths != []) or
5277 (collectConfig.excludePatterns is not None and collectConfig.excludePatterns != [])):
5278 excludeNode = addContainerNode(xmlDom, sectionNode, "exclude")
5279 if collectConfig.absoluteExcludePaths is not None:
5280 for absolutePath in collectConfig.absoluteExcludePaths:
5281 addStringNode(xmlDom, excludeNode, "abs_path", absolutePath)
5282 if collectConfig.excludePatterns is not None:
5283 for pattern in collectConfig.excludePatterns:
5284 addStringNode(xmlDom, excludeNode, "pattern", pattern)
5285 if collectConfig.collectFiles is not None:
5286 for collectFile in collectConfig.collectFiles:
5287 Config._addCollectFile(xmlDom, sectionNode, collectFile)
5288 if collectConfig.collectDirs is not None:
5289 for collectDir in collectConfig.collectDirs:
5290 Config._addCollectDir(xmlDom, sectionNode, collectDir)
5291 _addCollect = staticmethod(_addCollect)
5292
5293 - def _addStage(xmlDom, parentNode, stageConfig):
5294 """
5295 Adds a <stage> configuration section as the next child of a parent.
5296
5297 We add the following fields to the document::
5298
5299 targetDir //cb_config/stage/staging_dir
5300
5301 We also add groups of the following items, one list element per
5302 item::
5303
5304 localPeers //cb_config/stage/peer
5305 remotePeers //cb_config/stage/peer
5306
5307 The individual local and remote peer entries are added by
5308 L{_addLocalPeer} and L{_addRemotePeer}, respectively.
5309
5310 If C{stageConfig} is C{None}, then no container will be added.
5311
5312 @param xmlDom: DOM tree as from L{createOutputDom}.
5313 @param parentNode: Parent that the section should be appended to.
5314 @param stageConfig: Stage configuration section to be added to the document.
5315 """
5316 if stageConfig is not None:
5317 sectionNode = addContainerNode(xmlDom, parentNode, "stage")
5318 addStringNode(xmlDom, sectionNode, "staging_dir", stageConfig.targetDir)
5319 if stageConfig.localPeers is not None:
5320 for localPeer in stageConfig.localPeers:
5321 Config._addLocalPeer(xmlDom, sectionNode, localPeer)
5322 if stageConfig.remotePeers is not None:
5323 for remotePeer in stageConfig.remotePeers:
5324 Config._addRemotePeer(xmlDom, sectionNode, remotePeer)
5325 _addStage = staticmethod(_addStage)
5326
5327 - def _addStore(xmlDom, parentNode, storeConfig):
5328 """
5329 Adds a <store> configuration section as the next child of a parent.
5330
5331 We add the following fields to the document::
5332
5333 sourceDir //cb_config/store/source_dir
5334 mediaType //cb_config/store/media_type
5335 deviceType //cb_config/store/device_type
5336 devicePath //cb_config/store/target_device
5337 deviceScsiId //cb_config/store/target_scsi_id
5338 driveSpeed //cb_config/store/drive_speed
5339 checkData //cb_config/store/check_data
5340 checkMedia //cb_config/store/check_media
5341 warnMidnite //cb_config/store/warn_midnite
5342 noEject //cb_config/store/no_eject
5343
5344 Blanking behavior configuration is added by the L{_addBlankBehavior}
5345 method.
5346
5347 If C{storeConfig} is C{None}, then no container will be added.
5348
5349 @param xmlDom: DOM tree as from L{createOutputDom}.
5350 @param parentNode: Parent that the section should be appended to.
5351 @param storeConfig: Store configuration section to be added to the document.
5352 """
5353 if storeConfig is not None:
5354 sectionNode = addContainerNode(xmlDom, parentNode, "store")
5355 addStringNode(xmlDom, sectionNode, "source_dir", storeConfig.sourceDir)
5356 addStringNode(xmlDom, sectionNode, "media_type", storeConfig.mediaType)
5357 addStringNode(xmlDom, sectionNode, "device_type", storeConfig.deviceType)
5358 addStringNode(xmlDom, sectionNode, "target_device", storeConfig.devicePath)
5359 addStringNode(xmlDom, sectionNode, "target_scsi_id", storeConfig.deviceScsiId)
5360 addIntegerNode(xmlDom, sectionNode, "drive_speed", storeConfig.driveSpeed)
5361 addBooleanNode(xmlDom, sectionNode, "check_data", storeConfig.checkData)
5362 addBooleanNode(xmlDom, sectionNode, "check_media", storeConfig.checkMedia)
5363 addBooleanNode(xmlDom, sectionNode, "warn_midnite", storeConfig.warnMidnite)
5364 addBooleanNode(xmlDom, sectionNode, "no_eject", storeConfig.noEject)
5365 addIntegerNode(xmlDom, sectionNode, "refresh_media_delay", storeConfig.refreshMediaDelay)
5366 Config._addBlankBehavior(xmlDom, sectionNode, storeConfig.blankBehavior)
5367 _addStore = staticmethod(_addStore)
5368
5369 - def _addPurge(xmlDom, parentNode, purgeConfig):
5370 """
5371 Adds a <purge> configuration section as the next child of a parent.
5372
5373 We add the following fields to the document::
5374
5375 purgeDirs //cb_config/purge/dir
5376
5377 The individual directory entries are added by L{_addPurgeDir}.
5378
5379 If C{purgeConfig} is C{None}, then no container will be added.
5380
5381 @param xmlDom: DOM tree as from L{createOutputDom}.
5382 @param parentNode: Parent that the section should be appended to.
5383 @param purgeConfig: Purge configuration section to be added to the document.
5384 """
5385 if purgeConfig is not None:
5386 sectionNode = addContainerNode(xmlDom, parentNode, "purge")
5387 if purgeConfig.purgeDirs is not None:
5388 for purgeDir in purgeConfig.purgeDirs:
5389 Config._addPurgeDir(xmlDom, sectionNode, purgeDir)
5390 _addPurge = staticmethod(_addPurge)
5391
5393 """
5394 Adds an extended action container as the next child of a parent.
5395
5396 We add the following fields to the document::
5397
5398 name action/name
5399 module action/module
5400 function action/function
5401 index action/index
5402 dependencies action/depends
5403
5404 Dependencies are added by the L{_addDependencies} method.
5405
5406 The <action> node itself is created as the next child of the parent node.
5407 This method only adds one action node. The parent must loop for each action
5408 in the C{ExtensionsConfig} object.
5409
5410 If C{action} is C{None}, this method call will be a no-op.
5411
5412 @param xmlDom: DOM tree as from L{createOutputDom}.
5413 @param parentNode: Parent that the section should be appended to.
5414 @param action: Purge directory to be added to the document.
5415 """
5416 if action is not None:
5417 sectionNode = addContainerNode(xmlDom, parentNode, "action")
5418 addStringNode(xmlDom, sectionNode, "name", action.name)
5419 addStringNode(xmlDom, sectionNode, "module", action.module)
5420 addStringNode(xmlDom, sectionNode, "function", action.function)
5421 addIntegerNode(xmlDom, sectionNode, "index", action.index)
5422 Config._addDependencies(xmlDom, sectionNode, action.dependencies)
5423 _addExtendedAction = staticmethod(_addExtendedAction)
5424
5426 """
5427 Adds a command override container as the next child of a parent.
5428
5429 We add the following fields to the document::
5430
5431 command override/command
5432 absolutePath override/abs_path
5433
5434 The <override> node itself is created as the next child of the parent
5435 node. This method only adds one override node. The parent must loop for
5436 each override in the C{OptionsConfig} object.
5437
5438 If C{override} is C{None}, this method call will be a no-op.
5439
5440 @param xmlDom: DOM tree as from L{createOutputDom}.
5441 @param parentNode: Parent that the section should be appended to.
5442 @param override: Command override to be added to the document.
5443 """
5444 if override is not None:
5445 sectionNode = addContainerNode(xmlDom, parentNode, "override")
5446 addStringNode(xmlDom, sectionNode, "command", override.command)
5447 addStringNode(xmlDom, sectionNode, "abs_path", override.absolutePath)
5448 _addOverride = staticmethod(_addOverride)
5449
5450 - def _addHook(xmlDom, parentNode, hook):
5451 """
5452 Adds an action hook container as the next child of a parent.
5453
5454 The behavior varies depending on the value of the C{before} and C{after}
5455 flags on the hook. If the C{before} flag is set, it's a pre-action hook,
5456 and we'll add the following fields::
5457
5458 action pre_action_hook/action
5459 command pre_action_hook/command
5460
5461 If the C{after} flag is set, it's a post-action hook, and we'll add the
5462 following fields::
5463
5464 action post_action_hook/action
5465 command post_action_hook/command
5466
5467 The <pre_action_hook> or <post_action_hook> node itself is created as the
5468 next child of the parent node. This method only adds one hook node. The
5469 parent must loop for each hook in the C{OptionsConfig} object.
5470
5471 If C{hook} is C{None}, this method call will be a no-op.
5472
5473 @param xmlDom: DOM tree as from L{createOutputDom}.
5474 @param parentNode: Parent that the section should be appended to.
5475 @param hook: Command hook to be added to the document.
5476 """
5477 if hook is not None:
5478 if hook.before:
5479 sectionNode = addContainerNode(xmlDom, parentNode, "pre_action_hook")
5480 else:
5481 sectionNode = addContainerNode(xmlDom, parentNode, "post_action_hook")
5482 addStringNode(xmlDom, sectionNode, "action", hook.action)
5483 addStringNode(xmlDom, sectionNode, "command", hook.command)
5484 _addHook = staticmethod(_addHook)
5485
5487 """
5488 Adds a collect file container as the next child of a parent.
5489
5490 We add the following fields to the document::
5491
5492 absolutePath dir/abs_path
5493 collectMode dir/collect_mode
5494 archiveMode dir/archive_mode
5495
5496 Note that for consistency with collect directory handling we'll only emit
5497 the preferred C{collect_mode} tag.
5498
5499 The <file> node itself is created as the next child of the parent node.
5500 This method only adds one collect file node. The parent must loop
5501 for each collect file in the C{CollectConfig} object.
5502
5503 If C{collectFile} is C{None}, this method call will be a no-op.
5504
5505 @param xmlDom: DOM tree as from L{createOutputDom}.
5506 @param parentNode: Parent that the section should be appended to.
5507 @param collectFile: Collect file to be added to the document.
5508 """
5509 if collectFile is not None:
5510 sectionNode = addContainerNode(xmlDom, parentNode, "file")
5511 addStringNode(xmlDom, sectionNode, "abs_path", collectFile.absolutePath)
5512 addStringNode(xmlDom, sectionNode, "collect_mode", collectFile.collectMode)
5513 addStringNode(xmlDom, sectionNode, "archive_mode", collectFile.archiveMode)
5514 _addCollectFile = staticmethod(_addCollectFile)
5515
5517 """
5518 Adds a collect directory container as the next child of a parent.
5519
5520 We add the following fields to the document::
5521
5522 absolutePath dir/abs_path
5523 collectMode dir/collect_mode
5524 archiveMode dir/archive_mode
5525 ignoreFile dir/ignore_file
5526 linkDepth dir/link_depth
5527 dereference dir/dereference
5528
5529 Note that an original XML document might have listed the collect mode
5530 using the C{mode} tag, since we accept both C{collect_mode} and C{mode}.
5531 However, here we'll only emit the preferred C{collect_mode} tag.
5532
5533 We also add groups of the following items, one list element per item::
5534
5535 absoluteExcludePaths dir/exclude/abs_path
5536 relativeExcludePaths dir/exclude/rel_path
5537 excludePatterns dir/exclude/pattern
5538
5539 The <dir> node itself is created as the next child of the parent node.
5540 This method only adds one collect directory node. The parent must loop
5541 for each collect directory in the C{CollectConfig} object.
5542
5543 If C{collectDir} is C{None}, this method call will be a no-op.
5544
5545 @param xmlDom: DOM tree as from L{createOutputDom}.
5546 @param parentNode: Parent that the section should be appended to.
5547 @param collectDir: Collect directory to be added to the document.
5548 """
5549 if collectDir is not None:
5550 sectionNode = addContainerNode(xmlDom, parentNode, "dir")
5551 addStringNode(xmlDom, sectionNode, "abs_path", collectDir.absolutePath)
5552 addStringNode(xmlDom, sectionNode, "collect_mode", collectDir.collectMode)
5553 addStringNode(xmlDom, sectionNode, "archive_mode", collectDir.archiveMode)
5554 addStringNode(xmlDom, sectionNode, "ignore_file", collectDir.ignoreFile)
5555 addIntegerNode(xmlDom, sectionNode, "link_depth", collectDir.linkDepth)
5556 addBooleanNode(xmlDom, sectionNode, "dereference", collectDir.dereference)
5557 if ((collectDir.absoluteExcludePaths is not None and collectDir.absoluteExcludePaths != []) or
5558 (collectDir.relativeExcludePaths is not None and collectDir.relativeExcludePaths != []) or
5559 (collectDir.excludePatterns is not None and collectDir.excludePatterns != [])):
5560 excludeNode = addContainerNode(xmlDom, sectionNode, "exclude")
5561 if collectDir.absoluteExcludePaths is not None:
5562 for absolutePath in collectDir.absoluteExcludePaths:
5563 addStringNode(xmlDom, excludeNode, "abs_path", absolutePath)
5564 if collectDir.relativeExcludePaths is not None:
5565 for relativePath in collectDir.relativeExcludePaths:
5566 addStringNode(xmlDom, excludeNode, "rel_path", relativePath)
5567 if collectDir.excludePatterns is not None:
5568 for pattern in collectDir.excludePatterns:
5569 addStringNode(xmlDom, excludeNode, "pattern", pattern)
5570 _addCollectDir = staticmethod(_addCollectDir)
5571
5573 """
5574 Adds a local peer container as the next child of a parent.
5575
5576 We add the following fields to the document::
5577
5578 name peer/name
5579 collectDir peer/collect_dir
5580 ignoreFailureMode peer/ignore_failures
5581
5582 Additionally, C{peer/type} is filled in with C{"local"}, since this is a
5583 local peer.
5584
5585 The <peer> node itself is created as the next child of the parent node.
5586 This method only adds one peer node. The parent must loop for each peer
5587 in the C{StageConfig} object.
5588
5589 If C{localPeer} is C{None}, this method call will be a no-op.
5590
5591 @param xmlDom: DOM tree as from L{createOutputDom}.
5592 @param parentNode: Parent that the section should be appended to.
5593 @param localPeer: Purge directory to be added to the document.
5594 """
5595 if localPeer is not None:
5596 sectionNode = addContainerNode(xmlDom, parentNode, "peer")
5597 addStringNode(xmlDom, sectionNode, "name", localPeer.name)
5598 addStringNode(xmlDom, sectionNode, "type", "local")
5599 addStringNode(xmlDom, sectionNode, "collect_dir", localPeer.collectDir)
5600 addStringNode(xmlDom, sectionNode, "ignore_failures", localPeer.ignoreFailureMode)
5601 _addLocalPeer = staticmethod(_addLocalPeer)
5602
5604 """
5605 Adds a remote peer container as the next child of a parent.
5606
5607 We add the following fields to the document::
5608
5609 name peer/name
5610 collectDir peer/collect_dir
5611 remoteUser peer/backup_user
5612 rcpCommand peer/rcp_command
5613 rcpCommand peer/rcp_command
5614 rshCommand peer/rsh_command
5615 cbackCommand peer/cback_command
5616 ignoreFailureMode peer/ignore_failures
5617 managed peer/managed
5618 managedActions peer/managed_actions
5619
5620 Additionally, C{peer/type} is filled in with C{"remote"}, since this is a
5621 remote peer.
5622
5623 The <peer> node itself is created as the next child of the parent node.
5624 This method only adds one peer node. The parent must loop for each peer
5625 in the C{StageConfig} object.
5626
5627 If C{remotePeer} is C{None}, this method call will be a no-op.
5628
5629 @param xmlDom: DOM tree as from L{createOutputDom}.
5630 @param parentNode: Parent that the section should be appended to.
5631 @param remotePeer: Purge directory to be added to the document.
5632 """
5633 if remotePeer is not None:
5634 sectionNode = addContainerNode(xmlDom, parentNode, "peer")
5635 addStringNode(xmlDom, sectionNode, "name", remotePeer.name)
5636 addStringNode(xmlDom, sectionNode, "type", "remote")
5637 addStringNode(xmlDom, sectionNode, "collect_dir", remotePeer.collectDir)
5638 addStringNode(xmlDom, sectionNode, "backup_user", remotePeer.remoteUser)
5639 addStringNode(xmlDom, sectionNode, "rcp_command", remotePeer.rcpCommand)
5640 addStringNode(xmlDom, sectionNode, "rsh_command", remotePeer.rshCommand)
5641 addStringNode(xmlDom, sectionNode, "cback_command", remotePeer.cbackCommand)
5642 addStringNode(xmlDom, sectionNode, "ignore_failures", remotePeer.ignoreFailureMode)
5643 addBooleanNode(xmlDom, sectionNode, "managed", remotePeer.managed)
5644 managedActions = Config._buildCommaSeparatedString(remotePeer.managedActions)
5645 addStringNode(xmlDom, sectionNode, "managed_actions", managedActions)
5646 _addRemotePeer = staticmethod(_addRemotePeer)
5647
5649 """
5650 Adds a purge directory container as the next child of a parent.
5651
5652 We add the following fields to the document::
5653
5654 absolutePath dir/abs_path
5655 retainDays dir/retain_days
5656
5657 The <dir> node itself is created as the next child of the parent node.
5658 This method only adds one purge directory node. The parent must loop for
5659 each purge directory in the C{PurgeConfig} object.
5660
5661 If C{purgeDir} is C{None}, this method call will be a no-op.
5662
5663 @param xmlDom: DOM tree as from L{createOutputDom}.
5664 @param parentNode: Parent that the section should be appended to.
5665 @param purgeDir: Purge directory to be added to the document.
5666 """
5667 if purgeDir is not None:
5668 sectionNode = addContainerNode(xmlDom, parentNode, "dir")
5669 addStringNode(xmlDom, sectionNode, "abs_path", purgeDir.absolutePath)
5670 addIntegerNode(xmlDom, sectionNode, "retain_days", purgeDir.retainDays)
5671 _addPurgeDir = staticmethod(_addPurgeDir)
5672
5674 """
5675 Adds a extended action dependencies to parent node.
5676
5677 We add the following fields to the document::
5678
5679 runBefore depends/run_before
5680 runAfter depends/run_after
5681
5682 If C{dependencies} is C{None}, this method call will be a no-op.
5683
5684 @param xmlDom: DOM tree as from L{createOutputDom}.
5685 @param parentNode: Parent that the section should be appended to.
5686 @param dependencies: C{ActionDependencies} object to be added to the document
5687 """
5688 if dependencies is not None:
5689 sectionNode = addContainerNode(xmlDom, parentNode, "depends")
5690 runBefore = Config._buildCommaSeparatedString(dependencies.beforeList)
5691 runAfter = Config._buildCommaSeparatedString(dependencies.afterList)
5692 addStringNode(xmlDom, sectionNode, "run_before", runBefore)
5693 addStringNode(xmlDom, sectionNode, "run_after", runAfter)
5694 _addDependencies = staticmethod(_addDependencies)
5695
5697 """
5698 Creates a comma-separated string from a list of values.
5699
5700 As a special case, if C{valueList} is C{None}, then C{None} will be
5701 returned.
5702
5703 @param valueList: List of values to be placed into a string
5704
5705 @return: Values from valueList as a comma-separated string.
5706 """
5707 if valueList is None:
5708 return None
5709 return ",".join(valueList)
5710 _buildCommaSeparatedString = staticmethod(_buildCommaSeparatedString)
5711
5713 """
5714 Adds a blanking behavior container as the next child of a parent.
5715
5716 We add the following fields to the document::
5717
5718 blankMode blank_behavior/mode
5719 blankFactor blank_behavior/factor
5720
5721 The <blank_behavior> node itself is created as the next child of the
5722 parent node.
5723
5724 If C{blankBehavior} is C{None}, this method call will be a no-op.
5725
5726 @param xmlDom: DOM tree as from L{createOutputDom}.
5727 @param parentNode: Parent that the section should be appended to.
5728 @param blankBehavior: Blanking behavior to be added to the document.
5729 """
5730 if blankBehavior is not None:
5731 sectionNode = addContainerNode(xmlDom, parentNode, "blank_behavior")
5732 addStringNode(xmlDom, sectionNode, "mode", blankBehavior.blankMode)
5733 addStringNode(xmlDom, sectionNode, "factor", blankBehavior.blankFactor)
5734 _addBlankBehavior = staticmethod(_addBlankBehavior)
5735
5736
5737
5738
5739
5740
5742 """
5743 Validates configuration contents per rules discussed in module
5744 documentation.
5745
5746 This is the second pass at validation. It ensures that any filled-in
5747 section contains valid data. Any sections which is not set to C{None} is
5748 validated per the rules for that section, laid out in the module
5749 documentation (above).
5750
5751 @raise ValueError: If configuration is invalid.
5752 """
5753 self._validateReference()
5754 self._validateExtensions()
5755 self._validateOptions()
5756 self._validatePeers()
5757 self._validateCollect()
5758 self._validateStage()
5759 self._validateStore()
5760 self._validatePurge()
5761
5763 """
5764 Validates reference configuration.
5765 There are currently no reference-related validations.
5766 @raise ValueError: If reference configuration is invalid.
5767 """
5768 pass
5769
5771 """
5772 Validates extensions configuration.
5773
5774 The list of actions may be either C{None} or an empty list C{[]} if
5775 desired. Each extended action must include a name, a module, and a
5776 function.
5777
5778 Then, if the order mode is None or "index", an index is required; and if
5779 the order mode is "dependency", dependency information is required.
5780
5781 @raise ValueError: If reference configuration is invalid.
5782 """
5783 if self.extensions is not None:
5784 if self.extensions.actions is not None:
5785 names = []
5786 for action in self.extensions.actions:
5787 if action.name is None:
5788 raise ValueError("Each extended action must set a name.")
5789 names.append(action.name)
5790 if action.module is None:
5791 raise ValueError("Each extended action must set a module.")
5792 if action.function is None:
5793 raise ValueError("Each extended action must set a function.")
5794 if self.extensions.orderMode is None or self.extensions.orderMode == "index":
5795 if action.index is None:
5796 raise ValueError("Each extended action must set an index, based on order mode.")
5797 elif self.extensions.orderMode == "dependency":
5798 if action.dependencies is None:
5799 raise ValueError("Each extended action must set dependency information, based on order mode.")
5800 Config._checkUnique("Duplicate extension names exist:", names)
5801
5803 """
5804 Validates options configuration.
5805
5806 All fields must be filled in except the rsh command. The rcp and rsh
5807 commands are used as default values for all remote peers. Remote peers
5808 can also rely on the backup user as the default remote user name if they
5809 choose.
5810
5811 @raise ValueError: If reference configuration is invalid.
5812 """
5813 if self.options is not None:
5814 if self.options.startingDay is None:
5815 raise ValueError("Options section starting day must be filled in.")
5816 if self.options.workingDir is None:
5817 raise ValueError("Options section working directory must be filled in.")
5818 if self.options.backupUser is None:
5819 raise ValueError("Options section backup user must be filled in.")
5820 if self.options.backupGroup is None:
5821 raise ValueError("Options section backup group must be filled in.")
5822 if self.options.rcpCommand is None:
5823 raise ValueError("Options section remote copy command must be filled in.")
5824
5832
5834 """
5835 Validates collect configuration.
5836
5837 The target directory must be filled in. The collect mode, archive mode
5838 and ignore file are all optional. The list of absolute paths to exclude
5839 and patterns to exclude may be either C{None} or an empty list C{[]} if
5840 desired.
5841
5842 Each collect directory entry must contain an absolute path to collect,
5843 and then must either be able to take collect mode, archive mode and
5844 ignore file configuration from the parent C{CollectConfig} object, or
5845 must set each value on its own. The list of absolute paths to exclude,
5846 relative paths to exclude and patterns to exclude may be either C{None}
5847 or an empty list C{[]} if desired. Any list of absolute paths to exclude
5848 or patterns to exclude will be combined with the same list in the
5849 C{CollectConfig} object to make the complete list for a given directory.
5850
5851 @raise ValueError: If collect configuration is invalid.
5852 """
5853 if self.collect is not None:
5854 if self.collect.targetDir is None:
5855 raise ValueError("Collect section target directory must be filled in.")
5856 if self.collect.collectFiles is not None:
5857 for collectFile in self.collect.collectFiles:
5858 if collectFile.absolutePath is None:
5859 raise ValueError("Each collect file must set an absolute path.")
5860 if self.collect.collectMode is None and collectFile.collectMode is None:
5861 raise ValueError("Collect mode must either be set in parent collect section or individual collect file.")
5862 if self.collect.archiveMode is None and collectFile.archiveMode is None:
5863 raise ValueError("Archive mode must either be set in parent collect section or individual collect file.")
5864 if self.collect.collectDirs is not None:
5865 for collectDir in self.collect.collectDirs:
5866 if collectDir.absolutePath is None:
5867 raise ValueError("Each collect directory must set an absolute path.")
5868 if self.collect.collectMode is None and collectDir.collectMode is None:
5869 raise ValueError("Collect mode must either be set in parent collect section or individual collect directory.")
5870 if self.collect.archiveMode is None and collectDir.archiveMode is None:
5871 raise ValueError("Archive mode must either be set in parent collect section or individual collect directory.")
5872 if self.collect.ignoreFile is None and collectDir.ignoreFile is None:
5873 raise ValueError("Ignore file must either be set in parent collect section or individual collect directory.")
5874 if (collectDir.linkDepth is None or collectDir.linkDepth < 1) and collectDir.dereference:
5875 raise ValueError("Dereference flag is only valid when a non-zero link depth is in use.")
5876
5878 """
5879 Validates stage configuration.
5880
5881 The target directory must be filled in, and the peers are
5882 also validated.
5883
5884 Peers are only required in this section if the peers configuration
5885 section is not filled in. However, if any peers are filled in
5886 here, they override the peers configuration and must meet the
5887 validation criteria in L{_validatePeerList}.
5888
5889 @raise ValueError: If stage configuration is invalid.
5890 """
5891 if self.stage is not None:
5892 if self.stage.targetDir is None:
5893 raise ValueError("Stage section target directory must be filled in.")
5894 if self.peers is None:
5895
5896 self._validatePeerList(self.stage.localPeers, self.stage.remotePeers)
5897 else:
5898
5899
5900 if self.stage.hasPeers():
5901 self._validatePeerList(self.stage.localPeers, self.stage.remotePeers)
5902
5904 """
5905 Validates store configuration.
5906
5907 The device type, drive speed, and blanking behavior are optional. All
5908 other values are required. Missing booleans will be set to defaults.
5909
5910 If blanking behavior is provided, then both a blanking mode and a
5911 blanking factor are required.
5912
5913 The image writer functionality in the C{writer} module is supposed to be
5914 able to handle a device speed of C{None}.
5915
5916 Any caller which needs a "real" (non-C{None}) value for the device type
5917 can use C{DEFAULT_DEVICE_TYPE}, which is guaranteed to be sensible.
5918
5919 This is also where we make sure that the media type -- which is already a
5920 valid type -- matches up properly with the device type.
5921
5922 @raise ValueError: If store configuration is invalid.
5923 """
5924 if self.store is not None:
5925 if self.store.sourceDir is None:
5926 raise ValueError("Store section source directory must be filled in.")
5927 if self.store.mediaType is None:
5928 raise ValueError("Store section media type must be filled in.")
5929 if self.store.devicePath is None:
5930 raise ValueError("Store section device path must be filled in.")
5931 if self.store.deviceType == None or self.store.deviceType == "cdwriter":
5932 if self.store.mediaType not in VALID_CD_MEDIA_TYPES:
5933 raise ValueError("Media type must match device type.")
5934 elif self.store.deviceType == "dvdwriter":
5935 if self.store.mediaType not in VALID_DVD_MEDIA_TYPES:
5936 raise ValueError("Media type must match device type.")
5937 if self.store.blankBehavior is not None:
5938 if self.store.blankBehavior.blankMode is None and self.store.blankBehavior.blankFactor is None:
5939 raise ValueError("If blanking behavior is provided, all values must be filled in.")
5940
5942 """
5943 Validates purge configuration.
5944
5945 The list of purge directories may be either C{None} or an empty list
5946 C{[]} if desired. All purge directories must contain a path and a retain
5947 days value.
5948
5949 @raise ValueError: If purge configuration is invalid.
5950 """
5951 if self.purge is not None:
5952 if self.purge.purgeDirs is not None:
5953 for purgeDir in self.purge.purgeDirs:
5954 if purgeDir.absolutePath is None:
5955 raise ValueError("Each purge directory must set an absolute path.")
5956 if purgeDir.retainDays is None:
5957 raise ValueError("Each purge directory must set a retain days value.")
5958
5960 """
5961 Validates the set of local and remote peers.
5962
5963 Local peers must be completely filled in, including both name and collect
5964 directory. Remote peers must also fill in the name and collect
5965 directory, but can leave the remote user and rcp command unset. In this
5966 case, the remote user is assumed to match the backup user from the
5967 options section and rcp command is taken directly from the options
5968 section.
5969
5970 @param localPeers: List of local peers
5971 @param remotePeers: List of remote peers
5972
5973 @raise ValueError: If stage configuration is invalid.
5974 """
5975 if localPeers is None and remotePeers is None:
5976 raise ValueError("Peer list must contain at least one backup peer.")
5977 if localPeers is None and remotePeers is not None:
5978 if len(remotePeers) < 1:
5979 raise ValueError("Peer list must contain at least one backup peer.")
5980 elif localPeers is not None and remotePeers is None:
5981 if len(localPeers) < 1:
5982 raise ValueError("Peer list must contain at least one backup peer.")
5983 elif localPeers is not None and remotePeers is not None:
5984 if len(localPeers) + len(remotePeers) < 1:
5985 raise ValueError("Peer list must contain at least one backup peer.")
5986 names = []
5987 if localPeers is not None:
5988 for localPeer in localPeers:
5989 if localPeer.name is None:
5990 raise ValueError("Local peers must set a name.")
5991 names.append(localPeer.name)
5992 if localPeer.collectDir is None:
5993 raise ValueError("Local peers must set a collect directory.")
5994 if remotePeers is not None:
5995 for remotePeer in remotePeers:
5996 if remotePeer.name is None:
5997 raise ValueError("Remote peers must set a name.")
5998 names.append(remotePeer.name)
5999 if remotePeer.collectDir is None:
6000 raise ValueError("Remote peers must set a collect directory.")
6001 if (self.options is None or self.options.backupUser is None) and remotePeer.remoteUser is None:
6002 raise ValueError("Remote user must either be set in options section or individual remote peer.")
6003 if (self.options is None or self.options.rcpCommand is None) and remotePeer.rcpCommand is None:
6004 raise ValueError("Remote copy command must either be set in options section or individual remote peer.")
6005 if remotePeer.managed:
6006 if (self.options is None or self.options.rshCommand is None) and remotePeer.rshCommand is None:
6007 raise ValueError("Remote shell command must either be set in options section or individual remote peer.")
6008 if (self.options is None or self.options.cbackCommand is None) and remotePeer.cbackCommand is None:
6009 raise ValueError("Remote cback command must either be set in options section or individual remote peer.")
6010 if ((self.options is None or self.options.managedActions is None or len(self.options.managedActions) < 1)
6011 and (remotePeer.managedActions is None or len(remotePeer.managedActions) < 1)):
6012 raise ValueError("Managed actions list must be set in options section or individual remote peer.")
6013 Config._checkUnique("Duplicate peer names exist:", names)
6014
6015
6016
6017
6018
6019
6021 """
6022 Checks that all values are unique.
6023
6024 The values list is checked for duplicate values. If there are
6025 duplicates, an exception is thrown. All duplicate values are listed in
6026 the exception.
6027
6028 @param prefix: Prefix to use in the thrown exception
6029 @param values: List of values to check
6030
6031 @raise ValueError: If there are duplicates in the list
6032 """
6033 values.sort()
6034 duplicates = []
6035 for i in range(1, len(values)):
6036 if values[i-1] == values[i]:
6037 duplicates.append(values[i])
6038 if duplicates:
6039 raise ValueError("%s %s" % (prefix, duplicates))
6040 _checkUnique = staticmethod(_checkUnique)
6041
6042
6043
6044
6045
6046
6048 """
6049 Read a byte size value from an XML document.
6050
6051 A byte size value is an interpreted string value. If the string value
6052 ends with "MB" or "GB", then the string before that is interpreted as
6053 megabytes or gigabytes. Otherwise, it is intepreted as bytes.
6054
6055 @param parent: Parent node to search beneath.
6056 @param name: Name of node to search for.
6057
6058 @return: ByteQuantity parsed from XML document
6059 """
6060 data = readString(parent, name)
6061 if data is None:
6062 return None
6063 data = data.strip()
6064 if data.endswith("KB"):
6065 quantity = data[0:data.rfind("KB")].strip()
6066 units = UNIT_KBYTES
6067 elif data.endswith("MB"):
6068 quantity = data[0:data.rfind("MB")].strip()
6069 units = UNIT_MBYTES;
6070 elif data.endswith("GB"):
6071 quantity = data[0:data.rfind("GB")].strip()
6072 units = UNIT_GBYTES
6073 else:
6074 quantity = data.strip()
6075 units = UNIT_BYTES
6076 return ByteQuantity(quantity, units)
6077
6079 """
6080 Adds a text node as the next child of a parent, to contain a byte size.
6081
6082 If the C{byteQuantity} is None, then the node will be created, but will
6083 be empty (i.e. will contain no text node child).
6084
6085 The size in bytes will be normalized. If it is larger than 1.0 GB, it will
6086 be shown in GB ("1.0 GB"). If it is larger than 1.0 MB ("1.0 MB"), it will
6087 be shown in MB. Otherwise, it will be shown in bytes ("423413").
6088
6089 @param xmlDom: DOM tree as from C{impl.createDocument()}.
6090 @param parentNode: Parent node to create child for.
6091 @param nodeName: Name of the new container node.
6092 @param byteQuantity: ByteQuantity object to put into the XML document
6093
6094 @return: Reference to the newly-created node.
6095 """
6096 if byteQuantity is None:
6097 byteString = None
6098 elif byteQuantity.units == UNIT_KBYTES:
6099 byteString = "%s KB" % byteQuantity.quantity
6100 elif byteQuantity.units == UNIT_MBYTES:
6101 byteString = "%s MB" % byteQuantity.quantity
6102 elif byteQuantity.units == UNIT_GBYTES:
6103 byteString = "%s GB" % byteQuantity.quantity
6104 else:
6105 byteString = byteQuantity.quantity
6106 return addStringNode(xmlDom, parentNode, nodeName, byteString)
6107