remove class APIDaemon
Moved last used sub into PVE::API2Tools.
This commit is contained in:
parent
5c173cc1df
commit
8208f7db2f
@ -2,6 +2,8 @@ package PVE::API2Tools;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Net::IP;
|
||||
|
||||
use PVE::Tools;
|
||||
use Digest::MD5 qw(md5_hex);
|
||||
use URI;
|
||||
@ -195,4 +197,42 @@ sub run_spiceterm {
|
||||
return $remote_viewer_config;
|
||||
}
|
||||
|
||||
sub read_proxy_config {
|
||||
|
||||
my $conffile = "/etc/default/pveproxy";
|
||||
|
||||
# Note: evaluate with bash
|
||||
my $shcmd = ". $conffile;\n";
|
||||
$shcmd .= 'echo \"ALLOW_FROM:\$ALLOW_FROM\";';
|
||||
$shcmd .= 'echo \"DENY_FROM:\$DENY_FROM\";';
|
||||
$shcmd .= 'echo \"POLICY:\$POLICY\";';
|
||||
$shcmd .= 'echo \"CIPHERS:\$CIPHERS\";';
|
||||
|
||||
my $data = -f $conffile ? `bash -c "$shcmd"` : '';
|
||||
|
||||
my $res = {};
|
||||
|
||||
while ($data =~ s/^(.*)\n//) {
|
||||
my ($key, $value) = split(/:/, $1, 2);
|
||||
next if !$value;
|
||||
if ($key eq 'ALLOW_FROM' || $key eq 'DENY_FROM') {
|
||||
my $ips = [];
|
||||
foreach my $ip (split(/,/, $value)) {
|
||||
$ip = "0/0" if $ip eq 'all';
|
||||
push @$ips, Net::IP->new($ip) || die Net::IP::Error() . "\n";
|
||||
}
|
||||
$res->{$key} = $ips;
|
||||
} elsif ($key eq 'POLICY') {
|
||||
die "unknown policy '$value'\n" if $value !~ m/^(allow|deny)$/;
|
||||
$res->{$key} = $value;
|
||||
} elsif ($key eq 'CIPHERS') {
|
||||
$res->{$key} = $value;
|
||||
} else {
|
||||
# silently skip everythin else?
|
||||
}
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
1;
|
||||
|
252
PVE/APIDaemon.pm
252
PVE/APIDaemon.pm
@ -1,252 +0,0 @@
|
||||
package PVE::APIDaemon;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use POSIX ":sys_wait_h";
|
||||
use Socket qw(IPPROTO_TCP TCP_NODELAY SOMAXCONN);
|
||||
use IO::Socket::INET;
|
||||
use Net::IP;
|
||||
|
||||
use PVE::INotify;
|
||||
use PVE::SafeSyslog;
|
||||
use PVE::HTTPServer;
|
||||
|
||||
my $workers = {};
|
||||
|
||||
sub new {
|
||||
my ($this, %args) = @_;
|
||||
|
||||
my $class = ref($this) || $this;
|
||||
|
||||
die "no lockfile" if !$args{lockfile};
|
||||
|
||||
die "no base_handler_class" if !$args{base_handler_class};
|
||||
#require $args{base_handler_class};
|
||||
|
||||
my $lockfh = IO::File->new(">>$args{lockfile}") ||
|
||||
die "unable to open lock file '$args{lockfile}' - $!\n";
|
||||
|
||||
my $socket = IO::Socket::INET->new(
|
||||
LocalAddr => $args{host} || undef,
|
||||
LocalPort => $args{port} || 80,
|
||||
Listen => SOMAXCONN,
|
||||
Proto => 'tcp',
|
||||
ReuseAddr => 1) ||
|
||||
die "unable to create socket - $@\n";
|
||||
|
||||
# we ofter observe delays when using Nagle algorithm,
|
||||
# so we disable that to maximize performance
|
||||
setsockopt($socket, IPPROTO_TCP, TCP_NODELAY, 1);
|
||||
|
||||
my $cfg = { %args };
|
||||
my $self = bless { cfg => $cfg }, $class;
|
||||
|
||||
$cfg->{base_handler_class} = $args{base_handler_class};
|
||||
|
||||
$cfg->{socket} = $socket;
|
||||
$cfg->{lockfh} = $lockfh;
|
||||
$cfg->{max_workers} = 3 if !$cfg->{max_workers};
|
||||
$cfg->{trusted_env} = 0 if !defined($cfg->{trusted_env});
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub worker_finished {
|
||||
my $cpid = shift;
|
||||
|
||||
syslog('info', "worker $cpid finished");
|
||||
}
|
||||
|
||||
sub finish_workers {
|
||||
local $!; local $?;
|
||||
foreach my $cpid (keys %$workers) {
|
||||
my $waitpid = waitpid ($cpid, WNOHANG);
|
||||
if (defined($waitpid) && ($waitpid == $cpid)) {
|
||||
delete ($workers->{$cpid});
|
||||
worker_finished ($cpid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub test_workers {
|
||||
foreach my $cpid (keys %$workers) {
|
||||
if (!kill(0, $cpid)) {
|
||||
waitpid($cpid, POSIX::WNOHANG());
|
||||
delete $workers->{$cpid};
|
||||
worker_finished ($cpid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub start_workers {
|
||||
my ($self) = @_;
|
||||
|
||||
my $count = 0;
|
||||
foreach my $cpid (keys %$workers) {
|
||||
$count++;
|
||||
}
|
||||
|
||||
my $need = $self->{cfg}->{max_workers} - $count;
|
||||
|
||||
return if $need <= 0;
|
||||
|
||||
syslog('info', "starting $need worker(s)");
|
||||
|
||||
while ($need > 0) {
|
||||
my $pid = fork;
|
||||
|
||||
if (!defined ($pid)) {
|
||||
syslog('err', "can't fork worker");
|
||||
sleep (1);
|
||||
} elsif ($pid) { #parent
|
||||
$workers->{$pid} = 1;
|
||||
syslog('info', "worker $pid started");
|
||||
$need--;
|
||||
} else {
|
||||
$0 = "$0 worker";
|
||||
|
||||
PVE::INotify::inotify_close();
|
||||
|
||||
for my $sig (qw(CHLD HUP INT TERM QUIT)) {
|
||||
$SIG{$sig} = 'DEFAULT'; # restore default handler
|
||||
# AnyEvent signals only works if $SIG{XX} is
|
||||
# undefined (perl event loop)
|
||||
delete $SIG{$sig}; # so that we can handle events with AnyEvent
|
||||
}
|
||||
|
||||
eval {
|
||||
my $server = PVE::HTTPServer->new(%{$self->{cfg}});
|
||||
$server->run();
|
||||
};
|
||||
if (my $err = $@) {
|
||||
syslog('err', $err);
|
||||
sleep(5); # avoid fast restarts
|
||||
}
|
||||
|
||||
syslog('info', "worker exit");
|
||||
exit (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub terminate_server {
|
||||
|
||||
syslog('info', "received terminate request");
|
||||
|
||||
foreach my $cpid (keys %$workers) {
|
||||
kill (15, $cpid); # TERM childs
|
||||
}
|
||||
|
||||
# nicely shutdown childs (give them max 10 seconds to shut down)
|
||||
my $previous_alarm = alarm (10);
|
||||
eval {
|
||||
local $SIG{ALRM} = sub { die "timeout\n" };
|
||||
|
||||
while ((my $pid = waitpid (-1, 0)) > 0) {
|
||||
if (defined($workers->{$pid})) {
|
||||
delete ($workers->{$pid});
|
||||
worker_finished ($pid);
|
||||
}
|
||||
}
|
||||
alarm(0); # avoid race condition
|
||||
};
|
||||
my $err = $@;
|
||||
|
||||
alarm ($previous_alarm);
|
||||
|
||||
if ($err) {
|
||||
syslog('err', "error stopping workers (will kill them now) - $err");
|
||||
foreach my $cpid (keys %$workers) {
|
||||
# KILL childs still alive!
|
||||
if (kill (0, $cpid)) {
|
||||
delete ($workers->{$cpid});
|
||||
syslog("err", "kill worker $cpid");
|
||||
kill (9, $cpid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub start_server {
|
||||
my $self = shift;
|
||||
|
||||
eval {
|
||||
my $old_sig_chld = $SIG{CHLD};
|
||||
local $SIG{CHLD} = sub {
|
||||
finish_workers ();
|
||||
&$old_sig_chld(@_) if $old_sig_chld;
|
||||
};
|
||||
|
||||
my $old_sig_term = $SIG{TERM};
|
||||
local $SIG{TERM} = sub {
|
||||
terminate_server ();
|
||||
&$old_sig_term(@_) if $old_sig_term;
|
||||
};
|
||||
local $SIG{QUIT} = sub {
|
||||
terminate_server();
|
||||
&$old_sig_term(@_) if $old_sig_term;
|
||||
};
|
||||
local $SIG{INT} = sub {
|
||||
terminate_server();
|
||||
&$old_sig_term(@_) if $old_sig_term;
|
||||
};
|
||||
|
||||
local $SIG{HUP} = sub {
|
||||
syslog("info", "received reload request");
|
||||
foreach my $cpid (keys %$workers) {
|
||||
kill (15, $cpid); # kill childs
|
||||
}
|
||||
};
|
||||
|
||||
for (;;) { # forever
|
||||
$self->start_workers();
|
||||
sleep (5);
|
||||
$self->test_workers();
|
||||
}
|
||||
};
|
||||
my $err = $@;
|
||||
|
||||
if ($err) {
|
||||
syslog('err', "ERROR: $err");
|
||||
}
|
||||
}
|
||||
|
||||
sub read_proxy_config {
|
||||
|
||||
my $conffile = "/etc/default/pveproxy";
|
||||
|
||||
# Note: evaluate with bash
|
||||
my $shcmd = ". $conffile;\n";
|
||||
$shcmd .= 'echo \"ALLOW_FROM:\$ALLOW_FROM\";';
|
||||
$shcmd .= 'echo \"DENY_FROM:\$DENY_FROM\";';
|
||||
$shcmd .= 'echo \"POLICY:\$POLICY\";';
|
||||
$shcmd .= 'echo \"CIPHERS:\$CIPHERS\";';
|
||||
|
||||
my $data = -f $conffile ? `bash -c "$shcmd"` : '';
|
||||
|
||||
my $res = {};
|
||||
|
||||
while ($data =~ s/^(.*)\n//) {
|
||||
my ($key, $value) = split(/:/, $1, 2);
|
||||
next if !$value;
|
||||
if ($key eq 'ALLOW_FROM' || $key eq 'DENY_FROM') {
|
||||
my $ips = [];
|
||||
foreach my $ip (split(/,/, $value)) {
|
||||
$ip = "0/0" if $ip eq 'all';
|
||||
push @$ips, Net::IP->new($ip) || die Net::IP::Error() . "\n";
|
||||
}
|
||||
$res->{$key} = $ips;
|
||||
} elsif ($key eq 'POLICY') {
|
||||
die "unknown policy '$value'\n" if $value !~ m/^(allow|deny)$/;
|
||||
$res->{$key} = $value;
|
||||
} elsif ($key eq 'CIPHERS') {
|
||||
$res->{$key} = $value;
|
||||
} else {
|
||||
# silently skip everythin else?
|
||||
}
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
1;
|
@ -10,7 +10,6 @@ PERLSOURCE = \
|
||||
TouchIndex.pm \
|
||||
NoVncIndex.pm \
|
||||
HTTPServer.pm \
|
||||
APIDaemon.pm \
|
||||
REST.pm \
|
||||
OpenVZ.pm \
|
||||
OpenVZMigrate.pm \
|
||||
|
@ -12,6 +12,7 @@ use PVE::Daemon;
|
||||
use PVE::API2;
|
||||
use PVE::API2::Formatter::Standard;
|
||||
use PVE::API2::Formatter::HTML;
|
||||
use PVE::HTTPServer;
|
||||
|
||||
use base qw(PVE::Daemon);
|
||||
|
||||
|
@ -10,16 +10,17 @@ use English;
|
||||
|
||||
use PVE::SafeSyslog;
|
||||
use PVE::Daemon;
|
||||
use PVE::APIDaemon; # fixme: remove
|
||||
use HTTP::Response;
|
||||
use Encode;
|
||||
use URI;
|
||||
use URI::QueryParam;
|
||||
use File::Find;
|
||||
use Data::Dumper;
|
||||
use PVE::API2Tools;
|
||||
use PVE::API2;
|
||||
use PVE::API2::Formatter::Standard;
|
||||
use PVE::API2::Formatter::HTML;
|
||||
use PVE::HTTPServer;
|
||||
|
||||
use PVE::ExtJSIndex;
|
||||
use PVE::NoVncIndex;
|
||||
@ -78,7 +79,7 @@ sub init {
|
||||
my ($self) = @_;
|
||||
|
||||
# we use same ALLOW/DENY/POLICY as pveproxy
|
||||
my $proxyconf = PVE::APIDaemon::read_proxy_config();
|
||||
my $proxyconf = PVE::API2Tools::read_proxy_config();
|
||||
|
||||
my $accept_lock_fn = "/var/lock/pveproxy.lck";
|
||||
|
||||
|
@ -14,8 +14,9 @@ use English;
|
||||
|
||||
use PVE::SafeSyslog;
|
||||
use PVE::Daemon;
|
||||
use PVE::APIDaemon; # fixme: remove
|
||||
use PVE::API2Tools;
|
||||
use PVE::API2;
|
||||
use PVE::HTTPServer;
|
||||
|
||||
use base qw(PVE::Daemon);
|
||||
|
||||
@ -53,7 +54,7 @@ sub init {
|
||||
my ($self) = @_;
|
||||
|
||||
# we use same ALLOW/DENY/POLICY as pveproxy
|
||||
my $proxyconf = PVE::APIDaemon::read_proxy_config();
|
||||
my $proxyconf = PVE::API2Tools::read_proxy_config();
|
||||
|
||||
my $accept_lock_fn = "/var/lock/spiceproxy.lck";
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user