From aa6351f7c6ce41350aecff7d77d3dff1705f5a59 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Wed, 4 Sep 2024 16:34:50 +0700 Subject: [PATCH] feat: cortex update command --- engine/commands/cortex_upd_cmd.cc | 143 ++++++++++++++++++++++ engine/commands/cortex_upd_cmd.h | 15 +++ engine/controllers/command_line_parser.cc | 15 ++- engine/services/download_service.h | 2 +- 4 files changed, 173 insertions(+), 2 deletions(-) create mode 100644 engine/commands/cortex_upd_cmd.cc create mode 100644 engine/commands/cortex_upd_cmd.h diff --git a/engine/commands/cortex_upd_cmd.cc b/engine/commands/cortex_upd_cmd.cc new file mode 100644 index 000000000..c05ecea16 --- /dev/null +++ b/engine/commands/cortex_upd_cmd.cc @@ -0,0 +1,143 @@ +// clang-format off +#include "utils/cortex_utils.h" +// clang-format on +#include "cortex_upd_cmd.h" +#include "httplib.h" +#include "nlohmann/json.hpp" +#include "services/download_service.h" +#include "utils/archive_utils.h" +#include "utils/logging_utils.h" +#include "utils/system_info_utils.h" +#if defined(_WIN32) || defined(__linux__) +#include "utils/file_manager_utils.h" +#endif + +namespace commands { +CortexUpdCmd::CortexUpdCmd() {} + +void CortexUpdCmd::Exec() { + std::cout << "1" << std::endl; + // Check if the architecture and OS are supported + auto system_info = system_info_utils::GetSystemInfo(); + if (system_info.arch == system_info_utils::kUnsupported || + system_info.os == system_info_utils::kUnsupported) { + CTL_ERR("Unsupported OS or architecture: " << system_info.os << ", " + << system_info.arch); + return; + } + CTL_INF("OS: " << system_info.os << ", Arch: " << system_info.arch); + + // Download file + constexpr auto github_host = "https://api.github.com"; + // std::string version = version_.empty() ? "latest" : version_; + std::string version = "latest"; + std::ostringstream release_path; + release_path << "/repos/janhq/cortex.cpp/releases/" << version; + CTL_INF("Engine release path: " << github_host << release_path.str()); + + httplib::Client cli(github_host); + if (auto res = cli.Get(release_path.str())) { + if (res->status == httplib::StatusCode::OK_200) { + try { + auto jsonResponse = nlohmann::json::parse(res->body); + auto assets = jsonResponse["assets"]; + auto os_arch{system_info.os + "-" + system_info.arch}; + + std::string matched_variant = ""; + for (auto& asset : assets) { + auto asset_name = asset["name"].get(); + if (asset_name.find("cortex-cpp") != std::string::npos && + asset_name.find(os_arch) != std::string::npos) { + matched_variant = asset_name; + break; + } + CTL_INF(asset_name); + } + if (matched_variant.empty()) { + CTL_ERR("No variant found for " << os_arch); + return; + } + CTL_INF("Matched variant: " << matched_variant); + + for (auto& asset : assets) { + auto asset_name = asset["name"].get(); + if (asset_name == matched_variant) { + std::string host{"https://github.com"}; + + auto full_url = asset["browser_download_url"].get(); + std::string path = full_url.substr(host.length()); + + auto fileName = asset["name"].get(); + CTL_INF("URL: " << full_url); + + auto download_task = DownloadTask{.id = "cortex", + .type = DownloadType::Cortex, + .error = std::nullopt, + .items = {DownloadItem{ + .id = "cortex", + .host = host, + .fileName = fileName, + .type = DownloadType::Cortex, + .path = path, + }}}; + + DownloadService download_service; + download_service.AddDownloadTask( + download_task, + [this](const std::string& absolute_path, bool unused) { + // try to unzip the downloaded file + std::filesystem::path download_path{absolute_path}; + CTL_INF("Downloaded engine path: " << download_path.string()); + + std::filesystem::path extract_path = + download_path.parent_path().parent_path(); + + archive_utils::ExtractArchive(download_path.string(), + extract_path.string()); + + // remove the downloaded file + // TODO(any) Could not delete file on Windows because it is currently hold by httplib(?) + // Not sure about other platforms + try { + std::filesystem::remove(absolute_path); + } catch (const std::exception& e) { + CTL_WRN("Could not delete file: " << e.what()); + } + CTL_INF("Finished!"); + }); + break; + } + } + } catch (const nlohmann::json::parse_error& e) { + std::cerr << "JSON parse error: " << e.what() << std::endl; + return; + } + } else { + CTL_ERR("HTTP error: " << res->status); + return; + } + } else { + auto err = res.error(); + CTL_ERR("HTTP error: " << httplib::to_string(err)); + return; + } +#if defined(_WIN32) + std::string temp = ".\\cortex-cpp_tmp.exe"; + remove(temp.c_str()); // ignore return code + + std::string src = ".\\misc\\cortex-cpp\\cortex-cpp.exe"; + std::string dst = ".\\cortex-cpp.exe"; + // Rename + rename(dst.c_str(), temp.c_str()); + // Update + CopyFile(const_cast(src.c_str()), const_cast(dst.c_str()), + false); +#else + std::string src = "./misc/cortex-cpp/cortex-cpp"; + std::string dst = "./cortex-cpp"; + std::filesystem::copy_file(src, dst, + std::filesystem::copy_options::overwrite_existing); +#endif + CLI_LOG("Update cortex sucessfully"); +} +} // namespace commands \ No newline at end of file diff --git a/engine/commands/cortex_upd_cmd.h b/engine/commands/cortex_upd_cmd.h new file mode 100644 index 000000000..32a1096b6 --- /dev/null +++ b/engine/commands/cortex_upd_cmd.h @@ -0,0 +1,15 @@ +#pragma once +#include +#include + +namespace commands { + +class CortexUpdCmd{ + public: + CortexUpdCmd(); + void Exec(); + + private: +}; + +} // namespace commands \ No newline at end of file diff --git a/engine/controllers/command_line_parser.cc b/engine/controllers/command_line_parser.cc index 12e1db88c..653a40ca2 100644 --- a/engine/controllers/command_line_parser.cc +++ b/engine/controllers/command_line_parser.cc @@ -1,14 +1,15 @@ #include "command_line_parser.h" #include "commands/chat_cmd.h" #include "commands/cmd_info.h" +#include "commands/cortex_upd_cmd.h" #include "commands/engine_init_cmd.h" #include "commands/engine_list_cmd.h" #include "commands/model_get_cmd.h" #include "commands/model_list_cmd.h" #include "commands/model_pull_cmd.h" #include "commands/model_start_cmd.h" -#include "commands/run_cmd.h" #include "commands/model_stop_cmd.h" +#include "commands/run_cmd.h" #include "commands/server_stop_cmd.h" #include "config/yaml_config.h" #include "utils/cortex_utils.h" @@ -153,6 +154,18 @@ bool CommandLineParser::SetupCommand(int argc, char** argv) { app_.add_flag("--verbose", log_verbose, "Verbose logging"); + std::string cortex_version; + { + // cortex run tinyllama:gguf + auto update_cmd = app_.add_subcommand("update", "Update cortex version"); + + update_cmd->add_option("-v", cortex_version, ""); + update_cmd->callback([&cortex_version] { + commands::CortexUpdCmd cuc; + cuc.Exec(); + }); + } + CLI11_PARSE(app_, argc, argv); return true; } diff --git a/engine/services/download_service.h b/engine/services/download_service.h index a8f7f109b..b3c405c9a 100644 --- a/engine/services/download_service.h +++ b/engine/services/download_service.h @@ -4,7 +4,7 @@ #include #include -enum class DownloadType { Model, Engine, Miscellaneous, CudaToolkit }; +enum class DownloadType { Model, Engine, Miscellaneous, CudaToolkit, Cortex }; enum class DownloadStatus { Pending,