ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-MP/bin/aemp
Revision: 1.11
Committed: Thu Aug 13 22:32:41 2009 UTC (14 years, 9 months ago) by root
Branch: MAIN
Changes since 1.10: +42 -0 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 #!/opt/bin/perl
2    
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.8 aemp snd <port> <arg...> # send a message
13     aemp mon <port> # wait till port is killed
14     aemp rpc <port> <arg...> # send message, append reply
15    
16     # run a node
17     aemp run initialise_args... # run a node
18    
19     # node configuration: protocol endpoints
20     aemp setnoderef <noderef> # configure the real noderef
21     aemp clrnoderef # reset noderef to default
22 root 1.1
23     # node configuration: secret
24 root 1.8 aemp gensecret # generate a random shared secret
25     aemp setsecret <secret> # set the shared secret
26     aemp clrsecret # remove the secret
27 root 1.1
28     # node configuration: TLS
29 root 1.8 aemp setcert <file> # set a certificate (key.pem + certificate.pem)
30     aemp clrcert # remove certificate
31     aemp gencert # generate a random certificate
32    
33     # node configuration: seed nodes for bootstrapping
34     aemp setseeds <noderef>... # set seednodes
35     aemp addseed <noderef> # add a seednode
36     aemp delseed <noderef> # remove seednode
37    
38     # node configuration: services
39     aemp setservices initfunc... # set service functions
40     aemp addservice <initfunc> # add an instance of a service
41     aemp delservice <initfunc> # delete one instance of a service
42 root 1.6
43 root 1.10 # profile-specific configuration
44     aemp profile <name> <command>... # apply command to profile only
45     aemp delprofile <name> # eradicate the named profile
46    
47 root 1.11 # debugging
48     aemp trace <noderef> # trace the network topology
49    
50 root 1.1 =head1 DESCRIPTION
51    
52 root 1.8 With aemp you can configure various aspects of AnyEvent::MP and its
53     protocol.
54    
55     You can also start a "default node", a node that only depends on the
56     static configuration.
57 root 1.1
58     =cut
59    
60     use common::sense;
61    
62 root 1.8 BEGIN {
63     if ($ARGV[0] eq "run") {
64     shift;
65    
66     #TODO: watchdog? how?
67     #require AnyEvent::Watchdog;
68     require AnyEvent;
69     require AnyEvent::MP;
70     AnyEvent::MP::initialise_node (@ARGV);
71    
72     AnyEvent::detect () eq "AnyEvent::Impl::E"
73     ? EV::loop ()
74     : AE::cv ()->recv;
75     }
76     }
77    
78 root 1.1 use Carp ();
79    
80     use AnyEvent;
81 root 1.4 use AnyEvent::Util;
82    
83 root 1.8 use AnyEvent::MP;
84 root 1.1 use AnyEvent::MP::Config;
85    
86     sub my_run_cmd {
87     my ($cmd) = @_;
88    
89     my $cv = &run_cmd;
90     my $status = $cv->recv;
91    
92     $status
93     and die "@$cmd: command failed with exit status $status.";
94     }
95    
96     sub gen_cert {
97 root 1.2 my_run_cmd [qw(openssl req
98     -new -nodes -x509 -days 3650
99     -newkey rsa:2048 -keyout /dev/fd/3
100     -batch -subj /CN=AnyEvent::MP
101     )],
102 root 1.5 "<", "/dev/null",
103 root 1.1 ">" , \my $cert,
104     "3>", \my $key,
105 root 1.4 "2>", "/dev/null";
106 root 1.1
107     "$cert$key"
108     }
109    
110 root 1.10 our $cfg = AnyEvent::MP::Config::config;
111 root 1.8 our $profile = $cfg;
112 root 1.1
113     sub resolve_port {
114     my ($node, $port) = split /#/, $_[0], 2;
115    
116     $node = (resolve_node $node)->recv;
117     "$node#$port"
118     }
119    
120 root 1.11 sub trace {
121     my ($node) = @_;
122     my $cv = AE::cv;
123     my %seen;
124    
125     my $to = AE::timer 15, 0, sub {
126     warn "timeout\n";
127     $cv->();
128     };
129    
130     initialise_node "slave/", $node;
131    
132     my $reply = port {
133     print +(join " ", @_), "\n";
134    
135     shift;
136     for (@_) {
137     unless ($seen{$_}++) {
138     $cv->begin;
139     snd $_, up_nodes => $SELF => $_;
140     }
141     }
142    
143     $cv->end;
144     };
145    
146     $cv->begin;
147     snd $reply, seed => $node;
148    
149     $cv->recv;
150     }
151    
152 root 1.10 sub docmd;
153    
154 root 1.1 our %CMD = (
155     snd => sub {
156     my $port = resolve_port shift @ARGV;
157     initialise_node "slave/", node_of $port;
158    
159 root 1.7 snd $port, @ARGV; @ARGV = ();
160 root 1.1
161     my $cv = AE::cv;
162 root 1.7 my $to = AE::timer 5, 0, sub { $cv->("timeout") };
163 root 1.1 mon $port, $cv;
164 root 1.7 my $reply = port { &$cv; 1 };
165 root 1.1 snd node_of $port, relay => $reply, "ok";
166    
167     print join " ", $cv->recv, "\n";
168     },
169    
170 root 1.7 rpc => sub {
171     my $port = resolve_port shift @ARGV;
172     initialise_node "slave/", node_of $port;
173    
174     my $cv = AE::cv;
175     my $to = AE::timer 5, 0, sub { $cv->("timeout") };
176     my $reply = port { &$cv; 1 };
177     snd $port, @ARGV, $reply; @ARGV = ();
178     mon $port, $cv;
179    
180     print join " ", $cv->recv, "\n";
181     },
182    
183 root 1.1 mon => sub {
184     my $port = resolve_port shift @ARGV;
185     initialise_node "slave/", node_of $port;
186    
187     mon $port, my $cv = AE::cv;
188     print join " ", $cv->recv, "\n";
189     },
190    
191 root 1.11 trace => sub {
192     @ARGV >= 1
193     or die "noderef missing\n";
194    
195     trace +(resolve_node shift @ARGV)->recv;
196     },
197    
198 root 1.8 setnoderef => sub {
199     @ARGV >= 1
200     or die "shared secret missing\n";
201    
202     $profile->{noderef} = shift @ARGV;
203     ++$cfg->{dirty};
204     },
205     clrnoderef => sub {
206     delete $profile->{noderef};
207     ++$cfg->{dirty};
208     },
209    
210 root 1.1 setsecret => sub {
211 root 1.8 @ARGV >= 1
212 root 1.1 or die "shared secret missing\n";
213    
214 root 1.8 $profile->{secret} = shift @ARGV;
215 root 1.1 ++$cfg->{dirty};
216     },
217     gensecret => sub {
218 root 1.8 $profile->{secret} = AnyEvent::MP::Base::asciibits AnyEvent::MP::Base::nonce 64;
219 root 1.1 ++$cfg->{dirty};
220     },
221     clrsecret => sub {
222 root 1.8 delete $profile->{secret};
223 root 1.1 ++$cfg->{dirty};
224     },
225    
226     setcert => sub {
227 root 1.8 @ARGV >= 1
228 root 1.1 or die "key+certificate pem filename missing\n";
229    
230     open my $fh, "<", $ARGV[0]
231     or die "$ARGV[0]: $!";
232    
233     local $/;
234 root 1.8 $profile->{cert} = <$fh>;
235 root 1.1 ++$cfg->{dirty};
236     },
237     gencert => sub {
238 root 1.8 $profile->{cert} = gen_cert;
239 root 1.1 ++$cfg->{dirty};
240     },
241     clrcert => sub {
242 root 1.8 delete $profile->{cert};
243 root 1.1 ++$cfg->{dirty};
244     },
245 root 1.6
246     setseeds => sub {
247 root 1.8 $profile->{seeds} = [@ARGV];
248 root 1.6 @ARGV = ();
249     ++$cfg->{dirty};
250     },
251     addseed => sub {
252 root 1.10 @ARGV >= 1
253     or die "seed noderef missing\n";
254 root 1.6 my $seed = shift @ARGV;
255 root 1.10
256 root 1.8 @{ $profile->{seeds} } = grep $_ ne $seed, @{ $profile->{seeds} };
257     push @{ $profile->{seeds} }, $seed;
258     ++$cfg->{dirty};
259     },
260     delseed => sub {
261 root 1.10 @ARGV >= 1
262     or die "seed noderef missing\n";
263 root 1.8 my $seed = shift @ARGV;
264 root 1.10
265 root 1.8 @{ $profile->{seeds} } = grep $_ ne $seed, @{ $profile->{seeds} };
266     ++$cfg->{dirty};
267     },
268    
269     setservices => sub {
270     $profile->{services} = [@ARGV];
271     @ARGV = ();
272 root 1.6 ++$cfg->{dirty};
273     },
274 root 1.9 addservice => sub {
275 root 1.10 @ARGV >= 1
276     or die "service specification missing\n";
277 root 1.8 my $service = shift @ARGV;
278     push @{ $profile->{services} }, $service;
279     ++$cfg->{dirty};
280     },
281 root 1.9 delservice => sub {
282 root 1.10 @ARGV >= 1
283     or die "service specification missing\n";
284 root 1.8 my $service = shift @ARGV;
285     for (0 .. $#{ $profile->{services} }) {
286     next unless $profile->{services}[$_] eq $service;
287     splice @{ $profile->{services} }, $_, 1;
288     last;
289     }
290 root 1.6 ++$cfg->{dirty};
291     },
292 root 1.10
293     profile => sub {
294     @ARGV >= 2
295     or die "profile name or subcommand are missing\n";
296     my $name = shift @ARGV;
297    
298     $profile = $cfg->{profile}{$name} ||= {};
299    
300     docmd;
301     },
302     delprofile => sub {
303     @ARGV >= 1
304     or die "profile name is missing\n";
305     my $name = shift @ARGV;
306    
307     delete $cfg->{profile}{$name};
308     },
309 root 1.1 );
310    
311     sub docmd {
312     my $cmd = shift @ARGV;
313    
314     $CMD{$cmd}
315     or die "$cmd: no such aemp command (try man aemp)";
316    
317     $CMD{$cmd}();
318     }
319    
320     @ARGV
321     or die "Usage: aemp subcommand ... (try man aemp)\n";
322    
323     docmd;
324    
325