1Net::Remctl::Backend(3)User Contributed Perl DocumentatioNnet::Remctl::Backend(3)
2
3
4
6 Net::Remctl::Backend - Helper infrastructure for remctl backend
7 programs
8
10 use Net::Remctl::Backend;
11
12 my %commands = (
13 cmd1 => { code => \&run_cmd1 },
14 cmd2 => { code => \&run_cmd2 },
15 );
16 my $backend = Net::Remctl::Backend->new({
17 commands => \%commands,
18 });
19 exit $backend->run();
20
22 Net::Remctl::Backend provides a framework for remctl backend commands
23 (commands run by remctld). It can be configured with a list of
24 supported subcommands and handles all the command-line parsing and
25 syntax checking, dispatching the command to the appropriate sub if it
26 is valid.
27
29 new(CONFIG)
30 Create a new backend object with the given configuration. CONFIG
31 should be an anonymous hash with one or more of the following keys:
32
33 command
34 If set, defines the base remctl command implemented by this
35 backend. The primary use of this string is in usage and help
36 output. If set, it will be added to the beginning of each
37 command syntax description so that the help output will match
38 the remctl command that the user actually runs.
39
40 commands
41 The value of this key should be an anonymous hash describing
42 all of the commands that are supported. See below for the
43 supported keys in the command configuration.
44
45 help_banner
46 If set, the value will be displayed as the first line of help
47 output. Recommended best practice is to use a string of the
48 form:
49
50 <service> remctl help:
51
52 where <service> is something like "Event handling" or "User
53 database" or whatever this set of commands generally does or
54 manipulates.
55
56 The commands key, described above, takes a hash of properties for
57 each subcommand supported by this backend. The possible keys in
58 that hash are:
59
60 args_match
61 A reference to an array of regexes that must match the
62 arguments to this function. Each element of the array is
63 matched against the corresponding element in the array of
64 arguments, and if the corresponding regular expression does not
65 match, the command will be rejected with an error about an
66 invalid argument. Set the regular expression to undef to not
67 check the corresponding argument.
68
69 There is currently no way to check all arguments in commands
70 that take any number of arguments.
71
72 args_max
73 The maximum number of arguments. If there are more than this
74 number of arguments, run() will die with an error message
75 without running the command.
76
77 args_min
78 The minimum number of arguments. If there are fewer than this
79 number of arguments, run() will die with an error message
80 without running the command.
81
82 code
83 A reference to the sub that implements this command. This sub
84 will be called with the arguments passed on the command line as
85 its arguments (possibly preceded by the options hash if the
86 "options" parameter is set as described below). It should
87 return the exit status that should be used by the backend as a
88 whole: 0 for success and some non-zero value for an error
89 condition. This sub should print to STDOUT and STDERR to
90 communicate back to the remctl client.
91
92 nested
93 If set, indicates that this is a nested command. The value
94 should be a nested hash of command definitions, the same as the
95 parameter to the "commands" argument to new(). When this is
96 set, the first argument to this command is taken to be a
97 subcommand name, which is looked up in the hash. All of the
98 hash parameters are interpreted the same as if it were a top-
99 level command.
100
101 If this command is called without any arguments, behavior
102 varies based on whether the "code" parameter is also set
103 alongside the "nested" parameter. If "code" is set, the
104 command is called normally, with no arguments. If "code" is
105 not set, calling this command without a subcommand is treated
106 as an unknown command.
107
108 options
109 A reference to an array of Getopt::Long option specifications.
110 If this setting is present, the arguments passed to run() will
111 be parsed by Getopt::Long using this option specification
112 first, before any other option processing (including checking
113 for minimum and maximum numbers of arguments, checking the
114 validity of arguments, or replacing arguments with data from
115 standard input). The result of parsing options will be passed,
116 as a reference to a hash, as the first argument to the code
117 that implements this command, with all remaining arguments
118 passed as the subsequent arguments.
119
120 For example, if this is set to "['help|h', 'version|v']" and
121 the arguments passed to run() are:
122
123 command -hv foo bar
124
125 then the code implementing "command" will be called with the
126 following arguments:
127
128 { help => 1, version => 1 }, 'foo', 'bar'
129
130 Getopt::Long will always be configured with the options
131 "bundling", "no_ignore_case", and "require_order". This means,
132 among other things, that the first non-option argument will
133 stop option parsing and all remaining arguments will be passed
134 through verbatim.
135
136 If Getopt::Long rejects the options (due to an unknown option
137 or an invalid argument to an option, for example), run() will
138 die with the error message from Getopt::Long without running
139 the command.
140
141 stdin
142 Specifies that one argument to this function should be read
143 from standard input. All of the data on standard input until
144 end of file will be read into memory, and that data will become
145 the argument number given by the value of this key is the
146 argument (based at 1). So if this property is set to 1, the
147 first argument will be the data from standard input, and any
148 other arguments will be shifted down accordingly. The value
149 may be -1, in which case the data from standard input will
150 become the last argument, no matter how many arguments there
151 currently are.
152
153 Checks for the number of arguments and for the validity of
154 arguments with regular expression verification are done after
155 reading the data from standard input and transforming the
156 argument list accordingly.
157
158 summary
159 The summary of what this subcommand does, as text. Ideally,
160 this should fit on the same line with the syntax after the help
161 output has been laid out in columns. If it is too long to fit,
162 it will be wrapped, with each subsequent line indented to the
163 column where the summaries start.
164
165 If this key is omitted, the subcommand will still be shown in
166 help output, provided that it has a syntax key, but without any
167 trailing summary.
168
169 syntax
170 The syntax of this subcommand. This should be short, since it
171 needs to fit on the same line as the summary of what this
172 subcommand does. Both the command and subcommand should be
173 omitted; the former will be set by the command parameter to the
174 new() constructor for Net::Remctl::Backend, and the latter will
175 come from the command itself. A typical example will look
176 like:
177
178 syntax => '<object>'
179
180 which will result in help output (assuming command is set to
181 "object" and this parameter is set on the "delete" command)
182 that looks like:
183
184 object delete <object>
185
186 Use abbreviations heavily to keep this string short so that the
187 help output will remain readable.
188
189 Set this key to the empty string to indicate that this
190 subcommand takes no arguments or flags.
191
192 If this key is omitted, the subcommand will be omitted from
193 help output.
194
196 help()
197 Returns the formatted help summary for the commands supported by
198 this backend. This is the same as would be printed to standard
199 output in response to the command "help" with no arguments. The
200 output will consist of the syntax and summary attributes for each
201 command that has a syntax attribute defined, as described above
202 under the command specification. It will be wrapped to 80 columns.
203
204 run([COMMAND[, ARG ...]])
205 Parse the command line and perform the appropriate action. The
206 return value will be the return value of the command run (if any),
207 which should be the exit status that the backend script should use.
208
209 The command (which is the remctl subcommand) and arguments can be
210 passed directly to run() as parameters. If no arguments are
211 passed, run() expects @ARGV to contain the parameters passed to the
212 backend script. Either way the first argument will be the
213 subcommand, used to find the appropriate command to run, and any
214 remaining arguments will be arguments to that command. (Note that
215 if the "options" parameter is set, the first argument passed to the
216 underlying command will be the options hash.)
217
218 If there are errors in the parameters to the command, run() will
219 die with an appropriate error message.
220
222 Since Net::Remctl::Backend is designed to handle command line parsing
223 for a script and report appropriate errors if there are problems with
224 the argument, its run() method may die with various errors. The
225 possible errors are listed below. All will be terminated with a
226 newline so the Perl context information won't be appended.
227
228 %s: insufficient arguments
229 The given command was configured with a "args_min" parameter, and
230 the user passed in fewer arguments than that.
231
232 %s: invalid argument: %s
233 The given argument to the given command failed to match a regular
234 expression that was set with an "args_match" parameter.
235
236 %s: too many arguments
237 The given command was configured with a "args_max" parameter, and
238 the user passed in more arguments than that.
239
241 This module was added in the 3.4 release of remctl. Since 3.5, the
242 module version matches the remctl version but with a leading zero added
243 so that the minor version always has two numbers (so
244 Net::Remctl::Backend 3.05 was included in remctl 3.5).
245
246 All currently-supported methods and options have been supported since
247 the original release of the module.
248
250 There is no way to check all arguments with a regex when the command
251 supports any number of arguments.
252
254 Russ Allbery <eagle@eyrie.org>
255
257 Copyright 2019-2020 Russ Allbery <eagle@eyrie.org>
258
259 Copyright 2012-2014 The Board of Trustees of the Leland Stanford Junior
260 University
261
262 Permission is hereby granted, free of charge, to any person obtaining a
263 copy of this software and associated documentation files (the
264 "Software"), to deal in the Software without restriction, including
265 without limitation the rights to use, copy, modify, merge, publish,
266 distribute, sublicense, and/or sell copies of the Software, and to
267 permit persons to whom the Software is furnished to do so, subject to
268 the following conditions:
269
270 The above copyright notice and this permission notice shall be included
271 in all copies or substantial portions of the Software.
272
273 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
274 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
275 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
276 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
277 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
278 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
279 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
280
282 remctld(8)
283
284 The current version of this module is available from its web page at
285 <https://www.eyrie.org/~eagle/software/remctl/>.
286
287
288
289perl v5.34.0 2022-01-27 Net::Remctl::Backend(3)