/* * 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 #include #include "absl/status/status.h" #include "absl/status/statusor.h" #include "cdc_rsync/base/message_pump.h" #include "cdc_rsync/progress_tracker.h" #include "common/client_socket.h" #include "common/path_filter.h" #include "common/process.h" namespace cdc_ft { class PortManager; class Process; class RemoteUtil; class ServerArch; 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 sftp_command; std::string sources_dir; // Base dir for files loaded for --files-from. PathFilter filter; // Backwards compatibility for switching from scp to sftp. // Used internally, do not use. std::string deprecated_scp_command; // Compression level 0 is invalid. static constexpr int kMinCompressLevel = -5; static constexpr int kMaxCompressLevel = 22; }; CdcRsyncClient(const Options& options, std::vector 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(const ServerArch& arch); // 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(const ServerArch& arch); // 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* 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(); // Returns true if the target is a remote target. bool IsRemoteConnection() const { return remote_util_ != nullptr; } Options options_; std::vector sources_; const std::string destination_; WinProcessFactory process_factory_; std::unique_ptr remote_util_; std::unique_ptr port_manager_; std::unique_ptr socket_finalizer_; ClientSocket socket_; MessagePump message_pump_{&socket_, MessagePump::PacketReceivedDelegate()}; ConsoleProgressPrinter printer_; ProgressTracker progress_; std::unique_ptr compression_stream_; std::unique_ptr server_process_; std::unique_ptr port_forwarding_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_int server_listen_port_{0}; bool is_server_error_ = false; // All source files found on the client. std::vector files_; // All source dirs found on the client. std::vector dirs_; // Indices (into files_) of files that are missing on the server. std::vector missing_file_indices_; // Indices (into files_) of files that exist, but are different on the server. std::vector changed_file_indices_; }; } // namespace cdc_ft #endif // CDC_RSYNC_CDC_RSYNC_CLIENT_H_