mirror of
https://github.com/nestriness/cdc-file-transfer.git
synced 2026-01-30 12:25:35 +02:00
Adds a flag to set the SSH forwarding port or port range used for 'cdc_stream start-service' and 'cdc_rsync'. If a single number is passed, e.g. --forward-port 12345, then this port is used without checking availability of local and remote ports. If the port is taken, this results in an error when trying to connect. Note that this restricts the number of connections that stream can make to one. If a range is passed, e.g. --forward-port 45000-46000, the tools search for available ports locally and remotely in that range. This is more robust, but a bit slower due to the extra overhead. Optimizes port_manager_win as it was very slow for a large port range. It's still not optimal, but the time needed to scan 30k ports is << 1 seconds now. Fixes #12
155 lines
4.7 KiB
C++
155 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.
|
|
*/
|
|
|
|
#ifndef CDC_RSYNC_CDC_RSYNC_CLIENT_H_
|
|
#define CDC_RSYNC_CDC_RSYNC_CLIENT_H_
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "absl/status/status.h"
|
|
#include "cdc_rsync/base/message_pump.h"
|
|
#include "cdc_rsync/client_socket.h"
|
|
#include "cdc_rsync/progress_tracker.h"
|
|
#include "common/path_filter.h"
|
|
#include "common/port_manager.h"
|
|
#include "common/remote_util.h"
|
|
|
|
namespace cdc_ft {
|
|
|
|
class Process;
|
|
class ZstdStream;
|
|
|
|
class CdcRsyncClient {
|
|
public:
|
|
struct Options {
|
|
bool delete_ = false;
|
|
bool recursive = false;
|
|
int verbosity = 0;
|
|
bool quiet = false;
|
|
bool whole_file = false;
|
|
bool relative = false;
|
|
bool compress = false;
|
|
bool checksum = false;
|
|
bool dry_run = false;
|
|
bool existing = false;
|
|
bool json = false;
|
|
std::string copy_dest;
|
|
int compress_level = 6;
|
|
int connection_timeout_sec = 10;
|
|
int forward_port_first = 44450;
|
|
int forward_port_last = 44459;
|
|
std::string ssh_command;
|
|
std::string scp_command;
|
|
std::string sources_dir; // Base dir for files loaded for --files-from.
|
|
PathFilter filter;
|
|
|
|
// Compression level 0 is invalid.
|
|
static constexpr int kMinCompressLevel = -5;
|
|
static constexpr int kMaxCompressLevel = 22;
|
|
};
|
|
|
|
CdcRsyncClient(const Options& options, std::vector<std::string> sources,
|
|
std::string user_host, std::string destination);
|
|
|
|
~CdcRsyncClient();
|
|
|
|
// Deploys the server if necessary, starts it and runs the rsync procedure.
|
|
absl::Status Run();
|
|
|
|
private:
|
|
// Starts the server process. If the method returns a status with tag
|
|
// |kTagDeployServer|, Run() calls DeployServer() and tries again.
|
|
absl::Status StartServer();
|
|
|
|
// Stops the server process.
|
|
absl::Status StopServer();
|
|
|
|
// Handler for stdout and stderr data emitted by the server.
|
|
absl::Status HandleServerOutput(const char* data);
|
|
|
|
// Runs the rsync procedure.
|
|
absl::Status Sync();
|
|
|
|
// Copies all gamelet components to the gamelet.
|
|
absl::Status DeployServer();
|
|
|
|
// Sends relevant options to the server.
|
|
absl::Status SendOptions();
|
|
|
|
// Finds all source files and sends the file infos to the server.
|
|
absl::Status FindAndSendAllSourceFiles();
|
|
|
|
// Receives the stats from the file diffs (e.g. number of missing, changed
|
|
// etc. files) from the server.
|
|
absl::Status ReceiveFileStats();
|
|
|
|
// Receives paths of deleted files and prints them out.
|
|
absl::Status ReceiveDeletedFiles();
|
|
|
|
// Receives file indices from the server. Used for missing and changed files.
|
|
absl::Status ReceiveFileIndices(const char* file_type,
|
|
std::vector<uint32_t>* file_indices);
|
|
|
|
// Copies missing files to the server.
|
|
absl::Status SendMissingFiles();
|
|
|
|
// Core rsync algorithm. Receives signatures of changed files from server,
|
|
// calculates the diffs and sends them to the server.
|
|
absl::Status ReceiveSignaturesAndSendDelta();
|
|
|
|
// Start the zstd compression stream. Used before file copy and diff.
|
|
absl::Status StartCompressionStream();
|
|
|
|
// Stops the zstd compression stream.
|
|
absl::Status StopCompressionStream();
|
|
|
|
Options options_;
|
|
std::vector<std::string> sources_;
|
|
const std::string destination_;
|
|
WinProcessFactory process_factory_;
|
|
RemoteUtil remote_util_;
|
|
PortManager port_manager_;
|
|
ClientSocket socket_;
|
|
MessagePump message_pump_{&socket_, MessagePump::PacketReceivedDelegate()};
|
|
ConsoleProgressPrinter printer_;
|
|
ProgressTracker progress_;
|
|
std::unique_ptr<ZstdStream> compression_stream_;
|
|
|
|
std::unique_ptr<Process> server_process_;
|
|
std::string server_output_; // Written in a background thread. Do not access
|
|
std::string server_error_; // while the server process is active.
|
|
int server_exit_code_ = 0;
|
|
std::atomic_bool is_server_listening_{false};
|
|
bool is_server_error_ = false;
|
|
|
|
// All source files found on the client.
|
|
std::vector<ClientFileInfo> files_;
|
|
|
|
// All source dirs found on the client.
|
|
std::vector<ClientDirInfo> dirs_;
|
|
|
|
// Indices (into files_) of files that are missing on the server.
|
|
std::vector<uint32_t> missing_file_indices_;
|
|
|
|
// Indices (into files_) of files that exist, but are different on the server.
|
|
std::vector<uint32_t> changed_file_indices_;
|
|
};
|
|
|
|
} // namespace cdc_ft
|
|
|
|
#endif // CDC_RSYNC_CDC_RSYNC_CLIENT_H_
|