Files
netris-cdc-file-transfer/cdc_rsync/main.cc
Lutz Justen f8438aec66 [cdc_rsync] [cdc_stream] Remove SSH port argument (#41)
This CL removes the port arguments for both tools.

The port argument can also be specified via the ssh-command and
scp-command flags. In fact, if a port is specified by both port flags
and ssh/scp commands, they interfere with each other. For ssh, the one
specified in ssh-command wins. For scp, the one specified in
scp-command wins. To fix this, one would have to parse scp-command and
remove the port arg there. Or we could just remove the ssh-port arg.
This is what this CL does. Note that if you need a custom port, it's
very likely that you also have to define custom ssh and scp commands.
2022-12-12 10:58:33 +01:00

148 lines
4.7 KiB
C++

// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>
#include <vector>
#include "cdc_rsync/cdc_rsync_client.h"
#include "cdc_rsync/params.h"
#include "common/log.h"
#include "common/status.h"
#include "common/util.h"
namespace {
enum class ReturnCode {
// No error. Will match the tool's exit code, so OK must be 0.
kOk = 0,
// Generic error.
kGenericError = 1,
// Server connection timed out.
kConnectionTimeout = 2,
// Connection to the server was shut down unexpectedly.
kConnectionLost = 3,
// Binding to the forward port failed, probably because there's another
// instance of cdc_rsync running.
kAddressInUse = 4,
// Server deployment failed. This should be rare, it means that the server
// components were successfully copied, but the up-to-date check still fails.
kDeployFailed = 5,
};
ReturnCode TagToMessage(cdc_ft::Tag tag,
const cdc_ft::params::Parameters& params,
std::string* msg) {
msg->clear();
switch (tag) {
case cdc_ft::Tag::kSocketEof:
// Receiving pipe end was shut down unexpectedly.
*msg = "The connection to the instance was shut down unexpectedly.";
return ReturnCode::kConnectionLost;
case cdc_ft::Tag::kAddressInUse:
*msg =
"Failed to establish a connection to the instance. All ports are "
"already in use. This can happen if another instance of this command "
"is running. Currently, only 10 simultaneous connections are "
"supported.";
return ReturnCode::kAddressInUse;
case cdc_ft::Tag::kDeployServer:
*msg =
"Failed to deploy the instance components for unknown reasons. "
"Please report this issue.";
return ReturnCode::kDeployFailed;
case cdc_ft::Tag::kConnectionTimeout:
// Server connection timed out. SSH probably stale.
*msg = absl::StrFormat(
"Server connection timed out. Verify that the host '%s' "
"is correct, or specify a larger timeout with --contimeout.",
params.user_host);
return ReturnCode::kConnectionTimeout;
case cdc_ft::Tag::kCount:
return ReturnCode::kGenericError;
}
// Should not happen (TM). Will fall back to status message in this case.
return ReturnCode::kGenericError;
}
} // namespace
int wmain(int argc, wchar_t* argv[]) {
// Convert args from wide to UTF8 strings.
std::vector<std::string> utf8_str_args;
utf8_str_args.reserve(argc);
for (int i = 0; i < argc; i++) {
utf8_str_args.push_back(cdc_ft::Util::WideToUtf8Str(argv[i]));
}
// Convert args from UTF8 strings to UTF8 c-strings.
std::vector<const char*> utf8_args;
utf8_args.reserve(argc);
for (const auto& utf8_str_arg : utf8_str_args) {
utf8_args.push_back(utf8_str_arg.c_str());
}
// Read parameters from the environment and the command line.
cdc_ft::params::Parameters parameters;
if (!cdc_ft::params::Parse(argc, utf8_args.data(), &parameters)) {
return 1;
}
// Initialize logging.
cdc_ft::LogLevel log_level =
cdc_ft::Log::VerbosityToLogLevel(parameters.options.verbosity);
cdc_ft::Log::Initialize(std::make_unique<cdc_ft::ConsoleLog>(log_level));
// Run rsync.
cdc_ft::CdcRsyncClient client(parameters.options, parameters.sources,
parameters.user_host, parameters.destination);
absl::Status status = client.Run();
if (status.ok()) {
return static_cast<int>(ReturnCode::kOk);
}
// Get an error message from the tag associated with the status.
std::string error_message;
ReturnCode code = ReturnCode::kGenericError;
absl::optional<cdc_ft::Tag> tag = cdc_ft::GetTag(status);
if (tag.has_value()) {
code = TagToMessage(tag.value(), parameters, &error_message);
}
// Fall back to status message if there was no tag.
if (error_message.empty()) {
error_message = status.message();
} else if (parameters.options.verbosity >= 2) {
// In verbose mode, log the status as well, so nothing gets lost.
LOG_ERROR("%s", status.ToString());
}
if (!error_message.empty()) {
fprintf(stderr, "Error: %s\n", error_message.c_str());
}
return static_cast<int>(code);
}