2 .\" Automatically generated by Pandoc 3.6.2
4 .TH "R7" "1" "Tue Jun 3 2025" "v0.1.3" "User Manual"
7 R7 is a configuration management framework made to configure nodes with
8 configuration files and related operations versionned in a central
10 To remain code versionning system agnostic, manual or automated
11 versionning 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].
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.
19 \f[I]Nodes sub\-directories are hostnames understood by the ssh client
20 and configuration.\f[R]
22 \f[I]Currently, r7 requires valid ssh configuration and keyfiles in the
23 repository \f[CI].ssh/\f[I] directory.\f[R]
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]
30 \f[I]See Technical Notes for dependencies and supported platforms.\f[R]
32 There is an example of r7 repository:
46 \&./.ssh/id_ed25519_r7
47 \&./.ssh/id_ed25519_r7.pub
51 There is an example of r7 site configuration (\f[CR]site\-config\f[R]
55 prefix install state doc
56 group common \[aq].*\[aq]
57 group test0 hostB hostC
62 There is an exemple of the deployment of that configuration within the
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
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.
85 There is the \f[CR]common\f[R] group:
88 install_nothing() \f[B]{\f[R]
89 echo Nothing installed
92 state_uname() \f[B]{\f[R]
96 doc_tutorial() \f[B]{\f[R]
97 echo \[dq]## Welcome to the R7 tutorial!\[dq]
101 And there is the \f[CR]test0\f[R] group:
104 state_test() \f[B]{\f[R]
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].
112 Group files names can\[cq]t contain spaces, tabs or newlines, as well
114 \f[I]The `:' character is not recommanded as well as it may reduce
115 lisibility of the interactive output.\f[R]
117 Called groups and node directories are copied to related nodes in
118 \f[CR]hostname:/tmp/r7/\f[R]:
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
126 Groups may have no \f[CR].dir\f[R] directory, in this case, nothing is
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):
133 prefix install state doc
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.
141 Site confiurations 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 catched 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.
155 state_test() \f[B]{\f[R]
160 And we re\-run the configuration to see what\[cq]s happenning.
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)
179 The last two lines are part of the \f[CR]summary\f[R] output.
181 Let\[cq]s modify the \f[CR]state_test\f[R] function again to add some
182 verbosity to it\[cq]s output.
184 \f[I]Note that we also change the return value.\f[R]
187 state_test() \f[B]{\f[R]
189 false \f[B]||\f[R] \f[B]{\f[R]
196 This will produce the following summary:
199 \- (error 22) \- in hostB test0 state_test (1748622980)
204 \- (error 22) \- in hostC test0 state_test (1748622980)
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 specifed work directory to be created and act as an r7 repository.
217 \f[I]Automated versionning of outputs are currently let to the user, a
218 recommended place would be the end of the site configuration file.\f[R]
220 This command initializes a new directory called \f[CR]test.org\f[R]:
227 Once this step is done, it is required to:
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]
233 Adjust the SSH client configuration file in the repository
234 \f[CR].ssh/config\f[R]
236 \f[I]Note that it is possible to import additionnal SSH configurations,
237 like the user one from the SSH configuration, but it is advised to keep
239 .SS SSH agent handling
240 The function \f[CR]unlock\f[R] can be used to set the SSH agent
241 environement, this will be required for any automated operation later
246 \&. $(command \-v r7) \f[I]# Sourcing r7\f[R]
248 tmux \f[B]||\f[R] screen
251 \f[I]\f[BI]\f[B]Warning:\f[BI]\f[I] Unlock will terminate any running
252 \f[CI]ssh\-agent\f[I] instances.\f[R]
254 For adding a new host, the simplest way is to have pre\-configured
255 \f[CR]authorized_keys\f[R] for the target user, it is then required to
256 add it to the \f[CR]known_hosts\f[R] file.
257 For that, it is possible to use r7 SSH functions:
260 \&. $(command \-v r7) \f[I]# Sourcing r7\f[R]
261 ssh\-accept\-new hostname
264 If resetting the target\[cq]s user \f[CR]authorized_keys\f[R] file is
265 needed, the following function can be used:
268 \&. $(command \-v r7) \f[I]# Sourcing r7\f[R]
269 ssh\-authorized\-keys\-reset hostname
272 \f[I]\f[BI]Warning:\f[I] This will resets the SSH authorized_keys file
273 for the target user (root, by default) and put the
274 \f[CI].ssh/id_ed25519\-r7.pub\f[I] in place.\f[R]
276 Once the host is accepted in the \f[CR]known_hosts\f[R] file, it\[cq]s
277 possible to import it automatically.
278 .SS Importing hosts configurations
279 \f[I]This feature currently only support OpenBSD.\f[R]
281 Avoiding to import the configuration manually is possible with the
282 \f[CR]import\f[R] command:
288 Most common configuration files will be copied in a newly created
289 \f[CR]nodes/hostname\f[R] sub\-directory.
290 .SS Writing group files
291 Group files collects fonctions related to the configuration of the
292 operating system, networking, services, global and user configurations
293 packages installations and application deployments.
295 By specifying the execution prefix, the user determines the order of
296 execution of the functions declared in the group file.
299 service_A() \f[B]{\f[R]
304 service_B() \f[B]{\f[R]
309 state_A() \f[B]{\f[R]
314 echo \[dq]## Service A\[dq]
316 echo \[dq]\- [url](http://test.org/)\[dq]
321 \f[I]\f[BI]file\f[I]: \f[CI]groups/example1\f[I]\f[R]
323 With the default prefix, \f[CR]install\f[R], \f[CR]state\f[R],
324 \f[CR]doc\f[R], the fonction that will be executed are
325 \f[CR]state_A\f[R] and \f[CR]doc_A\f[R].
326 To test that group file with all the functions inside we can call r7 the
330 r7 \-P \[aq]service state doc\[aq] group example1 hostname
333 Or using the \f[CR]\-a\f[R] flag which will create a prefix
334 automatically with all functions present in the group file:
337 r7 \-a group example1 hostname
340 In a real situation, this example will have failing functions because
341 the \f[CR]service\f[R] command may not be found or the services named
342 \f[CR]A\f[R] or \f[CR]B\f[R] does not exist.
345 ! (error 127) tools0:example1::service_A
346 ! (error 127) tools0:example1::service_B
347 ! (error 127) tools0:example1::state_A
348 \- (ok) tools0:example1::doc_A
351 We could force the group execution to stop using a combination of the
352 \f[CR]\-e\f[R] flag and the \f[CR]error\f[R] group function.
355 service_A() \f[B]{\f[R]
356 service A enable \f[B]&&\f[R]
357 service A restart \f[B]||\f[R]
358 error unable to setup service A
361 service_B() \f[B]{\f[R]
362 service B enable \f[B]&&\f[R]
363 service B restart \f[B]||\f[R]
364 error unable to setup service B
367 state_A() \f[B]{\f[R]
372 echo \[dq]## Service A\[dq]
374 echo \[dq]\- [url](http://test.org/)\[dq]
379 \f[I]\f[BI]file:\f[I] \f[CI]groups/example2\f[I]\f[R]
381 Let\[cq]s run the updated example with the \f[CR]\-s\f[R] flag to
382 trigger the summary output.
386 r7 \-sea group example2 hostname
389 This will produce something like the following:
392 ! (error) tools0:example2::service_A
393 ! (exit) tools0:example2::service_A
394 \- (error 127) \- in tools0 example2 service_A (1748791986)
396 /bin/sh: <stdin>[155]: service: not found
397 :: 1748791986 tools0 ERROR unable to setup service A
399 .SS Using the r7 install functions
400 The group library comes with the following functions that will allow
401 installation of files and triggering actions if necessary:
402 \f[CR]install\f[R], \f[CR]groupinstall\f[R], \f[CR]nodeinstall\f[R].
403 They are all shortcuts to an internal \f[CR]r7_install\f[R] function,
404 it\[cq]s just the wrappers changes directory to respectively
405 \f[CR]/tmp/r7\f[R], \f[CR]/tmp/r7/groupname.dir/\f[R] and
406 \f[CR]/tmp/r7/hostname/\f[R].
408 If we want to install files from the group directory we will use
412 install_program() \f[B]{\f[R]
413 groupinstall \-m 755 \-o root:bin my_program /usr/local/bin
417 \f[I]We are supposing to have the file
418 \f[CI]groups/example3.dir/my_program\f[I]\f[R]
420 And if it\[cq]s something from node, we should use:
423 install_program_config() \f[B]{\f[R]
424 nodeinstall \-m 644 \-o root:wheel my_config /etc
428 We can now chain the \f[CR]install\f[R] functions to configuration
429 checking and initialization of programs, services or network features
430 like in the following example, in which we install \f[CR]ntp.conf\f[R]
431 from the deployed node directory to \f[CR]/etc\f[R]:
434 service_ntpd() \f[B]{\f[R]
435 nodeinstall \-m 644 \-o root:wheel ntpd.conf /etc \f[B]&&\f[R]
436 ntpd \-n \f[B]&&\f[R]
437 rcctl enable ntpd \f[B]&&\f[R]
441 .SS Using the r7 node function
442 We may want to avoid executing a function or parts of it if the node has
443 no related files before executing the installation and actions handling
445 This can be done with the help of the \f[CR]node\f[R] function.
448 service_ntpd() \f[B]{\f[R]
449 node ntpd.conf \f[B]&&\f[R]
450 nodeinstall \-m 644 \-o root:wheel ntpd.conf /etc \f[B]&&\f[R]
451 ntpd \-n \f[B]&&\f[R]
452 rcctl enable ntpd \f[B]&&\f[R]
457 Here, \f[CR]node\f[R] will return \f[CR]31\f[R] if there is no file or
458 directory called \f[CR]ntpd.conf\f[R] inside the deployed node directory
459 (\f[CR]/tmp/r7/hostname\f[R]).
461 \f[CR]0\f[R], \f[CR]30\f[R] and \f[CR]31\f[R] exit codes are ignored
462 when r7 will search for execution errors.
463 This means \f[CR]30\f[R] and \f[CR]31\f[R] exit code are reserved to r7.
465 In other terms, this will update the NTP daemon configuration only if
466 \f[CR]ntpd.conf\f[R] is present in the node directory, otherwise it is
467 kept by default, which is the system provided default
468 \f[CR]ntpd.conf\f[R].
469 .SS Sourcing specific files
470 Here\[cq]s an example how to source additionnal shell from the deployed
471 node directory, or elsewhere:
474 service_sysrc() \f[B]{\f[R]
476 sysrc kld_list=\[dq]vmm if_tuntap if_bridge nmdm\[dq]
477 sysrc microcode_update_enable=YES
478 sysrc mountd_enable=YES
479 sysrc nfs_server_enable=YES
480 sysrc ntpdate_enable=YES
481 sysrc powerd_enable=YES
482 sysrc rcshutdown_timeout=900
483 sysrc rpcbind_enable=YES
484 sysrc sshd_enable=YES
486 nodesource sysrc.local
490 In this FreeBSD example, we configure the system RC globally with
491 \f[CR]service_sysrc\f[R] which apply, if \f[CR]sysrc.local\f[R] is found
492 in the root of the node directory, it\[cq]s sourcing in the current
493 scope via the help of \f[CR]nodesource sysrc.local\f[R].
495 The file \f[CR]nodes/hostname/sysrcl.local\f[R] contains the following:
498 sysrc ifconfig_igb0=DHCP
499 sysrc ifconfig_igb1=up
502 Inside the r7 release, a small example groups library can be found in
503 the \f[CR]groups\f[R] directory, that can also be browsed in the \c
504 .UR https://got.inda.re/?action=summary&path=r7.git
508 .SS System shell profile
509 Here we install the \f[CR]profile\f[R] file provided in the
510 \f[CR]groupname.dir\f[R] directory or the profile provided by the node
514 setup_profile() \f[B]{\f[R]
515 groupinstall \-m 644 \-o root:wheel profile /etc
516 node profile \f[B]&&\f[R]
517 nodeinstall \-m 644 \-o root:wheel profile /etc
521 Here we add new users:
524 setup_users() \f[B]{\f[R]
525 useradd user1 2>/dev/null \f[B]||\f[R] :
526 useradd user2 2>/dev/null \f[B]||\f[R] :
530 In the following example, we install a script and call it from a
531 dedicated user crontab.
534 mail_admins=admins\[at]test.org
536 install_myscript() \f[B]{\f[R]
537 groupinstall \-o root:bin \-m 755 myscript /usr/local/bin \f[B]&&\f[R]
538 useradd \-d /var/empty \-s /sbin/nologin _myscript
539 crontab \-u _myscript \- <<\-/
545 .SS Consulting the output
546 After the execution is done, the result are saved in the \f[CR]_run\f[R]
547 directory, \f[CR]output\-dump\f[R] needs to be called to produce the
548 current \f[CR]_output\f[R] structure.
550 The r7 \f[CR]output\f[R] command can then be used to show specific
551 output groups or functions:
557 Will show the whole output of the latest groups deployments.
559 This format can be used to match specific host, group or function:
562 r7 output [hostname [groupname [funcname]]]
568 $ r7 output tools0 OpenBSD state_packages\[rs]*
569 \- tools0 OpenBSD state_packages_upgrades
571 quirks\-7.103 signed on 2025\-05\-30T01:12:03Z
573 \- tools0 OpenBSD state_packages_repository
575 https://cdn.openbsd.org/pub/OpenBSD
578 \f[I]Note that the \f[CI]output\f[I] function arguments are using
579 shell\[cq]s case globbing patterns.\f[R]
581 \f[B]\f[BI]Usage:\f[B]\f[R]
584 r7 [options] [command [arguments...]]
588 \f[B]\-h\f[R] Show usage and exit
590 \f[B]\-d\f[R] Enable debug mode
592 \f[B]\-i\f[R] Specify the SSH identity file
594 \f[B]\-F\f[R] Specify the SSH client configuration file
596 \f[B]\-w\f[R] Set the work directory where \f[CR]./nodes\f[R] and
597 \f[CR]./groups\f[R] can be found
599 \f[B]\-r\f[R] Set the run directory (default: \f[CR]./_run\f[R])
601 \f[B]\-o\f[R] Set the output directory (default: \f[CR]./_output\f[R])
603 \f[B]\-c\f[R] Specify the site configuration file (default:
604 \f[CR]./site\-config\f[R])
606 \f[B]\-n\f[R] Enable dry run mode; prevents any modification on hosts
608 \f[B]\-e\f[R] Exit the group execution on the error function
610 \f[B]\-p\f[R] Run each host in parallel per group call
612 \f[B]\-O\f[R] Show output interactively
614 \f[B]\-P\f[R] Specify a prefix
616 \f[B]\-a\f[R] Select all available prefixes for a group command
618 \f[B]\-s\f[R] Apply output\-dump and summary after a group command
631 \f[B]run\-config\f[R]
633 Run the site configuration
638 Deploy specified group to hosts
641 \f[B]output\-dump\f[R]
643 Dump the run directory to the output directory
653 Produce a summary of errors and changes
656 \f[B]digraph\-host\f[R]
658 Produce a dot digraph for hosts
661 \f[B]digraph\-ssh\f[R]
663 Produce a dot digraph of SSH ID\[cq]s, users and nodes relations
668 Import TARGET host in the current nodes directory
673 Default command showing active nodes and summary
678 Initialize a new work directory
685 lw(9.7n) lw(31.4n) lw(29.0n).
713 Group selects all available prefix
720 Enable output\-dump and summary after group execution
727 Enable exit on error function
734 Enable group nodes parallel execution
741 Set the r7 group execution prefix
748 Show interactive output
755 Set the r7 repository path
760 R7_WORKDIR/site\-config
762 Set the r7 \f[CR]site\-config\f[R] path
769 Set the r7 output directory path
776 Set the SSH configuration directory path
781 R7_WORKDIR/.ssh/config
783 Set the SSH configuration file path
788 SSH_CONFIG_DIR/control
790 Set the SSH control dir path
795 R7_WORKDIR/.ssh/id_ed25519_r7
797 Set the SSH identity file
802 R7_WORKDIR/.ssh/known_hosts
804 Set the SSH known hosts file
811 Set the SSH connect timeout
815 Those variables are available during the execution of th group
816 file\[cq]s functions.
835 Current group name being executed
840 Cause the error function to exit if equals \f[CR]yes\f[R]
845 Contains the output of \f[CR]nodename\f[R]
850 Contains the output of \f[CR]nodedir\f[R]
855 Contains the output of \f[CR]groupdir\f[R]
859 Those functions are accessible during the execution of the group
860 file\[cq]s functions.
861 Non documented functions are reserved for internal use.
895 \f[B]\f[BI]Description:\f[B]\f[R] Append a trace containing the current
896 node name and \f[CR]trace_id\f[R]
904 \f[B]\f[BI]Description:\f[B]\f[R] Trace an error message that will
905 inform the user of an event in the summary output, exit the group
906 execution if \f[CR]\-e\f[R] is set
914 \f[B]\f[BI]Description:\f[B]\f[R] Returns true if the argument is an
915 existing file or directory inside \f[CR]/tmp/r7/$(nodename)\f[R], else,
918 \f[B]\f[BI]Usage:\f[B]\f[R]
921 node [filename\f[B]|\f[R]dirname]
924 \f[B]\f[BI]Description:\f[B]\f[R] Returns the small hostname of the
927 \f[B]\f[BI]Usage:\f[B]\f[R]
933 \f[B]\f[BI]Description:\f[B]\f[R] Returns \f[CR]/tmp/r7/$(nodename)\f[R]
935 \f[B]\f[BI]Usage:\f[B]\f[R]
941 \f[B]\f[BI]Description:\f[B]\f[R] Returns
942 \f[CR]/tmp/r7/$groupname.dir\f[R]
944 \f[B]\f[BI]Usage:\f[B]\f[R]
950 \f[B]\f[BI]Description:\f[B]\f[R] Change directory to \f[CR]/tmp/r7\f[R]
951 and install files if changed and sets mode and owner, returns true if
952 the file changed, otherwise returns 30
954 \f[B]\f[BI]Usage:\f[B]\f[R]
957 install [\-o owner] [\-m mode] source destintaion
960 \f[B]\f[BI]Description:\f[B]\f[R] Change directory to the current group
961 \f[CR].dir\f[R] directory in \f[CR]/tmp/r7\f[R] then performs like
964 \f[B]\f[BI]Usage:\f[B]\f[R]
967 groupinstall [\-o owner] [\-m mode] source destintaion
970 \f[B]\f[BI]Description:\f[B]\f[R] Change directory to the current node
971 directory in \f[CR]/tmp/r7\f[R] then performs like \f[CR]install\f[R]
973 \f[B]\f[BI]Usage:\f[B]\f[R]
976 nodeinstall [\-o owner] [\-m mode] source destintaion
979 \f[B]\f[BI]Description:\f[B]\f[R] Install directory calling
980 \f[CR]install\f[R] for each file and checking for permissions changes.
982 \f[B]\f[BI]Usage:\f[B]\f[R]
985 installdir [\-o fileowner] [\-m filemode] [\-O dirowner] [\-O dirmode] source
989 \f[B]\f[BI]Description:\f[B]\f[R] Change directory to the current group
990 directoy then call installdir
992 \f[B]\f[BI]Usage:\f[B]\f[R]
995 groupinstalldir [\-o fileowner] [\-m filemode] [\-O dirowner] [\-O dirmode] source
999 \f[B]\f[BI]Description:\f[B]\f[R] Change directory to the current group
1000 directoy then call installdir
1002 \f[B]\f[BI]Usage:\f[B]\f[R]
1005 nodeinstalldir [\-o fileowner] [\-m filemode] [\-O dirowner] [\-O dirmode] source
1009 \f[B]\f[BI]Description:\f[B]\f[R] Source a POSIX shell file in the
1012 \f[B]\f[BI]Usage:\f[B]\f[R]
1018 \f[B]\f[BI]Description:\f[B]\f[R] Change directory to the current group
1019 directory then call source with the file name as argument, produces an
1020 error if filename is not found from the group directory
1023 groupsource filename
1026 \f[B]\f[BI]Description:\f[B]\f[R] Change directory to the current group
1027 directory then call node and source with the file name as argument
1028 without producing an error if the filename is not found
1034 Usable from the r7 \f[CR]site\-config\f[R] file or sourced in the
1035 current shell using:
1038 \&. $(command \-v r7)
1041 Each functions are declared with underscore names and aliased with
1043 Shorter aliases are also available, list all declared aliases with:
1049 Non documented functions are reserved for internal use.
1058 \f[B]\f[BI]Description:\f[B]\f[R] Default command showing active nodes
1059 and summary, ran when sourced
1061 \f[B]\f[BI]Usage:\f[B]\f[R]
1067 \f[B]\f[BI]Description:\f[B]\f[R] Shows the command line help
1069 \f[B]\f[BI]Usage:\f[B]\f[R]
1086 ssh\-authorized\-keys\-reset
1090 ssh\-control\-master\-clean
1096 ssh\-authorized\-keys
1102 \f[B]\f[BI]Description:\f[B]\f[R] Resets the SSH agent environment and
1103 issues ssh\-add for SSH_IDENTITY_FILE
1105 \f[B]\f[BI]Usage:\f[B]\f[R]
1111 \f[B]\f[BI]Description:\f[B]\f[R] r7 openrsync, rsync, scp wrapper;
1112 selected in order of availability
1114 \f[B]\f[BI]Usage:\f[B]\f[R]
1120 \f[B]\f[BI]Description:\f[B]\f[R] r7 SSH wrapper; behaves like the
1121 standard OpenSSH command
1123 \f[B]\f[BI]Usage:\f[B]\f[R]
1129 \f[B]\f[BI]Description:\f[B]\f[R] r7 SSH with debug connection mode for
1132 \f[B]\f[BI]Usage:\f[B]\f[R]
1137 .SS ssh\-known\-hosts
1138 \f[B]\f[BI]Description:\f[B]\f[R] Calls ssh\-keygen to dump the SSH
1141 \f[B]\f[BI]Usage:\f[B]\f[R]
1146 .SS ssh\-authorized\-keys\-reset
1147 \f[B]\f[BI]Description:\f[B]\f[R] Resets SSH authorized_keys on the
1150 \f[B]\f[BI]Usage:\f[B]\f[R]
1153 ssh\-authorized\-keys\-reset HOST
1155 .SS ssh\-accept\-new
1156 \f[B]\f[BI]Description:\f[B]\f[R] Adds a new host entry in the SSH
1159 \f[B]\f[BI]Usage:\f[B]\f[R]
1162 ssh\-accept\-new HOST
1164 .SS ssh\-control\-master\-clean
1165 \f[B]\f[BI]Description:\f[B]\f[R] Cleans the SSH control master
1168 \f[B]\f[BI]Usage:\f[B]\f[R]
1171 ssh\-control\-master\-clean
1174 \f[B]\f[BI]Description:\f[B]\f[R] Searches nodes for authorized_keys_*
1175 and returns a list of users
1177 \f[B]\f[BI]Usage:\f[B]\f[R]
1183 \f[B]\f[BI]Description:\f[B]\f[R] Returns sorted SSH IDs
1185 \f[B]\f[BI]Usage:\f[B]\f[R]
1190 .SS ssh\-authorized\-keys
1191 \f[B]\f[BI]Description:\f[B]\f[R] Returns the list of authorized_keys
1194 \f[B]\f[BI]Usage:\f[B]\f[R]
1197 ssh\-authorized\-keys
1200 \f[B]\f[BI]Description:\f[B]\f[R] Returns SSH IDs along with matching
1201 keyfile and hostname
1203 \f[B]\f[BI]Usage:\f[B]\f[R]
1208 .SS Deployment functions
1226 \f[B]\f[BI]Description:\f[B]\f[R] Returns a list of available nodes
1228 \f[B]\f[BI]Usage:\f[B]\f[R]
1234 \f[B]\f[BI]Description:\f[B]\f[R] Returns a list of active nodes by
1235 detecting SSH availability
1237 \f[B]\f[BI]Usage:\f[B]\f[R]
1243 \f[B]\f[BI]Description:\f[B]\f[R] Executes \f[CR]R7_SITE_CONFIG\f[R] in
1244 the loaded environment
1246 \f[B]\f[BI]Usage:\f[B]\f[R]
1252 \f[B]\f[BI]Description:\f[B]\f[R] Returns a list of active nodes
1253 matching a list of grep REGEXES
1255 \f[B]\f[BI]Usage:\f[B]\f[R]
1261 \f[B]\f[BI]Description:\f[B]\f[R] Applies GROUPNAME functions (in prefix
1262 order) to the provided MEMBERS list
1264 \f[B]\f[BI]Usage:\f[B]\f[R]
1267 group GROUPNAME MEMBERS
1269 .SS group\-functions
1270 \f[B]\f[BI]Description:\f[B]\f[R] Returns a list of functions found in
1271 the specified GROUPNAME
1273 \f[B]\f[BI]Usage:\f[B]\f[R]
1276 group\-functions GROUPNAME
1279 \f[B]\f[BI]Description:\f[B]\f[R] Sets the current PREFIX for matching
1282 \f[B]\f[BI]Usage:\f[B]\f[R]
1287 .SS Text output functions
1311 \f[B]\f[BI]Description:\f[B]\f[R] Dumps R7_RUNDIR to R7_OUTPUTDIR
1313 \f[B]\f[BI]Usage:\f[B]\f[R]
1319 \f[B]\f[BI]Description:\f[B]\f[R] Returns a list of outputs from the
1322 \f[B]\f[BI]Usage:\f[B]\f[R]
1328 \f[B]\f[BI]Description:\f[B]\f[R] Returns a list of current dumped
1329 functions exit status codes
1331 \f[B]\f[BI]Usage:\f[B]\f[R]
1336 .SS output\-duration
1337 \f[B]\f[BI]Description:\f[B]\f[R] Returns a list of durations of
1340 \f[B]\f[BI]Usage:\f[B]\f[R]
1346 \f[B]\f[BI]Description:\f[B]\f[R] Shows the dumped output matching HOST,
1347 GROUPNAME, and FUNCTION (or any if unspecified)
1349 \f[B]\f[BI]Usage:\f[B]\f[R]
1352 output HOST GROUPNAME FUNCTION
1355 \f[B]\f[BI]Description:\f[B]\f[R] Returns the latest execution trace_id
1357 \f[B]\f[BI]Usage:\f[B]\f[R]
1363 \f[B]\f[BI]Description:\f[B]\f[R] Returns the diffs from the latest
1366 \f[B]\f[BI]Usage:\f[B]\f[R]
1371 .SS output\-permissions
1372 \f[B]\f[BI]Description:\f[B]\f[R] Returns the latest permission changes
1374 \f[B]\f[BI]Usage:\f[B]\f[R]
1380 \f[B]\f[BI]Description:\f[B]\f[R] Returns the latest errors detected
1382 \f[B]\f[BI]Usage:\f[B]\f[R]
1388 \f[B]\f[BI]Description:\f[B]\f[R] Produces a summary of errors, diffs,
1389 and permission outputs
1391 \f[B]\f[BI]Usage:\f[B]\f[R]
1400 digraph\-ssh\-id\-hosts
1404 \f[B]\f[BI]Description:\f[B]\f[R] Returns a directed graph (in DOT
1405 format) showing relations among groups, functions, and nodes
1407 \f[B]\f[BI]Usage:\f[B]\f[R]
1412 .SS digraph\-ssh\-id\-hosts
1413 \f[B]\f[BI]Description:\f[B]\f[R] Returns a directed graph (in DOT
1414 format) of relations between SSH IDs and hosts
1416 \f[B]\f[BI]Usage:\f[B]\f[R]
1419 digraph\-ssh\-id\-hosts
1425 \f[B]\f[BI]Description:\f[B]\f[R] Retunrs a report page with the content
1426 of \f[CR]README.md\f[R] in HTML format
1428 \f[B]\f[BI]Usage:\f[B]\f[R]
1439 \f[B]\f[BI]Description:\f[B]\f[R] Import configuration files from a
1442 \f[B]\f[BI]Usage:\f[B]\f[R]
1451 Supported shells are ksh93, oksh, yash and bash.
1453 Supported platforms are OpenBSD, FreeBSD, NetBSD and GNU/Linux.
1455 Busybox support is planned.
1457 Optional dependencies are openrsync, rsync, column, graphviz and pandoc.
1459 The HTML output is a work in progress.
1463 The provided group library is shared as additionnal examples of the
1464 documentation and contain the following third\-party files under the ISC
1466 Copyright information are indicated in the LICENSE section of related
1469 \f[CR]pf\-badhost.sh\f[R]
1471 \f[CR]unbound\-adblock.sh\f[R]
1473 \f[CR]http\-ban.sh\f[R]
1475 The project is shared under the terms of the ISC license.
1476 Any version previous \f[CR]0.1.0\f[R] needs to be considered obsolete
1477 and should not be redistributed.
1478 History in the GIT repository is kept for transparency purpose only.
1480 Below is a copy of the applicable license:
1485 Copyright 2025 xs <xs\[at]inda.re>
1487 Permission to use, copy, modify, and/or distribute this software for any
1488 purpose with or without fee is hereby granted, provided that the above
1489 copyright notice and this permission notice appear in all copies.
1491 THE SOFTWARE IS PROVIDED \[dq]AS IS\[dq] AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
1492 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
1493 FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
1494 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
1495 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
1496 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
1497 PERFORMANCE OF THIS SOFTWARE.