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