ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-MP/bin/aemp
Revision: 1.10
Committed: Thu Aug 13 15:29:59 2009 UTC (14 years, 9 months ago) by root
Branch: MAIN
Changes since 1.9: +34 -1 lines
Log Message:
*** empty log message ***

File Contents

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