ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-MP/bin/aemp
Revision: 1.12
Committed: Thu Aug 13 22:43:38 2009 UTC (14 years, 9 months ago) by root
Branch: MAIN
Changes since 1.11: +6 -3 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 root 1.12 my ($node, @neigh) = @_;
134 root 1.11
135 root 1.12 @neigh = grep $_ ne $NODE, @neigh;
136    
137     print +(join " ", $node, @neigh), "\n";
138    
139     for (@neigh) {
140 root 1.11 unless ($seen{$_}++) {
141     $cv->begin;
142     snd $_, up_nodes => $SELF => $_;
143     }
144     }
145    
146     $cv->end;
147     };
148    
149     $cv->begin;
150     snd $reply, seed => $node;
151    
152     $cv->recv;
153     }
154    
155 root 1.10 sub docmd;
156    
157 root 1.1 our %CMD = (
158     snd => sub {
159     my $port = resolve_port shift @ARGV;
160     initialise_node "slave/", node_of $port;
161    
162 root 1.7 snd $port, @ARGV; @ARGV = ();
163 root 1.1
164     my $cv = AE::cv;
165 root 1.7 my $to = AE::timer 5, 0, sub { $cv->("timeout") };
166 root 1.1 mon $port, $cv;
167 root 1.7 my $reply = port { &$cv; 1 };
168 root 1.1 snd node_of $port, relay => $reply, "ok";
169    
170     print join " ", $cv->recv, "\n";
171     },
172    
173 root 1.7 rpc => sub {
174     my $port = resolve_port shift @ARGV;
175     initialise_node "slave/", node_of $port;
176    
177     my $cv = AE::cv;
178     my $to = AE::timer 5, 0, sub { $cv->("timeout") };
179     my $reply = port { &$cv; 1 };
180     snd $port, @ARGV, $reply; @ARGV = ();
181     mon $port, $cv;
182    
183     print join " ", $cv->recv, "\n";
184     },
185    
186 root 1.1 mon => sub {
187     my $port = resolve_port shift @ARGV;
188     initialise_node "slave/", node_of $port;
189    
190     mon $port, my $cv = AE::cv;
191     print join " ", $cv->recv, "\n";
192     },
193    
194 root 1.11 trace => sub {
195     @ARGV >= 1
196     or die "noderef missing\n";
197    
198     trace +(resolve_node shift @ARGV)->recv;
199     },
200    
201 root 1.8 setnoderef => sub {
202     @ARGV >= 1
203     or die "shared secret missing\n";
204    
205     $profile->{noderef} = shift @ARGV;
206     ++$cfg->{dirty};
207     },
208     clrnoderef => sub {
209     delete $profile->{noderef};
210     ++$cfg->{dirty};
211     },
212    
213 root 1.1 setsecret => sub {
214 root 1.8 @ARGV >= 1
215 root 1.1 or die "shared secret missing\n";
216    
217 root 1.8 $profile->{secret} = shift @ARGV;
218 root 1.1 ++$cfg->{dirty};
219     },
220     gensecret => sub {
221 root 1.8 $profile->{secret} = AnyEvent::MP::Base::asciibits AnyEvent::MP::Base::nonce 64;
222 root 1.1 ++$cfg->{dirty};
223     },
224     clrsecret => sub {
225 root 1.8 delete $profile->{secret};
226 root 1.1 ++$cfg->{dirty};
227     },
228    
229     setcert => sub {
230 root 1.8 @ARGV >= 1
231 root 1.1 or die "key+certificate pem filename missing\n";
232    
233     open my $fh, "<", $ARGV[0]
234     or die "$ARGV[0]: $!";
235    
236     local $/;
237 root 1.8 $profile->{cert} = <$fh>;
238 root 1.1 ++$cfg->{dirty};
239     },
240     gencert => sub {
241 root 1.8 $profile->{cert} = gen_cert;
242 root 1.1 ++$cfg->{dirty};
243     },
244     clrcert => sub {
245 root 1.8 delete $profile->{cert};
246 root 1.1 ++$cfg->{dirty};
247     },
248 root 1.6
249     setseeds => sub {
250 root 1.8 $profile->{seeds} = [@ARGV];
251 root 1.6 @ARGV = ();
252     ++$cfg->{dirty};
253     },
254     addseed => sub {
255 root 1.10 @ARGV >= 1
256     or die "seed noderef missing\n";
257 root 1.6 my $seed = shift @ARGV;
258 root 1.10
259 root 1.8 @{ $profile->{seeds} } = grep $_ ne $seed, @{ $profile->{seeds} };
260     push @{ $profile->{seeds} }, $seed;
261     ++$cfg->{dirty};
262     },
263     delseed => sub {
264 root 1.10 @ARGV >= 1
265     or die "seed noderef missing\n";
266 root 1.8 my $seed = shift @ARGV;
267 root 1.10
268 root 1.8 @{ $profile->{seeds} } = grep $_ ne $seed, @{ $profile->{seeds} };
269     ++$cfg->{dirty};
270     },
271    
272     setservices => sub {
273     $profile->{services} = [@ARGV];
274     @ARGV = ();
275 root 1.6 ++$cfg->{dirty};
276     },
277 root 1.9 addservice => sub {
278 root 1.10 @ARGV >= 1
279     or die "service specification missing\n";
280 root 1.8 my $service = shift @ARGV;
281     push @{ $profile->{services} }, $service;
282     ++$cfg->{dirty};
283     },
284 root 1.9 delservice => sub {
285 root 1.10 @ARGV >= 1
286     or die "service specification missing\n";
287 root 1.8 my $service = shift @ARGV;
288     for (0 .. $#{ $profile->{services} }) {
289     next unless $profile->{services}[$_] eq $service;
290     splice @{ $profile->{services} }, $_, 1;
291     last;
292     }
293 root 1.6 ++$cfg->{dirty};
294     },
295 root 1.10
296     profile => sub {
297     @ARGV >= 2
298     or die "profile name or subcommand are missing\n";
299     my $name = shift @ARGV;
300    
301     $profile = $cfg->{profile}{$name} ||= {};
302    
303     docmd;
304     },
305     delprofile => sub {
306     @ARGV >= 1
307     or die "profile name is missing\n";
308     my $name = shift @ARGV;
309    
310     delete $cfg->{profile}{$name};
311     },
312 root 1.1 );
313    
314     sub docmd {
315     my $cmd = shift @ARGV;
316    
317     $CMD{$cmd}
318     or die "$cmd: no such aemp command (try man aemp)";
319    
320     $CMD{$cmd}();
321     }
322    
323     @ARGV
324     or die "Usage: aemp subcommand ... (try man aemp)\n";
325    
326     docmd;
327    
328