[cdc_stream] Append errors from netstart to status (#9)

So far, errors from the remote netstat process would only be logged in
the asset stream service, for instance when SSH auth failed. However,
the errors were not shown to the client, and that's the most important
thing.

Also adds some feedback to cdc_stream in case of success.
This commit is contained in:
Lutz Justen
2022-11-21 09:07:05 +01:00
committed by GitHub
parent 269fb2be45
commit bccc025945
6 changed files with 43 additions and 30 deletions

View File

@@ -127,18 +127,17 @@ absl::StatusOr<int> PortManager::ReservePort(bool check_remote,
std::unordered_set<int> local_ports;
ASSIGN_OR_RETURN(local_ports,
FindAvailableLocalPorts(first_port_, last_port_, "127.0.0.1",
process_factory_, false),
process_factory_),
"Failed to find available ports on workstation");
// Find available port on remote instance.
std::unordered_set<int> remote_ports = local_ports;
if (check_remote) {
ASSIGN_OR_RETURN(
remote_ports,
FindAvailableRemotePorts(first_port_, last_port_, "0.0.0.0",
process_factory_, remote_util_,
remote_timeout_sec, false, steady_clock_),
"Failed to find available ports on instance");
ASSIGN_OR_RETURN(remote_ports,
FindAvailableRemotePorts(
first_port_, last_port_, "0.0.0.0", process_factory_,
remote_util_, remote_timeout_sec, steady_clock_),
"Failed to find available ports on instance");
}
// Fetch shared memory.
@@ -206,7 +205,7 @@ absl::Status PortManager::ReleasePort(int port) {
// static
absl::StatusOr<std::unordered_set<int>> PortManager::FindAvailableLocalPorts(
int first_port, int last_port, const char* ip,
ProcessFactory* process_factory, bool forward_output_to_log) {
ProcessFactory* process_factory) {
// -a to get the connection and ports the computer is listening on.
// -n to get numerical addresses to avoid the overhead of determining names.
// -p tcp to limit the output to TCPv4 connections.
@@ -220,10 +219,16 @@ absl::StatusOr<std::unordered_set<int>> PortManager::FindAvailableLocalPorts(
output.append(data, data_size);
return absl::OkStatus();
};
start_info.forward_output_to_log = forward_output_to_log;
std::string errors;
start_info.stderr_handler = [&errors](const char* data, size_t data_size) {
errors.append(data, data_size);
return absl::OkStatus();
};
absl::Status status = process_factory->Run(start_info);
if (!status.ok()) return WrapStatus(status, "Failed to run netstat");
if (!status.ok()) {
return WrapStatus(status, "Failed to run netstat:\n%s", errors);
}
LOG_DEBUG("netstat (workstation) output:\n%s", output);
return FindAvailablePorts(first_port, last_port, output, ip);
@@ -233,7 +238,7 @@ absl::StatusOr<std::unordered_set<int>> PortManager::FindAvailableLocalPorts(
absl::StatusOr<std::unordered_set<int>> PortManager::FindAvailableRemotePorts(
int first_port, int last_port, const char* ip,
ProcessFactory* process_factory, RemoteUtil* remote_util, int timeout_sec,
bool forward_output_to_log, SteadyClock* steady_clock) {
SteadyClock* steady_clock) {
// --numeric to get numerical addresses.
// --listening to get only listening sockets.
// --tcp to get only TCP connections.
@@ -247,12 +252,15 @@ absl::StatusOr<std::unordered_set<int>> PortManager::FindAvailableRemotePorts(
output.append(data, data_size);
return absl::OkStatus();
};
start_info.forward_output_to_log = forward_output_to_log;
std::string errors;
start_info.stderr_handler = [&errors](const char* data, size_t data_size) {
errors.append(data, data_size);
return absl::OkStatus();
};
std::unique_ptr<Process> process = process_factory->Create(start_info);
absl::Status status = process->Start();
if (!status.ok())
return WrapStatus(status, "Failed to start netstat process");
if (!status.ok()) return WrapStatus(status, "Failed to start netstat");
Stopwatch timeout_timer(steady_clock);
bool is_timeout = false;
@@ -266,8 +274,10 @@ absl::StatusOr<std::unordered_set<int>> PortManager::FindAvailableRemotePorts(
return absl::DeadlineExceededError("Timeout while running netstat");
uint32_t exit_code = process->ExitCode();
if (exit_code != 0)
return MakeStatus("netstat process exited with code %u", exit_code);
if (exit_code != 0) {
return MakeStatus("netstat process exited with code %u:\n%s", exit_code,
errors);
}
LOG_DEBUG("netstat (instance) output:\n%s", output);
return FindAvailablePorts(first_port, last_port, output, ip);