Blob


1 '\" t
2 .\" Automatically generated by Pandoc 3.6.2
3 .\"
4 .TH "R7" "1" "Tue Jun 3 2025" "v0.2.0" "User Manual"
5 .SS Tutorial
6 .SS Introduction
7 R7 is a configuration management framework made to configure nodes with
8 configuration files and related operations versioned in a central
9 repository.
10 To remain code versioning system agnostic, manual or automated
11 versioning is left to the user, via makefiles or triggered from r7
12 \f[CR]site\-config\f[R] configuration file \f[I](See below)\f[R].
13 .PP
14 The idea is to store hosts configurations in \f[CR]nodes/hostname\f[R]
15 directories that maps each host\[cq]s \f[CR]/etc\f[R] and to assign
16 those hosts to configuration groups containing the directives to install
17 the configuration and potential requirements.
18 .PP
19 \f[I]Nodes sub\-directories are host names understood by the ssh client
20 and configuration.\f[R]
21 .PP
22 \f[I]Currently, r7 requires valid ssh configuration and key files in the
23 repository \f[CI].ssh/\f[I] directory.\f[R]
24 .PP
25 \f[I]Repositories can be initialized with \f[CI]rset init\f[I] or
26 \f[CI]rset \-w path/to/new\-repository init\f[I], the user will then
27 have to provide valid configurations and keys for \f[CI].ssh/\f[I] in
28 the newly created directory.\f[R]
29 .PP
30 \f[I]See Technical Notes for dependencies and supported platforms.\f[R]
31 .PP
32 There is an example of r7 repository:
33 .IP
34 .EX
35 \&./nodes/
36 \&./nodes/hostA
37 \&./nodes/hostB
38 \&./nodes/hostC
39 \&./groups/
40 \&./groups/common
41 \&./groups/test0
42 \&./groups/common.dir
43 \&./groups/test0.dir
44 \&./.ssh/
45 \&./.ssh/config
46 \&./.ssh/id_ed25519_r7
47 \&./.ssh/id_ed25519_r7.pub
48 \&./site\-config
49 .EE
50 .PP
51 There is an example of r7 site configuration (\f[CR]site\-config\f[R]
52 file):
53 .IP
54 .EX
55 prefix install state doc
56 group common \[aq].*\[aq]
57 group test0 hostB hostC
58 output\-dump
59 summary
60 .EE
61 .PP
62 There is an example of the deployment of that configuration within the
63 r7 repository:
64 .IP
65 .EX
66 $ r7 run\-config
67 \- (ok) hostA:common::install_nothing
68 \- (ok) hostA:common::state_uname
69 \- (ok) hostA:common::doc_tutorial
70 \- (ok) hostB:common::install_nothing
71 \- (ok) hostB:common::state_uname
72 \- (ok) hostB:common::doc_tutorial
73 \- (ok) hostC:common::install_nothing
74 \- (ok) hostC:common::state_uname
75 \- (ok) hostC:common::doc_tutorial
76 \- (ok) hostB:test0::state_test
77 \- (ok) hostC:test0::state_test
78 .EE
79 .PP
80 In this example, everything goes fine, groups are executed on each
81 related nodes, note the \f[CR]\[aq].*\[aq]\f[R] matching all hosts
82 present in \f[CR]./nodes\f[R].
83 Groups are POSIX shell scripts that are a collection of functions.
84 .PP
85 There is the \f[CR]common\f[R] group:
86 .IP
87 .EX
88 install_nothing() \f[B]{\f[R]
89 echo Nothing installed
90 \f[B]}\f[R]
92 state_uname() \f[B]{\f[R]
93 uname \-a
94 \f[B]}\f[R]
96 doc_tutorial() \f[B]{\f[R]
97 echo \[dq]## Welcome to the R7 tutorial!\[dq]
98 \f[B]}\f[R]
99 .EE
100 .PP
101 And there is the \f[CR]test0\f[R] group:
102 .IP
103 .EX
104 state_test() \f[B]{\f[R]
105 test 1 \-eq 1
106 \f[B]}\f[R]
107 .EE
108 .PP
109 Any function managed by \f[CR]r7\f[R] needs to be declared in the format
110 \f[CR]\[ha]PREFIX_NAME()\f[R].
111 .PP
112 Group files names can\[cq]t contain spaces, tabs or newlines, as well
113 for nodes \f[CR]dirnames\f[R].
114 \f[I]The `:' character is not recommended as well as it may reduce
115 readability of the interactive output.\f[R]
116 .PP
117 Called groups and node directories are copied to related nodes in
118 \f[CR]hostname:/tmp/r7/\f[R]:
119 .IP
120 .EX
121 /tmp/r7/hostA/ # Contents of test.org/nodes/hostA/
122 /tmp/r7/common.dir # Contents of test.org/groups/common.dir/
123 /tmp/r7/test.dir # Contents of test.org/groups/test.dir
124 .EE
125 .PP
126 Groups may have no \f[CR].dir\f[R] directory, in this case, nothing is
127 copied.
128 .PP
129 Once the group copy is done, functions are executed in the order of the
130 defined prefix (part of the \f[CR]site\-config\f[R] file shown before):
131 .IP
132 .EX
133 prefix install state doc
134 .EE
135 .PP
136 This means the functions matching \f[CR]\[ha]install.*()\f[R],
137 \f[CR]\[ha]state.*()\f[R] and \f[CR]\[ha]doc.*()\f[R] (the default
138 \f[CR]R7_PREFIX\f[R]) in the respective declaration order they\[cq]re
139 found in the related group file will be executed.
140 .PP
141 Site configurations are shell scripts sourced by r7 after it\[cq]s
142 environment is initialized, so \f[CR]prefix\f[R], \f[CR]group\f[R],
143 \f[CR]output\-dump\f[R], \f[CR]summary\f[R] are the functions or aliases
144 provided by r7 itself.
145 This allow for scripting from the \f[CR]site\-config\f[R] file.
146 Here \f[CR]output\-dump\f[R], and \f[CR]summary\f[R] are called to
147 output potential errors, diffs and permissions changes at the end of the
148 interactive output obtained by \f[CR]r7 run\-config\f[R].
149 If nothing happened, nothing is added to the output.
150 .SS Errors during remote execution of groups
151 In our previous example, we modify \f[CR]state_test\f[R] so the
152 \f[CR]test\f[R] fails.
153 .IP
154 .EX
155 state_test() \f[B]{\f[R]
156 test 1 \-eq 2
157 \f[B]}\f[R]
158 .EE
159 .PP
160 And we re\-run the configuration to see what\[cq]s happening.
161 .IP
162 .EX
163 $ r7 run\-config
164 \- (ok) hostA:common::install_nothing
165 \- (ok) hostA:common::state_uname
166 \- (ok) hostA:common::doc_tutorial
167 \- (ok) hostB:common::install_nothing
168 \- (ok) hostB:common::state_uname
169 \- (ok) hostB:common::doc_tutorial
170 \- (ok) hostC:common::install_nothing
171 \- (ok) hostC:common::state_uname
172 \- (ok) hostC:common::doc_tutorial
173 \- (error 1) hostB:test0::state_test
174 \- (error 1) hostC:test0::state_test
175 \- (error 1) \- in hostB test0 state_test (1748622980)
176 \- (error 1) \- in hostC test0 state_test (1748622980)
177 .EE
178 .PP
179 The last two lines are part of the \f[CR]summary\f[R] output.
180 .PP
181 Let\[cq]s modify the \f[CR]state_test\f[R] function again to add some
182 verbosity to it\[cq]s output.
183 .PP
184 \f[I]Note that we also change the return value.\f[R]
185 .IP
186 .EX
187 state_test() \f[B]{\f[R]
188 echo something
189 false \f[B]||\f[R] \f[B]{\f[R]
190 echo >&2 failed
191 \f[B]return\f[R] 22
192 \f[B]}\f[R]
193 \f[B]}\f[R]
194 .EE
195 .PP
196 This will produce the following summary:
197 .IP
198 .EX
199 \- (error 22) \- in hostB test0 state_test (1748622980)
201 something
202 failed
204 \- (error 22) \- in hostC test0 state_test (1748622980)
206 something
207 failed
208 .EE
209 .PP
210 Diffs and permissions changes are also displayed by the
211 \f[CR]summary\f[R] command.
212 When they\[cq]re are detected, the captured related output is shown.
213 .SS Repository initialisation
214 Using the \f[CR]init\f[R] command, we can specify the current or a
215 specified work directory to be created and act as an r7 repository.
216 .PP
217 \f[I]Automated versioning of outputs are currently let to the user, a
218 recommended place would be the end of the site configuration file.\f[R]
219 .PP
220 This command initializes a new directory called \f[CR]test.org\f[R]:
221 .IP
222 .EX
223 r7 \-w test.org init
224 cd test.org
225 .EE
226 .PP
227 Once this step is done, it is required to:
228 .IP \[bu] 2
229 Copy or initialize the ssh key to the \f[CR].ssh\f[R] folder in the
230 repository created in \f[CR].ssh/id_ed25519\-r7\f[R] and
231 \f[CR]./ssh/id_ed25519\-r7.pub\f[R]
232 .IP \[bu] 2
233 Adjust the SSH client configuration file in the repository
234 \f[CR].ssh/config\f[R]
235 .PP
236 \f[I]Note that it is possible to import additional SSH configurations,
237 like the user one from the SSH configuration, but it is advised to keep
238 them separate.\f[R]
239 .SS SSH agent handling
240 The function \f[CR]unlock\f[R] can be used to set the SSH agent
241 environment, this will be required for any automated operation later
242 done by r7:
243 .IP
244 .EX
245 cd test.org
246 \&. $(command \-v r7) \f[I]# Sourcing r7\f[R]
247 unlock
248 tmux \f[B]||\f[R] screen
249 .EE
250 .SS Tmux configuration
251 .IP
252 .EX
253 set \-g update\-environment \-r
254 .EE
255 .SS Optional Shell configuration
256 This is useful for handling multiple tmux sessions.
257 .IP
258 .EX
259 \f[I]# Add this to the shell\[aq]s rc\f[R]
260 \f[B]if\f[R] [ \-z \[dq]$TMUX\[dq] ]\f[B];\f[R] \f[B]then\f[R]
261 \f[B]if\f[R] [ \-n \[dq]$SSH_TTY\[dq] ]\f[B];\f[R] \f[B]then\f[R]
262 \f[B]if\f[R] [ \-z \[dq]$SSH_AUTH_SOCK\[dq] ]\f[B];\f[R] \f[B]then\f[R]
263 export SSH_AUTH_SOCK=\[dq]$HOME/.ssh/.auth_socket\[dq]
264 \f[B]fi\f[R]
265 \f[B]if\f[R] [ ! \-S \[dq]$SSH_AUTH_SOCK\[dq] ]\f[B];\f[R] \f[B]then\f[R]
266 eval $(ssh\-agent \-a $SSH_AUTH_SOCK) >/dev/null 2>&1
267 echo $SSH_AGENT_PID >$HOME/.ssh/.auth_pid
268 \f[B]fi\f[R]
269 \f[B]if\f[R] [ \-z $SSH_AGENT_PID ]\f[B];\f[R] \f[B]then\f[R]
270 export SSH_AGENT_PID=$(cat $HOME/.ssh/.auth_pid)
271 \f[B]fi\f[R]
272 ssh\-add \[dq]$SSH_ID\[dq] 2>/dev/null
273 \f[B]fi\f[R]
274 \f[B]fi\f[R]
275 .EE
276 .SS Adding new hosts
277 For adding a new host, the simplest way is to have pre\-configured
278 \f[CR]authorized_keys\f[R] for the target user, it is then required to
279 add it to the \f[CR]known_hosts\f[R] file.
280 For that, it is possible to use r7 SSH functions:
281 .IP
282 .EX
283 \&. $(command \-v r7) \f[I]# Sourcing r7\f[R]
284 ssh\-accept\-new hostname
285 .EE
286 .PP
287 If resetting the target\[cq]s user \f[CR]authorized_keys\f[R] file is
288 needed, the following function can be used:
289 .IP
290 .EX
291 \&. $(command \-v r7) \f[I]# Sourcing r7\f[R]
292 ssh\-authorized\-keys\-reset hostname
293 .EE
294 .PP
295 \f[I]\f[BI]Warning:\f[I] This will resets the SSH authorized_keys file
296 for the target user (root, by default) and put the
297 \f[CI].ssh/id_ed25519\-r7.pub\f[I] in place.\f[R]
298 .PP
299 Once the host is accepted in the \f[CR]known_hosts\f[R] file, it\[cq]s
300 possible to import it automatically.
301 .SS Importing hosts configurations
302 Avoiding to import the configuration manually is possible with the
303 \f[CR]import\f[R] command:
304 .IP
305 .EX
306 r7 import hostname
307 .EE
308 .PP
309 Most common configuration files will be copied in a newly created
310 \f[CR]nodes/hostname\f[R] sub\-directory.
311 .SS Writing group files
312 Group files collects functions related to the configuration of the
313 operating system, networking, services, global and user configurations
314 packages installations and application deployments.
315 .PP
316 By specifying the execution prefix, the user determines the order of
317 execution of the functions declared in the group file.
318 .IP
319 .EX
320 service_A() \f[B]{\f[R]
321 service A enable
322 service A restart
323 \f[B]}\f[R]
325 service_B() \f[B]{\f[R]
326 service B enable
327 service B restart
328 \f[B]}\f[R]
330 state_A() \f[B]{\f[R]
331 service A status
332 \f[B]}\f[R]
334 doc_A() \f[B]{\f[R]
335 echo \[dq]## Service A\[dq]
336 echo
337 echo \[dq]\- [url](http://test.org/)\[dq]
338 echo
339 \f[B]}\f[R]
340 .EE
341 .PP
342 \f[I]\f[BI]file\f[I]: \f[CI]groups/example1\f[I]\f[R]
343 .PP
344 With the default prefix, \f[CR]install\f[R], \f[CR]state\f[R],
345 \f[CR]doc\f[R], the function that will be executed are
346 \f[CR]state_A\f[R] and \f[CR]doc_A\f[R].
347 To test that group file with all the functions inside we can call r7 the
348 following way:
349 .IP
350 .EX
351 r7 \-P \[aq]service state doc\[aq] group example1 hostname
352 .EE
353 .PP
354 Or using the \f[CR]\-a\f[R] flag which will create a prefix
355 automatically with all functions present in the group file:
356 .IP
357 .EX
358 r7 \-a group example1 hostname
359 .EE
360 .PP
361 In a real situation, this example will have failing functions because
362 the \f[CR]service\f[R] command may not be found or the services named
363 \f[CR]A\f[R] or \f[CR]B\f[R] does not exist.
364 .IP
365 .EX
366 ! (error 127) tools0:example1::service_A
367 ! (error 127) tools0:example1::service_B
368 ! (error 127) tools0:example1::state_A
369 \- (ok) tools0:example1::doc_A
370 .EE
371 .PP
372 We could force the group execution to stop using a combination of the
373 \f[CR]\-e\f[R] flag and the \f[CR]error\f[R] group function.
374 .IP
375 .EX
376 service_A() \f[B]{\f[R]
377 service A enable \f[B]&&\f[R]
378 service A restart \f[B]||\f[R]
379 error unable to setup service A
380 \f[B]}\f[R]
382 service_B() \f[B]{\f[R]
383 service B enable \f[B]&&\f[R]
384 service B restart \f[B]||\f[R]
385 error unable to setup service B
386 \f[B]}\f[R]
388 state_A() \f[B]{\f[R]
389 service A status
390 \f[B]}\f[R]
392 doc_A() \f[B]{\f[R]
393 echo \[dq]## Service A\[dq]
394 echo
395 echo \[dq]\- [url](http://test.org/)\[dq]
396 echo
397 \f[B]}\f[R]
398 .EE
399 .PP
400 \f[I]\f[BI]file:\f[I] \f[CI]groups/example2\f[I]\f[R]
401 .PP
402 Let\[cq]s run the updated example with the \f[CR]\-s\f[R] flag to
403 trigger the summary output.
404 .IP
405 .EX
406 rm \-fr _output
407 r7 \-sea group example2 hostname
408 .EE
409 .PP
410 This will produce something like the following:
411 .IP
412 .EX
413 ! (error) tools0:example2::service_A
414 ! (exit) tools0:example2::service_A
415 \- (error 127) \- in tools0 example2 service_A (1748791986)
417 /bin/sh: <stdin>[155]: service: not found
418 :: 1748791986 tools0 ERROR unable to setup service A
419 .EE
420 .SS Cleaning functions
421 To remove a function from a group, we need to ensure that this function
422 returned 0 for the last execution.
423 .IP
424 .EX
425 state_function_to_remove() \f[B]{\f[R]
426 \f[I]# old code\f[R]
427 \f[I]# not used anymore\f[R]
429 \f[B]}\f[R]
430 .EE
431 .PP
432 This would prevent for seeing potential past errors caused by this
433 function in the summary output.
434 .SS Using the r7 install functions
435 The group library comes with the following functions that will allow
436 installation of files and triggering actions if necessary:
437 \f[CR]install\f[R], \f[CR]groupinstall\f[R], \f[CR]nodeinstall\f[R].
438 They are all shortcuts to an internal \f[CR]r7_install\f[R] function,
439 it\[cq]s just the wrappers changes directory to respectively
440 \f[CR]/tmp/r7\f[R], \f[CR]/tmp/r7/groupname.dir/\f[R] and
441 \f[CR]/tmp/r7/hostname/\f[R].
442 .PP
443 If we want to install files from the group directory we will use
444 something like:
445 .IP
446 .EX
447 install_program() \f[B]{\f[R]
448 groupinstall \-m 755 \-o root:bin my_program /usr/local/bin
449 \f[B]}\f[R]
450 .EE
451 .PP
452 \f[I]We are supposing to have the file
453 \f[CI]groups/example3.dir/my_program\f[I]\f[R]
454 .PP
455 And if it\[cq]s something from node, we should use:
456 .IP
457 .EX
458 install_program_config() \f[B]{\f[R]
459 nodeinstall \-m 644 \-o root:wheel my_config /etc
460 \f[B]}\f[R]
461 .EE
462 .PP
463 We can now chain the \f[CR]install\f[R] functions to configuration
464 checking and initialization of programs, services or network features
465 like in the following example, in which we install \f[CR]ntp.conf\f[R]
466 from the deployed node directory to \f[CR]/etc\f[R]:
467 .IP
468 .EX
469 service_ntpd() \f[B]{\f[R]
470 nodeinstall \-m 644 \-o root:wheel ntpd.conf /etc \f[B]&&\f[R]
471 ntpd \-n \f[B]&&\f[R]
472 rcctl enable ntpd \f[B]&&\f[R]
473 rcctl restart ntpd
474 \f[B]}\f[R]
475 .EE
476 .SS Using the r7 node function
477 We may want to avoid executing a function or parts of it if the node has
478 no related files before executing the installation and actions handling
479 parts.
480 This can be done with the help of the \f[CR]node\f[R] function.
481 .IP
482 .EX
483 service_ntpd() \f[B]{\f[R]
484 node ntpd.conf \f[B]&&\f[R]
485 nodeinstall \-m 644 \-o root:wheel ntpd.conf /etc \f[B]&&\f[R]
486 ntpd \-n \f[B]&&\f[R]
487 rcctl enable ntpd \f[B]&&\f[R]
488 rcctl restart ntpd
489 \f[B]}\f[R]
490 .EE
491 .PP
492 Here, \f[CR]node\f[R] will return \f[CR]31\f[R] if there is no file or
493 directory called \f[CR]ntpd.conf\f[R] inside the deployed node directory
494 (\f[CR]/tmp/r7/hostname\f[R]).
495 .PP
496 \f[CR]0\f[R], \f[CR]30\f[R] and \f[CR]31\f[R] exit codes are ignored
497 when r7 will search for execution errors.
498 This means \f[CR]30\f[R] and \f[CR]31\f[R] exit code are reserved to r7.
499 .PP
500 In other terms, this will update the NTP daemon configuration only if
501 \f[CR]ntpd.conf\f[R] is present in the node directory, otherwise it is
502 kept by default, which is the system provided default
503 \f[CR]ntpd.conf\f[R].
504 .SS Sourcing specific files
505 Here\[cq]s an example how to source additional shell from the deployed
506 node directory, or elsewhere:
507 .IP
508 .EX
509 service_sysrc() \f[B]{\f[R]
510 sysrc dumpdev=NO
511 sysrc kld_list=\[dq]vmm if_tuntap if_bridge nmdm\[dq]
512 sysrc microcode_update_enable=YES
513 sysrc mountd_enable=YES
514 sysrc nfs_server_enable=YES
515 sysrc ntpdate_enable=YES
516 sysrc powerd_enable=YES
517 sysrc rcshutdown_timeout=900
518 sysrc rpcbind_enable=YES
519 sysrc sshd_enable=YES
520 sysrc zfs_enable=YES
521 nodesource sysrc.local
522 \f[B]}\f[R]
523 .EE
524 .PP
525 In this FreeBSD example, we configure the system RC globally with
526 \f[CR]service_sysrc\f[R] which apply, if \f[CR]sysrc.local\f[R] is found
527 in the root of the node directory, it\[cq]s sourcing in the current
528 scope via the help of \f[CR]nodesource sysrc.local\f[R].
529 .PP
530 The file \f[CR]nodes/hostname/sysrcl.local\f[R] contains the following:
531 .IP
532 .EX
533 sysrc ifconfig_igb0=DHCP
534 sysrc ifconfig_igb1=up
535 .EE
536 .SS Other examples
537 Inside the r7 release, a small example groups library can be found in
538 the \f[CR]groups\f[R] directory, that can also be browsed in the \c
539 .UR https://got.inda.re/?action=summary&path=r7.git
540 repository
541 .UE \c
542 \&.
543 .SS System shell profile
544 Here we install the \f[CR]profile\f[R] file provided in the
545 \f[CR]groupname.dir\f[R] directory or the profile provided by the node
546 directory:
547 .IP
548 .EX
549 setup_profile() \f[B]{\f[R]
550 groupinstall \-m 644 \-o root:wheel profile /etc
551 node profile \f[B]&&\f[R]
552 nodeinstall \-m 644 \-o root:wheel profile /etc
553 \f[B]}\f[R]
554 .EE
555 .SS Users
556 Here we add new users:
557 .IP
558 .EX
559 setup_users() \f[B]{\f[R]
560 useradd user1 2>/dev/null \f[B]||\f[R] :
561 useradd user2 2>/dev/null \f[B]||\f[R] :
562 \f[B]}\f[R]
563 .EE
564 .SS Crontab
565 In the following example, we install a script and call it from a
566 dedicated user crontab.
567 .IP
568 .EX
569 mail_admins=admins\[at]test.org
571 install_myscript() \f[B]{\f[R]
572 groupinstall \-o root:bin \-m 755 myscript /usr/local/bin \f[B]&&\f[R]
573 useradd \-d /var/empty \-s /sbin/nologin _myscript
574 crontab \-u _myscript \- <<\-/
575 MAILTO=$mail_admins
576 */5 * * * * myscript
579 .EE
580 .SS Consulting the output
581 After the execution is done, the result are saved in the \f[CR]_run\f[R]
582 directory, \f[CR]output\-dump\f[R] needs to be called to produce the
583 current \f[CR]_output\f[R] structure.
584 .PP
585 The r7 \f[CR]output\f[R] command can then be used to show specific
586 output groups or functions:
587 .IP
588 .EX
589 r7 output
590 .EE
591 .PP
592 Will show the whole output of the latest groups deployments.
593 .PP
594 This format can be used to match specific host, group or function:
595 .IP
596 .EX
597 r7 output [hostname [groupname [funcname]]]
598 .EE
599 .PP
600 For example:
601 .IP
602 .EX
603 $ r7 output tools0 OpenBSD state_packages\[rs]*
604 \- tools0 OpenBSD state_packages_upgrades
606 quirks\-7.103 signed on 2025\-05\-30T01:12:03Z
608 \- tools0 OpenBSD state_packages_repository
610 https://cdn.openbsd.org/pub/OpenBSD
611 .EE
612 .PP
613 \f[I]Note that the \f[CI]output\f[I] function arguments are using
614 shell\[cq]s case glob patterns.\f[R]
615 .SS Active nodes
616 A \f[CR]R7_WORKDIR/.active_nodes\f[R] file is automatically created when
617 r7 tries to connect to a list of hosts via the \f[CR]group\f[R] command
618 or function.
619 This serves as a cache of available hosts reachable via SSH login (the
620 username is specified in the SSH configuration file).
621 .PP
622 To add a previously non\-available host, simply remove the file and use
623 \f[CR]group\f[R] (here via \f[CR]run\-config\f[R]):
624 .IP
625 .EX
626 rm .active_nodes
627 r7 run\-config
628 .EE
629 .SS r7 command line
630 \f[B]\f[BI]Usage:\f[B]\f[R]
631 .IP
632 .EX
633 r7 [options] [command [arguments...]]
634 .EE
635 .SS Options
636 .IP \[bu] 2
637 \f[B]\-h\f[R] Show usage and exit
638 .IP \[bu] 2
639 \f[B]\-d\f[R] Enable debug mode
640 .IP \[bu] 2
641 \f[B]\-i\f[R] Specify the SSH identity file
642 .IP \[bu] 2
643 \f[B]\-F\f[R] Specify the SSH client configuration file
644 .IP \[bu] 2
645 \f[B]\-w\f[R] Set the work directory where \f[CR]./nodes\f[R] and
646 \f[CR]./groups\f[R] can be found
647 .IP \[bu] 2
648 \f[B]\-r\f[R] Set the run directory (default: \f[CR]./_run\f[R])
649 .IP \[bu] 2
650 \f[B]\-o\f[R] Set the output directory (default: \f[CR]./_output\f[R])
651 .IP \[bu] 2
652 \f[B]\-c\f[R] Specify the site configuration file (default:
653 \f[CR]./site\-config\f[R])
654 .IP \[bu] 2
655 \f[B]\-n\f[R] Enable dry run mode; prevents any modification on hosts
656 .IP \[bu] 2
657 \f[B]\-e\f[R] Exit the group execution on the error function
658 .IP \[bu] 2
659 \f[B]\-p\f[R] Run each host in parallel per group call
660 .IP \[bu] 2
661 \f[B]\-O\f[R] Show output interactively
662 .IP \[bu] 2
663 \f[B]\-P\f[R] Specify a prefix, can contain whole function names
664 .IP \[bu] 2
665 \f[B]\-a\f[R] Select all available prefixes for a group command
666 .IP \[bu] 2
667 \f[B]\-s\f[R] Apply output\-dump and summary after a group command
668 .SS Commands
669 .PP
670 .TS
671 tab(@);
672 lw(18.7n) lw(51.3n).
673 T{
674 Name
675 T}@T{
676 Description
677 T}
679 T{
680 \f[B]run\-config\f[R]
681 T}@T{
682 Run the site configuration
683 T}
684 T{
685 \f[B]group\f[R]
686 T}@T{
687 Deploy specified group to hosts
688 T}
689 T{
690 \f[B]output\-dump\f[R]
691 T}@T{
692 Dump the run directory to the output directory
693 T}
694 T{
695 \f[B]output\f[R]
696 T}@T{
697 Consult the output
698 T}
699 T{
700 \f[B]summary\f[R]
701 T}@T{
702 Produce a summary of errors and changes
703 T}
704 T{
705 \f[B]digraph\-host\f[R]
706 T}@T{
707 Produce a dot digraph for hosts
708 T}
709 T{
710 \f[B]digraph\-ssh\f[R]
711 T}@T{
712 Produce a dot digraph of SSH ID\[cq]s, users and nodes relations
713 T}
714 T{
715 \f[B]import\f[R]
716 T}@T{
717 Import TARGET host in the current nodes directory
718 T}
719 T{
720 \f[B]info\f[R]
721 T}@T{
722 Default command showing active nodes and summary
723 T}
724 T{
725 \f[B]init\f[R]
726 T}@T{
727 Initialize a new work directory
728 T}
729 .TE
730 .SS Environment
731 .PP
732 .TS
733 tab(@);
734 lw(9.7n) lw(31.4n) lw(29.0n).
735 T{
736 Name
737 T}@T{
738 Default value
739 T}@T{
740 Description
741 T}
743 T{
744 R7_DEBUG
745 T}@T{
746 no
747 T}@T{
748 Enable debug mode
749 T}
750 T{
751 R7_DRYRUN
752 T}@T{
753 no
754 T}@T{
755 Enable dry\-run mode
756 T}
757 T{
758 R7_GROUP_ALLPREFIX
759 T}@T{
760 no
761 T}@T{
762 Group selects all available prefix
763 T}
764 T{
765 R7_GROUP_SUMMARY
766 T}@T{
767 no
768 T}@T{
769 Enable output\-dump and summary after group execution
770 T}
771 T{
772 R7_GROUP_EXITONERROR
773 T}@T{
774 no
775 T}@T{
776 Enable exit on error function
777 T}
778 T{
779 R7_PARALLEL
780 T}@T{
781 no
782 T}@T{
783 Enable group nodes parallel execution
784 T}
785 T{
786 R7_PREFIX
787 T}@T{
788 install state doc
789 T}@T{
790 Set the r7 group execution prefix
791 T}
792 T{
793 R7_SHOWOUTPUT
794 T}@T{
795 no
796 T}@T{
797 Show interactive output
798 T}
799 T{
800 R7_WORKDIR
801 T}@T{
802 PWD
803 T}@T{
804 Set the r7 repository path
805 T}
806 T{
807 R7_SITE_CONFIG
808 T}@T{
809 R7_WORKDIR/site\-config
810 T}@T{
811 Set the r7 \f[CR]site\-config\f[R] path
812 T}
813 T{
814 R7_OUTPUTDIR
815 T}@T{
816 R7_WORKDIR/_output
817 T}@T{
818 Set the r7 output directory path
819 T}
820 T{
821 SSH_CONFIG_DIR
822 T}@T{
823 R7_WORKDIR/.ssh
824 T}@T{
825 Set the SSH configuration directory path
826 T}
827 T{
828 SSH_CONFIG_FILE
829 T}@T{
830 R7_WORKDIR/.ssh/config
831 T}@T{
832 Set the SSH configuration file path
833 T}
834 T{
835 SSH_CONTROL_DIR
836 T}@T{
837 SSH_CONFIG_DIR/control
838 T}@T{
839 Set the SSH control dir path
840 T}
841 T{
842 SSH_IDENTITY_FILE
843 T}@T{
844 R7_WORKDIR/.ssh/id_ed25519_r7
845 T}@T{
846 Set the SSH identity file
847 T}
848 T{
849 SSH_KNOWN_HOSTS
850 T}@T{
851 R7_WORKDIR/.ssh/known_hosts
852 T}@T{
853 Set the SSH known hosts file
854 T}
855 T{
856 SSH_CONNECT_TIMEOUT
857 T}@T{
859 T}@T{
860 Set the SSH connect timeout
861 T}
862 .TE
863 .SS Group variables
864 Those variables are available during the execution of th group
865 file\[cq]s functions.
866 .PP
867 .TS
868 tab(@);
869 l l.
870 T{
871 Name
872 T}@T{
873 Description
874 T}
876 T{
877 trace_id
878 T}@T{
879 Current run trace ID
880 T}
881 T{
882 groupname
883 T}@T{
884 Current group name being executed
885 T}
886 T{
887 exitonerror
888 T}@T{
889 Cause the error function to exit if equals \f[CR]yes\f[R]
890 T}
891 T{
892 nodename
893 T}@T{
894 Contains the output of \f[CR]nodename\f[R]
895 T}
896 T{
897 nodedir
898 T}@T{
899 Contains the output of \f[CR]nodedir\f[R]
900 T}
901 T{
902 groupdir
903 T}@T{
904 Contains the output of \f[CR]groupdir\f[R]
905 T}
906 .TE
907 .SS Group functions
908 Those functions are accessible during the execution of the group
909 file\[cq]s functions.
910 Non documented functions are reserved for internal use.
911 .IP " 1." 4
912 trace
913 .IP " 2." 4
914 error
915 .IP " 3." 4
916 node
917 .IP " 4." 4
918 nodename
919 .IP " 5." 4
920 nodedir
921 .IP " 6." 4
922 groupdir
923 .IP " 7." 4
924 install
925 .IP " 8." 4
926 groupinstall
927 .IP " 9." 4
928 nodeinstall
929 .IP "10." 4
930 installdir
931 .IP "11." 4
932 groupinstalldir
933 .IP "12." 4
934 nodeinstalldir
935 .IP "13." 4
936 source
937 .IP "14." 4
938 groupsource
939 .IP "15." 4
940 nodesource
941 .IP "16." 4
942 template
943 .IP "17." 4
944 grouptemplate
945 .IP "18." 4
946 nodetemplate
947 .PP
948 * * * * *
949 .SS trace
950 \f[B]\f[BI]Description:\f[B]\f[R] Append a trace containing the current
951 node name and \f[CR]trace_id\f[R]
952 .PP
953 \f[B]Usage:\f[R]
954 .IP
955 .EX
956 trace [string...]
957 .EE
958 .SS error
959 \f[B]\f[BI]Description:\f[B]\f[R] Trace an error message that will
960 inform the user of an event in the summary output, exit the group
961 execution if \f[CR]\-e\f[R] is set
962 .PP
963 \f[B]Usage:\f[R]
964 .IP
965 .EX
966 error [string...]
967 .EE
968 .SS node
969 \f[B]\f[BI]Description:\f[B]\f[R] Returns true if the argument is an
970 existing file or directory inside \f[CR]/tmp/r7/$(nodename)\f[R], else,
971 returns 31
972 .PP
973 \f[B]\f[BI]Usage:\f[B]\f[R]
974 .IP
975 .EX
976 node [filename\f[B]|\f[R]dirname]
977 .EE
978 .SS nodename
979 \f[B]\f[BI]Description:\f[B]\f[R] Returns the small host name of the
980 current host
981 .PP
982 \f[B]\f[BI]Usage:\f[B]\f[R]
983 .IP
984 .EX
985 nodename
986 .EE
987 .SS nodedir
988 \f[B]\f[BI]Description:\f[B]\f[R] Returns \f[CR]/tmp/r7/$(nodename)\f[R]
989 .PP
990 \f[B]\f[BI]Usage:\f[B]\f[R]
991 .IP
992 .EX
993 nodename
994 .EE
995 .SS groupdir
996 \f[B]\f[BI]Description:\f[B]\f[R] Returns
997 \f[CR]/tmp/r7/$groupname.dir\f[R]
998 .PP
999 \f[B]\f[BI]Usage:\f[B]\f[R]
1000 .IP
1001 .EX
1002 groupdir
1003 .EE
1004 .SS install
1005 \f[B]\f[BI]Description:\f[B]\f[R] Change directory to \f[CR]/tmp/r7\f[R]
1006 and install files if changed and sets mode and owner, returns true if
1007 the file changed, otherwise returns 30
1008 .PP
1009 \f[B]\f[BI]Usage:\f[B]\f[R]
1010 .IP
1011 .EX
1012 install [\-o owner] [\-m mode] source destintaion
1013 .EE
1014 .SS groupinstall
1015 \f[B]\f[BI]Description:\f[B]\f[R] Change directory to the current group
1016 \f[CR].dir\f[R] directory in \f[CR]/tmp/r7\f[R] then performs like
1017 \f[CR]install\f[R]
1018 .PP
1019 \f[B]\f[BI]Usage:\f[B]\f[R]
1020 .IP
1021 .EX
1022 groupinstall [\-o owner] [\-m mode] source destintaion
1023 .EE
1024 .SS nodeinstall
1025 \f[B]\f[BI]Description:\f[B]\f[R] Change directory to the current node
1026 directory in \f[CR]/tmp/r7\f[R] then performs like \f[CR]install\f[R]
1027 .PP
1028 \f[B]\f[BI]Usage:\f[B]\f[R]
1029 .IP
1030 .EX
1031 nodeinstall [\-o owner] [\-m mode] source destintaion
1032 .EE
1033 .SS installdir
1034 \f[B]\f[BI]Description:\f[B]\f[R] Install directory calling
1035 \f[CR]install\f[R] for each file and checking for permissions changes.
1036 .PP
1037 \f[B]\f[BI]Usage:\f[B]\f[R]
1038 .IP
1039 .EX
1040 installdir [\-o fileowner] [\-m filemode] [\-O dirowner] [\-O dirmode] source
1041 destination
1042 .EE
1043 .SS groupinstalldir
1044 \f[B]\f[BI]Description:\f[B]\f[R] Change directory to the current group
1045 directory then call installdir
1046 .PP
1047 \f[B]\f[BI]Usage:\f[B]\f[R]
1048 .IP
1049 .EX
1050 groupinstalldir [\-o fileowner] [\-m filemode] [\-O dirowner] [\-O dirmode] source
1051 destination
1052 .EE
1053 .SS nodeinstalldir
1054 \f[B]\f[BI]Description:\f[B]\f[R] Change directory to the current group
1055 directory then call installdir
1056 .PP
1057 \f[B]\f[BI]Usage:\f[B]\f[R]
1058 .IP
1059 .EX
1060 nodeinstalldir [\-o fileowner] [\-m filemode] [\-O dirowner] [\-O dirmode] source
1061 destination
1062 .EE
1063 .SS fsource
1064 \f[B]\f[BI]Description:\f[B]\f[R] Source a POSIX shell file in the
1065 current execution
1066 .PP
1067 \f[B]\f[BI]Usage:\f[B]\f[R]
1068 .IP
1069 .EX
1070 fsource filename
1071 .EE
1072 .SS groupsource
1073 \f[B]\f[BI]Description:\f[B]\f[R] Change directory to the current group
1074 directory then call fsource with the file name as argument, produces an
1075 error if filename is not found from the group directory
1076 .PP
1077 \f[B]\f[BI]Usage:\f[B]\f[R]
1078 .IP
1079 .EX
1080 groupsource filename
1081 .EE
1082 .SS nodesource
1083 \f[B]\f[BI]Description:\f[B]\f[R] Change directory to the current group
1084 directory then call node and fsource with the file name as argument
1085 without producing an error if the filename is not found
1086 .PP
1087 \f[B]\f[BI]Usage:\f[B]\f[R]
1088 .IP
1089 .EX
1090 nodesource filename
1091 .EE
1092 .SS template
1093 \f[B]\f[BI]Description:\f[B]\f[R] Template the files passed as arguments
1094 with the current environment or by sourcing a specified file
1095 .PP
1096 \f[B]\f[BI]Usage:\f[B]\f[R]
1097 .IP
1098 .EX
1099 template [\-s sourcefile] [file...]
1100 .EE
1101 .SS grouptemplate
1102 \f[B]\f[BI]Description:\f[B]\f[R] Change directory to the current group
1103 directory before calling template
1104 .PP
1105 \f[B]\f[BI]Usage:\f[B]\f[R]
1106 .IP
1107 .EX
1108 grouptemplate [\-s sourcefile] [file...]
1109 .EE
1110 .SS nodetemplate
1111 \f[B]\f[BI]Description:\f[B]\f[R] Change directory to the current node
1112 directory before calling template
1113 .PP
1114 \f[B]\f[BI]Usage:\f[B]\f[R]
1115 .IP
1116 .EX
1117 nodetemplate [\-s sourcefile] [file...]
1118 .EE
1119 .SH r7 library
1120 Usable from the r7 \f[CR]site\-config\f[R] file or sourced in the
1121 current shell using:
1122 .IP
1123 .EX
1124 \&. $(command \-v r7)
1125 .EE
1126 .PP
1127 Each functions are declared with underscore names and aliased with
1128 dashes.
1129 Shorter aliases are also available, list all declared aliases with:
1130 .IP
1131 .EX
1132 alias
1133 .EE
1134 .PP
1135 Non documented functions are reserved for internal use.
1136 .SS Interface
1137 .IP "1." 3
1138 info
1139 .IP "2." 3
1140 usage
1141 .PP
1142 * * * * *
1143 .SS info
1144 \f[B]\f[BI]Description:\f[B]\f[R] Default command showing active nodes
1145 and summary, ran when sourced
1146 .PP
1147 \f[B]\f[BI]Usage:\f[B]\f[R]
1148 .IP
1149 .EX
1150 info
1151 .EE
1152 .SS usage
1153 \f[B]\f[BI]Description:\f[B]\f[R] Shows the command line help
1154 .PP
1155 \f[B]\f[BI]Usage:\f[B]\f[R]
1156 .IP
1157 .EX
1158 usage
1159 .EE
1160 .SS SSH functions
1161 .IP " 1." 4
1162 unlock
1163 .IP " 2." 4
1164 copy
1165 .IP " 3." 4
1166 ssh
1167 .IP " 4." 4
1168 ssh\-debug
1169 .IP " 5." 4
1170 ssh\-known\-hosts
1171 .IP " 6." 4
1172 ssh\-authorized\-keys\-reset
1173 .IP " 7." 4
1174 ssh\-accept\-new
1175 .IP " 8." 4
1176 ssh\-control\-master\-clean
1177 .IP " 9." 4
1178 ssh\-users
1179 .IP "10." 4
1180 ssh\-ids
1181 .IP "11." 4
1182 ssh\-authorized\-keys
1183 .IP "12." 4
1184 ssh\-ids\-hosts
1185 .PP
1186 * * * * *
1187 .SS unlock
1188 \f[B]\f[BI]Description:\f[B]\f[R] Resets the SSH agent environment and
1189 issues ssh\-add for SSH_IDENTITY_FILE
1190 .PP
1191 \f[B]\f[BI]Usage:\f[B]\f[R]
1192 .IP
1193 .EX
1194 unlock
1195 .EE
1196 .SS copy
1197 \f[B]\f[BI]Description:\f[B]\f[R] r7 openrsync, rsync, scp wrapper;
1198 selected in order of availability
1199 .PP
1200 \f[B]\f[BI]Usage:\f[B]\f[R]
1201 .IP
1202 .EX
1203 copy SRC DST
1204 .EE
1205 .SS ssh
1206 \f[B]\f[BI]Description:\f[B]\f[R] r7 SSH wrapper; behaves like the
1207 standard OpenSSH command
1208 .PP
1209 \f[B]\f[BI]Usage:\f[B]\f[R]
1210 .IP
1211 .EX
1212 ssh OPTION HOST
1213 .EE
1214 .SS ssh\-debug
1215 \f[B]\f[BI]Description:\f[B]\f[R] r7 SSH with debug connection mode for
1216 a specific HOST
1217 .PP
1218 \f[B]\f[BI]Usage:\f[B]\f[R]
1219 .IP
1220 .EX
1221 ssh\-debug HOST
1222 .EE
1223 .SS ssh\-known\-hosts
1224 \f[B]\f[BI]Description:\f[B]\f[R] Calls ssh\-keygen to dump the SSH
1225 known_hosts file
1226 .PP
1227 \f[B]\f[BI]Usage:\f[B]\f[R]
1228 .IP
1229 .EX
1230 ssh\-known\-hosts
1231 .EE
1232 .SS ssh\-authorized\-keys\-reset
1233 \f[B]\f[BI]Description:\f[B]\f[R] Resets SSH authorized_keys on the
1234 specified HOST
1235 .PP
1236 \f[B]\f[BI]Usage:\f[B]\f[R]
1237 .IP
1238 .EX
1239 ssh\-authorized\-keys\-reset HOST
1240 .EE
1241 .SS ssh\-accept\-new
1242 \f[B]\f[BI]Description:\f[B]\f[R] Adds a new host entry in the SSH
1243 known_hosts file
1244 .PP
1245 \f[B]\f[BI]Usage:\f[B]\f[R]
1246 .IP
1247 .EX
1248 ssh\-accept\-new HOST
1249 .EE
1250 .SS ssh\-control\-master\-clean
1251 \f[B]\f[BI]Description:\f[B]\f[R] Cleans the SSH control master
1252 directory
1253 .PP
1254 \f[B]\f[BI]Usage:\f[B]\f[R]
1255 .IP
1256 .EX
1257 ssh\-control\-master\-clean
1258 .EE
1259 .SS ssh\-users
1260 \f[B]\f[BI]Description:\f[B]\f[R] Searches nodes for authorized_keys_*
1261 and returns a list of users
1262 .PP
1263 \f[B]\f[BI]Usage:\f[B]\f[R]
1264 .IP
1265 .EX
1266 ssh\-users
1267 .EE
1268 .SS ssh\-ids
1269 \f[B]\f[BI]Description:\f[B]\f[R] Returns sorted SSH IDs
1270 .PP
1271 \f[B]\f[BI]Usage:\f[B]\f[R]
1272 .IP
1273 .EX
1274 ssh\-ids
1275 .EE
1276 .SS ssh\-authorized\-keys
1277 \f[B]\f[BI]Description:\f[B]\f[R] Returns the list of authorized_keys
1278 from nodes
1279 .PP
1280 \f[B]\f[BI]Usage:\f[B]\f[R]
1281 .IP
1282 .EX
1283 ssh\-authorized\-keys
1284 .EE
1285 .SS ssh\-ids\-hosts
1286 \f[B]\f[BI]Description:\f[B]\f[R] Returns SSH IDs along with matching
1287 key file and host name
1288 .PP
1289 \f[B]\f[BI]Usage:\f[B]\f[R]
1290 .IP
1291 .EX
1292 ssh\-ids\-hosts
1293 .EE
1294 .SS Deployment functions
1295 .IP "1." 3
1296 nodes
1297 .IP "2." 3
1298 nodes\-active
1299 .IP "3." 3
1300 run\-config
1301 .IP "4." 3
1302 members
1303 .IP "5." 3
1304 group
1305 .IP "6." 3
1306 group\-functions
1307 .IP "7." 3
1308 group\-functions\-all
1309 .IP "8." 3
1310 prefix
1311 .PP
1312 * * * * *
1313 .SS nodes
1314 \f[B]\f[BI]Description:\f[B]\f[R] Returns a list of available nodes
1315 .PP
1316 \f[B]\f[BI]Usage:\f[B]\f[R]
1317 .IP
1318 .EX
1319 nodes
1320 .EE
1321 .SS nodes\-active
1322 \f[B]\f[BI]Description:\f[B]\f[R] Returns a list of active nodes by
1323 detecting SSH availability (a login is done), writes
1324 \f[CR]R7_WORKDIR/.active_nodes\f[R] containing the available hosts
1325 .PP
1326 \f[B]\f[BI]Usage:\f[B]\f[R]
1327 .IP
1328 .EX
1329 nodes\-active
1330 .EE
1331 .SS run\-config
1332 \f[B]\f[BI]Description:\f[B]\f[R] Executes \f[CR]R7_SITE_CONFIG\f[R] in
1333 the loaded environment
1334 .PP
1335 \f[B]\f[BI]Usage:\f[B]\f[R]
1336 .IP
1337 .EX
1338 run\-config
1339 .EE
1340 .SS members
1341 \f[B]\f[BI]Description:\f[B]\f[R] Returns a list of active nodes
1342 matching a list of grep REGEXES
1343 .PP
1344 \f[B]\f[BI]Usage:\f[B]\f[R]
1345 .IP
1346 .EX
1347 members REGEXES
1348 .EE
1349 .SS group
1350 \f[B]\f[BI]Description:\f[B]\f[R] Applies GROUPNAME functions (in prefix
1351 order) to the provided MEMBERS list
1352 .PP
1353 \f[B]\f[BI]Usage:\f[B]\f[R]
1354 .IP
1355 .EX
1356 group GROUPNAME MEMBERS
1357 .EE
1358 .SS group\-functions
1359 \f[B]\f[BI]Description:\f[B]\f[R] Returns a list of functions found in
1360 the specified GROUPNAME
1361 .PP
1362 \f[B]\f[BI]Usage:\f[B]\f[R]
1363 .IP
1364 .EX
1365 group\-functions GROUPNAME
1366 .EE
1367 .SS group\-functions\-all
1368 \f[B]\f[BI]Description:\f[B]\f[R] Returns a list of all group functions
1369 found in the current \f[CR]R7_WORKDIR/groups\f[R] directory with the
1370 \f[CR]group_name::function_name\f[R] format
1371 .PP
1372 \f[B]\f[BI]Usage:\f[B]\f[R]
1373 .IP
1374 .EX
1375 group\-functions\-all
1376 .EE
1377 .SS prefix
1378 \f[B]\f[BI]Description:\f[B]\f[R] Sets the current PREFIX for matching
1379 function names, can match for the whole unique name in the group, for
1380 executing one specified function only
1381 .PP
1382 \f[B]\f[BI]Usage:\f[B]\f[R]
1383 .IP
1384 .EX
1385 prefix PREFIX
1386 .EE
1387 .SS Text output functions
1388 .IP " 1." 4
1389 output\-dump
1390 .IP " 2." 4
1391 output\-latest
1392 .IP " 3." 4
1393 output\-status
1394 .IP " 4." 4
1395 output\-duration
1396 .IP " 5." 4
1397 output
1398 .IP " 6." 4
1399 output\-diffs
1400 .IP " 7." 4
1401 output\-permissions
1402 .IP " 8." 4
1403 output\-errors
1404 .IP " 9." 4
1405 summary
1406 .IP "10." 4
1407 trace\-id\-last
1408 .PP
1409 * * * * *
1410 .SS output\-dump
1411 \f[B]\f[BI]Description:\f[B]\f[R] Dumps R7_RUNDIR to R7_OUTPUTDIR
1412 .PP
1413 \f[B]\f[BI]Usage:\f[B]\f[R]
1414 .IP
1415 .EX
1416 output\-dump
1417 .EE
1418 .SS output\-latest
1419 \f[B]\f[BI]Description:\f[B]\f[R] Returns a list of outputs from the
1420 latest run
1421 .PP
1422 \f[B]\f[BI]Usage:\f[B]\f[R]
1423 .IP
1424 .EX
1425 output\-latest
1426 .EE
1427 .SS output\-status
1428 \f[B]\f[BI]Description:\f[B]\f[R] Returns a list of current dumped
1429 functions exit status codes
1430 .PP
1431 \f[B]\f[BI]Usage:\f[B]\f[R]
1432 .IP
1433 .EX
1434 output\-status
1435 .EE
1436 .SS output\-duration
1437 \f[B]\f[BI]Description:\f[B]\f[R] Returns a list of durations of
1438 executed groups
1439 .PP
1440 \f[B]\f[BI]Usage:\f[B]\f[R]
1441 .IP
1442 .EX
1443 output\-duration
1444 .EE
1445 .SS output
1446 \f[B]\f[BI]Description:\f[B]\f[R] Shows the dumped output matching HOST,
1447 GROUPNAME, and FUNCTION (or any if unspecified)
1448 .PP
1449 \f[B]\f[BI]Usage:\f[B]\f[R]
1450 .IP
1451 .EX
1452 output HOST GROUPNAME FUNCTION
1453 .EE
1454 .SS trace\-id\-last
1455 \f[B]\f[BI]Description:\f[B]\f[R] Returns the latest execution trace_id
1456 .PP
1457 \f[B]\f[BI]Usage:\f[B]\f[R]
1458 .IP
1459 .EX
1460 trace\-id\-last
1461 .EE
1462 .SS output\-diffs
1463 \f[B]\f[BI]Description:\f[B]\f[R] Returns the diffs from the latest
1464 execution
1465 .PP
1466 \f[B]\f[BI]Usage:\f[B]\f[R]
1467 .IP
1468 .EX
1469 output\-diffs
1470 .EE
1471 .SS output\-permissions
1472 \f[B]\f[BI]Description:\f[B]\f[R] Returns the latest permission changes
1473 .PP
1474 \f[B]\f[BI]Usage:\f[B]\f[R]
1475 .IP
1476 .EX
1477 output\-permissions
1478 .EE
1479 .SS output\-errors
1480 \f[B]\f[BI]Description:\f[B]\f[R] Returns the latest errors detected
1481 .PP
1482 \f[B]\f[BI]Usage:\f[B]\f[R]
1483 .IP
1484 .EX
1485 output\-errors
1486 .EE
1487 .SS summary
1488 \f[B]\f[BI]Description:\f[B]\f[R] Produces a summary of errors, diffs,
1489 and permission outputs
1490 .PP
1491 \f[B]\f[BI]Usage:\f[B]\f[R]
1492 .IP
1493 .EX
1494 summary
1495 .EE
1496 .SS Digraph output
1497 .IP "1." 3
1498 digraph\-host
1499 .IP "2." 3
1500 digraph\-ssh\-id\-hosts
1501 .PP
1502 * * * * *
1503 .SS digraph\-host
1504 \f[B]\f[BI]Description:\f[B]\f[R] Returns a directed graph (in DOT
1505 format) showing relations among groups, functions, and nodes
1506 .PP
1507 \f[B]\f[BI]Usage:\f[B]\f[R]
1508 .IP
1509 .EX
1510 digraph\-host
1511 .EE
1512 .SS digraph\-ssh\-id\-hosts
1513 \f[B]\f[BI]Description:\f[B]\f[R] Returns a directed graph (in DOT
1514 format) of relations between SSH IDs and hosts
1515 .PP
1516 \f[B]\f[BI]Usage:\f[B]\f[R]
1517 .IP
1518 .EX
1519 digraph\-ssh\-id\-hosts
1520 .EE
1521 .SS HTML output
1522 .IP "1." 3
1523 html
1524 .SS html
1525 \f[B]\f[BI]Description:\f[B]\f[R] Retunrs a report page with the content
1526 of \f[CR]README.md\f[R] in HTML format
1527 .PP
1528 \f[B]\f[BI]Usage:\f[B]\f[R]
1529 .IP
1530 .EX
1531 html
1532 .EE
1533 .PP
1534 * * * * *
1535 .SS Node importing
1536 .IP "1." 3
1537 import
1538 .SS import
1539 \f[B]\f[BI]Description:\f[B]\f[R] Import configuration files from a
1540 target host
1541 .PP
1542 \f[B]\f[BI]Usage:\f[B]\f[R]
1543 .IP
1544 .EX
1545 import HOST
1546 .EE
1547 .PP
1548 * * * * *
1549 .SS Technical notes
1550 .IP \[bu] 2
1551 Supported shells are ksh93, oksh, yash and bash
1552 .IP \[bu] 2
1553 Supported target platforms are POSIX compatible systems
1554 .RS 2
1555 .IP \[bu] 2
1556 \f[CR]/bin/sh\f[R] or compatible must be set for the user\[cq]s shell
1557 (which is usually the case by default)
1558 .IP \[bu] 2
1559 \f[CR]/tmp\f[R] must be writable by the user
1560 .RE
1561 .IP \[bu] 2
1562 Supported control node platforms are supposed to be POSIX compatible
1563 systems but currently limited to BSD\[cq]s, Darwin and GNU/Linux
1564 .RS 2
1565 .IP \[bu] 2
1566 Dependencies are awk, OpenSSH and column
1567 .IP \[bu] 2
1568 Optional dependencies are openrsync, rsync, column, graphviz and pandoc
1569 .RE
1570 .IP \[bu] 2
1571 The r7 importer supports the following platforms:
1572 .RS 2
1573 .IP \[bu] 2
1574 Alpine Linux
1575 .IP \[bu] 2
1576 Archlinux
1577 .IP \[bu] 2
1578 Crux
1579 .IP \[bu] 2
1580 Debian
1581 .IP \[bu] 2
1582 DragonFlyBSD
1583 .IP \[bu] 2
1584 FreeBSD
1585 .IP \[bu] 2
1586 Gentoo
1587 .IP \[bu] 2
1588 Guix
1589 .IP \[bu] 2
1590 Haiku
1591 .IP \[bu] 2
1592 Minix
1593 .IP \[bu] 2
1594 NetBSD
1595 .IP \[bu] 2
1596 Omnios
1597 .IP \[bu] 2
1598 OpenBSD
1599 .IP \[bu] 2
1600 OpenSUSE
1601 .IP \[bu] 2
1602 QNX
1603 .IP \[bu] 2
1604 Rocky Linux
1605 .IP \[bu] 2
1606 Salix
1607 .IP \[bu] 2
1608 Void Linux
1609 .RE
1610 .PP
1611 * * * * *
1612 .SS License
1613 The provided group library is shared as additional examples WITH NO
1614 WARRANTIES of the documentation and contain the following third\-party
1615 files under the ISC License.
1616 Copyright information are indicated in the LICENSE section of related
1617 files.
1618 .IP \[bu] 2
1619 \f[CR]pf\-badhost.sh\f[R]
1620 .IP \[bu] 2
1621 \f[CR]unbound\-adblock.sh\f[R]
1622 .IP \[bu] 2
1623 \f[CR]http\-ban.sh\f[R]
1624 .PP
1625 The project is shared under the terms of the ISC license.
1626 Any version previous \f[CR]0.1.0\f[R] needs to be considered obsolete
1627 and should not be redistributed.
1628 History in the GIT repository is kept for transparency purpose only.
1629 .PP
1630 Below is a copy of the applicable license:
1631 .IP
1632 .EX
1633 ISC License
1635 Copyright 2025 xs <xs\[at]inda.re>
1637 Permission to use, copy, modify, and/or distribute this software for any
1638 purpose with or without fee is hereby granted, provided that the above
1639 copyright notice and this permission notice appear in all copies.
1641 THE SOFTWARE IS PROVIDED \[dq]AS IS\[dq] AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
1642 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
1643 FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
1644 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
1645 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
1646 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
1647 PERFORMANCE OF THIS SOFTWARE.
1648 .EE