]>
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 '-o', "HostKeyAlias=$ni->{name}",
100 '-L', "$dbport:/var/run/postgresql/.s.PGSQL.5432",
108 my ($self, $cinfo) = @_;
110 foreach my $cpid (keys %$workers) {
111 my $ip = $workers->{$cpid}->{ip
};
112 my $dbport = $workers->{$cpid}->{dbport
};
113 my $cid = $workers->{$cpid}->{cid
};
116 foreach my $ni (values %{$cinfo->{ids
}}) {
117 my $ni_dbport = $cinfo->{dbport
}->{$ni->{cid
}};
118 $found = 1 if (($ni->{ip
} eq $ip) && ($ni_dbport eq $dbport));
121 my $role = $cinfo->{local}->{type
} // '-';
122 $found = 0 if $role eq '-';
125 syslog
('info', "trying to finish tunnel $cpid $ip");
127 $delayed_exec->{$cid} = time + ($startcount->{$cid} > 5 ?
60 : 10);
128 delete $workers->{$cpid};
140 syslog
('info' , "server closing");
142 foreach my $cpid (keys %$workers) {
143 if (kill (15, $cpid) || ! kill(0, $cpid)) {
144 my $ip = $workers->{$cpid}->{ip
};
145 delete $workers->{$cpid};
146 syslog
('info', "successfully deleted tunnel $cpid $ip");
151 1 while (waitpid(-1, POSIX
::WNOHANG
()) > 0);
153 # $self->exit_daemon(0);
159 $restart_request = 1;
167 local $SIG{CHLD
} = \
&finish_children
;
171 $next_update = time() + $updatetime;
174 my $cinfo = PMG
::ClusterConfig-
>new(); # reload
175 $self->purge_tunnels($cinfo);
176 $self->start_tunnels($cinfo);
181 syslog
('err', "status update error: $err");
185 while ((time() < $next_update) &&
186 ($wcount < $updatetime) && # protect against time wrap
187 !$restart_request && !$self->{terminate
}) {
191 $wcount++; sleep (1);
194 last if $self->{terminate
};
196 $self->restart_daemon() if $restart_request;
200 __PACKAGE__-
>register_method ({
204 description
=> "Print cluster tunnel status.",
206 additionalProperties
=> 0,
209 returns
=> { type
=> 'null' },
213 my $status = $daemon->running() ?
'running' : 'stopped';
220 $daemon->register_start_command("Start the Cluster Tunnel Daemon");
221 $daemon->register_stop_command("Stop the Cluster Tunnel Daemon");
222 $daemon->register_restart_command(1, "Restart the Cluster Tunnel Daemon");
225 start
=> [ __PACKAGE__
, 'start', []],
226 restart
=> [ __PACKAGE__
, 'restart', []],
227 stop
=> [ __PACKAGE__
, 'stop', []],
228 status
=> [ __PACKAGE__
, 'status', []]