… | |
… | |
16 | aemp trace <nodeid> # trace the network topology |
16 | aemp trace <nodeid> # trace the network topology |
17 | |
17 | |
18 | # run a node |
18 | # run a node |
19 | aemp run initialise_args... # run a node |
19 | aemp run initialise_args... # run a node |
20 | |
20 | |
21 | # node configuration: protocol endpoints |
21 | # node configuration: node ID |
22 | aemp setnodeid <nodeid> # configure the real node id |
22 | aemp setnodeid <nodeid> # configure the real node id |
23 | aemp delnodeid # reset node id to default (= inherit) |
23 | aemp delnodeid # reset node id to default (= inherit) |
24 | |
24 | |
25 | # node configuration: secret |
25 | # node configuration: secret |
26 | aemp gensecret # generate a random shared secret |
26 | aemp gensecret # generate a random shared secret |
… | |
… | |
58 | |
58 | |
59 | =head1 DESCRIPTION |
59 | =head1 DESCRIPTION |
60 | |
60 | |
61 | With aemp you can configure various aspects of AnyEvent::MP and its |
61 | With aemp you can configure various aspects of AnyEvent::MP and its |
62 | protocol, send various messages and even run a node. |
62 | protocol, send various messages and even run a node. |
|
|
63 | |
|
|
64 | The F<aemp> utility works like F<cvs>, F<svn> or other commands: the first |
|
|
65 | argument defines which operation (subcommand) is requested, after which |
|
|
66 | arguments for this operation are expected. When a subcommand does not eat |
|
|
67 | all remaining arguments, the remaining arguments will again be interpreted |
|
|
68 | as subcommand and so on. |
|
|
69 | |
|
|
70 | This means you can chain multiple commands, which is handy for profile |
|
|
71 | configuration, e.g.: |
|
|
72 | |
|
|
73 | aemp gensecret profile xyzzy setbinds 4040,4041 setnodeid anon/ |
|
|
74 | |
|
|
75 | =head2 RUNNING A NODE |
|
|
76 | |
|
|
77 | This can be used to run a node - together with some services, this makes |
|
|
78 | it unnecesary to write any wrapper programs. |
|
|
79 | |
|
|
80 | =over 4 |
|
|
81 | |
|
|
82 | =item run <profile> <...> |
|
|
83 | |
|
|
84 | Runs a node by calling C<AnyEvent::MP::initialise_node> with the given |
|
|
85 | arguments. The node runs under L<AnyEvent::Watchdog>, can be restarted |
|
|
86 | (and autorestarted, see the L<AnyEvent::Watchdog> manual). |
|
|
87 | |
|
|
88 | Care has been taken to load (almost) no modules other than |
|
|
89 | L<AnyEvent::Watchdog> and the modules it loads, so everything (including |
|
|
90 | the L<AnyEvent::MP> modules themselves) will be freshly loaded on restart, |
|
|
91 | which makes upgrading everything except the perl binary easy. |
|
|
92 | |
|
|
93 | =back |
|
|
94 | |
|
|
95 | =head2 PROTOCOL COMMANDS |
|
|
96 | |
|
|
97 | These commands actually communicate with other nodes. They all use a node |
|
|
98 | profile name of L<anon/> currently. |
|
|
99 | |
|
|
100 | They all use a timeout of five seconds, after which they give up. |
|
|
101 | |
|
|
102 | =over 4 |
|
|
103 | |
|
|
104 | =item snd <port> <arguments...> |
|
|
105 | |
|
|
106 | Simply send a message to the given port - where you get the port ID from |
|
|
107 | is your problem. |
|
|
108 | |
|
|
109 | Exits after ensuring that the message has been delivered to its node. |
|
|
110 | |
|
|
111 | Most useful to take avdantage of some undocumented functionality inside |
|
|
112 | nodes, such as node ports being able to call any method: |
|
|
113 | |
|
|
114 | aemp snd doomed AnyEvent::Watchdog::restart 1 |
|
|
115 | |
|
|
116 | =item rpc <port> <arg...> |
|
|
117 | |
|
|
118 | Like F<aemp snd>, but appends a local reply port to the message and waits |
|
|
119 | for a message to it. |
|
|
120 | |
|
|
121 | Any return values will be JSON-encoded and printed separated by commas |
|
|
122 | (kind of like a JSON array without []-brackets). |
|
|
123 | |
|
|
124 | Example: ask the (undocumented) time service of a node for it'S current |
|
|
125 | time. |
|
|
126 | |
|
|
127 | aemp rpc mynode time |
|
|
128 | |
|
|
129 | =item mon <port> |
|
|
130 | |
|
|
131 | Monitors the port and exits when it's monitorign callback is called. Most |
|
|
132 | useful to monitor node ports. |
|
|
133 | |
|
|
134 | Example: monitor some node. |
|
|
135 | |
|
|
136 | aemp mon doomed |
|
|
137 | |
|
|
138 | =item eval <node> <expr...> |
|
|
139 | |
|
|
140 | Joins all remaining arguments into a string and evaluates it on the given |
|
|
141 | node. Return values are handled as with F<aemp rpc>. |
|
|
142 | |
|
|
143 | Example: find the unix process ID of the node called posicks. |
|
|
144 | |
|
|
145 | aemp eval posicks '$$' |
|
|
146 | |
|
|
147 | =item trace <node> |
|
|
148 | |
|
|
149 | Asks the given node for all currently connected nodes, then asks those |
|
|
150 | nodes for the same, thus tracing all node connections. |
|
|
151 | |
|
|
152 | =cut |
|
|
153 | |
|
|
154 | =head2 CONFIGURATION/NODE ID/SECRET/CERTIFICATE |
|
|
155 | |
|
|
156 | These commands deal with rather basic settings, the node ID, the shared |
|
|
157 | secret and the TLS certificate. |
|
|
158 | |
|
|
159 | =over 4 |
|
|
160 | |
|
|
161 | =item setnodeid <nodeid> |
|
|
162 | |
|
|
163 | Set the node ID to the given string. |
|
|
164 | |
|
|
165 | =item delnodeid |
|
|
166 | |
|
|
167 | Removes the node ID again, which means it is inherited again from it's |
|
|
168 | parent profile, or stays unset. |
|
|
169 | |
|
|
170 | =item gensecret |
|
|
171 | |
|
|
172 | Generates a random shared secret and sets it. The shared secret is used to |
|
|
173 | authenticate nodes to each other when TLS is not required. |
|
|
174 | |
|
|
175 | =item setsecret <secret> |
|
|
176 | |
|
|
177 | Sets the shared secret tot he given string, which can be anything. |
|
|
178 | |
|
|
179 | =item delsecret |
|
|
180 | |
|
|
181 | Removes the shared secret again, which means it is inherited again from |
|
|
182 | it's parent profile, or stays unset. |
|
|
183 | |
|
|
184 | =item gencert |
|
|
185 | |
|
|
186 | Generates a self-signed certficate and key, and sets it. This works |
|
|
187 | similarly to a shared secret: when all nodes have it, TLS will be used to |
|
|
188 | authenticate and encrypt all traffic. |
|
|
189 | |
|
|
190 | =item setcert <file> |
|
|
191 | |
|
|
192 | Set a node certificate (and optionally any CA certificates) from the given |
|
|
193 | file. The file must contain the key, followed by the certificate, followed |
|
|
194 | by any CA certificates you want to trust, all in PEM format. |
|
|
195 | |
|
|
196 | See L<AnyEvent::TLS> for some more details - this sets the C<cert> and |
|
|
197 | C<ca_cert> options. |
|
|
198 | |
|
|
199 | =item delcert |
|
|
200 | |
|
|
201 | Removes the certificate(s) again, which means it is inherited again from |
|
|
202 | it's parent profile, or stays unset. |
|
|
203 | |
|
|
204 | =back |
|
|
205 | |
|
|
206 | =head2 CONFIGURATION/SEEDS |
|
|
207 | |
|
|
208 | To discover the network you have to specify some seed addresses, which are |
|
|
209 | basically C<host:port> pairs where you expect some long-running nodes. It |
|
|
210 | does no harm to have a node as its own seed (they will eventually be |
|
|
211 | ignored). |
|
|
212 | |
|
|
213 | =item setseeds <host:port>,... |
|
|
214 | |
|
|
215 | Sets or replaces the list of seeds, which must be specified as a |
|
|
216 | comma-separated list of C<host:port> pairs. The C<host> can be a hostname, |
|
|
217 | an IP address, or C<*> to signify all local host addresses. If the |
|
|
218 | C<:port> is omitted, then the default port of C<4040> is assumed. |
|
|
219 | |
|
|
220 | An empty list is allowed. |
|
|
221 | |
|
|
222 | Example: use C<doomed> with default port as only seednode. |
|
|
223 | |
|
|
224 | aemp setseeds doomed |
|
|
225 | |
|
|
226 | =item delseeds |
|
|
227 | |
|
|
228 | Removes the seed list again, which means it is inherited again from it's |
|
|
229 | parent profile, or stays unset. |
|
|
230 | |
|
|
231 | =item addseed <host:port> |
|
|
232 | |
|
|
233 | Adds a single seed address. |
|
|
234 | |
|
|
235 | =item delseed <host:port> |
|
|
236 | |
|
|
237 | Deletes the given seed address, if it exists. |
|
|
238 | |
|
|
239 | =back |
|
|
240 | |
|
|
241 | =head2 CONFIGURATION/BINDS |
|
|
242 | |
|
|
243 | To be able to be reached from other nodes, a node must I<bind> itself |
|
|
244 | to some listening socket(s). The list of these can either bs specified |
|
|
245 | manually, or AnyEvent::MP can guess them. Nodes without any binds are |
|
|
246 | possible to some extent. |
|
|
247 | |
|
|
248 | =over 4 |
|
|
249 | |
|
|
250 | =item setbinds <host:port>,... |
|
|
251 | |
|
|
252 | Sets the list of bind addresses explicitly - see the F<aemp setseeds> |
|
|
253 | command for the exact syntax. In addition, a value of C<0> for the port |
|
|
254 | means to use a dynamically-assigned port. |
|
|
255 | |
|
|
256 | Note that the C<*>, C<*:0> or C<*:port> values are very useful here. |
|
|
257 | |
|
|
258 | Example: bind on the default port (4040) on all local interfaces. |
|
|
259 | |
|
|
260 | aemp setbinds "*" |
|
|
261 | |
|
|
262 | Example: bind on a random port on all local interfaces. |
|
|
263 | |
|
|
264 | aemp setbinds "*:0" |
|
|
265 | |
|
|
266 | Example: resolve "doomed.mydomain" and try to bind on port C<4040> of all |
|
|
267 | IP addressess returned. |
|
|
268 | |
|
|
269 | aep setbinds doomed.mydomain |
|
|
270 | |
|
|
271 | =item delbinds |
|
|
272 | |
|
|
273 | Removes the bind list again, which means it is inherited again from it's |
|
|
274 | parent profile, or stays unset. |
|
|
275 | |
|
|
276 | =item addbind <host:port> |
|
|
277 | |
|
|
278 | Adds a single bind address. |
|
|
279 | |
|
|
280 | =item delbind <host:port> |
|
|
281 | |
|
|
282 | Deletes the given bind address, if it exists. |
|
|
283 | |
|
|
284 | =back |
|
|
285 | |
|
|
286 | =head2 CONFIGURATION/SERVICES |
|
|
287 | |
|
|
288 | Services are modules (or functions) that are automatically loaded (or |
|
|
289 | executed) when a node starts. They are especially useful when used in |
|
|
290 | conjunction with F<aemp run>, to configure which services a node should |
|
|
291 | run. |
|
|
292 | |
|
|
293 | =over 4 |
|
|
294 | |
|
|
295 | =item setservices <initfunc>... |
|
|
296 | |
|
|
297 | Sets or replaces the list of services, which must be specified as a |
|
|
298 | comma-separated list. |
|
|
299 | |
|
|
300 | Each entry in the list is interpreted as either a module name to |
|
|
301 | load (when it ends with C<::>) or a function to call (all other |
|
|
302 | cases). The algorithm to find the function is the same as used for C<< |
|
|
303 | L<AnyEvent::MP>::spawn >>. |
|
|
304 | |
|
|
305 | =item delservices |
|
|
306 | |
|
|
307 | Removes the service list again, which means it is inherited again from |
|
|
308 | it's parent profile, or stays unset. |
|
|
309 | |
|
|
310 | =item addservice <initfunc> |
|
|
311 | |
|
|
312 | Adds a single service. |
|
|
313 | |
|
|
314 | =item delservice <initfunc> |
|
|
315 | |
|
|
316 | Deletes the given service, if it exists. |
|
|
317 | |
|
|
318 | =back |
|
|
319 | |
|
|
320 | =head2 CONFIGURATION/PROFILE MANAGEMENT |
|
|
321 | |
|
|
322 | All the above configuration functions by default affect the I<global |
|
|
323 | default configuration>, which is basically used to augment every profile |
|
|
324 | and node configuration. |
|
|
325 | |
|
|
326 | =over 4 |
|
|
327 | |
|
|
328 | =item profile <name> ... |
|
|
329 | |
|
|
330 | This subcommand makes the following subcommands act only on a specific |
|
|
331 | named profile, instead of on the global default. The profile is created if |
|
|
332 | necessary. |
|
|
333 | |
|
|
334 | Example: create a C<server> profile, give it a random node name, some seed |
|
|
335 | nodes and bind it on an unspecified port on all local interfaces. You |
|
|
336 | should add some services then and run the node... |
|
|
337 | |
|
|
338 | aemp server setnodeid anon/ setseeds doomed,10.0.0.2:5000 setbinds "*:0" |
|
|
339 | |
|
|
340 | =item delprofile <name> |
|
|
341 | |
|
|
342 | Deletes the profile of the given name. |
|
|
343 | |
|
|
344 | =item showprofile <name> |
|
|
345 | |
|
|
346 | Shows the values of the given profile, and only those, no inherited |
|
|
347 | values. |
|
|
348 | |
|
|
349 | =item showconfig <name> |
|
|
350 | |
|
|
351 | Shows the I<effective> config, i.e. the values as used by a node started with the given profile name. |
|
|
352 | |
|
|
353 | =back |
63 | |
354 | |
64 | =cut |
355 | =cut |
65 | |
356 | |
66 | use common::sense; |
357 | use common::sense; |
67 | |
358 | |
… | |
… | |
185 | my $cv = AE::cv; |
476 | my $cv = AE::cv; |
186 | my $to = AE::timer 5, 0, sub { $cv->("timeout") }; |
477 | my $to = AE::timer 5, 0, sub { $cv->("timeout") }; |
187 | snd $port, @ARGV, port { &$cv }; @ARGV = (); |
478 | snd $port, @ARGV, port { &$cv }; @ARGV = (); |
188 | mon $port, $cv; |
479 | mon $port, $cv; |
189 | |
480 | |
190 | print join " ", $cv->recv, "\n"; |
481 | print +(substr JSON::XS->new->encode ([$cv->recv]), 1, -1), "\n"; |
191 | }, |
482 | }, |
192 | |
483 | |
193 | mon => sub { |
484 | mon => sub { |
194 | my $port = shift @ARGV; |
485 | my $port = shift @ARGV; |
195 | initialise_node "anon/"; |
486 | initialise_node "anon/"; |
… | |
… | |
388 | |
679 | |
389 | sub docmd { |
680 | sub docmd { |
390 | my $cmd = shift @ARGV; |
681 | my $cmd = shift @ARGV; |
391 | |
682 | |
392 | $CMD{$cmd} |
683 | $CMD{$cmd} |
393 | or die "$cmd: no such aemp command (try man aemp)"; |
684 | or die "$cmd: no such aemp command (try perldoc aemp, or man aemp)"; |
394 | |
685 | |
395 | $CMD{$cmd}(); |
686 | $CMD{$cmd}(); |
396 | } |
687 | } |
397 | |
688 | |
398 | @ARGV |
689 | @ARGV |
399 | or die "Usage: aemp subcommand ... (try man aemp)\n"; |
690 | or die "Usage: aemp subcommand ... (try perldoc aemp, or man aemp)\n"; |
400 | |
691 | |
401 | docmd while @ARGV; |
692 | docmd while @ARGV; |
402 | |
693 | |
403 | |
694 | |