diff --git a/tools/striker-manage-vnc-pipes b/tools/striker-manage-vnc-pipes index 50df21ee..71b1ee3b 100755 --- a/tools/striker-manage-vnc-pipes +++ b/tools/striker-manage-vnc-pipes @@ -88,6 +88,8 @@ WHERE server_uuid = ".$anvil->Database->quote($server_uuid)." my $results = $anvil->Database->query({ query => $query, source => $THIS_FILE, line => __LINE__ }); my $count = @{$results}; + $anvil->Log->variables({ source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query, count => $count }, prefix => "get_server_info" }); + if ($count == 1) { my $row = $results->[0]; @@ -205,34 +207,46 @@ sub is_websockify_exists my $ws_host_uuid = $parameters->{ws_host_uuid}; my $server_vnc_port = $parameters->{server_vnc_port}; + # Expect 0 to 1 record(s) because each VM server can only have 1 + # websockify instance (not considering shared VNC sessions). my $query = " SELECT - vnc.server_vnc_port, hos.host_name, vnc.ws_host_uuid, vnc.ws_pid, vnc.ws_source_port, vnc.ssh_tunnel_host_uuid -FROM - public.vnc_pipes AS vnc -JOIN - public.hosts AS hos -ON - vnc.ws_host_uuid = hos.host_uuid + a.server_vnc_port, + b.host_name, + a.ws_host_uuid, + a.ws_pid, + a.ws_dest_port, + a.ssh_tunnel_host_uuid +FROM vnc_pipes AS a +JOIN hosts AS b ON a.ws_host_uuid = b.host_uuid WHERE - vnc.server_uuid = ".$anvil->Database->quote($server_uuid)." + a.server_uuid = ".$anvil->Database->quote($server_uuid)." +AND + a.ws_host_uuid = ".$anvil->Database->quote($ws_host_uuid)." AND - vnc.ws_host_uuid = ".$anvil->Database->quote($ws_host_uuid)." + a.server_vnc_port IS NOT NULL +ORDER BY a.ws_pid DESC ;"; - my $results = $anvil->Database->query({ query => $query, source => $THIS_FILE, line => __LINE__ }); + my $results = $anvil->Database->query({ query => $query, source => $THIS_FILE, line => __LINE__ }); + my $count = @{$results}; + + $anvil->Log->variables({ source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query, count => $count }, prefix => "is_websockify_exists" }); + my $ws_exists_info = { exists_code => 0 }; foreach my $row (@{$results}) { - my $server_vnc_port_in_record = $row->[0] // 0; + my $server_vnc_port_in_record = $row->[0]; my $ws_host_name = $row->[1]; - my $ws_host_uuid_in_record = $row->[2] // ''; + my $ws_host_uuid_in_record = $row->[2]; my $ws_pid = $row->[3]; - my $ws_source_port = $row->[4]; + my $ws_dest_port = $row->[4]; my $ssh_tunnel_host_uuid = $row->[5]; my $clean_up_parameters = { host_name => $ws_host_name, ws_pid => $ws_pid }; + $ws_exists_info->{exists_code} = 1; + if ($ws_host_uuid ne $ws_host_uuid_in_record) { # VNC server host mismatch; try to stop the recorded instance. @@ -242,32 +256,25 @@ AND # No need to preserve the websockify source port in # this case because the tunnel will need to be replaced # as well. - $ws_exists_info->{exists_code} = 1; } elsif ($server_vnc_port != $server_vnc_port_in_record) { # VNC server port mismatch; try to stop the recorded instance. stop_websockify($clean_up_parameters); - $ws_exists_info->{ws_source_port} = $ws_source_port; - $ws_exists_info->{exists_code} = 1; + $ws_exists_info->{ws_dest_port} = $ws_dest_port; } elsif (not is_websockify_process($clean_up_parameters)) { # The recorded instance died. - $ws_exists_info->{ws_source_port} = $ws_source_port; - $ws_exists_info->{exists_code} = 1; + $ws_exists_info->{ws_dest_port} = $ws_dest_port; } else { # Found one websockify instance that passed all tests. - $ws_exists_info->{ws_pid} = $ws_pid; - $ws_exists_info->{ws_source_port} = $ws_source_port; - # Code 2: the websockify instance is not recorded for the pipe made from the current host, do update only. - # Code 3: the websockify instance is recorded for the pipe made from the current host, do nothing. - $ws_exists_info->{exists_code} = $host_uuid eq $ssh_tunnel_host_uuid ? 3 : 2; - # Don't continue the loop because all pipes should align to this verified instance. - last; + $ws_exists_info->{exists_code} = 2; + $ws_exists_info->{ws_pid} = $ws_pid; + $ws_exists_info->{ws_dest_port} = $ws_dest_port; } } @@ -282,66 +289,88 @@ sub is_ssh_tunnel_exists my $server_uuid = $parameters->{server_uuid}; my $ssh_tunnel_host_uuid = $parameters->{ssh_tunnel_host_uuid}; my $ws_host_uuid = $parameters->{ws_host_uuid}; - my $ws_source_port = $parameters->{ws_source_port}; - + my $ws_dest_port = $parameters->{ws_dest_port}; + + # Expect 0 to n record(s), where n is the number of subnodes: + # n=0: no SSH tunnel connected to the server's ws instance + # n>0: at least one SSH tunnel is known, regardless of whether it is + # actually alive + # + # Order by clause ensures NULL record(s) are at first. my $query = " SELECT - ws_host_uuid, ws_source_port, ssh_tunnel_pid, ssh_tunnel_forward_port -FROM - public.vnc_pipes + a.ws_host_uuid, + a.ws_pid, + a.ws_dest_port, + a.ssh_tunnel_dest_port, + b.host_name, + a.ssh_tunnel_host_uuid, + a.ssh_tunnel_pid, + a.ssh_tunnel_source_port +FROM vnc_pipes AS a +JOIN hosts AS b ON a.ssh_tunnel_host_uuid = b.host_uuid WHERE - server_uuid = ".$anvil->Database->quote($server_uuid)." + a.server_uuid = ".$anvil->Database->quote($server_uuid)." AND - ssh_tunnel_host_uuid = ".$anvil->Database->quote($ssh_tunnel_host_uuid)." + a.ssh_tunnel_host_uuid IS NOT NULL +ORDER BY a.ws_pid DESC ;"; - my $results = $anvil->Database->query({ query => $query, source => $THIS_FILE, line => __LINE__ }); - my $count = @{$results}; - my $ssh_tunnel_exists_info = { exists_code => 0 }; + my $results = $anvil->Database->query({ query => $query, source => $THIS_FILE, line => __LINE__ }); + my $count = @{$results}; - if ($count == 1) - { - my $row = $results->[0]; - my $ws_host_uuid_in_record = $row->[0] // ''; - my $ws_source_port_in_record = $row->[1] // 0; - my $ssh_tunnel_pid = $row->[2]; - my $ssh_tunnel_forward_port = $row->[3]; - my $clean_up_parameters = { ssh_tunnel_pid => $ssh_tunnel_pid }; + $anvil->Log->variables({ source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query, count => $count }, prefix => "is_ssh_tunnel_exists" }); - $ssh_tunnel_exists_info->{ssh_tunnel_pid} = $ssh_tunnel_pid; - $ssh_tunnel_exists_info->{ssh_tunnel_forward_port} = $ssh_tunnel_forward_port; - $ssh_tunnel_exists_info->{exists_code} = 1; + my $ssh_tunnel_exists_info = { exists_code => 0 }; - if ($ws_host_uuid ne $ws_host_uuid_in_record) + foreach my $row (@{$results}) + { + my $row = $results->[0]; + my $ws_host_uuid_in_record = $row->[0]; + my $ws_pid_in_record = $row->[1]; + my $ws_dest_port_in_record = $row->[2]; + my $ssh_tunnel_dest_port = $row->[3]; + my $ssh_tunnel_host_name = $row->[4]; + my $ssh_tunnel_host_uuid_in_record = $row->[5]; + my $ssh_tunnel_pid = $row->[6]; + my $ssh_tunnel_source_port = $row->[7]; + my $clean_up_parameters = { host_name => $ssh_tunnel_host_name, ssh_tunnel_pid => $ssh_tunnel_pid }; + + $ssh_tunnel_exists_info->{exists_code} = 1; + + if (not defined $ws_pid_in_record and defined $ssh_tunnel_pid) { - # Websockify host mismatch; try to stop the recorded instance. - # Likely happens after a server migration. + # Websockify instance doesn't exist but tunnel does. + # Remove the tunnel that's not connected to anything. stop_ssh_tunnel($clean_up_parameters); - # No need to preserve the SSH tunnel forward port in - # this case because the websockify instance will need - # to be replaced as well. - delete $ssh_tunnel_exists_info->{ssh_tunnel_forward_port}; + clear_vnc_pipe_st({ server_uuid => $server_uuid, ws_host_uuid => $ws_host_uuid_in_record }); - return $ssh_tunnel_exists_info; + # No need to preserve any tunnel info because this + # tunnel doesn't need to be recreated. } - - if ($ws_source_port != $ws_source_port_in_record) + elsif ($ssh_tunnel_source_port != $ws_dest_port_in_record) { - # Websockify source port mismatch; try to stop the recorded instance. + # Tunnel is not pointing to the destination port of the + # websockify instance; stop it and recreate. stop_ssh_tunnel($clean_up_parameters); - return $ssh_tunnel_exists_info; + # Port mismatch means we need to recreate the tunnel. + $ssh_tunnel_exists_info->{ssh_tunnel_dest_port} = $ssh_tunnel_dest_port; } - - if (not is_ssh_process($clean_up_parameters)) + elsif (not is_ssh_process($clean_up_parameters)) { - # The recorded tunnel died. - return $ssh_tunnel_exists_info; + # The tunnel pid doesn't point to an active tunnel; + # mark as need-to-be recreated. + $ssh_tunnel_exists_info->{ssh_tunnel_dest_port} = $ssh_tunnel_dest_port; + } + else + { + # Passed all tests; tunnel considered exists. + $ssh_tunnel_exists_info->{exists_code} = 2; + $ssh_tunnel_exists_info->{ssh_tunnel_dest_port} = $ssh_tunnel_dest_port; + $ssh_tunnel_exists_info->{ssh_tunnel_pid} = $ssh_tunnel_pid; } - - # Passed all tests; tunnel considered exists. - $ssh_tunnel_exists_info->{exists_code} = 2; } $anvil->Log->variables({ source => $THIS_FILE, line => __LINE__, level => 2, list => $ssh_tunnel_exists_info, prefix => "is_ssh_tunnel_exists" }); @@ -388,24 +417,19 @@ sub start_websockify server_vnc_port => $target_port }); - if ($ws_exists_info->{exists_code} =~ /^[23]$/) + if ($ws_exists_info->{exists_code} == 2) { $ws_info = {}; $ws_info->{pid} = $ws_exists_info->{ws_pid}; - $ws_info->{source_port} = $ws_exists_info->{ws_source_port}; - - if ($ws_exists_info->{exists_code} == 2) - { - $ws_info->{is_update} = 1; - } + $ws_info->{source_port} = $ws_exists_info->{ws_dest_port}; } else { if (not defined $source_port) { - if (defined $ws_exists_info->{ws_source_port}) + if (defined $ws_exists_info->{ws_dest_port}) { - $source_port = $ws_exists_info->{ws_source_port}; + $source_port = $ws_exists_info->{ws_dest_port}; } else { @@ -467,58 +491,58 @@ sub stop_websockify sub start_ssh_tunnel { - my $parameters = shift; - my $server_uuid = $parameters->{server_uuid}; - my $host_name = $parameters->{host_name}; - my $host_uuid = $parameters->{host_uuid}; - my $ws_host_name = $parameters->{ws_host_name}; - my $ws_host_uuid = $parameters->{ws_host_uuid}; - my $ws_source_port = $parameters->{ws_source_port}; - my $ssh_tunnel_forward_port = $parameters->{ssh_tunnel_forward_port}; + my $parameters = shift; + my $server_uuid = $parameters->{server_uuid}; + my $host_name = $parameters->{host_name}; + my $host_uuid = $parameters->{host_uuid}; + my $ws_host_name = $parameters->{ws_host_name}; + my $ws_host_uuid = $parameters->{ws_host_uuid}; + my $ws_dest_port = $parameters->{ws_dest_port}; + my $ssh_tunnel_dest_port = $parameters->{ssh_tunnel_dest_port}; my $ssh_tunnel_info; my $ssh_tunnel_exists_info = is_ssh_tunnel_exists({ server_uuid => $server_uuid, ssh_tunnel_host_uuid => $host_uuid, ws_host_uuid => $ws_host_uuid, - ws_source_port => $ws_source_port + ws_dest_port => $ws_dest_port }); if ($ssh_tunnel_exists_info->{exists_code} == 2) { $ssh_tunnel_info = {}; $ssh_tunnel_info->{pid} = $ssh_tunnel_exists_info->{ssh_tunnel_pid}; - $ssh_tunnel_info->{forward_port} = $ssh_tunnel_exists_info->{ssh_tunnel_forward_port}; + $ssh_tunnel_info->{forward_port} = $ssh_tunnel_exists_info->{ssh_tunnel_dest_port}; } else { - if (not defined $ssh_tunnel_forward_port) + if (not defined $ssh_tunnel_dest_port) { - if (defined $ssh_tunnel_exists_info->{ssh_tunnel_forward_port}) + if (defined $ssh_tunnel_exists_info->{ssh_tunnel_dest_port}) { - $ssh_tunnel_forward_port = $ssh_tunnel_exists_info->{ssh_tunnel_forward_port}; + $ssh_tunnel_dest_port = $ssh_tunnel_exists_info->{ssh_tunnel_dest_port}; } else { - $ssh_tunnel_forward_port = $ws_source_port; + $ssh_tunnel_dest_port = $ws_dest_port; } } - $ssh_tunnel_forward_port = get_available_port({ start_port => $ssh_tunnel_forward_port }); + $ssh_tunnel_dest_port = get_available_port({ start_port => $ssh_tunnel_dest_port }); $anvil->Log->variables({ source => $THIS_FILE, line => __LINE__, level => 2, list => { - ssh_tunnel_forward_port => $ssh_tunnel_forward_port + ssh_tunnel_dest_port => $ssh_tunnel_dest_port }, prefix => "start_ssh_tunnel" }); - if (not defined $ssh_tunnel_forward_port) + if (not defined $ssh_tunnel_dest_port) { return; } my $shell_call = $anvil->data->{path}{exe}{'striker-open-ssh-tunnel'} ." --remote-user admin --target ".$ws_host_name - ." --forward-local-port ".$ssh_tunnel_forward_port - ." --forward-remote-port ".$ws_source_port + ." --forward-local-port ".$ssh_tunnel_dest_port + ." --forward-remote-port ".$ws_dest_port ." &>/dev/null & echo pid:\$!"; my ($shell_output, $shell_error, $shell_return_code) = call({ host_name => $host_name, shell_call => $shell_call }); @@ -529,7 +553,7 @@ sub start_ssh_tunnel $ssh_tunnel_info = {}; $ssh_tunnel_info->{pid} = $ssh_tunnel_pid; - $ssh_tunnel_info->{forward_port} = $ssh_tunnel_forward_port; + $ssh_tunnel_info->{forward_port} = $ssh_tunnel_dest_port; if ($ssh_tunnel_exists_info->{exists_code} == 1) { @@ -567,10 +591,11 @@ CREATE TABLE IF NOT EXISTS public.vnc_pipes ( server_vnc_port numeric, ws_host_uuid uuid, ws_pid numeric, - ws_source_port numeric, + ws_dest_port numeric, + ssh_tunnel_dest_port numeric, ssh_tunnel_host_uuid uuid, ssh_tunnel_pid numeric, - ssh_tunnel_forward_port numeric, + ssh_tunnel_source_port numeric, modified_date timestamp with time zone not null, unique(server_uuid, ws_host_uuid) );"; @@ -592,14 +617,15 @@ sub insert_or_update_vnc_pipe return (1) if (not defined $server_uuid); - my $server_vnc_port = $parameters->{server_vnc_port}; - my $ssh_tunnel_forward_port = $parameters->{ssh_tunnel_forward_port}; - my $ssh_tunnel_host_uuid = $parameters->{ssh_tunnel_host_uuid}; - my $ssh_tunnel_pid = $parameters->{ssh_tunnel_pid}; - my $vnc_pipe_uuid = $parameters->{vnc_pipe_uuid} // $anvil->Get->uuid(); - my $ws_host_uuid = $parameters->{ws_host_uuid}; - my $ws_pid = $parameters->{ws_pid}; - my $ws_source_port = $parameters->{ws_source_port}; + my $server_vnc_port = $parameters->{server_vnc_port}; + my $ssh_tunnel_dest_port = $parameters->{ssh_tunnel_dest_port}; + my $ssh_tunnel_host_uuid = $parameters->{ssh_tunnel_host_uuid}; + my $ssh_tunnel_pid = $parameters->{ssh_tunnel_pid}; + my $ssh_tunnel_source_port = $parameters->{ssh_tunnel_source_port}; + my $vnc_pipe_uuid = $parameters->{vnc_pipe_uuid} // $anvil->Get->uuid(); + my $ws_host_uuid = $parameters->{ws_host_uuid}; + my $ws_pid = $parameters->{ws_pid}; + my $ws_dest_port = $parameters->{ws_dest_port}; $anvil->Log->variables({ source => $THIS_FILE, line => __LINE__, level => 2, list => $parameters, prefix => "insert_or_update_vnc_pipe" }); @@ -614,10 +640,11 @@ sub insert_or_update_vnc_pipe "server_vnc_port", "ws_host_uuid", "ws_pid", - "ws_source_port", + "ws_dest_port", + "ssh_tunnel_dest_port", "ssh_tunnel_host_uuid", "ssh_tunnel_pid", - "ssh_tunnel_forward_port" + "ssh_tunnel_source_port" ) { my $column_value = $parameters->{$column_name}; @@ -649,6 +676,45 @@ INSERT INTO public.vnc_pipes ( modified_date = $quoted_vnc_pipe_mdate;"; $anvil->Database->write({ query => $query, source => $THIS_FILE, line => __LINE__ }); + + return (0); +} + +sub clear_vnc_pipe_ws +{ + my $parameters = shift; + my $server_uuid = $parameters->{server_uuid}; + my $ws_host_uuid = $parameters->{ws_host_uuid}; + + return (1) if (not defined $ws_host_uuid); + + insert_or_update_vnc_pipe({ + server_uuid => $server_uuid, + server_vnc_port => "NULL", + ws_dest_port => "NULL", + ws_host_uuid => $ws_host_uuid, + ws_pid => "NULL" + }); + + return (0); +} + +sub clear_vnc_pipe_st +{ + my $parameters = shift; + my $server_uuid = $parameters->{server_uuid}; + my $ws_host_uuid = $parameters->{ws_host_uuid}; + + return (1) if (not defined $ws_host_uuid); + + insert_or_update_vnc_pipe({ + server_uuid => $server_uuid, + ssh_tunnel_dest_port => "NULL", + ssh_tunnel_host_uuid => "NULL", + ssh_tunnel_pid => "NULL", + ssh_tunnel_source_port => "NULL", + ws_host_uuid => $ws_host_uuid + }); } sub get_vnc_pipe @@ -658,56 +724,62 @@ sub get_vnc_pipe return if (not defined $server_uuid); + my $is_ws_pid = $parameters->{is_ws_pid}; my $ssh_tunnel_host_uuid = $parameters->{ssh_tunnel_host_uuid}; my $ws_host_uuid = $parameters->{ws_host_uuid}; my $vnc_pipe_info; + my $cond_ws_pid = defined $is_ws_pid + ? "AND a.ws_pid IS NOT NULL" : ""; my $cond_ssht_huuid = defined $ssh_tunnel_host_uuid - ? "AND ssh_tunnel_host_uuid = ".$anvil->Database->quote($ssh_tunnel_host_uuid) : ""; + ? "AND a.ssh_tunnel_host_uuid = ".$anvil->Database->quote($ssh_tunnel_host_uuid) : ""; my $cond_ws_huuid = defined $ws_host_uuid - ? "AND ws_host_uuid = ".$anvil->Database->quote($ws_host_uuid) : ""; + ? "AND a.ws_host_uuid = ".$anvil->Database->quote($ws_host_uuid) : ""; my $query = " SELECT - vnc.server_vnc_port, - hos.host_name, - vnc.ws_host_uuid, - vnc.ws_pid, - vnc.ws_source_port, - vnc.ssh_tunnel_host_uuid, - vnc.ssh_tunnel_pid, - vnc.ssh_tunnel_forward_port + a.server_vnc_port, + b.host_name, + a.ws_host_uuid, + a.ws_pid, + a.ws_dest_port, + a.ssh_tunnel_host_uuid, + a.ssh_tunnel_pid, + a.ssh_tunnel_dest_port FROM - public.vnc_pipes AS vnc + public.vnc_pipes AS a JOIN - public.hosts AS hos + public.hosts AS b ON - vnc.ws_host_uuid = hos.host_uuid + a.ws_host_uuid = b.host_uuid WHERE server_uuid = ".$anvil->Database->quote($server_uuid)." + $cond_ws_pid $cond_ssht_huuid $cond_ws_huuid ORDER BY - vnc.modified_date DESC + a.modified_date DESC ;"; my $results = $anvil->Database->query({ query => $query, source => $THIS_FILE, line => __LINE__ }); my $count = @{$results}; + $anvil->Log->variables({ source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query, count => $count }, prefix => "get_vnc_pipe" }); + if ($count == 1) { my $row = $results->[0]; - $vnc_pipe_info = {}; - $vnc_pipe_info->{server_vnc_port} = $row->[0]; - $vnc_pipe_info->{host_name} = $row->[1]; - $vnc_pipe_info->{ws_host_uuid} = $row->[2]; - $vnc_pipe_info->{ws_pid} = $row->[3]; - $vnc_pipe_info->{ws_source_port} = $row->[4]; - $vnc_pipe_info->{ssh_tunnel_host_uuid} = $row->[5]; - $vnc_pipe_info->{ssh_tunnel_pid} = $row->[6]; - $vnc_pipe_info->{ssh_tunnel_forward_port} = $row->[7]; + $vnc_pipe_info = {}; + $vnc_pipe_info->{server_vnc_port} = $row->[0]; + $vnc_pipe_info->{host_name} = $row->[1]; + $vnc_pipe_info->{ws_host_uuid} = $row->[2]; + $vnc_pipe_info->{ws_pid} = $row->[3]; + $vnc_pipe_info->{ws_dest_port} = $row->[4]; + $vnc_pipe_info->{ssh_tunnel_host_uuid} = $row->[5]; + $vnc_pipe_info->{ssh_tunnel_pid} = $row->[6]; + $vnc_pipe_info->{ssh_tunnel_dest_port} = $row->[7]; } $anvil->Log->variables({ source => $THIS_FILE, line => __LINE__, level => 2, list => $vnc_pipe_info, prefix => "get_vnc_pipe" }); @@ -753,7 +825,7 @@ sub open_ws server_vnc_port => $vnc_info->{port}, ws_host_uuid => $server_info->{host_uuid}, ws_pid => $ws_info->{pid}, - ws_source_port => $ws_info->{source_port} + ws_dest_port => $ws_info->{source_port} }); } @@ -776,13 +848,7 @@ sub close_ws stop_websockify({ host_name => $vnc_pipe_info->{host_name}, ws_pid => $vnc_pipe_info->{ws_pid} }); - insert_or_update_vnc_pipe({ - server_uuid => $server_uuid, - server_vnc_port => "NULL", - ws_host_uuid => $vnc_pipe_info->{ws_host_uuid}, - ws_pid => "NULL", - ws_source_port => "NULL" - }); + clear_vnc_pipe_ws({ server_uuid => $server_uuid, ws_host_uuid => $vnc_pipe_info->{ws_host_uuid} }); return (0); } @@ -801,16 +867,16 @@ sub open_st return (1, "error_0313") if (not defined $server_info); - my $vnc_pipe_info = get_vnc_pipe({ server_uuid => $server_uuid, ws_host_uuid => $server_info->{host_uuid} }); + my $vnc_pipe_info = get_vnc_pipe({ is_ws_pid => 1, server_uuid => $server_uuid, ws_host_uuid => $server_info->{host_uuid} }); return (1, "error_0317") if (not defined $vnc_pipe_info); my $ssh_tunnel_info = start_ssh_tunnel({ - server_uuid => $server_uuid, - host_uuid => $host_uuid, - ws_host_name => $vnc_pipe_info->{host_name}, - ws_host_uuid => $vnc_pipe_info->{ws_host_uuid}, - ws_source_port => $vnc_pipe_info->{ws_source_port} + server_uuid => $server_uuid, + host_uuid => $host_uuid, + ws_host_name => $vnc_pipe_info->{host_name}, + ws_host_uuid => $vnc_pipe_info->{ws_host_uuid}, + ws_dest_port => $vnc_pipe_info->{ws_dest_port} }); return (1, "error_0316") if (not defined $ssh_tunnel_info); @@ -818,11 +884,12 @@ sub open_st if ($ssh_tunnel_info->{is_new} or $ssh_tunnel_info->{is_update}) { insert_or_update_vnc_pipe({ - server_uuid => $server_uuid, - ssh_tunnel_host_uuid => $host_uuid, - ssh_tunnel_pid => $ssh_tunnel_info->{pid}, - ssh_tunnel_forward_port => $ssh_tunnel_info->{forward_port}, - ws_host_uuid => $vnc_pipe_info->{ws_host_uuid} + server_uuid => $server_uuid, + ssh_tunnel_dest_port => $ssh_tunnel_info->{forward_port}, + ssh_tunnel_host_uuid => $host_uuid, + ssh_tunnel_pid => $ssh_tunnel_info->{pid}, + ssh_tunnel_source_port => $vnc_pipe_info->{ws_dest_port}, + ws_host_uuid => $vnc_pipe_info->{ws_host_uuid} }); } @@ -852,104 +919,11 @@ sub close_st stop_ssh_tunnel({ ssh_tunnel_pid => $vnc_pipe_info->{ssh_tunnel_pid} }); - insert_or_update_vnc_pipe({ - server_uuid => $server_uuid, - ssh_tunnel_host_uuid => "NULL", - ssh_tunnel_pid => "NULL", - ssh_tunnel_forward_port => "NULL", - ws_host_uuid => $vnc_pipe_info->{ws_host_uuid} - }); + clear_vnc_pipe_st({ server_uuid => $server_uuid, ws_host_uuid => $vnc_pipe_info->{ws_host_uuid} }); return (0); } -sub handle_vnc_pipe_error -{ - my $error_key = shift; - my $parameters = shift; - my $host_uuid = $parameters->{host_uuid}; - my $server_uuid = $parameters->{server_uuid}; - - $anvil->Log->entry({ source => $THIS_FILE, line => __LINE__, level => 1, key => $error_key, variables => { - server_uuid => $server_uuid, - host_uuid => $host_uuid - } }); - - $anvil->Job->update_progress({ - progress => 100, - message => "$error_key,!!server_uuid!$server_uuid!!,!!host_uuid!$host_uuid!!", - job_status => "failed" - }); -} - -sub open_vnc_pipe -{ - my $parameters = shift; - my $host_uuid = $parameters->{host_uuid}; - my $is_print = $parameters->{print}; - my $server_host_uuid = $parameters->{server_host_uuid}; - my $server_uuid = $parameters->{server_uuid}; - my $server_vnc_port = $parameters->{server_vnc_port}; - - my $is_error; - my $open_output; - - my $open_params = { - host_uuid => $host_uuid, - print => $is_print, - server_info => get_server_info($parameters), - server_uuid => $server_uuid, - server_vnc_port => $server_vnc_port - }; - - ($is_error, $open_output) = open_ws($open_params); - - return handle_vnc_pipe_error($open_output, $open_params) if ($is_error); - - ($is_error, $open_output) = open_st($open_params); - - return handle_vnc_pipe_error($open_output, $open_params) if ($is_error); - - $anvil->Job->update_progress({ - progress => 100, - message => "message_0260,!!operation!opening!!,!!server_uuid!".$server_uuid."!!,!!host_uuid!".$host_uuid."!!" - }); - - return (0, { forward_port => $open_params->{forward_port} }); -} - -sub close_vnc_pipe -{ - my $parameters = shift; - my $host_uuid = $parameters->{host_uuid}; - my $server_uuid = $parameters->{server_uuid}; - - my $is_error; - my $close_output; - - my $close_params = { - host_uuid => $host_uuid, - server_uuid => $server_uuid, - vnc_pipe_info => get_vnc_pipe({ - server_uuid => $server_uuid, - ssh_tunnel_host_uuid => $host_uuid - }) - }; - - ($is_error, $close_output) = close_ws($close_params); - - return handle_vnc_pipe_error($close_output, $close_params) if ($is_error); - - ($is_error, $close_output) = close_st($close_params); - - return handle_vnc_pipe_error($close_output, $close_params) if ($is_error); - - $anvil->Job->update_progress({ - progress => 100, - message => "message_0260,!!operation!closing!!,!!server_uuid!".$server_uuid."!!,!!host_uuid!".$host_uuid."!!" - }); -} - $anvil->Get->switches; $anvil->Database->connect; @@ -1036,7 +1010,6 @@ $anvil->Log->variables({ source => $THIS_FILE, line => __LINE__, level => 2, lis } }); my $map_to_operation = { - all => { close => \&close_vnc_pipe, open => \&open_vnc_pipe }, st => { close => \&close_st, open => \&open_st }, ws => { close => \&close_ws, open => \&open_ws }, }; @@ -1055,14 +1028,39 @@ if ($server_uuid =~ /[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9]{3}- $anvil->Log->variables({ source => $THIS_FILE, line => __LINE__, level => 2, list => { operation => $op } }); - my ($is_error) = $ops->{$op}({ - host_uuid => $anvil->data->{sys}{host_uuid}, + my $host_uuid = $anvil->data->{sys}{host_uuid}; + + my ($is_error, $error) = $ops->{$op}({ + host_uuid => $host_uuid, server_host_uuid => $server_host_uuid, server_uuid => $server_uuid, server_vnc_port => $server_vnc_port }); - $anvil->nice_exit({ exit_code => 2 }) if ($is_error); + if ($is_error) + { + $anvil->Log->variables({ source => $THIS_FILE, line => __LINE__, level => 1, list => { + error => $error, + host_uuid => $host_uuid, + server_uuid => $server_uuid + } }); + + if (defined $error and $error =~ /^error_/) + { + $anvil->Job->update_progress({ + progress => 100, + message => "$error,!!server_uuid!$server_uuid!!,!!host_uuid!$host_uuid!!", + job_status => "failed" + }); + } + + $anvil->nice_exit({ exit_code => 2 }); + } + + $anvil->Job->update_progress({ + progress => 100, + message => "message_0260,!!operation!$op!!,!!server_uuid!$server_uuid!!,!!host_uuid!$host_uuid!!" + }); } elsif ($is_drop_table) {