mirror of
https://github.com/nestriness/cdc-file-transfer.git
synced 2026-01-30 10:35:37 +02:00
Implements the cdc_stream client and adjusts asset streaming in various places to work better outside of a GGP environment. This CL tries to get quoting for SSH commands right. It also brings back the ability to start a streaming session from asset_stream_manager. Also cleans up Bazel targets setup. Since the sln file is now in root, it is no longer necessary to prepend ../ to relative filenames to make clicking on errors work.
200 lines
8.1 KiB
C++
200 lines
8.1 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.
|
|
|
|
#include "asset_stream_manager/asset_stream_config.h"
|
|
|
|
#include <sstream>
|
|
|
|
#include "absl/flags/flag.h"
|
|
#include "absl/flags/parse.h"
|
|
#include "absl/strings/str_format.h"
|
|
#include "absl/strings/str_join.h"
|
|
#include "absl_helper/jedec_size_flag.h"
|
|
#include "common/buffer.h"
|
|
#include "common/path.h"
|
|
#include "common/status_macros.h"
|
|
#include "json/json.h"
|
|
|
|
ABSL_DECLARE_FLAG(int, verbosity);
|
|
ABSL_DECLARE_FLAG(bool, debug);
|
|
ABSL_DECLARE_FLAG(bool, singlethreaded);
|
|
ABSL_DECLARE_FLAG(bool, stats);
|
|
ABSL_DECLARE_FLAG(bool, quiet);
|
|
ABSL_DECLARE_FLAG(bool, check);
|
|
ABSL_DECLARE_FLAG(bool, log_to_stdout);
|
|
ABSL_DECLARE_FLAG(cdc_ft::JedecSize, cache_capacity);
|
|
ABSL_DECLARE_FLAG(uint32_t, cleanup_timeout);
|
|
ABSL_DECLARE_FLAG(uint32_t, access_idle_timeout);
|
|
ABSL_DECLARE_FLAG(int, manifest_updater_threads);
|
|
ABSL_DECLARE_FLAG(int, file_change_wait_duration_ms);
|
|
|
|
// Development flags.
|
|
ABSL_DECLARE_FLAG(std::string, dev_src_dir);
|
|
ABSL_DECLARE_FLAG(std::string, dev_user_host);
|
|
ABSL_DECLARE_FLAG(uint16_t, dev_ssh_port);
|
|
ABSL_DECLARE_FLAG(std::string, dev_ssh_command);
|
|
ABSL_DECLARE_FLAG(std::string, dev_scp_command);
|
|
ABSL_DECLARE_FLAG(std::string, dev_mount_dir);
|
|
|
|
// Declare AS20 flags, so that AS30 can be used on older SDKs simply by
|
|
// replacing the binary. Note that the RETIRED_FLAGS macro can't be used
|
|
// because the flags contain dashes. This code mimics the macro.
|
|
absl::flags_internal::RetiredFlag<std::string> RETIRED_FLAGS_session_ports;
|
|
absl::flags_internal::RetiredFlag<std::string> RETIRED_FLAGS_gm_mount_point;
|
|
absl::flags_internal::RetiredFlag<bool> RETIRED_FLAGS_allow_edge;
|
|
|
|
const auto RETIRED_FLAGS_REG_session_ports =
|
|
(RETIRED_FLAGS_session_ports.Retire("session-ports"),
|
|
::absl::flags_internal::FlagRegistrarEmpty{});
|
|
const auto RETIRED_FLAGS_REG_gm_mount_point =
|
|
(RETIRED_FLAGS_gm_mount_point.Retire("gamelet-mount-point"),
|
|
::absl::flags_internal::FlagRegistrarEmpty{});
|
|
const auto RETIRED_FLAGS_REG_allow_edge =
|
|
(RETIRED_FLAGS_allow_edge.Retire("allow-edge"),
|
|
::absl::flags_internal::FlagRegistrarEmpty{});
|
|
|
|
namespace cdc_ft {
|
|
|
|
AssetStreamConfig::AssetStreamConfig() {
|
|
session_cfg_.verbosity = absl::GetFlag(FLAGS_verbosity);
|
|
session_cfg_.fuse_debug = absl::GetFlag(FLAGS_debug);
|
|
session_cfg_.fuse_singlethreaded = absl::GetFlag(FLAGS_singlethreaded);
|
|
session_cfg_.stats = absl::GetFlag(FLAGS_stats);
|
|
session_cfg_.quiet = absl::GetFlag(FLAGS_quiet);
|
|
session_cfg_.fuse_check = absl::GetFlag(FLAGS_check);
|
|
log_to_stdout_ = absl::GetFlag(FLAGS_log_to_stdout);
|
|
session_cfg_.fuse_cache_capacity = absl::GetFlag(FLAGS_cache_capacity).Size();
|
|
session_cfg_.fuse_cleanup_timeout_sec = absl::GetFlag(FLAGS_cleanup_timeout);
|
|
session_cfg_.fuse_access_idle_timeout_sec =
|
|
absl::GetFlag(FLAGS_access_idle_timeout);
|
|
session_cfg_.manifest_updater_threads =
|
|
absl::GetFlag(FLAGS_manifest_updater_threads);
|
|
session_cfg_.file_change_wait_duration_ms =
|
|
absl::GetFlag(FLAGS_file_change_wait_duration_ms);
|
|
|
|
dev_src_dir_ = absl::GetFlag(FLAGS_dev_src_dir);
|
|
dev_target_.user_host = absl::GetFlag(FLAGS_dev_user_host);
|
|
dev_target_.ssh_port = absl::GetFlag(FLAGS_dev_ssh_port);
|
|
dev_target_.ssh_command = absl::GetFlag(FLAGS_dev_ssh_command);
|
|
dev_target_.scp_command = absl::GetFlag(FLAGS_dev_scp_command);
|
|
dev_target_.mount_dir = absl::GetFlag(FLAGS_dev_mount_dir);
|
|
}
|
|
|
|
AssetStreamConfig::~AssetStreamConfig() = default;
|
|
|
|
absl::Status AssetStreamConfig::LoadFromFile(const std::string& path) {
|
|
Buffer buffer;
|
|
RETURN_IF_ERROR(path::ReadFile(path, &buffer));
|
|
|
|
Json::Value config;
|
|
Json::Reader reader;
|
|
if (!reader.parse(buffer.data(), buffer.data() + buffer.size(), config,
|
|
false)) {
|
|
return absl::InvalidArgumentError(
|
|
absl::StrFormat("Failed to parse config file '%s': %s", path,
|
|
reader.getFormattedErrorMessages()));
|
|
}
|
|
|
|
#define ASSIGN_VAR(var, flag, type) \
|
|
do { \
|
|
if (config.isMember(#flag)) { \
|
|
var = config[#flag].as##type(); \
|
|
flags_read_from_file_.insert(#flag); \
|
|
} \
|
|
} while (0)
|
|
|
|
ASSIGN_VAR(session_cfg_.verbosity, verbosity, Int);
|
|
ASSIGN_VAR(session_cfg_.fuse_debug, debug, Bool);
|
|
ASSIGN_VAR(session_cfg_.fuse_singlethreaded, singlethreaded, Bool);
|
|
ASSIGN_VAR(session_cfg_.stats, stats, Bool);
|
|
ASSIGN_VAR(session_cfg_.quiet, quiet, Bool);
|
|
ASSIGN_VAR(session_cfg_.fuse_check, check, Bool);
|
|
ASSIGN_VAR(log_to_stdout_, log_to_stdout, Bool);
|
|
ASSIGN_VAR(session_cfg_.fuse_cleanup_timeout_sec, cleanup_timeout, Int);
|
|
ASSIGN_VAR(session_cfg_.fuse_access_idle_timeout_sec, access_idle_timeout,
|
|
Int);
|
|
ASSIGN_VAR(session_cfg_.manifest_updater_threads, manifest_updater_threads,
|
|
Int);
|
|
ASSIGN_VAR(session_cfg_.file_change_wait_duration_ms,
|
|
file_change_wait_duration_ms, Int);
|
|
|
|
// cache_capacity requires Jedec size conversion.
|
|
constexpr char kCacheCapacity[] = "cache_capacity";
|
|
if (config.isMember(kCacheCapacity)) {
|
|
JedecSize cache_capacity;
|
|
std::string error;
|
|
if (AbslParseFlag(config[kCacheCapacity].asString(), &cache_capacity,
|
|
&error)) {
|
|
session_cfg_.fuse_cache_capacity = cache_capacity.Size();
|
|
flags_read_from_file_.insert(kCacheCapacity);
|
|
} else {
|
|
// Note that |error| can't be logged here since this code runs before
|
|
// logging is initialized.
|
|
flag_read_errors_[kCacheCapacity] = error;
|
|
}
|
|
}
|
|
|
|
#undef ASSIGN_VAR
|
|
|
|
return absl::OkStatus();
|
|
} // namespace cdc_ft
|
|
|
|
std::string AssetStreamConfig::ToString() {
|
|
std::ostringstream ss;
|
|
ss << "verbosity = " << session_cfg_.verbosity
|
|
<< std::endl;
|
|
ss << "debug = " << session_cfg_.fuse_debug
|
|
<< std::endl;
|
|
ss << "singlethreaded = " << session_cfg_.fuse_singlethreaded
|
|
<< std::endl;
|
|
ss << "stats = " << session_cfg_.stats << std::endl;
|
|
ss << "quiet = " << session_cfg_.quiet << std::endl;
|
|
ss << "check = " << session_cfg_.fuse_check
|
|
<< std::endl;
|
|
ss << "log_to_stdout = " << log_to_stdout_ << std::endl;
|
|
ss << "cache_capacity = " << session_cfg_.fuse_cache_capacity
|
|
<< std::endl;
|
|
ss << "cleanup_timeout = "
|
|
<< session_cfg_.fuse_cleanup_timeout_sec << std::endl;
|
|
ss << "access_idle_timeout = "
|
|
<< session_cfg_.fuse_access_idle_timeout_sec << std::endl;
|
|
ss << "manifest_updater_threads = "
|
|
<< session_cfg_.manifest_updater_threads << std::endl;
|
|
ss << "file_change_wait_duration_ms = "
|
|
<< session_cfg_.file_change_wait_duration_ms << std::endl;
|
|
ss << "dev_src_dir = " << dev_src_dir_ << std::endl;
|
|
ss << "dev_user_host = " << dev_target_.user_host << std::endl;
|
|
ss << "dev_ssh_port = " << dev_target_.ssh_port << std::endl;
|
|
ss << "dev_ssh_command = " << dev_target_.ssh_command
|
|
<< std::endl;
|
|
ss << "dev_scp_command = " << dev_target_.scp_command
|
|
<< std::endl;
|
|
ss << "dev_mount_dir = " << dev_target_.mount_dir << std::endl;
|
|
return ss.str();
|
|
}
|
|
|
|
std::string AssetStreamConfig::GetFlagsReadFromFile() {
|
|
return absl::StrJoin(flags_read_from_file_, ", ");
|
|
}
|
|
|
|
std::string AssetStreamConfig::GetFlagReadErrors() {
|
|
std::string error_str;
|
|
for (const auto& [flag, error] : flag_read_errors_)
|
|
error_str += absl::StrFormat("%sFailed to read '%s': %s",
|
|
error_str.empty() ? "" : "\n", flag, error);
|
|
return error_str;
|
|
}
|
|
|
|
} // namespace cdc_ft
|