]>
git.proxmox.com Git - pmg-api.git/blob - PMG/Service/pmgtunnel.pm
1 package PMG
::Service
::pmgtunnel
;
6 use Time
::HiRes qw
(gettimeofday
);
9 use PVE
::Tools
qw(extract_param);
13 use PMG
::RESTEnvironment
;
17 use PMG
::ClusterConfig
;
20 use base
qw(PVE::Daemon);
22 my $cmdline = [$0, @ARGV];
24 my %daemon_options = (restart_on_error
=> 5, stop_wait_time
=> 5);
26 my $daemon = __PACKAGE__-
>new('pmgtunnel', $cmdline, %daemon_options);
28 my $restart_request = 0;
35 my $delayed_exec = {};
39 while ((my $cpid = waitpid(-1, POSIX
::WNOHANG
())) > 0) {
40 if (defined($workers->{$cpid})) {
41 my $ip = $workers->{$cpid}->{ip
};
42 my $cid = $workers->{$cpid}->{cid
};
43 syslog
('err', "tunnel finished $cpid $ip");
44 $delayed_exec->{$cid} = time + ($startcount->{$cid} > 5 ?
60 : 10);
45 delete $workers->{$cpid};
51 my ($self, $cinfo) = @_;
53 my $role = $cinfo->{local}->{type
} // '-';
54 return if $role eq '-';
56 foreach my $cid (keys %{$cinfo->{ids
}}) {
57 my $ni = $cinfo->{ids
}->{$cid};
58 next if $ni->{ip
} eq $cinfo->{local}->{ip
}; # just to be sure
60 my $dbport = $cinfo->{dbport
}->{$cid};
61 next if !$dbport; # just to be sure
64 foreach my $cpid (keys %$workers) {
65 $running = 1 if $workers->{$cpid}->{ip
} eq $ni->{ip
};
69 if ($delayed_exec->{$cid} && (time < $delayed_exec->{$cid})) {
72 $delayed_exec->{$cid} = 0;
73 $startcount->{$cid}++;
77 if (!defined ($pid)) {
79 syslog
('err', "can't fork tunnel");
81 } elsif($pid) { # parent
83 $workers->{$pid}->{ip
} = $ni->{ip
};
84 $workers->{$pid}->{cid
} = $cid;
85 $workers->{$pid}->{dbport
} = $dbport;
87 if ($startcount->{$cid} > 1) {
88 syslog
('info', "restarting crashed tunnel $pid $ni->{ip}");
90 syslog
('info', "starting tunnel $pid $ni->{ip}");
95 $self->after_fork_cleanup();
97 # make sure we use ipv4 127.0.0.1 (instead of ipv6 :::1)
98 exec('/usr/bin/ssh', '-N', '-o', 'BatchMode=yes',
99 '-L', "$dbport:127.0.0.1:5432",
107 my ($self, $cinfo) = @_;
109 foreach my $cpid (keys %$workers) {
110 my $ip = $workers->{$cpid}->{ip
};
111 my $dbport = $workers->{$cpid}->{dbport
};
112 my $cid = $workers->{$cpid}->{cid
};
115 foreach my $ni (values %{$cinfo->{ids
}}) {
116 my $ni_dbport = $cinfo->{dbport
}->{$ni->{cid
}};
117 $found = 1 if (($ni->{ip
} eq $ip) && ($ni_dbport eq $dbport));
120 my $role = $cinfo->{local}->{type
} // '-';
121 $found = 0 if $role eq '-';
124 syslog
('info', "trying to finish tunnel $cpid $ip");
126 $delayed_exec->{$cid} = time + ($startcount->{$cid} > 5 ?
60 : 10);
127 delete $workers->{$cpid};
139 syslog
('info' , "server closing");
141 foreach my $cpid (keys %$workers) {
142 if (kill (15, $cpid) || ! kill(0, $cpid)) {
143 my $ip = $workers->{$cpid}->{ip
};
144 delete $workers->{$cpid};
145 syslog
('info', "successfully deleted tunnel $cpid $ip");
150 1 while (waitpid(-1, POSIX
::WNOHANG
()) > 0);
152 # $self->exit_daemon(0);
158 $restart_request = 1;
166 local $SIG{CHLD
} = \
&finish_children
;
170 $next_update = time() + $updatetime;
173 my $cinfo = PMG
::ClusterConfig-
>new(); # reload
174 $self->purge_tunnels($cinfo);
175 $self->start_tunnels($cinfo);
180 syslog
('err', "status update error: $err");
184 while ((time() < $next_update) &&
185 ($wcount < $updatetime) && # protect against time wrap
186 !$restart_request && !$self->{terminate
}) {
190 $wcount++; sleep (1);
193 last if $self->{terminate
};
195 $self->restart_daemon() if $restart_request;
199 __PACKAGE__-
>register_method ({
203 description
=> "Print cluster tunnel status.",
205 additionalProperties
=> 0,
208 returns
=> { type
=> 'null' },
212 my $status = $daemon->running() ?
'running' : 'stopped';
219 $daemon->register_start_command("Start the Cluster Tunnel Daemon");
220 $daemon->register_stop_command("Stop the Cluster Tunnel Daemon");
221 $daemon->register_restart_command(1, "Restart the Cluster Tunnel Daemon");
224 start
=> [ __PACKAGE__
, 'start', []],
225 restart
=> [ __PACKAGE__
, 'restart', []],
226 stop
=> [ __PACKAGE__
, 'stop', []],
227 status
=> [ __PACKAGE__
, 'status', []]