ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-MP/bin/aemp
Revision: 1.58
Committed: Fri Mar 23 00:38:14 2012 UTC (12 years, 2 months ago) by root
Branch: MAIN
Changes since 1.57: +22 -1 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.38 #!/opt/bin/perl
2 root 1.1
3     =head1 NAME
4    
5     aemp - AnyEvent:MP utility
6    
7     =head1 SYNOPSIS
8    
9     aemp command args...
10    
11     # protocol commands
12 root 1.19 aemp snd <port> <arg...> # send a message
13     aemp mon <port> # wait till port is killed
14 root 1.41 aemp cal <port> <arg...> # send message, append reply
15 root 1.19 aemp eval <node> <expr...> # evaluate expression
16 root 1.42 aemp shell [<node>] # run an interactive shell
17 root 1.37 aemp trace <node> # trace the network topology
18 root 1.8
19     # run a node
20 root 1.26 aemp run configure_args... # run a node
21 root 1.37 aemp restart <node> # restart a node if running under watchdog
22 root 1.8
23 root 1.23 # node configuration: node ID
24 root 1.19 aemp setnodeid <nodeid> # configure the real node id
25     aemp delnodeid # reset node id to default (= inherit)
26 root 1.1
27 root 1.47 # node configuration: authentication
28 root 1.19 aemp gensecret # generate a random shared secret
29     aemp setsecret <secret> # set the shared secret
30     aemp delsecret # remove the secret (= inherit)
31     aemp gencert # generate a random certificate
32     aemp setcert <file> # set a certificate (key.pem + certificate.pem)
33     aemp delcert # remove certificate (= inherit)
34 root 1.8
35 root 1.17 # node configuration: seed addresses for bootstrapping
36 root 1.19 aemp setseeds <host:port>,... # set seeds
37     aemp delseeds # clear all seeds (= inherit)
38     aemp addseed <host:port> # add a seed
39     aemp delseed <host:port> # remove seed
40 root 1.17
41     # node configuration: bind addresses
42 root 1.19 aemp setbinds <host:port>,... # set binds
43     aemp delbinds # clear all binds (= inherit)
44     aemp addbind <host:port> # add a bind address
45     aemp delbind <host:port> # remove a bind address
46 root 1.8
47     # node configuration: services
48 root 1.19 aemp setservices initfunc,... # set service functions
49     aemp delservices # clear all services (= inherit)
50     aemp addservice <initfunc> # add an instance of a service
51     aemp delservice <initfunc> # delete one instance of a service
52 root 1.6
53 root 1.47 # profile management
54 root 1.10 aemp profile <name> <command>... # apply command to profile only
55 root 1.26 aemp setparent <name> # specify a parent profile
56 root 1.25 aemp delparent # clear parent again
57 root 1.19 aemp delprofile <name> # eradicate the named profile
58     aemp showprofile <name> # display given profile
59 root 1.25 aemp showconfig <name> ... # display effective config
60 root 1.10
61 root 1.47 # node configuration: low-level protocol
62 root 1.54 aemp [set|del]secure <boolean>
63 root 1.47 aemp [set|del]monitor_timeout <seconds>
64     aemp [set|del]connect_interval <seconds>
65     aemp [set|del]framing_format [array]
66     aemp [set|del]auth_offer [array]
67     aemp [set|del]auth_accept [array]
68     aemp [set|del]autocork <boolean>
69     aemp [set|del]nodelay <boolean>
70    
71 root 1.1 =head1 DESCRIPTION
72    
73 root 1.8 With aemp you can configure various aspects of AnyEvent::MP and its
74 root 1.22 protocol, send various messages and even run a node.
75 root 1.1
76 root 1.23 The F<aemp> utility works like F<cvs>, F<svn> or other commands: the first
77     argument defines which operation (subcommand) is requested, after which
78     arguments for this operation are expected. When a subcommand does not eat
79     all remaining arguments, the remaining arguments will again be interpreted
80     as subcommand and so on.
81    
82     This means you can chain multiple commands, which is handy for profile
83     configuration, e.g.:
84    
85 root 1.27 aemp gensecret profile xyzzy binds 4040,4041 nodeid anon/
86    
87     Please note that all C<setxxx> subcommands have an alias without the
88     C<set> prefix.
89 root 1.23
90 root 1.34 All configuration data is stored in a human-readable (JSON) config file
91 root 1.46 stored in F<~/.perl-anyevent-mp> (or F<%appdata%/perl-anyevent-mp> on
92 root 1.49 loser systems, or wherever C<$ENV{PERL_ANYEVENT_MP_RC}> points to). Feel
93 root 1.46 free to look at it or edit it, the format is relatively simple.
94 root 1.34
95 root 1.35 =head2 SPECIFYING ARGUMENTS
96    
97     Arguments can be specified just as with any other shell command, with a
98     few special cases:
99    
100     If the I<first> argument starts with a literal C<[>-character, then it is
101     interpreted as a UTF-8 encoded JSON text. The resulting array replaces all
102     arguments.
103    
104     Otherwise, if I<any> argument starts with one of C<[>, C<{> or C<">, then
105     it is interpreted as UTF-8 encoded JSON text (or a single value in case of
106     C<">), and the resulting reference or scalar replaces the argument.
107    
108     This allows you, for example, to specify binds in F<aemp run> (using POSIX
109     shell syntax):
110    
111     aemp run binds '["*:4040"]'
112    
113 root 1.23 =head2 RUNNING A NODE
114    
115     This can be used to run a node - together with some services, this makes
116 elmex 1.32 it unnecessary to write any wrapper programs.
117 root 1.23
118     =over 4
119    
120 root 1.30 =item run <configure_args>...
121 root 1.23
122 root 1.26 Runs a node by calling C<AnyEvent::MP::Kernel::configure> with the given
123 root 1.23 arguments. The node runs under L<AnyEvent::Watchdog>, can be restarted
124 root 1.30 (and autorestarted, see the L<AnyEvent::Watchdog> manual). A very common
125 root 1.33 invocation is to just specify a profile using the profile name
126 root 1.30
127 root 1.33 aemp run database-backend
128 root 1.30
129     ... but you can use most arguments that C<configure> understands:
130    
131     aemp run nodeid mynode2 profile someprofile
132 root 1.23
133     Care has been taken to load (almost) no modules other than
134     L<AnyEvent::Watchdog> and the modules it loads, so everything (including
135     the L<AnyEvent::MP> modules themselves) will be freshly loaded on restart,
136     which makes upgrading everything except the perl binary easy.
137    
138 root 1.37 =item restart <node>
139    
140     Restarts the node using C<AnyEvent::Watchdog::Util::restart>. This works
141     for nodes started by C<aemp run>, but also for any other node that uses
142     L<AnyEvent::Watchdog>.
143    
144 root 1.23 =back
145    
146     =head2 PROTOCOL COMMANDS
147    
148     These commands actually communicate with other nodes. They all use a node
149 elmex 1.32 profile name of C<aemp> (specifying a default node ID of C<anon/> and a
150 root 1.25 binds list containing C<*:*> only).
151 root 1.23
152     They all use a timeout of five seconds, after which they give up.
153    
154     =over 4
155    
156     =item snd <port> <arguments...>
157    
158     Simply send a message to the given port - where you get the port ID from
159     is your problem.
160    
161     Exits after ensuring that the message has been delivered to its node.
162    
163 elmex 1.32 Most useful to take advantage of some undocumented functionality inside
164 root 1.23 nodes, such as node ports being able to call any method:
165    
166     aemp snd doomed AnyEvent::Watchdog::restart 1
167    
168 root 1.41 =item cal <port> <arg...>
169 root 1.23
170 root 1.41 Like F<aemp cal>: appends a local reply port to the message and waits for
171     a message to it.
172 root 1.23
173     Any return values will be JSON-encoded and printed separated by commas
174     (kind of like a JSON array without []-brackets).
175    
176 root 1.41 Example: ask the (undocumented) time service of a node for its current
177 root 1.23 time.
178    
179 root 1.41 aemp cal mynode time
180 root 1.23
181     =item mon <port>
182    
183     Monitors the port and exits when it's monitorign callback is called. Most
184     useful to monitor node ports.
185    
186     Example: monitor some node.
187    
188     aemp mon doomed
189    
190     =item eval <node> <expr...>
191    
192     Joins all remaining arguments into a string and evaluates it on the given
193 root 1.41 node. Return values are handled as with F<aemp cal>.
194 root 1.23
195     Example: find the unix process ID of the node called posicks.
196    
197     aemp eval posicks '$$'
198    
199     =item trace <node>
200    
201     Asks the given node for all currently connected nodes, then asks those
202     nodes for the same, thus tracing all node connections.
203    
204 root 1.31 =back
205 root 1.23
206     =head2 CONFIGURATION/NODE ID/SECRET/CERTIFICATE
207    
208     These commands deal with rather basic settings, the node ID, the shared
209     secret and the TLS certificate.
210    
211     =over 4
212    
213     =item setnodeid <nodeid>
214    
215 root 1.50 Set the node ID to the given string. If it ends with a slash (C</>), then
216     a random string is appended to make it unique.
217    
218     If no nodeid is specified in any profile, then the profile name, plus
219     appended slash, is used.
220 root 1.23
221     =item delnodeid
222    
223     Removes the node ID again, which means it is inherited again from it's
224     parent profile, or stays unset.
225    
226     =item gensecret
227    
228 root 1.51 Generates a random shared secret (currently 1071 bits) and sets it. The
229     shared secret is used to authenticate nodes to each other when TLS is not
230     required.
231 root 1.23
232     =item setsecret <secret>
233    
234 root 1.51 Sets the shared secret to the given string, which can be anything.
235 root 1.23
236     =item delsecret
237    
238     Removes the shared secret again, which means it is inherited again from
239     it's parent profile, or stays unset.
240    
241     =item gencert
242    
243 elmex 1.32 Generates a self-signed certificate and key, and sets it. This works
244 root 1.23 similarly to a shared secret: when all nodes have it, TLS will be used to
245     authenticate and encrypt all traffic.
246    
247     =item setcert <file>
248    
249     Set a node certificate (and optionally any CA certificates) from the given
250     file. The file must contain the key, followed by the certificate, followed
251     by any CA certificates you want to trust, all in PEM format.
252    
253     See L<AnyEvent::TLS> for some more details - this sets the C<cert> and
254     C<ca_cert> options.
255    
256     =item delcert
257    
258     Removes the certificate(s) again, which means it is inherited again from
259     it's parent profile, or stays unset.
260    
261     =back
262    
263     =head2 CONFIGURATION/SEEDS
264    
265     To discover the network you have to specify some seed addresses, which are
266     basically C<host:port> pairs where you expect some long-running nodes. It
267     does no harm to have a node as its own seed (they will eventually be
268     ignored).
269    
270 root 1.31 =over 4
271    
272 root 1.23 =item setseeds <host:port>,...
273    
274     Sets or replaces the list of seeds, which must be specified as a
275     comma-separated list of C<host:port> pairs. The C<host> can be a hostname,
276 root 1.36 an IP address, or C<*> to signify all local host addresses (which makes
277     little sense for seeds, outside some examples, but a lot of sense for
278     binds).
279 root 1.23
280     An empty list is allowed.
281    
282     Example: use C<doomed> with default port as only seednode.
283    
284     aemp setseeds doomed
285    
286     =item delseeds
287    
288     Removes the seed list again, which means it is inherited again from it's
289     parent profile, or stays unset.
290    
291     =item addseed <host:port>
292    
293     Adds a single seed address.
294    
295     =item delseed <host:port>
296    
297     Deletes the given seed address, if it exists.
298    
299     =back
300    
301     =head2 CONFIGURATION/BINDS
302    
303     To be able to be reached from other nodes, a node must I<bind> itself
304     to some listening socket(s). The list of these can either bs specified
305     manually, or AnyEvent::MP can guess them. Nodes without any binds are
306     possible to some extent.
307    
308     =over 4
309    
310     =item setbinds <host:port>,...
311    
312     Sets the list of bind addresses explicitly - see the F<aemp setseeds>
313 root 1.36 command for the exact syntax. In addition, a value of C<*> for the port,
314     or not specifying a port, means to use a dynamically-assigned port.
315 root 1.23
316 root 1.36 Note that the C<*>, C<*:*> or C<*:port> patterns are very useful here.
317 root 1.23
318 root 1.36 Example: bind on a ephemeral port on all local interfaces.
319 root 1.23
320     aemp setbinds "*"
321    
322     Example: bind on a random port on all local interfaces.
323    
324 root 1.25 aemp setbinds "*:*"
325 root 1.23
326     Example: resolve "doomed.mydomain" and try to bind on port C<4040> of all
327     IP addressess returned.
328    
329 root 1.36 aep setbinds doomed.mydomain:4040
330 root 1.23
331     =item delbinds
332    
333     Removes the bind list again, which means it is inherited again from it's
334     parent profile, or stays unset.
335    
336     =item addbind <host:port>
337    
338     Adds a single bind address.
339    
340     =item delbind <host:port>
341    
342     Deletes the given bind address, if it exists.
343    
344     =back
345    
346     =head2 CONFIGURATION/SERVICES
347    
348     Services are modules (or functions) that are automatically loaded (or
349     executed) when a node starts. They are especially useful when used in
350     conjunction with F<aemp run>, to configure which services a node should
351     run.
352    
353 root 1.47 Despite the daunting name, services really I<are> nothing more than a
354     module name or a function name with arguments. The "service" aspect comes
355     only from the behaviour of the module or function, which is supposed to
356     implement, well, some kind of service for the node, network etc.
357    
358     Instead of writing a standalone program for each different node type in
359     your network, you can simply put your code into a module, and then let the
360     configuration decide which node runs which "services". This also makes it
361     easy to combine multiple different services within the same node.
362    
363 root 1.23 =over 4
364    
365     =item setservices <initfunc>...
366    
367     Sets or replaces the list of services, which must be specified as a
368 root 1.37 comma-separated list or a JSON array.
369    
370     Each string entry in the list is interpreted as either a module name to
371     load (when it ends with C<::>) or a function to call (all other cases).
372    
373     Each entry which is an array itself (you need to use JSON format to
374     specify those) is interpreted as a function name and the arguments to
375     pass.
376 root 1.23
377 root 1.37 The algorithm to find the function is the same as used for C<<
378 root 1.23 L<AnyEvent::MP>::spawn >>.
379    
380 root 1.58 Example: run the global service.
381 root 1.37
382     aemp setservices AnyEvent::MP::Global::
383    
384     Example: call the mymod::myfun function with arguments 1, 2 and 3.
385    
386     aemp setservices '[["mymod::myfun", 1,2,3]]'
387    
388 root 1.23 =item delservices
389    
390     Removes the service list again, which means it is inherited again from
391     it's parent profile, or stays unset.
392    
393     =item addservice <initfunc>
394    
395     Adds a single service.
396    
397     =item delservice <initfunc>
398    
399     Deletes the given service, if it exists.
400    
401 root 1.58 =item seteval <string>
402    
403     Sometimes, all you need is to evaluate a small perl snippet to bring a
404     node up. This sets a perl string that is eval'ed after the node has been
405     configured.
406    
407     =item deleval
408    
409     Delete any eval string set with seteval.
410    
411 root 1.23 =back
412    
413     =head2 CONFIGURATION/PROFILE MANAGEMENT
414    
415     All the above configuration functions by default affect the I<global
416     default configuration>, which is basically used to augment every profile
417     and node configuration.
418    
419     =over 4
420    
421     =item profile <name> ...
422    
423     This subcommand makes the following subcommands act only on a specific
424     named profile, instead of on the global default. The profile is created if
425     necessary.
426    
427     Example: create a C<server> profile, give it a random node name, some seed
428     nodes and bind it on an unspecified port on all local interfaces. You
429     should add some services then and run the node...
430    
431 root 1.30 aemp profile server nodeid anon/ seeds doomed,10.0.0.2:5000 binds "*:*"
432 root 1.23
433     =item delprofile <name>
434    
435     Deletes the profile of the given name.
436    
437 root 1.26 =item setparent <name>
438 root 1.24
439     Sets the parent profile to use - values not specified in a profile will be
440     taken from the parent profile (even recursively, with the global default
441     config being the default parent). This is useful to configure profile
442     I<classes> and then to inherit from them for individual nodes.
443    
444     Note that you can specify circular parent chains and even a parent for the
445     global configuration. Neither will do you any good, however.
446    
447     Example: inherit all values not specified in the C<doomed> profile from
448     the C<server> profile.
449    
450 root 1.26 aemp profile doomed setparent server
451 root 1.24
452     =item delparent
453    
454     Removes the parent again from the profile, if any was set, so the profile
455     inherits directly from the global default config again.
456    
457 root 1.23 =item showprofile <name>
458    
459     Shows the values of the given profile, and only those, no inherited
460     values.
461    
462 root 1.25 =item showconfig <name> <key value...>
463 root 1.23
464 root 1.24 Shows the I<effective> config, i.e. the values as used by a node started
465 root 1.25 with the given profile name. Any additional key-value pairs specified
466 root 1.26 augment the configuration, just as with C<configure>.
467 root 1.24
468 root 1.25 If all arguments are omitted, show the global default config.
469 root 1.23
470     =back
471    
472 root 1.47 =head2 LOW-LEVEL TRANSPORT PROTOCOL
473    
474     The low-level transport protocol betwene two nodes also has a number of
475     configurable options, most of which should not be touched unless you know
476     what you are doing.
477    
478     =over 4
479    
480 root 1.54 =item [set|del]secure <boolean>
481    
482     Normally, nodes allow anything to be done to them by remote nodes,
483     including remotely-triggered execution of code.
484    
485     Sometimes a more secure mode is desired - this can be achieved by setting
486     the secure option to a true value.
487    
488 root 1.56 When secure mode is enabled, then the node will not execute code locally,
489     at least not via the normal node protocol. All other messages are still
490     allowed. This means remote nodes can monitor, kill or local ports (port
491     names can be easily guessed). Specifically, note that the very common
492     "send me a list that I prepend to my reply message" idiom can easily
493     be used to subvert this security mechanism by asking a trusted node to
494     "reply" to some other message.
495 root 1.54
496 root 1.56 At the moment, this setting affects C<snd_on>, C<eval_on> and C<spawn>
497 root 1.55 functionality.
498 root 1.54
499     The C<configure> function additionally allows you to specify a callback
500     that can grant or suppress such requests on a per-node basis.
501    
502 root 1.47 =item [set|del]monitor_timeout <seconds>
503    
504     Sets the default monitor timeout, that is, when a connection to a node
505     cannot be established within this many seconds, the node is declared
506     unreachable and all monitors will fire.
507    
508     C<30> seconds are usually a good time span for this.
509    
510     =item [set|del]connect_interval <seconds>
511    
512     When a connection cannot be established successfully within this many
513     seconds, try the next transport address (e.g. the next IP address). If
514     your nodes have a lot of transports, you might have to set this to a low
515     value so that they will actually all be tried within the monitor timeout
516     interval.
517    
518     C<2> is usually a good value, unless you live in new zealand.
519    
520     =item [set|del]framing_format [array]
521    
522     Configures the list of framing formats offered to the other side. This is
523     simply a list of formatted read/write types used with L<AnyEvent::Handle>,
524     in order of decreasing preference.
525    
526     Nodes support both C<json> and C<storable> framing formats for data
527     packets out of the box, and usually choose C<json> because it is first in
528     the list.
529    
530     Example: prefer the C<My::Personal::Format> framing format over JSON over
531     Storable.
532    
533     aemp setframing_format '["My::Personal::Format", "json", "storable"]'
534    
535     =item [set|del]auth_offer [array]
536    
537     Configures the list of authentication types that the node offers to the
538     other side as acceptable, in order of decreasing preference. Only auth
539     methods that the node can actually support will be offered.
540    
541     The default is '["tls_md6_64_256", "hmac_md6_64_256"]' and is usually good
542     enough.
543    
544     =item [set|del]auth_accept [array]
545    
546     Configures the list of authentication types that remote nodes can use to
547     authenticate, in order of decreasing preference.
548    
549     The default is '["tls_md6_64_256", "hmac_md6_64_256", "tls_anon",
550     "cleartext"]' and is usually good enough.
551    
552     =item [set|del]autocork <boolean>
553    
554     Sets the default C<autocork> option value for the L<AnyEvent::Handle>
555     object used by transports. By default, autocorking is off.
556    
557     =item [set|del]nodelay <boolean>
558    
559     Sets the default C<nodelay> option value for the L<AnyEvent::Handle>
560     object used by transports. By default, nodelay is on.
561    
562     =back
563    
564 root 1.1 =cut
565    
566     use common::sense;
567    
568 root 1.19 # should come before anything else, so all modules
569     # will be loaded on each restart
570 root 1.22 BEGIN {
571 root 1.35 if (@ARGV == 1 && $ARGV[0] =~ /^\[/) {
572     require JSON::XS;
573     @ARGV = @{ JSON::XS->new->utf8->decode (shift) };
574     } else {
575     for (@ARGV) {
576     if (/^[\[\{\"]/) {
577     require JSON::XS;
578     $_ = JSON::XS->new->utf8->allow_nonref->decode ($_);
579     }
580     }
581     }
582    
583 root 1.8 if ($ARGV[0] eq "run") {
584     shift;
585    
586 root 1.13 # d'oh
587 root 1.22 require AnyEvent::Watchdog;
588 root 1.48 # only now can we load additional modules
589    
590     require AnyEvent;
591 root 1.19
592 root 1.29 require AnyEvent::Watchdog::Util;
593     AnyEvent::Watchdog::Util::autorestart (1);
594     AnyEvent::Watchdog::Util::heartbeat (300);
595 root 1.13
596 root 1.25 require AnyEvent::MP::Kernel;
597 root 1.26 AnyEvent::MP::Kernel::configure (@ARGV);
598 root 1.8
599 root 1.16 AnyEvent::detect () eq "AnyEvent::Impl::EV"
600 root 1.8 ? EV::loop ()
601     : AE::cv ()->recv;
602     }
603 root 1.22 }
604 root 1.8
605 root 1.1 use Carp ();
606    
607 root 1.17 use JSON::XS;
608    
609 root 1.1 use AnyEvent;
610 root 1.4 use AnyEvent::Util;
611    
612 root 1.8 use AnyEvent::MP;
613 root 1.1 use AnyEvent::MP::Config;
614    
615     sub my_run_cmd {
616     my ($cmd) = @_;
617    
618     my $cv = &run_cmd;
619     my $status = $cv->recv;
620    
621     $status
622     and die "@$cmd: command failed with exit status $status.";
623     }
624    
625     sub gen_cert {
626 root 1.2 my_run_cmd [qw(openssl req
627     -new -nodes -x509 -days 3650
628     -newkey rsa:2048 -keyout /dev/fd/3
629     -batch -subj /CN=AnyEvent::MP
630     )],
631 root 1.5 "<", "/dev/null",
632 root 1.1 ">" , \my $cert,
633     "3>", \my $key,
634 root 1.4 "2>", "/dev/null";
635 root 1.1
636     "$cert$key"
637     }
638    
639 root 1.25 sub init {
640 root 1.53 configure profile => "aemp", nodeid => "aemp/%n/%u";
641 root 1.25 }
642    
643 root 1.10 our $cfg = AnyEvent::MP::Config::config;
644 root 1.8 our $profile = $cfg;
645 root 1.1
646 root 1.11 sub trace {
647 root 1.56 my ($seed) = @_;
648 root 1.11 my $cv = AE::cv;
649     my %seen;
650 root 1.57 my $exit;
651 root 1.11
652 root 1.57 my %to;
653 root 1.11
654 root 1.25 init;
655 root 1.11
656     my $reply = port {
657 root 1.55 my ($node, undef, @neigh) = @_;
658 root 1.11
659 root 1.57 delete $to{$node};
660    
661 root 1.12 @neigh = grep $_ ne $NODE, @neigh;
662    
663 root 1.55 print $node, " -> ", (join " ", @neigh), "\n";
664 root 1.12
665 root 1.57 for my $neigh (@neigh) {
666     unless ($seen{$neigh}++) {
667 root 1.11 $cv->begin;
668 root 1.57 $to{$neigh} = AE::timer 15, 0, sub {
669     print "$neigh (timeout)\n";
670     $exit = 1;
671     $cv->end;
672     };
673     AnyEvent::MP::Kernel::eval_on $neigh, "AnyEvent::MP::Kernel::up_nodes" => $SELF => $neigh;
674 root 1.11 }
675     }
676    
677     $cv->end;
678     };
679    
680     $cv->begin;
681 root 1.56 snd $reply, seed => undef, $seed;
682 root 1.11
683     $cv->recv;
684 root 1.57
685     exit $exit;
686 root 1.11 }
687    
688 root 1.42 sub shell {
689     init;
690    
691     my $node = shift @ARGV || $NODE;
692     $| = 1;
693    
694     print <<EOF;
695     Entering interactive shell - no commandline editing of course (use rlfe etc.).
696    
697 root 1.43 \= display a list of nodes
698     \=name switch to another node
699 root 1.51 package P switch to package P when evaluating
700     \$ECHO contains the name of a port that echos everything sent to it
701 root 1.42
702     EOF
703 root 1.52 my $pkg = "AnyEvent::MP::Kernel";
704 root 1.42 my $cv = AE::cv;
705 root 1.51 my $echo = port {
706 root 1.56 print "\n ECHO<$AnyEvent::MP::Kernel::SRCNODE> ", JSON::XS::encode_json \@_, "\n$node $pkg> ";
707 root 1.51 };
708 root 1.52 print "$node $pkg> ";
709 root 1.42 my $t = AE::io *STDIN, 0, sub {
710     chomp (my $line = <STDIN>);
711    
712     if ($line =~ s/^=//) {
713     if (length $line) {
714     $node = $line;
715     } else {
716     print +(join " ", AnyEvent::MP::Kernel::up_nodes), "\n";
717     }
718 root 1.51 } elsif ($line =~ /^\s*package\s+(\S+)\s*;?\s*$/) {
719 root 1.52 $pkg = $1;
720 root 1.51 } elsif ($line =~ /\S/) {
721 root 1.42 my $time = AE::time;
722 root 1.52 AnyEvent::MP::Kernel::eval_on
723     $node,
724     "package $pkg; my \$ECHO = '$echo'; $line",
725     port {
726     kil $SELF;
727    
728     my ($err, @res) = @_;
729    
730     $time = AE::time - $time;
731    
732     print "\n $node: $line\n";
733     if (length $err) {
734     print " $err @res";
735     } else {
736     print " ", JSON::XS::encode_json \@res;
737     }
738     printf "\n %0.3fs\n", $time;
739     print "$node $pkg> ";
740 root 1.42 }
741 root 1.52 ;
742 root 1.42 }
743    
744 root 1.52 print "$node $pkg> ";
745 root 1.42 };
746     $cv->recv;
747     }
748    
749 root 1.37 sub node_eval {
750     my ($node, $expr) = @_;
751    
752     init;
753    
754     my $cv = AE::cv;
755     my $to = AE::timer 5, 0, sub { exit 1 };
756     AnyEvent::MP::Kernel::eval_on $node, $expr, port { &$cv };
757     mon $node, $cv;
758    
759     my ($err, @res) = $cv->recv;
760    
761 root 1.39 die "$err @res" if length $err;
762 root 1.37
763     print +(substr JSON::XS->new->encode (\@res), 1, -1), "\n";
764     }
765    
766 root 1.10 sub docmd;
767    
768 root 1.1 our %CMD = (
769     snd => sub {
770 root 1.17 my $port = shift @ARGV;
771 root 1.25 init;
772 root 1.1
773 root 1.7 snd $port, @ARGV; @ARGV = ();
774 root 1.1
775     my $cv = AE::cv;
776 root 1.28 my $to = AE::timer 5, 0, sub { exit 1 };
777 root 1.1 mon $port, $cv;
778 root 1.19 my $reply = port sub { &$cv };
779     snd node_of $port, snd => $reply, "message sent successfully";
780 root 1.1
781     print join " ", $cv->recv, "\n";
782     },
783    
784 root 1.41 cal => sub {
785 root 1.17 my $port = shift @ARGV;
786 root 1.25 init;
787 root 1.7
788     my $cv = AE::cv;
789 root 1.41 cal $port, @ARGV, sub { &$cv }; @ARGV = ();
790 root 1.7
791 root 1.23 print +(substr JSON::XS->new->encode ([$cv->recv]), 1, -1), "\n";
792 root 1.7 },
793    
794 root 1.1 mon => sub {
795 root 1.17 my $port = shift @ARGV;
796 root 1.25 init;
797 root 1.1
798     mon $port, my $cv = AE::cv;
799     print join " ", $cv->recv, "\n";
800     },
801    
802 root 1.19 eval => sub {
803     my $node = node_of shift @ARGV;
804     my $expr = join " ", @ARGV; @ARGV = ();
805 root 1.37 node_eval $node, $expr;
806 root 1.19 },
807    
808 root 1.42 shell => \&shell,
809    
810 root 1.11 trace => sub {
811     @ARGV >= 1
812 root 1.17 or die "node id missing\n";
813 root 1.11
814 root 1.17 trace shift @ARGV;
815 root 1.11 },
816 root 1.37 restart => sub {
817     my $node = node_of shift @ARGV;
818 root 1.44 node_eval $node, 'my $w; $w = AE::idle sub { '
819     . 'undef $w; '
820     . 'use AnyEvent::Watchdog::Util ();'
821     . 'AnyEvent::Watchdog::Util::restart'
822     . '}; ()';
823 root 1.37 },
824 root 1.11
825 root 1.17 setnodeid => sub {
826 root 1.8 @ARGV >= 1
827     or die "shared secret missing\n";
828    
829 root 1.17 $profile->{nodeid} = shift @ARGV;
830 root 1.8 ++$cfg->{dirty};
831     },
832 root 1.17 delnodeid => sub {
833     delete $profile->{nodeid};
834 root 1.8 ++$cfg->{dirty};
835     },
836    
837 root 1.1 setsecret => sub {
838 root 1.8 @ARGV >= 1
839 root 1.1 or die "shared secret missing\n";
840    
841 root 1.8 $profile->{secret} = shift @ARGV;
842 root 1.1 ++$cfg->{dirty};
843     },
844     gensecret => sub {
845 root 1.51 $profile->{secret} = AnyEvent::MP::Kernel::nonce62 180; # ~1071 bits
846 root 1.1 ++$cfg->{dirty};
847     },
848 root 1.17 delsecret => sub {
849 root 1.8 delete $profile->{secret};
850 root 1.1 ++$cfg->{dirty};
851     },
852    
853     setcert => sub {
854 root 1.8 @ARGV >= 1
855 root 1.1 or die "key+certificate pem filename missing\n";
856    
857 elmex 1.45 my $certfile = shift @ARGV;
858    
859     open my $fh, "<", $certfile
860     or die "$certfile: $!";
861 root 1.1
862     local $/;
863 root 1.8 $profile->{cert} = <$fh>;
864 root 1.1 ++$cfg->{dirty};
865     },
866     gencert => sub {
867 root 1.8 $profile->{cert} = gen_cert;
868 root 1.1 ++$cfg->{dirty};
869     },
870 root 1.17 delcert => sub {
871 root 1.8 delete $profile->{cert};
872 root 1.1 ++$cfg->{dirty};
873     },
874 root 1.6
875 root 1.17 setbinds => sub {
876 root 1.19 @ARGV >= 1
877     or die "bind addresses missing\n";
878 root 1.38 my $list = shift @ARGV;
879     $profile->{binds} = ref $list ? $list : [split /,/, $list];
880 root 1.17 ++$cfg->{dirty};
881     },
882     delbinds => sub {
883     delete $profile->{binds};
884     ++$cfg->{dirty};
885     },
886     addbind => sub {
887     @ARGV >= 1
888     or die "bind address missing\n";
889     my $bind = shift @ARGV;
890    
891     @{ $profile->{binds} } = grep $_ ne $bind, @{ $profile->{binds} };
892     push @{ $profile->{binds} }, $bind;
893     ++$cfg->{dirty};
894     },
895     delbind => sub {
896     @ARGV >= 1
897     or die "bind address missing\n";
898     my $bind = shift @ARGV;
899    
900     @{ $profile->{binds} } = grep $_ ne $bind, @{ $profile->{binds} };
901     ++$cfg->{dirty};
902     },
903    
904 root 1.6 setseeds => sub {
905 root 1.19 @ARGV >= 1
906     or die "seed addresses missing\n";
907 root 1.38 my $list = shift @ARGV;
908     $profile->{seeds} = ref $list ? $list : [split /,/, $list];
909 root 1.6 ++$cfg->{dirty};
910     },
911 root 1.17 delseeds => sub {
912     delete $profile->{seeds};
913     ++$cfg->{dirty};
914     },
915 root 1.6 addseed => sub {
916 root 1.10 @ARGV >= 1
917 root 1.17 or die "seed address missing\n";
918 root 1.6 my $seed = shift @ARGV;
919 root 1.10
920 root 1.8 @{ $profile->{seeds} } = grep $_ ne $seed, @{ $profile->{seeds} };
921     push @{ $profile->{seeds} }, $seed;
922     ++$cfg->{dirty};
923     },
924     delseed => sub {
925 root 1.10 @ARGV >= 1
926 root 1.17 or die "seed address missing\n";
927 root 1.8 my $seed = shift @ARGV;
928 root 1.10
929 root 1.8 @{ $profile->{seeds} } = grep $_ ne $seed, @{ $profile->{seeds} };
930     ++$cfg->{dirty};
931     },
932    
933     setservices => sub {
934 root 1.19 @ARGV >= 1
935     or die "service specifications missing\n";
936 root 1.38 my $list = shift @ARGV;
937     $profile->{services} = ref $list ? $list : [split /,/, $list];
938 root 1.6 ++$cfg->{dirty};
939     },
940 root 1.17 delservices => sub {
941     delete $profile->{services};
942     ++$cfg->{dirty};
943     },
944 root 1.9 addservice => sub {
945 root 1.10 @ARGV >= 1
946     or die "service specification missing\n";
947 root 1.8 my $service = shift @ARGV;
948     push @{ $profile->{services} }, $service;
949     ++$cfg->{dirty};
950     },
951 root 1.9 delservice => sub {
952 root 1.10 @ARGV >= 1
953     or die "service specification missing\n";
954 root 1.8 my $service = shift @ARGV;
955     for (0 .. $#{ $profile->{services} }) {
956     next unless $profile->{services}[$_] eq $service;
957     splice @{ $profile->{services} }, $_, 1;
958     last;
959     }
960 root 1.6 ++$cfg->{dirty};
961     },
962 root 1.58 seteval => sub {
963     @ARGV >= 1
964     or die "eval string missing\n";
965    
966     $profile->{eval} = shift @ARGV;
967     ++$cfg->{dirty};
968     },
969     deleval => sub {
970     delete $profile->{eval};
971     ++$cfg->{dirty};
972     },
973 root 1.10
974     profile => sub {
975 root 1.19 @ARGV >= 1
976     or die "profile name is missing\n";
977 root 1.10 my $name = shift @ARGV;
978    
979     $profile = $cfg->{profile}{$name} ||= {};
980 root 1.14 ++$cfg->{dirty};
981 root 1.10 },
982     delprofile => sub {
983     @ARGV >= 1
984     or die "profile name is missing\n";
985     my $name = shift @ARGV;
986    
987     delete $cfg->{profile}{$name};
988 root 1.14 ++$cfg->{dirty};
989 root 1.10 },
990 root 1.26 setparent => sub {
991 root 1.24 @ARGV >= 1
992     or die "profile name is missing\n";
993    
994     $profile->{parent} = shift @ARGV;
995     ++$cfg->{dirty};
996     },
997     delparent => sub {
998     delete $profile->{parent};
999     ++$cfg->{dirty};
1000     },
1001 root 1.17 showprofile => sub {
1002     @ARGV >= 1
1003     or die "profile name is missing\n";
1004     my $name = shift @ARGV;
1005    
1006     print JSON::XS->new->pretty->encode ($cfg->{profile}{$name} || {});
1007     },
1008     showconfig => sub {
1009 root 1.53 my $name = @ARGV ? shift @ARGV : AnyEvent::MP::Kernel::nodename;
1010 root 1.17
1011 root 1.25 my $profile = AnyEvent::MP::Config::find_profile $name, @ARGV;
1012     @ARGV = ();
1013 root 1.24
1014     # make it look nicer:
1015     delete $profile->{profile};
1016     delete $profile->{parent};
1017    
1018     print JSON::XS->new->pretty->encode ($profile);
1019 root 1.17 },
1020 root 1.25
1021     # undocumented
1022     _resolve => sub {
1023     print +(join ",", (AnyEvent::MP::Kernel::_resolve shift @ARGV)->recv), "\n";
1024     },
1025 root 1.1 );
1026    
1027 root 1.47 for my $attr (qw(
1028     monitor_timeout connect_interval framing_format auth_offer
1029 root 1.54 auth_accept autocork nodelay secure
1030 root 1.47 )) {
1031     $CMD{"set$attr"} = sub {
1032     @ARGV >= 1
1033     or die "$attr value is missing\n";
1034    
1035     $profile->{$attr} = shift @ARGV;
1036     ++$cfg->{dirty};
1037     };
1038     $CMD{"del$attr"} = sub {
1039     delete $profile->{$attr};
1040     ++$cfg->{dirty};
1041     };
1042     }
1043    
1044 root 1.27 for (keys %CMD) {
1045     $CMD{$1} = $CMD{$_} if /^set(.*)$/;
1046     }
1047    
1048 root 1.1 sub docmd {
1049     my $cmd = shift @ARGV;
1050    
1051     $CMD{$cmd}
1052 root 1.23 or die "$cmd: no such aemp command (try perldoc aemp, or man aemp)";
1053 root 1.1
1054     $CMD{$cmd}();
1055     }
1056    
1057     @ARGV
1058 root 1.23 or die "Usage: aemp subcommand ... (try perldoc aemp, or man aemp)\n";
1059 root 1.1
1060 root 1.19 docmd while @ARGV;
1061 root 1.1
1062