martin f. krafft | 8acd49d | 2013-08-26 21:22:25 +0200 | [diff] [blame] | 1 | ================== |
| 2 | reclass operations |
| 3 | ================== |
| 4 | |
martin f. krafft | f432053 | 2013-11-30 17:00:37 +0100 | [diff] [blame] | 5 | YAML FS storage |
| 6 | --------------- |
martin f. krafft | 8acd49d | 2013-08-26 21:22:25 +0200 | [diff] [blame] | 7 | While |reclass| has been built to support different storage backends through |
| 8 | plugins, currently only the ``yaml_fs`` storage backend exists. This is a very |
| 9 | simple, yet powerful, YAML-based backend, using flat files on the filesystem |
| 10 | (as suggested by the ``_fs`` postfix). |
| 11 | |
| 12 | ``yaml_fs`` works with two directories, one for node definitions, and another |
martin f. krafft | 16c9380 | 2013-11-30 13:23:16 +0100 | [diff] [blame] | 13 | for class definitions. The two directories must not be the same, nor can one |
| 14 | be a parent of the other. |
martin f. krafft | 8acd49d | 2013-08-26 21:22:25 +0200 | [diff] [blame] | 15 | |
| 16 | Files in those directories are YAML-files, specifying key-value pairs. The |
| 17 | following three keys are read by |reclass|: |
| 18 | |
| 19 | ============ ================================================================ |
| 20 | Key Description |
| 21 | ============ ================================================================ |
| 22 | classes a list of parent classes |
| 23 | appliations a list of applications to append to the applications defined by |
| 24 | ancestors. If an application name starts with ``~``, it would |
| 25 | remove this application from the list, if it had already been |
| 26 | added — but it does not prevent a future addition. |
| 27 | E.g. ``~firewalled`` |
| 28 | parameters key-value pairs to set defaults in class definitions, override |
| 29 | existing data, or provide node-specific information in node |
| 30 | specifications. |
| 31 | \ |
| 32 | By convention, parameters corresponding to an application |
| 33 | should be provided as subkey-value pairs, keyed by the name of |
| 34 | the application, e.g.:: |
| 35 | |
| 36 | applications: |
| 37 | - ssh.server |
| 38 | parameters: |
| 39 | ssh.server: |
| 40 | permit_root_login: no |
| 41 | ============ ================================================================ |
| 42 | |
martin f. krafft | 1f11ede | 2013-11-30 16:48:00 +0100 | [diff] [blame^] | 43 | Nodes may be defined in subdirectories. However, node names (filename) must be |
| 44 | unique across all subdirectories, and |reclass| will exit with an error if |
| 45 | a node is defined multiple times. Subdirectories therefore really only exist |
| 46 | for the administrator's sanity (and may be used in the future to tag |
| 47 | additional classes onto nodes). |
| 48 | |
martin f. krafft | f432053 | 2013-11-30 17:00:37 +0100 | [diff] [blame] | 49 | Data merging |
| 50 | ------------ |
| 51 | |reclass| has two modes of operation: node information retrieval and inventory |
| 52 | listing. The second is really just a loop of the first across all defined |
| 53 | nodes, and needs not be further described. |
martin f. krafft | 8acd49d | 2013-08-26 21:22:25 +0200 | [diff] [blame] | 54 | |
martin f. krafft | f432053 | 2013-11-30 17:00:37 +0100 | [diff] [blame] | 55 | When retrieving information about a node, |reclass| first obtains the node |
| 56 | definition from the storage backend. Then, it iterates the list of classes |
| 57 | defined for the node and recursively asks the storage backend for each class |
| 58 | definition (unless already cached). |
| 59 | |
| 60 | Next, |reclass| recursively descends each class, looking at the classes it |
| 61 | defines, and so on, until a leaf node is reached, i.e. a class that references |
| 62 | no other classes. |
| 63 | |
| 64 | Now, the merging starts. At every step, the list of applications and the set |
| 65 | of parameters at each level is merged into what has been accumulated so far. |
| 66 | |
| 67 | Merging of parameters is done "deeply", meaning that lists and dictionaries |
martin f. krafft | 8acd49d | 2013-08-26 21:22:25 +0200 | [diff] [blame] | 68 | are extended (recursively), rather than replaced. However, a scalar value |
| 69 | *does* overwrite a dictionary or list value. While the scalar could be |
| 70 | appended to an existing list, there is sane default assumption in the context |
| 71 | of a dictionary, so this behaviour seems the most logical. |
| 72 | |
martin f. krafft | f432053 | 2013-11-30 17:00:37 +0100 | [diff] [blame] | 73 | After all classes (and the classes they reference) have been visited, |
| 74 | |reclass| finally merges the applications list and parameters defined for the |
| 75 | node into what has been accumulated during the processing of the classes, and |
| 76 | returns the final result. |
| 77 | |
martin f. krafft | 8acd49d | 2013-08-26 21:22:25 +0200 | [diff] [blame] | 78 | Parameter interpolation |
| 79 | ------------------------ |
| 80 | Parameters may reference each other, including deep references, e.g.:: |
| 81 | |
| 82 | parameters: |
| 83 | location: Munich, Germany |
| 84 | motd: |
| 85 | header: This node sits in ${location} |
| 86 | for_demonstration: ${motd:header} |
| 87 | dict_reference: ${motd} |
| 88 | |
| 89 | After merging and interpolation, which happens automatically inside the |
| 90 | storage modules, the ``for_demonstration`` parameter will have a value of |
| 91 | "This node sits in Munich, Germany". |
| 92 | |
| 93 | Types are preserved if the value contains nothing but a reference. Hence, the |
| 94 | value of ``dict_reference`` will actually be a dictionary. |
| 95 | |
| 96 | You should now be ready to :doc:`use reclass <usage>`! |
| 97 | |
| 98 | .. include:: substs.inc |