diff options
| author | Dan Engelbrecht <[email protected]> | 2023-09-22 08:22:06 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-09-22 14:22:06 +0200 |
| commit | c7d4dc6a4d13881028d566f5ce501335e47e48bf (patch) | |
| tree | 493110da583a8e5d97fe05e14f23469ee6244d2b /src/zen/cmds/serve.cpp | |
| parent | add trace command to enable/disable tracing at runtime (#416) (diff) | |
| download | archived-zen-c7d4dc6a4d13881028d566f5ce501335e47e48bf.tar.xz archived-zen-c7d4dc6a4d13881028d566f5ce501335e47e48bf.zip | |
Collect all zen admin-related commands into admin.h/.cpp (#418)
* move commands in scrub.h/cpp to admin_cmd.h/cpp
* move job command into admin_cmd.h/.cpp
* admin -> admin_cmd
* bench -> bench_cmd
* cache -> cache_cmd
* copy -> copy_cmd
* dedup -> dedup_cmd
* hash -> hash_cmd
* print -> print_cmd
* projectstore -> projectstore_cmd
* rpcreplay -> rpcreplay_cmd
* serve -> serve_cmd
* status -> status_cmd
* top -> top_cmd
* trace -> trace_cmd
* up -> up_cmd
* version -> version_cmd
Diffstat (limited to 'src/zen/cmds/serve.cpp')
| -rw-r--r-- | src/zen/cmds/serve.cpp | 242 |
1 files changed, 0 insertions, 242 deletions
diff --git a/src/zen/cmds/serve.cpp b/src/zen/cmds/serve.cpp deleted file mode 100644 index 72afc105d..000000000 --- a/src/zen/cmds/serve.cpp +++ /dev/null @@ -1,242 +0,0 @@ -// Copyright Epic Games, Inc. All Rights Reserved. - -#include "serve.h" - -#include <zencore/blake3.h> -#include <zencore/compactbinarybuilder.h> -#include <zencore/compactbinarypackage.h> -#include <zencore/filesystem.h> -#include <zencore/fmtutils.h> -#include <zenhttp/httpclient.h> -#include <zenutil/zenserverprocess.h> - -#if ZEN_PLATFORM_WINDOWS -# include <conio.h> // TEMPORARY HACK -#endif - -namespace zen { - -using namespace std::literals; - -ServeCommand::ServeCommand() -{ - m_Options.add_options()("h,help", "Print help"); - m_Options.add_option("", "u", "hosturl", "Host URL", cxxopts::value(m_HostName)->default_value(""), "<hosturl>"); - m_Options.add_option("", "p", "project", "Project name", cxxopts::value(m_ProjectName), "<projectid>"); - m_Options.add_option("", "o", "oplog", "Oplog name", cxxopts::value(m_OplogName), "<oplogid>"); - m_Options.add_option("", "", "path", "Root path to directory", cxxopts::value(m_RootPath), "<rootpath>"); - - m_Options.parse_positional({"project", "path"}); - m_Options.positional_help("[<projectid> <rootpath>]"); -} - -ServeCommand::~ServeCommand() -{ -} - -int -ServeCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) -{ - ZEN_UNUSED(GlobalOptions); - - if (!ParseOptions(argc, argv)) - { - return 0; - } - - if (m_ProjectName.empty()) - { - throw zen::OptionParseException("command requires a project"); - } - - if (m_OplogName.empty()) - { - if (auto pos = m_ProjectName.find_first_of('/'); pos != std::string::npos) - { - m_OplogName = m_ProjectName.substr(pos + 1); - m_ProjectName = m_ProjectName.substr(0, pos); - } - else - { - throw zen::OptionParseException("command requires an oplog"); - } - } - - if (m_RootPath.empty()) - { - throw zen::OptionParseException("command requires a root path"); - } - - if (!std::filesystem::exists(m_RootPath) || !std::filesystem::is_directory(m_RootPath)) - { - throw zen::OptionParseException(fmt::format("path must exist and must be a directory: '{}'", m_RootPath)); - } - - uint16_t ServerPort = 0; - m_HostName = ResolveTargetHostSpec(m_HostName, ServerPort); - - ZenServerEnvironment ServerEnvironment; - std::optional<ZenServerInstance> ServerInstance; - - if (m_HostName.empty()) - { - // Spawn a server - - try - { - std::filesystem::path ExePath = zen::GetRunningExecutablePath(); - - ServerEnvironment.Initialize(ExePath.parent_path()); - ServerInstance.emplace(ServerEnvironment); - ServerInstance->SetOwnerPid(zen::GetCurrentProcessId()); - ServerInstance->SpawnServerAndWait(ServerPort); - } - catch (std::exception& Ex) - { - ZEN_CONSOLE("failed to spawn server on port {}: '{}'", ServerPort, Ex.what()); - - throw zen::OptionParseException("unable to resolve server specification (even after spawning server)"); - } - } - else - { - std::filesystem::path ExePath = zen::GetRunningExecutablePath(); - - ServerEnvironment.Initialize(ExePath.parent_path()); - ServerInstance.emplace(ServerEnvironment); - ServerInstance->DisableShutdownOnDestroy(); - ServerInstance->AttachToRunningServer(); - } - - if (ServerInstance) - { - m_HostName = ServerInstance->GetBaseUri(); - ZEN_CONSOLE("base uri: {}", m_HostName); - } - - // Generate manifest for tree - - FileSystemTraversal Traversal; - - struct FsVisitor : public FileSystemTraversal::TreeVisitor - { - virtual void VisitFile(const std::filesystem::path& Parent, const path_view& File, uint64_t FileSize) override - { - std::filesystem::path ServerPath = std::filesystem::relative(Parent / File, RootPath); - std::string ServerPathString = reinterpret_cast<const char*>(ServerPath.generic_u8string().c_str()); - - if (ServerPathString.starts_with("./")) - { - ServerPathString = ServerPathString.substr(2); - } - - Files.emplace_back(FileEntry{ServerPathString, ServerPathString, FileSize}); - } - - virtual bool VisitDirectory(const std::filesystem::path&, const path_view&) override { return true; } - - struct FileEntry - { - std::string FilePath; - std::string ClientFilePath; - uint64_t FileSize; - }; - - std::filesystem::path RootPath; - std::vector<FileEntry> Files; - }; - - FsVisitor Visitor; - Visitor.RootPath = m_RootPath; - Traversal.TraverseFileSystem(m_RootPath, Visitor); - - CbObjectWriter Cbo; - - Cbo << "key" - << "file_manifest"; - - Cbo.BeginArray("files"); - - for (const FsVisitor::FileEntry& Entry : Visitor.Files) - { - ZEN_CONSOLE("file: {}", Entry.FilePath); - - Cbo.BeginObject(); - - BLAKE3 Hash = BLAKE3::HashMemory(Entry.ClientFilePath.data(), Entry.ClientFilePath.size()); - Hash.Hash[11] = 7; // FIoChunkType::ExternalFile - Oid FileChunkId = Oid::FromMemory(Hash.Hash); - - Cbo << "id"sv << FileChunkId; - Cbo << "serverpath"sv << Entry.FilePath; - Cbo << "clientpath"sv << Entry.ClientFilePath; - - Cbo.EndObject(); - } - - Cbo.EndArray(); - - CbObject Manifest = Cbo.Save(); - - // Persist manifest - - const std::string ProjectUri = fmt::format("/prj/{}", m_ProjectName); - const std::string ProjectOplogUri = fmt::format("/prj/{}/oplog/{}", m_ProjectName, m_OplogName); - - HttpClient Client(m_HostName); - - // Ensure project exists - - if (HttpClient::Response ProjectResponse = Client.Get(ProjectUri); !ProjectResponse) - { - // Create project - - CbObjectWriter Project; - - Project << "root" << m_RootPath; - - if (auto NewProjectResponse = Client.Post(ProjectUri, Project.Save()); !NewProjectResponse) - { - // TODO: include details - throw std::runtime_error("failed to create project"); - } - } - - // Ensure oplog exists - - if (HttpClient::Response OplogResponse = Client.Get(ProjectOplogUri); !OplogResponse) - { - // Create oplog - - CbObjectWriter Oplog; - - if (auto NewOplogResponse = Client.Post(ProjectOplogUri, Oplog.Save()); !NewOplogResponse) - { - // TODO: include details - throw std::runtime_error("failed to create oplog"); - } - } - - // Append manifest - - const std::string Uri = fmt::format("/prj/{}/oplog/{}/new", m_ProjectName, m_OplogName); - - HttpClient::Response HttpResponse = Client.Post(Uri, Manifest); - - if (!HttpResponse) - { - ZEN_CONSOLE("error: failed to append manifest!"); - - return 1; - } - - ZEN_CONSOLE("ok serving files now"); - -#if ZEN_PLATFORM_WINDOWS - _getch(); // TEMPORARY HACK -#endif - - return 0; -} - -} // namespace zen |