1Config::Model::Manual::UMsoedrelCCornetarCtioibnoufntiAegdd:v:aPMneocrdeledl(D:3o:)cMuamneunatla:t:iMoondelCreationAdvanced(3)
2
3
4
6 Config::Model::Manual::ModelCreationAdvanced - Creating a model with
7 advanced features
8
10 version 2.141
11
13 The page Config::Model::Manual::ModelCreationIntroduction explains what
14 is a configuration tree and a configuration model and how to create a
15 simple configuration model.
16
17 But a configuration model can be more complex and define interactions
18 between elements with the following features:
19
20 • Model warp. For instance, Xorg driver options change depending on
21 driver name ("nvidia", "radeon"...)
22
23 • Simple computation from other elements (used for upgrades)
24
25 • References. For instance, in "Xorg::Device::Radeon",
26 "Monitor-DVI-0" name must refer to one of the monitors declared in
27 "Monitor" section.
28
29 Caveat: Xorg examples are based on Xorg 1.4 and may not be valid for
30 Xorg 1.5 or 1.6
31
33 Config::Model can also use model plugins. Each model can be augmented
34 by model snippets stored into directory "<model_name>.d". All files
35 found there are merged to existing model.
36
37 For instance, this model in file
38 ".../Config/Model/models/Fstab/Fsline.pl":
39
40 {
41 name => "Fstab::Fsline",
42 element => [
43 fs_vfstype => {
44 type => 'leaf',
45 value_type => 'enum',
46 choice => [ qw/ext2 ext3/ ],
47 },
48 fs_mntopts => {
49 type => 'warped_node',
50 follow => { 'f1' => '- fs_vfstype' },
51 rules => [
52 '$f1 eq \'ext2\'', { 'config_class_name' => 'Fstab::Ext2FsOpt' },
53 '$f1 eq \'ext3\'', { 'config_class_name' => 'Fstab::Ext3FsOpt' },
54 ],
55 }
56 ]
57 }
58
59 can be augmented with the content of
60 ".../Config/Model/models/Fstab/Fsline.d/addext4.pl":
61
62 {
63 name => "Fstab::Fsline",
64 element => [
65 fs_vfstype => { choice => [ qw/ext4/ ], },
66 fs_mntopts => {
67 rules => [
68 q!$f1 eq 'ext4'!, { 'config_class_name' => 'Fstab::Ext4FsOpt' },
69 ],
70 },
71 ]
72 } ;
73
74 Then, the merged model will feature "fs_vfstype" with choice "ext2 ext4
75 ext4". Likewise, "fs_mntopts" will feature rules for the 3
76 filesystems.
77
78 Under the hood, "augment_config_class" in Config::Model method is used
79 to load model snippets.
80
82 From a user's point of view, model warp looks like the structure or
83 properties of the configuration is changing (or adapting) dynamically
84 depending on the values being entered. For instance, when changing a
85 driver name from "fglrx" to "radeon", some options disappear from the
86 GUI and some other options pop-in.
87
88 Model warping need not be that spectacular and can have more subtle
89 effect like changing a default value.
90
91 Of course, there's no magic, model warp properties needs to be prepared
92 and declared in the model.
93
94 Warped value
95 Let's start simple with value warp: the properties of a single value is
96 changed dynamically. Let's imagine a configuration file with 2 values:
97 size which can be set to big or small and length whose maximum value is
98 10 when size is small and 50 when size is big. (this may be dumb, but
99 it's for the sake of the example).
100
101 So the basic model without warp is
102
103 element => [
104 size => { type => 'leaf',
105 value_type => 'enum',
106 choice => ['big','small'],
107 },
108 length => { type => 'leaf',
109 value_type => 'integer',
110 max => '10',
111 },
112 ]
113
114 Now we need to declare the relationship between size and length to be
115 able to change dynamically the max property.
116
117 This setup is made of 2 specifications:
118
119 • what is the element that triggers the change (called warp master in
120 the doc)
121
122 • what is the effect of the warp master change
123
124 The first is done with a declaration of the path to follow to find the
125 warp master (associated to a variable). The second is a set of value
126 properties:
127
128 element => [
129 size => {
130 type => 'leaf',
131 value_type => 'enum',
132 choice => ['big','small'],
133 },
134
135 length => {
136 type => 'leaf',
137 value_type => 'integer',
138 warp => { # change specification
139 follow => { # declare what trigger the change
140 size_type => '- size' # size_type: go 1 level above and fetch
141 # size value
142 },
143 rules => { # how to apply change
144 '$size_type eq "small"' => { # set max to 10 when size is small
145 max => 10
146 },
147 '$size_type eq "big" ' => { # set max to 50 when size is big
148 max => 50 },
149 },
150 },
151 }
152 ]
153
154 Warp in or warp out an element
155 Here's a real use case scenario from OpenSsh.
156
157 "ssh_config" enables a user to set up a tunnel through ssh. The input
158 of this tunnel can listen to localhost (default) or to other hosts.
159 These other hosts are specified by the bind_adress part of the
160 "LocalForward" parameter.
161
162 But this bind address is ignored if "GatewayPorts" is false (which is
163 the default).
164
165 In order to present only meaningful parameters to the user,
166 bind_address parameter must be hidden when "GatewayPorts" is false and
167 shown when "GatewayPorts" is true.
168
169 Here's the recipe. First create a boolean element for "GatewayPorts":
170
171 GatewayPorts => {
172 type => 'leaf',
173 value_type => 'boolean',
174 upstream_default => 0,
175 },
176
177 And "LocalForward" that provides bind_address parameter:
178
179 LocalForward => {
180 type => 'list',
181 cargo => {
182 type => 'node',
183 config_class_name => 'Ssh::PortForward'
184 },
185 summary => 'Local port forwarding',
186 }
187
188 In "Ssh::PortForward" configuration class, declare bind_address with
189 the warp instructions:
190
191 bind_address => {
192 type => 'leaf',
193 value_type => 'uniline',
194 level => 'hidden', # by default, is hidden from user
195 warp => { # instructions to show bind_address
196 follow => { # specify what does trigger the change
197 gp => '- - GatewayPorts' # gp: go to 2 levels above in tree ('- -') and
198 # fetch GatewayPorts value
199 },
200 rules => [ # specify how to apply the change triggered by gp
201 '$gp' => { # apply change when $gp is true
202 level => 'normal' # set level to normal (instead of 'hidden'). This change
203 # will show this parameter in the UI
204 }
205 ]
206 },
207 },
208
209 warped node
210 Sometimes, warping a value line by line is not practical. For instance,
211 in "/etc/fstab" the mount options of a file system change drastically
212 from one file system to another. In this case, it's better to swap a
213 configuration class with another.
214
215 For instance, swap "vfat" mount options with "ext3" mount options when
216 a file system is changed from "vfat" to "ext3".
217
218 Here's how this can be done. First declare the "fstype" parameter:
219
220 fs_vfstype => {
221 type => 'leaf',
222 mandatory => 1,
223 value_type => 'enum',
224 choice => [ 'auto', 'davfs', 'vfat', 'ext2', 'ext3', ] , # etc ...
225 }
226
227 Then declare "mntopts" as a warped_node (not a simple "node")) that
228 uses "fs_vfstype" to swap one config class with another:
229
230 fs_mntopts => {
231 type => 'warped_node', # a shape-shifting node
232 follow => {
233 f1 => '- fs_vfstype' , # use fs_vfstype as a trigger
234 },
235 rules => [
236 # condition => effect: config class to swap in
237
238 "$f1 eq 'proc'" => { config_class_name => 'Fstab::CommonOptions' },
239 "$f1 eq 'auto'" => { config_class_name => 'Fstab::CommonOptions' },
240 "$f1 eq 'vfat'" => { config_class_name => 'Fstab::CommonOptions' },
241 "$f1 eq 'swap'" => { config_class_name => 'Fstab::SwapOptions' },
242 "$f1 eq 'ext3'" => { config_class_name => 'Fstab::Ext3FsOpt' },
243 # etc ...
244 ]
245 }
246
249 Cascaded warp
250 Config::Model also supports cascaded warps: A warped value is dependent
251 on another value which is itself a warped value.
252
254 Feel free to send comments and suggestion about this page at
255
256 config-model-users at lists dot sourceforge dot net.
257
259 Dominique Dumont <ddumont at cpan.org>
260
262 Dominique Dumont
263
265 This software is Copyright (c) 2005-2021 by Dominique Dumont.
266
267 This is free software, licensed under:
268
269 The GNU Lesser General Public License, Version 2.1, February 1999
270
271
272
273perl v5.32.1 Con2f0i2g1:-:0M1o-d2e7l::Manual::ModelCreationAdvanced(3)