From 5454488a48bcbaa6df65b4e350052ff7705a0763 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Mon, 14 Oct 2024 15:17:26 +0700 Subject: [PATCH 01/40] fix: update swagger --- engine/controllers/swagger.cc | 360 +++++++++++++++++----------------- 1 file changed, 180 insertions(+), 180 deletions(-) diff --git a/engine/controllers/swagger.cc b/engine/controllers/swagger.cc index 27d9b7b15..94d2f1117 100644 --- a/engine/controllers/swagger.cc +++ b/engine/controllers/swagger.cc @@ -493,14 +493,14 @@ Json::Value SwaggerController::generateOpenAPISpec() { ["$ref"] = "#/components/schemas/ModelList"; // Create Fine-tuning Job - Json::Value& finetune = spec["paths"]["/v1/fine_tuning/job"]["post"]; - finetune["summary"] = "Create fine-tuning job"; - finetune["description"] = "Creates a job that fine-tunes a specified model"; - finetune["requestBody"]["content"]["application/json"]["schema"]["$ref"] = - "#/components/schemas/FineTuningRequest"; - finetune["responses"]["200"]["description"] = "Successful response"; - finetune["responses"]["200"]["content"]["application/json"]["schema"] - ["$ref"] = "#/components/schemas/FineTuningResponse"; + // Json::Value& finetune = spec["paths"]["/v1/fine_tuning/job"]["post"]; + // finetune["summary"] = "Create fine-tuning job"; + // finetune["description"] = "Creates a job that fine-tunes a specified model"; + // finetune["requestBody"]["content"]["application/json"]["schema"]["$ref"] = + // "#/components/schemas/FineTuningRequest"; + // finetune["responses"]["200"]["description"] = "Successful response"; + // finetune["responses"]["200"]["content"]["application/json"]["schema"] + // ["$ref"] = "#/components/schemas/FineTuningResponse"; // Create Embeddings Json::Value& embed = spec["paths"]["/v1/embeddings"]["post"]; @@ -517,104 +517,104 @@ Json::Value SwaggerController::generateOpenAPISpec() { // Custom Cortex Endpoints { // Chat Completion - Json::Value& chat = - spec["paths"]["/inferences/server/chat_completion"]["post"]; - chat["summary"] = "Create chat completion (Cortex)"; - chat["description"] = - "Creates a completion for the chat message using Cortex engine"; - chat["requestBody"]["content"]["application/json"]["schema"]["$ref"] = - "#/components/schemas/CortexChatCompletionRequest"; - chat["responses"]["200"]["description"] = "Successful response"; - chat["responses"]["200"]["content"]["application/json"]["schema"]["$ref"] = - "#/components/schemas/CortexChatCompletionResponse"; + // Json::Value& chat = + // spec["paths"]["/inferences/server/chat_completion"]["post"]; + // chat["summary"] = "Create chat completion (Cortex)"; + // chat["description"] = + // "Creates a completion for the chat message using Cortex engine"; + // chat["requestBody"]["content"]["application/json"]["schema"]["$ref"] = + // "#/components/schemas/CortexChatCompletionRequest"; + // chat["responses"]["200"]["description"] = "Successful response"; + // chat["responses"]["200"]["content"]["application/json"]["schema"]["$ref"] = + // "#/components/schemas/CortexChatCompletionResponse"; // Embedding - Json::Value& embed = spec["paths"]["/inferences/server/embedding"]["post"]; - embed["summary"] = "Create embeddings (Cortex)"; - embed["description"] = "Creates an embedding vector using Cortex engine"; - embed["requestBody"]["content"]["application/json"]["schema"]["$ref"] = - "#/components/schemas/CortexEmbeddingRequest"; - embed["responses"]["200"]["description"] = "Successful response"; - embed["responses"]["200"]["content"]["application/json"]["schema"]["$ref"] = - "#/components/schemas/CortexEmbeddingResponse"; + // Json::Value& embed = spec["paths"]["/inferences/server/embedding"]["post"]; + // embed["summary"] = "Create embeddings (Cortex)"; + // embed["description"] = "Creates an embedding vector using Cortex engine"; + // embed["requestBody"]["content"]["application/json"]["schema"]["$ref"] = + // "#/components/schemas/CortexEmbeddingRequest"; + // embed["responses"]["200"]["description"] = "Successful response"; + // embed["responses"]["200"]["content"]["application/json"]["schema"]["$ref"] = + // "#/components/schemas/CortexEmbeddingResponse"; // Load Model - Json::Value& load = spec["paths"]["/inferences/server/loadmodel"]["post"]; - load["summary"] = "Load a model"; - load["description"] = "Loads a specified model into the engine"; - load["requestBody"]["content"]["application/json"]["schema"]["$ref"] = - "#/components/schemas/LoadModelRequest"; - load["responses"]["200"]["description"] = "Model loaded successfully"; - load["responses"]["200"]["content"]["application/json"]["schema"]["$ref"] = - "#/components/schemas/SuccessResponse"; + // Json::Value& load = spec["paths"]["/inferences/server/loadmodel"]["post"]; + // load["summary"] = "Load a model"; + // load["description"] = "Loads a specified model into the engine"; + // load["requestBody"]["content"]["application/json"]["schema"]["$ref"] = + // "#/components/schemas/LoadModelRequest"; + // load["responses"]["200"]["description"] = "Model loaded successfully"; + // load["responses"]["200"]["content"]["application/json"]["schema"]["$ref"] = + // "#/components/schemas/SuccessResponse"; // Unload Model - Json::Value& unload = - spec["paths"]["/inferences/server/unloadmodel"]["post"]; - unload["summary"] = "Unload a model"; - unload["description"] = "Unloads a specified model from the engine"; - unload["requestBody"]["content"]["application/json"]["schema"]["$ref"] = - "#/components/schemas/UnloadModelRequest"; - unload["responses"]["200"]["description"] = "Model unloaded successfully"; - unload["responses"]["200"]["content"]["application/json"]["schema"] - ["$ref"] = "#/components/schemas/SuccessResponse"; + // Json::Value& unload = + // spec["paths"]["/inferences/server/unloadmodel"]["post"]; + // unload["summary"] = "Unload a model"; + // unload["description"] = "Unloads a specified model from the engine"; + // unload["requestBody"]["content"]["application/json"]["schema"]["$ref"] = + // "#/components/schemas/UnloadModelRequest"; + // unload["responses"]["200"]["description"] = "Model unloaded successfully"; + // unload["responses"]["200"]["content"]["application/json"]["schema"] + // ["$ref"] = "#/components/schemas/SuccessResponse"; // Model Status - Json::Value& status = - spec["paths"]["/inferences/server/modelstatus"]["post"]; - status["summary"] = "Get model status"; - status["description"] = "Retrieves the status of a specified model"; - status["requestBody"]["content"]["application/json"]["schema"]["$ref"] = - "#/components/schemas/ModelStatusRequest"; - status["responses"]["200"]["description"] = - "Model status retrieved successfully"; - status["responses"]["200"]["content"]["application/json"]["schema"] - ["$ref"] = "#/components/schemas/ModelStatusResponse"; + // Json::Value& status = + // spec["paths"]["/inferences/server/modelstatus"]["post"]; + // status["summary"] = "Get model status"; + // status["description"] = "Retrieves the status of a specified model"; + // status["requestBody"]["content"]["application/json"]["schema"]["$ref"] = + // "#/components/schemas/ModelStatusRequest"; + // status["responses"]["200"]["description"] = + // "Model status retrieved successfully"; + // status["responses"]["200"]["content"]["application/json"]["schema"] + // ["$ref"] = "#/components/schemas/ModelStatusResponse"; // Get Models - Json::Value& getModels = spec["paths"]["/inferences/server/models"]["get"]; - getModels["summary"] = "Get all models (Cortex)"; - getModels["description"] = - "Retrieves a list of all available models in Cortex"; - getModels["responses"]["200"]["description"] = - "Models retrieved successfully"; - getModels["responses"]["200"]["content"]["application/json"]["schema"] - ["$ref"] = "#/components/schemas/CortexModelList"; + // Json::Value& getModels = spec["paths"]["/inferences/server/models"]["get"]; + // getModels["summary"] = "Get all models (Cortex)"; + // getModels["description"] = + // "Retrieves a list of all available models in Cortex"; + // getModels["responses"]["200"]["description"] = + // "Models retrieved successfully"; + // getModels["responses"]["200"]["content"]["application/json"]["schema"] + // ["$ref"] = "#/components/schemas/CortexModelList"; // Get Engines - Json::Value& getEngines = - spec["paths"]["/inferences/server/engines"]["get"]; - getEngines["summary"] = "Get all engines"; - getEngines["description"] = "Retrieves a list of all available engines"; - getEngines["responses"]["200"]["description"] = - "Engines retrieved successfully"; - getEngines["responses"]["200"]["content"]["application/json"]["schema"] - ["$ref"] = "#/components/schemas/EngineList"; + // Json::Value& getEngines = + // spec["paths"]["/inferences/server/engines"]["get"]; + // getEngines["summary"] = "Get all engines"; + // getEngines["description"] = "Retrieves a list of all available engines"; + // getEngines["responses"]["200"]["description"] = + // "Engines retrieved successfully"; + // getEngines["responses"]["200"]["content"]["application/json"]["schema"] + // ["$ref"] = "#/components/schemas/EngineList"; // Fine Tuning - Json::Value& fineTuning = - spec["paths"]["/inferences/server/finetuning"]["post"]; - fineTuning["summary"] = "Create fine-tuning job (Cortex)"; - fineTuning["description"] = - "Creates a job that fine-tunes a specified model using Cortex engine"; - fineTuning["requestBody"]["content"]["application/json"]["schema"]["$ref"] = - "#/components/schemas/CortexFineTuningRequest"; - fineTuning["responses"]["200"]["description"] = - "Fine-tuning job created successfully"; - fineTuning["responses"]["200"]["content"]["application/json"]["schema"] - ["$ref"] = "#/components/schemas/CortexFineTuningResponse"; + // Json::Value& fineTuning = + // spec["paths"]["/inferences/server/finetuning"]["post"]; + // fineTuning["summary"] = "Create fine-tuning job (Cortex)"; + // fineTuning["description"] = + // "Creates a job that fine-tunes a specified model using Cortex engine"; + // fineTuning["requestBody"]["content"]["application/json"]["schema"]["$ref"] = + // "#/components/schemas/CortexFineTuningRequest"; + // fineTuning["responses"]["200"]["description"] = + // "Fine-tuning job created successfully"; + // fineTuning["responses"]["200"]["content"]["application/json"]["schema"] + // ["$ref"] = "#/components/schemas/CortexFineTuningResponse"; // Unload Engine - Json::Value& unloadEngine = - spec["paths"]["/inferences/server/unloadengine"]["post"]; - unloadEngine["summary"] = "Unload an engine"; - unloadEngine["description"] = "Unloads a specified engine"; - unloadEngine["requestBody"]["content"]["application/json"]["schema"] - ["$ref"] = "#/components/schemas/UnloadEngineRequest"; - unloadEngine["responses"]["200"]["description"] = - "Engine unloaded successfully"; - unloadEngine["responses"]["200"]["content"]["application/json"]["schema"] - ["$ref"] = "#/components/schemas/SuccessResponse"; + // Json::Value& unloadEngine = + // spec["paths"]["/inferences/server/unloadengine"]["post"]; + // unloadEngine["summary"] = "Unload an engine"; + // unloadEngine["description"] = "Unloads a specified engine"; + // unloadEngine["requestBody"]["content"]["application/json"]["schema"] + // ["$ref"] = "#/components/schemas/UnloadEngineRequest"; + // unloadEngine["responses"]["200"]["description"] = + // "Engine unloaded successfully"; + // unloadEngine["responses"]["200"]["content"]["application/json"]["schema"] + // ["$ref"] = "#/components/schemas/SuccessResponse"; } // Define schemas @@ -645,12 +645,12 @@ Json::Value SwaggerController::generateOpenAPISpec() { schemas["Model"]["properties"]["id"]["type"] = "string"; schemas["Model"]["properties"]["object"]["type"] = "string"; - schemas["FineTuningRequest"]["type"] = "object"; - schemas["FineTuningRequest"]["properties"]["model"]["type"] = "string"; - schemas["FineTuningRequest"]["properties"]["training_file"]["type"] = - "string"; +// schemas["FineTuningRequest"]["type"] = "object"; +// schemas["FineTuningRequest"]["properties"]["model"]["type"] = "string"; +// schemas["FineTuningRequest"]["properties"]["training_file"]["type"] = +// "string"; - schemas["FineTuningResponse"]["type"] = "object"; +// schemas["FineTuningResponse"]["type"] = "object"; // Add properties based on your implementation schemas["EmbeddingRequest"]["type"] = "object"; @@ -667,117 +667,117 @@ Json::Value SwaggerController::generateOpenAPISpec() { schemas["EmbeddingResponse"]["properties"]["data"]["items"]["properties"] ["embedding"]["items"]["type"] = "number"; - schemas["CortexChatCompletionRequest"]["type"] = "object"; - schemas["CortexChatCompletionRequest"]["properties"]["engine"]["type"] = - "string"; - schemas["CortexChatCompletionRequest"]["properties"]["model"]["type"] = - "string"; - schemas["CortexChatCompletionRequest"]["properties"]["messages"]["type"] = - "array"; - schemas["CortexChatCompletionRequest"]["properties"]["messages"]["items"] - ["$ref"] = "#/components/schemas/ChatMessage"; - schemas["CortexChatCompletionRequest"]["properties"]["stream"]["type"] = - "boolean"; +// schemas["CortexChatCompletionRequest"]["type"] = "object"; +// schemas["CortexChatCompletionRequest"]["properties"]["engine"]["type"] = +// "string"; +// schemas["CortexChatCompletionRequest"]["properties"]["model"]["type"] = +// "string"; +// schemas["CortexChatCompletionRequest"]["properties"]["messages"]["type"] = +// "array"; +// schemas["CortexChatCompletionRequest"]["properties"]["messages"]["items"] +// ["$ref"] = "#/components/schemas/ChatMessage"; +// schemas["CortexChatCompletionRequest"]["properties"]["stream"]["type"] = +// "boolean"; // Add other properties based on your implementation - schemas["CortexChatCompletionResponse"]["type"] = "object"; +// schemas["CortexChatCompletionResponse"]["type"] = "object"; // Add properties based on your implementation - schemas["CortexEmbeddingRequest"]["type"] = "object"; - schemas["CortexEmbeddingRequest"]["properties"]["engine"]["type"] = "string"; - schemas["CortexEmbeddingRequest"]["properties"]["input"]["type"] = "string"; +// schemas["CortexEmbeddingRequest"]["type"] = "object"; +// schemas["CortexEmbeddingRequest"]["properties"]["engine"]["type"] = "string"; +// schemas["CortexEmbeddingRequest"]["properties"]["input"]["type"] = "string"; - schemas["CortexEmbeddingResponse"]["type"] = "object"; +// schemas["CortexEmbeddingResponse"]["type"] = "object"; // Add properties based on your implementation - schemas["LoadModelRequest"]["type"] = "object"; - schemas["LoadModelRequest"]["properties"]["engine"]["type"] = "string"; - schemas["LoadModelRequest"]["properties"]["model_path"]["type"] = "string"; - schemas["LoadModelRequest"]["properties"]["model"]["type"] = "string"; - schemas["LoadModelRequest"]["properties"]["engine"]["type"] = "string"; - schemas["LoadModelRequest"]["properties"]["stop"]["type"] = "array"; - schemas["LoadModelRequest"]["properties"]["stop"]["items"]["type"] = "string"; - schemas["LoadModelRequest"]["properties"]["stop"]["description"] = - "List of stop sequences"; - - schemas["LoadModelRequest"]["properties"]["stream"]["type"] = "boolean"; - schemas["LoadModelRequest"]["properties"]["stream"]["description"] = - "Whether to stream the output"; - - schemas["LoadModelRequest"]["properties"]["ngl"]["type"] = "integer"; - schemas["LoadModelRequest"]["properties"]["ngl"]["description"] = - "Number of GPU layers"; - - schemas["LoadModelRequest"]["properties"]["ctx_len"]["type"] = "integer"; - schemas["LoadModelRequest"]["properties"]["ctx_len"]["description"] = - "Context length"; - - schemas["LoadModelRequest"]["properties"]["engine"]["type"] = "string"; - schemas["LoadModelRequest"]["properties"]["engine"]["description"] = - "Engine used for the model"; - - schemas["LoadModelRequest"]["properties"]["system_template"]["type"] = - "string"; - schemas["LoadModelRequest"]["properties"]["system_template"]["description"] = - "Template for system messages"; - - schemas["LoadModelRequest"]["properties"]["user_template"]["type"] = "string"; - schemas["LoadModelRequest"]["properties"]["user_template"]["description"] = - "Template for user messages"; - - schemas["LoadModelRequest"]["properties"]["ai_template"]["type"] = "string"; - schemas["LoadModelRequest"]["properties"]["ai_template"]["description"] = - "Template for AI responses"; - - schemas["LoadModelRequest"]["properties"]["n_probs"]["type"] = "integer"; - schemas["LoadModelRequest"]["properties"]["n_probs"]["description"] = - "Number of probabilities to return"; +// schemas["LoadModelRequest"]["type"] = "object"; +// schemas["LoadModelRequest"]["properties"]["engine"]["type"] = "string"; +// schemas["LoadModelRequest"]["properties"]["model_path"]["type"] = "string"; +// schemas["LoadModelRequest"]["properties"]["model"]["type"] = "string"; +// schemas["LoadModelRequest"]["properties"]["engine"]["type"] = "string"; +// schemas["LoadModelRequest"]["properties"]["stop"]["type"] = "array"; +// schemas["LoadModelRequest"]["properties"]["stop"]["items"]["type"] = "string"; +// schemas["LoadModelRequest"]["properties"]["stop"]["description"] = +// "List of stop sequences"; + +// schemas["LoadModelRequest"]["properties"]["stream"]["type"] = "boolean"; +// schemas["LoadModelRequest"]["properties"]["stream"]["description"] = +// "Whether to stream the output"; + +// schemas["LoadModelRequest"]["properties"]["ngl"]["type"] = "integer"; +// schemas["LoadModelRequest"]["properties"]["ngl"]["description"] = +// "Number of GPU layers"; + +// schemas["LoadModelRequest"]["properties"]["ctx_len"]["type"] = "integer"; +// schemas["LoadModelRequest"]["properties"]["ctx_len"]["description"] = +// "Context length"; + +// schemas["LoadModelRequest"]["properties"]["engine"]["type"] = "string"; +// schemas["LoadModelRequest"]["properties"]["engine"]["description"] = +// "Engine used for the model"; + +// schemas["LoadModelRequest"]["properties"]["system_template"]["type"] = +// "string"; +// schemas["LoadModelRequest"]["properties"]["system_template"]["description"] = +// "Template for system messages"; + +// schemas["LoadModelRequest"]["properties"]["user_template"]["type"] = "string"; +// schemas["LoadModelRequest"]["properties"]["user_template"]["description"] = +// "Template for user messages"; + +// schemas["LoadModelRequest"]["properties"]["ai_template"]["type"] = "string"; +// schemas["LoadModelRequest"]["properties"]["ai_template"]["description"] = +// "Template for AI responses"; + +// schemas["LoadModelRequest"]["properties"]["n_probs"]["type"] = "integer"; +// schemas["LoadModelRequest"]["properties"]["n_probs"]["description"] = +// "Number of probabilities to return"; // Add other properties based on your implementation - schemas["UnloadModelRequest"]["type"] = "object"; - schemas["UnloadModelRequest"]["properties"]["engine"]["type"] = "string"; - schemas["UnloadModelRequest"]["properties"]["model"]["type"] = "string"; +// schemas["UnloadModelRequest"]["type"] = "object"; +// schemas["UnloadModelRequest"]["properties"]["engine"]["type"] = "string"; +// schemas["UnloadModelRequest"]["properties"]["model"]["type"] = "string"; // Add other properties based on your implementation - schemas["ModelStatusRequest"]["type"] = "object"; - schemas["ModelStatusRequest"]["properties"]["engine"]["type"] = "string"; - schemas["ModelStatusRequest"]["properties"]["model"]["type"] = "string"; +// schemas["ModelStatusRequest"]["type"] = "object"; +// schemas["ModelStatusRequest"]["properties"]["engine"]["type"] = "string"; +// schemas["ModelStatusRequest"]["properties"]["model"]["type"] = "string"; // Add other properties based on your implementation - schemas["ModelStatusResponse"]["type"] = "object"; +// schemas["ModelStatusResponse"]["type"] = "object"; // Add properties based on your implementation - schemas["CortexModelList"]["type"] = "object"; - schemas["CortexModelList"]["properties"]["data"]["type"] = "array"; - schemas["CortexModelList"]["properties"]["data"]["items"]["$ref"] = - "#/components/schemas/CortexModel"; +// schemas["CortexModelList"]["type"] = "object"; +// schemas["CortexModelList"]["properties"]["data"]["type"] = "array"; +// schemas["CortexModelList"]["properties"]["data"]["items"]["$ref"] = +// "#/components/schemas/CortexModel"; - schemas["CortexModel"]["type"] = "object"; +// schemas["CortexModel"]["type"] = "object"; // Add properties based on your implementation - schemas["EngineList"]["type"] = "object"; - schemas["EngineList"]["properties"]["object"]["type"] = "string"; - schemas["EngineList"]["properties"]["data"]["type"] = "array"; - schemas["EngineList"]["properties"]["data"]["items"]["$ref"] = - "#/components/schemas/Engine"; +// schemas["EngineList"]["type"] = "object"; +// schemas["EngineList"]["properties"]["object"]["type"] = "string"; +// schemas["EngineList"]["properties"]["data"]["type"] = "array"; +// schemas["EngineList"]["properties"]["data"]["items"]["$ref"] = +// "#/components/schemas/Engine"; - schemas["Engine"]["type"] = "object"; - schemas["Engine"]["properties"]["id"]["type"] = "string"; - schemas["Engine"]["properties"]["object"]["type"] = "string"; +// schemas["Engine"]["type"] = "object"; +// schemas["Engine"]["properties"]["id"]["type"] = "string"; +// schemas["Engine"]["properties"]["object"]["type"] = "string"; - schemas["CortexFineTuningRequest"]["type"] = "object"; - schemas["CortexFineTuningRequest"]["properties"]["engine"]["type"] = "string"; +// schemas["CortexFineTuningRequest"]["type"] = "object"; +// schemas["CortexFineTuningRequest"]["properties"]["engine"]["type"] = "string"; // Add other properties based on your implementation - schemas["CortexFineTuningResponse"]["type"] = "object"; +// schemas["CortexFineTuningResponse"]["type"] = "object"; // Add properties based on your implementation - schemas["UnloadEngineRequest"]["type"] = "object"; - schemas["UnloadEngineRequest"]["properties"]["engine"]["type"] = "string"; +// schemas["UnloadEngineRequest"]["type"] = "object"; +// schemas["UnloadEngineRequest"]["properties"]["engine"]["type"] = "string"; - schemas["SuccessResponse"]["type"] = "object"; - schemas["SuccessResponse"]["properties"]["message"]["type"] = "string"; +// schemas["SuccessResponse"]["type"] = "object"; +// schemas["SuccessResponse"]["properties"]["message"]["type"] = "string"; // TODO: Add more paths and details based on your API return spec; From 3e3dff662243f9551b62bc8fc59bf34b1320ed74 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Mon, 14 Oct 2024 15:53:54 +0700 Subject: [PATCH 02/40] fix: start stop model with API call --- engine/commands/model_start_cmd.cc | 35 ++++++++++++++++++++++++------ engine/commands/model_stop_cmd.cc | 23 +++++++++++++++----- 2 files changed, 45 insertions(+), 13 deletions(-) diff --git a/engine/commands/model_start_cmd.cc b/engine/commands/model_start_cmd.cc index aebc8400c..5756a012d 100644 --- a/engine/commands/model_start_cmd.cc +++ b/engine/commands/model_start_cmd.cc @@ -1,18 +1,39 @@ #include "model_start_cmd.h" +#include "httplib.h" +#include "server_start_cmd.h" #include "utils/logging_utils.h" namespace commands { bool ModelStartCmd::Exec(const std::string& host, int port, const std::string& model_handle) { - auto res = model_service_.StartModel(host, port, model_handle); - - if (res.has_error()) { - CLI_LOG("Error: " + res.error()); + // Start server if server is not started yet + if (!commands::IsServerAlive(host, port)) { + CLI_LOG("Starting server ..."); + commands::ServerStartCmd ssc; + if (!ssc.Exec(host, port)) { + return false; + } + } + // Call API to start model + httplib::Client cli(host + ":" + std::to_string(port)); + Json::Value json_data; + json_data["model"] = model_handle; + auto data_str = json_data.toStyledString(); + auto res = cli.Post("/v1/models/start", httplib::Headers(), data_str.data(), + data_str.size(), "application/json"); + if (res) { + if (res->status == httplib::StatusCode::OK_200) { + CLI_LOG("Model loaded!"); + return true; + } else { + CTL_ERR("Model failed to load with status code: " << res->status); + return false; + } + } else { + auto err = res.error(); + CTL_ERR("HTTP error: " << httplib::to_string(err)); return false; } - - CLI_LOG("Model loaded!"); - return true; } }; // namespace commands diff --git a/engine/commands/model_stop_cmd.cc b/engine/commands/model_stop_cmd.cc index 15d3b0abd..d84f17003 100644 --- a/engine/commands/model_stop_cmd.cc +++ b/engine/commands/model_stop_cmd.cc @@ -1,17 +1,28 @@ #include "model_stop_cmd.h" #include "utils/logging_utils.h" +#include "httplib.h" namespace commands { void ModelStopCmd::Exec(const std::string& host, int port, const std::string& model_handle) { - auto res = model_service_.StopModel(host, port, model_handle); - - if (res.has_error()) { - CLI_LOG("Error: " + res.error()); - return; + // Call API to stop model + httplib::Client cli(host + ":" + std::to_string(port)); + Json::Value json_data; + json_data["model"] = model_handle; + auto data_str = json_data.toStyledString(); + auto res = cli.Post("/v1/models/stop", httplib::Headers(), data_str.data(), + data_str.size(), "application/json"); + if (res) { + if (res->status == httplib::StatusCode::OK_200) { + CLI_LOG("Model unloaded!"); + } else { + CTL_ERR("Model failed to unload with status code: " << res->status); + } + } else { + auto err = res.error(); + CTL_ERR("HTTP error: " << httplib::to_string(err)); } - CLI_LOG("Model unloaded!"); } }; // namespace commands From 1bd0bbfa8a8767f942cfe80cdf495ba40bb650a1 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Mon, 14 Oct 2024 16:09:31 +0700 Subject: [PATCH 03/40] fix: model del --- engine/commands/model_del_cmd.cc | 30 +++++++++++++++++++---- engine/commands/model_del_cmd.h | 2 +- engine/controllers/command_line_parser.cc | 4 ++- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/engine/commands/model_del_cmd.cc b/engine/commands/model_del_cmd.cc index f955a2591..693de804d 100644 --- a/engine/commands/model_del_cmd.cc +++ b/engine/commands/model_del_cmd.cc @@ -1,13 +1,33 @@ #include "model_del_cmd.h" +#include "httplib.h" +#include "server_start_cmd.h" #include "utils/logging_utils.h" namespace commands { -void ModelDelCmd::Exec(const std::string& model_handle) { - auto result = model_service_.DeleteModel(model_handle); - if (result.has_error()) { - CLI_LOG(result.error()); + +void ModelDelCmd::Exec(const std::string& host, int port, + const std::string& model_handle) { + // Start server if server is not started yet + if (!commands::IsServerAlive(host, port)) { + CLI_LOG("Starting server ..."); + commands::ServerStartCmd ssc; + if (!ssc.Exec(host, port)) { + return; + } + } + + // Call API to delete model + httplib::Client cli(host + ":" + std::to_string(port)); + auto res = cli.Delete("/v1/models/" + model_handle); + if (res) { + if (res->status == httplib::StatusCode::OK_200) { + CLI_LOG("Model " + model_handle + " deleted successfully"); + } else { + CTL_ERR("Model failed to delete with status code: " << res->status); + } } else { - CLI_LOG("Model " + model_handle + " deleted successfully"); + auto err = res.error(); + CTL_ERR("HTTP error: " << httplib::to_string(err)); } } } // namespace commands diff --git a/engine/commands/model_del_cmd.h b/engine/commands/model_del_cmd.h index 38f172ad2..008f43e73 100644 --- a/engine/commands/model_del_cmd.h +++ b/engine/commands/model_del_cmd.h @@ -10,7 +10,7 @@ class ModelDelCmd { explicit ModelDelCmd() : model_service_{ModelService(std::make_shared())} {}; - void Exec(const std::string& model_handle); + void Exec(const std::string& host, int port, const std::string& model_handle); private: ModelService model_service_; diff --git a/engine/controllers/command_line_parser.cc b/engine/controllers/command_line_parser.cc index ab7e41da5..cb54416d2 100644 --- a/engine/controllers/command_line_parser.cc +++ b/engine/controllers/command_line_parser.cc @@ -278,7 +278,9 @@ void CommandLineParser::SetupModelCommands() { CLI_LOG(model_del_cmd->help()); return; }; - commands::ModelDelCmd().Exec(cml_data_.model_id); + commands::ModelDelCmd().Exec(cml_data_.config.apiServerHost, + std::stoi(cml_data_.config.apiServerPort), + cml_data_.model_id); }); std::string model_alias; From 536e8ad9231688b2a55df03bd2b5dafe9042a984 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Tue, 15 Oct 2024 14:32:48 +0700 Subject: [PATCH 04/40] fix: model get --- engine/commands/model_get_cmd.cc | 41 ++++++++++++----------- engine/commands/model_get_cmd.h | 2 +- engine/controllers/command_line_parser.cc | 4 ++- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/engine/commands/model_get_cmd.cc b/engine/commands/model_get_cmd.cc index 3cf46bd84..b5b230c9c 100644 --- a/engine/commands/model_get_cmd.cc +++ b/engine/commands/model_get_cmd.cc @@ -5,33 +5,36 @@ #include #include "config/yaml_config.h" #include "database/models.h" +#include "httplib.h" +#include "server_start_cmd.h" #include "utils/file_manager_utils.h" #include "utils/logging_utils.h" namespace commands { -void ModelGetCmd::Exec(const std::string& model_handle) { - namespace fs = std::filesystem; - namespace fmu = file_manager_utils; - cortex::db::Models modellist_handler; - config::YamlHandler yaml_handler; - try { - auto model_entry = modellist_handler.GetModelInfo(model_handle); - if (model_entry.has_error()) { - CLI_LOG("Error: " + model_entry.error()); +void ModelGetCmd::Exec(const std::string& host, int port, + const std::string& model_handle) { + // Start server if server is not started yet + if (!commands::IsServerAlive(host, port)) { + CLI_LOG("Starting server ..."); + commands::ServerStartCmd ssc; + if (!ssc.Exec(host, port)) { return; } - yaml_handler.ModelConfigFromFile( - fmu::ToAbsoluteCortexDataPath( - fs::path(model_entry.value().path_to_model_yaml)) - .string()); - auto model_config = yaml_handler.GetModelConfig(); - - std::cout << model_config.ToString() << std::endl; + } - } catch (const std::exception& e) { - CLI_LOG("Fail to get model information with ID '" + model_handle + - "': " + e.what()); + // Call API to delete model + httplib::Client cli(host + ":" + std::to_string(port)); + auto res = cli.Get("/v1/models/" + model_handle); + if (res) { + if (res->status == httplib::StatusCode::OK_200) { + CLI_LOG(res->body); + } else { + CTL_ERR("Model failed to get with status code: " << res->status); + } + } else { + auto err = res.error(); + CTL_ERR("HTTP error: " << httplib::to_string(err)); } } diff --git a/engine/commands/model_get_cmd.h b/engine/commands/model_get_cmd.h index 1836f7d99..e903d4b64 100644 --- a/engine/commands/model_get_cmd.h +++ b/engine/commands/model_get_cmd.h @@ -5,6 +5,6 @@ namespace commands { class ModelGetCmd { public: - void Exec(const std::string& model_handle); + void Exec(const std::string& host, int port, const std::string& model_handle); }; } // namespace commands diff --git a/engine/controllers/command_line_parser.cc b/engine/controllers/command_line_parser.cc index cb54416d2..f4b2a33e2 100644 --- a/engine/controllers/command_line_parser.cc +++ b/engine/controllers/command_line_parser.cc @@ -261,7 +261,9 @@ void CommandLineParser::SetupModelCommands() { CLI_LOG(get_models_cmd->help()); return; }; - commands::ModelGetCmd().Exec(cml_data_.model_id); + commands::ModelGetCmd().Exec(cml_data_.config.apiServerHost, + std::stoi(cml_data_.config.apiServerPort), + cml_data_.model_id); }); auto model_del_cmd = From e4a6f7cae7296baa0dda46f42a7561966800f97d Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Tue, 15 Oct 2024 14:46:56 +0700 Subject: [PATCH 05/40] fix: model alias --- engine/commands/model_alias_cmd.cc | 46 ++++++++++++++--------- engine/commands/model_alias_cmd.h | 3 +- engine/controllers/command_line_parser.cc | 4 +- 3 files changed, 34 insertions(+), 19 deletions(-) diff --git a/engine/commands/model_alias_cmd.cc b/engine/commands/model_alias_cmd.cc index cd7f647a5..d7792e131 100644 --- a/engine/commands/model_alias_cmd.cc +++ b/engine/commands/model_alias_cmd.cc @@ -1,28 +1,40 @@ #include "model_alias_cmd.h" #include "database/models.h" +#include "httplib.h" +#include "server_start_cmd.h" +#include "json/json.h" namespace commands { -void ModelAliasCmd::Exec(const std::string& model_handle, +void ModelAliasCmd::Exec(const std::string& host, int port, + const std::string& model_handle, const std::string& model_alias) { - cortex::db::Models modellist_handler; - try { - auto result = modellist_handler.UpdateModelAlias(model_handle, model_alias); - if (result.has_error()) { - CLI_LOG(result.error()); - } else { - if (result.value()) { - CLI_LOG("Successfully set model alias '" + model_alias + - "' for modeID '" + model_handle + "'."); - } else { - CLI_LOG("Unable to set model alias for modelID '" + model_handle + - "': model alias '" + model_alias + "' is not unique!"); - } + // Start server if server is not started yet + if (!commands::IsServerAlive(host, port)) { + CLI_LOG("Starting server ..."); + commands::ServerStartCmd ssc; + if (!ssc.Exec(host, port)) { + return; } + } - } catch (const std::exception& e) { - CLI_LOG("Error when setting model alias ('" + model_alias + - "') for modelID '" + model_handle + "':" + e.what()); + // Call API to delete model + httplib::Client cli(host + ":" + std::to_string(port)); + Json::Value json_data; + json_data["model"] = model_handle; + auto data_str = json_data.toStyledString(); + auto res = cli.Post("/v1/models/alias", httplib::Headers(), data_str.data(), + data_str.size(), "application/json"); + if (res) { + if (res->status == httplib::StatusCode::OK_200) { + CLI_LOG("Successfully set model alias '" + model_alias + + "' for modeID '" + model_handle + "'."); + } else { + CTL_ERR("Model failed to set alias with status code: " << res->status); + } + } else { + auto err = res.error(); + CTL_ERR("HTTP error: " << httplib::to_string(err)); } } diff --git a/engine/commands/model_alias_cmd.h b/engine/commands/model_alias_cmd.h index dcec44947..b61dd724c 100644 --- a/engine/commands/model_alias_cmd.h +++ b/engine/commands/model_alias_cmd.h @@ -5,6 +5,7 @@ namespace commands { class ModelAliasCmd { public: - void Exec(const std::string& model_handle, const std::string& model_alias); + void Exec(const std::string& host, int port, const std::string& model_handle, + const std::string& model_alias); }; } // 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 f4b2a33e2..29da1a1ce 100644 --- a/engine/controllers/command_line_parser.cc +++ b/engine/controllers/command_line_parser.cc @@ -305,7 +305,9 @@ void CommandLineParser::SetupModelCommands() { return; } commands::ModelAliasCmd mdc; - mdc.Exec(cml_data_.model_id, cml_data_.model_alias); + mdc.Exec(cml_data_.config.apiServerHost, + std::stoi(cml_data_.config.apiServerPort), cml_data_.model_id, + cml_data_.model_alias); }); // Model update parameters comment ModelUpdate(models_cmd); From 30e62fd20dd2b9af15ec1db03ac348c46223673c Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Tue, 15 Oct 2024 14:52:19 +0700 Subject: [PATCH 06/40] fix: model import --- engine/commands/model_alias_cmd.cc | 1 + engine/commands/model_import_cmd.cc | 70 ++++++++++------------- engine/commands/model_import_cmd.h | 8 +-- engine/controllers/command_line_parser.cc | 5 +- 4 files changed, 36 insertions(+), 48 deletions(-) diff --git a/engine/commands/model_alias_cmd.cc b/engine/commands/model_alias_cmd.cc index d7792e131..08a0c88a0 100644 --- a/engine/commands/model_alias_cmd.cc +++ b/engine/commands/model_alias_cmd.cc @@ -22,6 +22,7 @@ void ModelAliasCmd::Exec(const std::string& host, int port, httplib::Client cli(host + ":" + std::to_string(port)); Json::Value json_data; json_data["model"] = model_handle; + json_data["modelAlias"] = model_alias; auto data_str = json_data.toStyledString(); auto res = cli.Post("/v1/models/alias", httplib::Headers(), data_str.data(), data_str.size(), "application/json"); diff --git a/engine/commands/model_import_cmd.cc b/engine/commands/model_import_cmd.cc index 15fc6f897..ef0bca556 100644 --- a/engine/commands/model_import_cmd.cc +++ b/engine/commands/model_import_cmd.cc @@ -4,54 +4,44 @@ #include "config/gguf_parser.h" #include "config/yaml_config.h" #include "database/models.h" +#include "httplib.h" +#include "json/json.h" +#include "server_start_cmd.h" #include "utils/file_manager_utils.h" #include "utils/logging_utils.h" namespace commands { -ModelImportCmd::ModelImportCmd(std::string model_handle, std::string model_path) - : model_handle_(std::move(model_handle)), - model_path_(std::move(model_path)) {} - -void ModelImportCmd::Exec() { - namespace fs = std::filesystem; - namespace fmu = file_manager_utils; - config::GGUFHandler gguf_handler; - config::YamlHandler yaml_handler; - cortex::db::Models modellist_utils_obj; - - std::string model_yaml_path = (file_manager_utils::GetModelsContainerPath() / - std::filesystem::path("imported") / - std::filesystem::path(model_handle_ + ".yml")) - .string(); - try { - // Use relative path for model_yaml_path. In case of import, we use absolute path for model - auto yaml_rel_path = - fmu::ToRelativeCortexDataPath(fs::path(model_yaml_path)); - cortex::db::ModelEntry model_entry{model_handle_, "local", "imported", - yaml_rel_path.string(), model_handle_}; - - std::filesystem::create_directories( - std::filesystem::path(model_yaml_path).parent_path()); - gguf_handler.Parse(model_path_); - auto model_config = gguf_handler.GetModelConfig(); - model_config.files.push_back(model_path_); - model_config.model = model_handle_; - yaml_handler.UpdateModelConfig(model_config); +void ModelImportCmd::Exec(const std::string& host, int port, + const std::string& model_handle, + const std::string& model_path) { + // Start server if server is not started yet + if (!commands::IsServerAlive(host, port)) { + CLI_LOG("Starting server ..."); + commands::ServerStartCmd ssc; + if (!ssc.Exec(host, port)) { + return; + } + } - if (modellist_utils_obj.AddModelEntry(model_entry).value()) { - yaml_handler.WriteYamlFile(model_yaml_path); - CLI_LOG("Model is imported successfully!"); + // Call API to delete model + httplib::Client cli(host + ":" + std::to_string(port)); + Json::Value json_data; + json_data["model"] = model_handle; + json_data["modelPath"] = model_path; + auto data_str = json_data.toStyledString(); + auto res = cli.Post("/v1/models/import", httplib::Headers(), data_str.data(), + data_str.size(), "application/json"); + if (res) { + if (res->status == httplib::StatusCode::OK_200) { + CLI_LOG("Successfully import model from '" + model_path + + "' for modeID '" + model_handle + "'."); } else { - CLI_LOG("Fail to import model, model_id '" + model_handle_ + - "' already exists!"); + CTL_ERR("Model failed to import model with status code: " << res->status); } - - } catch (const std::exception& e) { - // don't need to remove yml file here, because it's written only if model entry is successfully added, - // remove file here can make it fail with edge case when user try to import new model with existed model_id - CLI_LOG("Error importing model path '" + model_path_ + "' with model_id '" + - model_handle_ + "': " + e.what()); + } else { + auto err = res.error(); + CTL_ERR("HTTP error: " << httplib::to_string(err)); } } } // namespace commands diff --git a/engine/commands/model_import_cmd.h b/engine/commands/model_import_cmd.h index d4248281f..141351909 100644 --- a/engine/commands/model_import_cmd.h +++ b/engine/commands/model_import_cmd.h @@ -5,11 +5,7 @@ namespace commands { class ModelImportCmd { public: - ModelImportCmd(std::string model_handle, std::string model_path); - void Exec(); - - private: - std::string model_handle_; - std::string model_path_; + void Exec(const std::string& host, int port, const std::string& model_handle, + const std::string& model_path); }; } // 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 29da1a1ce..b3b0f8156 100644 --- a/engine/controllers/command_line_parser.cc +++ b/engine/controllers/command_line_parser.cc @@ -331,8 +331,9 @@ void CommandLineParser::SetupModelCommands() { CLI_LOG(model_import_cmd->help()); return; } - commands::ModelImportCmd command(cml_data_.model_id, cml_data_.model_path); - command.Exec(); + commands::ModelImportCmd().Exec(cml_data_.config.apiServerHost, + std::stoi(cml_data_.config.apiServerPort), + cml_data_.model_id, cml_data_.model_path); }); } From 0f2e0a4fc3052c0fecf6859d7972c4a99a1ff061 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Tue, 15 Oct 2024 17:58:36 +0700 Subject: [PATCH 07/40] fix: model status --- engine/commands/model_status_cmd.cc | 26 +++++++++++++++++++++++--- engine/controllers/models.cc | 23 +++++++++++++++++++++++ engine/controllers/models.h | 6 ++++++ 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/engine/commands/model_status_cmd.cc b/engine/commands/model_status_cmd.cc index 572b64bbe..6677fe0af 100644 --- a/engine/commands/model_status_cmd.cc +++ b/engine/commands/model_status_cmd.cc @@ -1,13 +1,33 @@ #include "model_status_cmd.h" +#include "httplib.h" +#include "server_start_cmd.h" #include "utils/logging_utils.h" namespace commands { bool ModelStatusCmd::IsLoaded(const std::string& host, int port, const std::string& model_handle) { - auto res = model_service_.GetModelStatus(host, port, model_handle); + // Start server if server is not started yet + if (!commands::IsServerAlive(host, port)) { + CLI_LOG("Starting server ..."); + commands::ServerStartCmd ssc; + if (!ssc.Exec(host, port)) { + return false; + } + } - if (res.has_error()) { - CTL_ERR("Error: " + res.error()); + // Call API to check model status + httplib::Client cli(host + ":" + std::to_string(port)); + auto res = cli.Get("/v1/models/status/" + model_handle); + if (res) { + if (res->status == httplib::StatusCode::OK_200) { + CTL_INF(res->body); + } else { + CTL_WRN("Failed to get model status with code: " << res->status); + return false; + } + } else { + auto err = res.error(); + CTL_WRN("HTTP error: " << httplib::to_string(err)); return false; } return true; diff --git a/engine/controllers/models.cc b/engine/controllers/models.cc index eefc0a941..c6b669f91 100644 --- a/engine/controllers/models.cc +++ b/engine/controllers/models.cc @@ -408,3 +408,26 @@ void Models::StopModel(const HttpRequestPtr& req, callback(resp); } } + +void Models::GetModelStatus( + const HttpRequestPtr& req, + std::function&& callback, + const std::string& model_id) { + auto config = file_manager_utils::GetCortexConfig(); + + auto result = model_service_->GetModelStatus( + config.apiServerHost, std::stoi(config.apiServerPort), model_id); + if (result.has_error()) { + Json::Value ret; + ret["message"] = result.error(); + auto resp = cortex_utils::CreateCortexHttpJsonResponse(ret); + resp->setStatusCode(drogon::k400BadRequest); + callback(resp); + } else { + Json::Value ret; + ret["message"] = "Model is running"; + auto resp = cortex_utils::CreateCortexHttpJsonResponse(ret); + resp->setStatusCode(k200OK); + callback(resp); + } +} diff --git a/engine/controllers/models.h b/engine/controllers/models.h index 2aa99f5e9..212432b76 100644 --- a/engine/controllers/models.h +++ b/engine/controllers/models.h @@ -18,6 +18,7 @@ class Models : public drogon::HttpController { METHOD_ADD(Models::SetModelAlias, "/alias", Post); METHOD_ADD(Models::StartModel, "/start", Post); METHOD_ADD(Models::StopModel, "/stop", Post); + METHOD_ADD(Models::GetModelStatus, "/status/{1}", Get); ADD_METHOD_TO(Models::PullModel, "/v1/models/pull", Post); ADD_METHOD_TO(Models::ListModel, "/v1/models", Get); @@ -28,6 +29,7 @@ class Models : public drogon::HttpController { ADD_METHOD_TO(Models::SetModelAlias, "/v1/models/alias", Post); ADD_METHOD_TO(Models::StartModel, "/v1/models/start", Post); ADD_METHOD_TO(Models::StopModel, "/v1/models/stop", Post); + ADD_METHOD_TO(Models::GetModelStatus, "/v1/models/status/{1}", Get); METHOD_LIST_END explicit Models(std::shared_ptr model_service) @@ -59,6 +61,10 @@ class Models : public drogon::HttpController { void StopModel(const HttpRequestPtr& req, std::function&& callback); + void GetModelStatus(const HttpRequestPtr& req, + std::function&& callback, + const std::string& model_id); + private: std::shared_ptr model_service_; }; From d37f0bff08d97e45a140f68ec50ef2ffeab0fe71 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Tue, 15 Oct 2024 18:52:00 +0700 Subject: [PATCH 08/40] fix: model list --- engine/commands/model_list_cmd.cc | 76 ++++++++++++----------- engine/commands/model_list_cmd.h | 3 +- engine/controllers/command_line_parser.cc | 3 +- engine/controllers/models.cc | 1 + 4 files changed, 44 insertions(+), 39 deletions(-) diff --git a/engine/commands/model_list_cmd.cc b/engine/commands/model_list_cmd.cc index 14f929c93..c92836456 100644 --- a/engine/commands/model_list_cmd.cc +++ b/engine/commands/model_list_cmd.cc @@ -1,19 +1,26 @@ #include "model_list_cmd.h" #include -#include + #include -#include "config/yaml_config.h" -#include "database/models.h" -#include "utils/file_manager_utils.h" +#include "httplib.h" +#include "json/json.h" +#include "server_start_cmd.h" #include "utils/logging_utils.h" - +// clang-format off +#include +// clang-format on namespace commands { -void ModelListCmd::Exec() { - namespace fs = std::filesystem; - namespace fmu = file_manager_utils; - cortex::db::Models modellist_handler; - config::YamlHandler yaml_handler; +void ModelListCmd::Exec(const std::string& host, int port) { + // Start server if server is not started yet + if (!commands::IsServerAlive(host, port)) { + CLI_LOG("Starting server ..."); + commands::ServerStartCmd ssc; + if (!ssc.Exec(host, port)) { + return; + } + } + tabulate::Table table; table.add_row({"(Index)", "ID", "model alias", "engine", "version"}); @@ -21,35 +28,30 @@ void ModelListCmd::Exec() { int count = 0; // Iterate through directory - auto list_entry = modellist_handler.LoadModelList(); - if (list_entry.has_error()) { - CTL_ERR("Fail to get list model information: " << list_entry.error()); - return; - } - for (const auto& model_entry : list_entry.value()) { - // auto model_entry = modellist_handler.GetModelInfo(model_handle); - try { - try { - yaml_handler.ModelConfigFromFile( - fmu::ToAbsoluteCortexDataPath( - fs::path(model_entry.path_to_model_yaml)) - .string()); - } catch (const std::exception& e) { - CTL_WRN("Fail to get model '" + model_entry.model + - "' information: " + std::string(e.what())); - yaml_handler.Reset(); - continue; + httplib::Client cli(host + ":" + std::to_string(port)); + auto res = cli.Get("/v1/models"); + if (res) { + if (res->status == httplib::StatusCode::OK_200) { + // CLI_LOG(res->body); + Json::Value body; + Json::Reader reader; + reader.parse(res->body, body); + if (!body["data"].isNull()) { + for (auto const& v : body["data"]) { + count += 1; + table.add_row({std::to_string(count), v["model"].asString(), + v["model_alias"].asString(), v["engine"].asString(), + v["version"].asString()}); + } } - - count += 1; - auto model_config = yaml_handler.GetModelConfig(); - table.add_row({std::to_string(count), model_entry.model, - model_entry.model_alias, model_config.engine, - model_config.version}); - yaml_handler.Reset(); - } catch (const std::exception& e) { - CTL_ERR("Fail to get list model information: " + std::string(e.what())); + } else { + CTL_ERR("Failed to get model list with status code: " << res->status); + return; } + } else { + auto err = res.error(); + CTL_ERR("HTTP error: " << httplib::to_string(err)); + return; } for (int i = 0; i < 5; i++) { diff --git a/engine/commands/model_list_cmd.h b/engine/commands/model_list_cmd.h index a24da8928..2f25cc1cf 100644 --- a/engine/commands/model_list_cmd.h +++ b/engine/commands/model_list_cmd.h @@ -1,9 +1,10 @@ #pragma once +#include namespace commands { class ModelListCmd { public: - void Exec(); + void Exec(const std::string& host, int port); }; } // namespace commands diff --git a/engine/controllers/command_line_parser.cc b/engine/controllers/command_line_parser.cc index b3b0f8156..58ee9160f 100644 --- a/engine/controllers/command_line_parser.cc +++ b/engine/controllers/command_line_parser.cc @@ -244,7 +244,8 @@ void CommandLineParser::SetupModelCommands() { list_models_cmd->callback([this]() { if (std::exchange(executed_, true)) return; - commands::ModelListCmd().Exec(); + commands::ModelListCmd().Exec(cml_data_.config.apiServerHost, + std::stoi(cml_data_.config.apiServerPort)); }); auto get_models_cmd = diff --git a/engine/controllers/models.cc b/engine/controllers/models.cc index c6b669f91..6ecc65289 100644 --- a/engine/controllers/models.cc +++ b/engine/controllers/models.cc @@ -82,6 +82,7 @@ void Models::ListModel( auto model_config = yaml_handler.GetModelConfig(); Json::Value obj = model_config.ToJson(); obj["id"] = model_config.model; + obj["model_alias"] = model_entry.model_alias; data.append(std::move(obj)); yaml_handler.Reset(); } catch (const std::exception& e) { From 2a00d34e02f3d0c17d86b7aaa535e6f526dbecf7 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Tue, 15 Oct 2024 19:48:48 +0700 Subject: [PATCH 09/40] fix: models update --- engine/commands/model_import_cmd.cc | 1 - engine/commands/model_upd_cmd.cc | 318 ++-------------------- engine/commands/model_upd_cmd.h | 17 +- engine/controllers/command_line_parser.cc | 6 +- 4 files changed, 36 insertions(+), 306 deletions(-) diff --git a/engine/commands/model_import_cmd.cc b/engine/commands/model_import_cmd.cc index ef0bca556..6abaad2c8 100644 --- a/engine/commands/model_import_cmd.cc +++ b/engine/commands/model_import_cmd.cc @@ -24,7 +24,6 @@ void ModelImportCmd::Exec(const std::string& host, int port, } } - // Call API to delete model httplib::Client cli(host + ":" + std::to_string(port)); Json::Value json_data; json_data["model"] = model_handle; diff --git a/engine/commands/model_upd_cmd.cc b/engine/commands/model_upd_cmd.cc index 0864c227a..18edf1b61 100644 --- a/engine/commands/model_upd_cmd.cc +++ b/engine/commands/model_upd_cmd.cc @@ -1,4 +1,7 @@ #include "model_upd_cmd.h" +#include "httplib.h" +#include "json/json.h" +#include "server_start_cmd.h" #include "utils/file_manager_utils.h" #include "utils/logging_utils.h" @@ -8,301 +11,40 @@ ModelUpdCmd::ModelUpdCmd(std::string model_handle) : model_handle_(std::move(model_handle)) {} void ModelUpdCmd::Exec( + const std::string& host, int port, const std::unordered_map& options) { - namespace fs = std::filesystem; - namespace fmu = file_manager_utils; - try { - auto model_entry = model_list_utils_.GetModelInfo(model_handle_); - if (model_entry.has_error()) { - CLI_LOG("Error: " + model_entry.error()); + // Start server if server is not started yet + if (!commands::IsServerAlive(host, port)) { + CLI_LOG("Starting server ..."); + commands::ServerStartCmd ssc; + if (!ssc.Exec(host, port)) { return; } - auto yaml_fp = fmu::ToAbsoluteCortexDataPath( - fs::path(model_entry.value().path_to_model_yaml)); - yaml_handler_.ModelConfigFromFile(yaml_fp.string()); - model_config_ = yaml_handler_.GetModelConfig(); + } - for (const auto& [key, value] : options) { - if (!value.empty()) { - UpdateConfig(key, value); - } + httplib::Client cli(host + ":" + std::to_string(port)); + Json::Value json_data; + for (const auto& [key, value] : options) { + if (!value.empty()) { + json_data[key] = value; + CLI_LOG("Updated " << key << " to: " << value); } - - yaml_handler_.UpdateModelConfig(model_config_); - yaml_handler_.WriteYamlFile(yaml_fp.string()); - CLI_LOG("Successfully updated model ID '" + model_handle_ + "'!"); - } catch (const std::exception& e) { - CLI_LOG("Failed to update model with model ID '" + model_handle_ + - "': " + e.what()); } -} - -void ModelUpdCmd::UpdateConfig(const std::string& key, - const std::string& value) { - static const std::unordered_map< - std::string, - std::function> - updaters = { - {"name", - [](ModelUpdCmd* self, const std::string&, const std::string& v) { - self->model_config_.name = v; - }}, - {"model", - [](ModelUpdCmd* self, const std::string&, const std::string& v) { - self->model_config_.model = v; - }}, - {"version", - [](ModelUpdCmd* self, const std::string&, const std::string& v) { - self->model_config_.version = v; - }}, - {"engine", - [](ModelUpdCmd* self, const std::string&, const std::string& v) { - self->model_config_.engine = v; - }}, - {"prompt_template", - [](ModelUpdCmd* self, const std::string&, const std::string& v) { - self->model_config_.prompt_template = v; - }}, - {"system_template", - [](ModelUpdCmd* self, const std::string&, const std::string& v) { - self->model_config_.system_template = v; - }}, - {"user_template", - [](ModelUpdCmd* self, const std::string&, const std::string& v) { - self->model_config_.user_template = v; - }}, - {"ai_template", - [](ModelUpdCmd* self, const std::string&, const std::string& v) { - self->model_config_.ai_template = v; - }}, - {"os", - [](ModelUpdCmd* self, const std::string&, const std::string& v) { - self->model_config_.os = v; - }}, - {"gpu_arch", - [](ModelUpdCmd* self, const std::string&, const std::string& v) { - self->model_config_.gpu_arch = v; - }}, - {"quantization_method", - [](ModelUpdCmd* self, const std::string&, const std::string& v) { - self->model_config_.quantization_method = v; - }}, - {"precision", - [](ModelUpdCmd* self, const std::string&, const std::string& v) { - self->model_config_.precision = v; - }}, - {"trtllm_version", - [](ModelUpdCmd* self, const std::string&, const std::string& v) { - self->model_config_.trtllm_version = v; - }}, - {"object", - [](ModelUpdCmd* self, const std::string&, const std::string& v) { - self->model_config_.object = v; - }}, - {"owned_by", - [](ModelUpdCmd* self, const std::string&, const std::string& v) { - self->model_config_.owned_by = v; - }}, - {"grammar", - [](ModelUpdCmd* self, const std::string&, const std::string& v) { - self->model_config_.grammar = v; - }}, - {"stop", &ModelUpdCmd::UpdateVectorField}, - {"files", &ModelUpdCmd::UpdateVectorField}, - {"top_p", - [](ModelUpdCmd* self, const std::string& k, const std::string& v) { - self->UpdateNumericField( - k, v, [self](float f) { self->model_config_.top_p = f; }); - }}, - {"temperature", - [](ModelUpdCmd* self, const std::string& k, const std::string& v) { - self->UpdateNumericField(k, v, [self](float f) { - self->model_config_.temperature = f; - }); - }}, - {"frequency_penalty", - [](ModelUpdCmd* self, const std::string& k, const std::string& v) { - self->UpdateNumericField(k, v, [self](float f) { - self->model_config_.frequency_penalty = f; - }); - }}, - {"presence_penalty", - [](ModelUpdCmd* self, const std::string& k, const std::string& v) { - self->UpdateNumericField(k, v, [self](float f) { - self->model_config_.presence_penalty = f; - }); - }}, - {"dynatemp_range", - [](ModelUpdCmd* self, const std::string& k, const std::string& v) { - self->UpdateNumericField(k, v, [self](float f) { - self->model_config_.dynatemp_range = f; - }); - }}, - {"dynatemp_exponent", - [](ModelUpdCmd* self, const std::string& k, const std::string& v) { - self->UpdateNumericField(k, v, [self](float f) { - self->model_config_.dynatemp_exponent = f; - }); - }}, - {"min_p", - [](ModelUpdCmd* self, const std::string& k, const std::string& v) { - self->UpdateNumericField( - k, v, [self](float f) { self->model_config_.min_p = f; }); - }}, - {"tfs_z", - [](ModelUpdCmd* self, const std::string& k, const std::string& v) { - self->UpdateNumericField( - k, v, [self](float f) { self->model_config_.tfs_z = f; }); - }}, - {"typ_p", - [](ModelUpdCmd* self, const std::string& k, const std::string& v) { - self->UpdateNumericField( - k, v, [self](float f) { self->model_config_.typ_p = f; }); - }}, - {"repeat_penalty", - [](ModelUpdCmd* self, const std::string& k, const std::string& v) { - self->UpdateNumericField(k, v, [self](float f) { - self->model_config_.repeat_penalty = f; - }); - }}, - {"mirostat_tau", - [](ModelUpdCmd* self, const std::string& k, const std::string& v) { - self->UpdateNumericField(k, v, [self](float f) { - self->model_config_.mirostat_tau = f; - }); - }}, - {"mirostat_eta", - [](ModelUpdCmd* self, const std::string& k, const std::string& v) { - self->UpdateNumericField(k, v, [self](float f) { - self->model_config_.mirostat_eta = f; - }); - }}, - {"max_tokens", - [](ModelUpdCmd* self, const std::string& k, const std::string& v) { - self->UpdateNumericField(k, v, [self](float f) { - self->model_config_.max_tokens = static_cast(f); - }); - }}, - {"ngl", - [](ModelUpdCmd* self, const std::string& k, const std::string& v) { - self->UpdateNumericField(k, v, [self](float f) { - self->model_config_.ngl = static_cast(f); - }); - }}, - {"ctx_len", - [](ModelUpdCmd* self, const std::string& k, const std::string& v) { - self->UpdateNumericField(k, v, [self](float f) { - self->model_config_.ctx_len = static_cast(f); - }); - }}, - {"tp", - [](ModelUpdCmd* self, const std::string& k, const std::string& v) { - self->UpdateNumericField(k, v, [self](float f) { - self->model_config_.tp = static_cast(f); - }); - }}, - {"seed", - [](ModelUpdCmd* self, const std::string& k, const std::string& v) { - self->UpdateNumericField(k, v, [self](float f) { - self->model_config_.seed = static_cast(f); - }); - }}, - {"top_k", - [](ModelUpdCmd* self, const std::string& k, const std::string& v) { - self->UpdateNumericField(k, v, [self](float f) { - self->model_config_.top_k = static_cast(f); - }); - }}, - {"repeat_last_n", - [](ModelUpdCmd* self, const std::string& k, const std::string& v) { - self->UpdateNumericField(k, v, [self](float f) { - self->model_config_.repeat_last_n = static_cast(f); - }); - }}, - {"n_probs", - [](ModelUpdCmd* self, const std::string& k, const std::string& v) { - self->UpdateNumericField(k, v, [self](float f) { - self->model_config_.n_probs = static_cast(f); - }); - }}, - {"min_keep", - [](ModelUpdCmd* self, const std::string& k, const std::string& v) { - self->UpdateNumericField(k, v, [self](float f) { - self->model_config_.min_keep = static_cast(f); - }); - }}, - {"stream", - [](ModelUpdCmd* self, const std::string& k, const std::string& v) { - self->UpdateBooleanField( - k, v, [self](bool b) { self->model_config_.stream = b; }); - }}, - {"text_model", - [](ModelUpdCmd* self, const std::string& k, const std::string& v) { - self->UpdateBooleanField( - k, v, [self](bool b) { self->model_config_.text_model = b; }); - }}, - {"mirostat", - [](ModelUpdCmd* self, const std::string& k, const std::string& v) { - self->UpdateBooleanField( - k, v, [self](bool b) { self->model_config_.mirostat = b; }); - }}, - {"penalize_nl", - [](ModelUpdCmd* self, const std::string& k, const std::string& v) { - self->UpdateBooleanField( - k, v, [self](bool b) { self->model_config_.penalize_nl = b; }); - }}, - {"ignore_eos", - [](ModelUpdCmd* self, const std::string& k, const std::string& v) { - self->UpdateBooleanField( - k, v, [self](bool b) { self->model_config_.ignore_eos = b; }); - }}, - {"created", - [](ModelUpdCmd* self, const std::string& k, const std::string& v) { - self->UpdateNumericField(k, v, [self](float f) { - self->model_config_.created = static_cast(f); - }); - }}, - }; - - if (auto it = updaters.find(key); it != updaters.end()) { - it->second(this, key, value); - LogUpdate(key, value); + auto data_str = json_data.toStyledString(); + auto res = cli.Patch("/v1/models/" + model_handle_, httplib::Headers(), + data_str.data(), data_str.size(), "application/json"); + if (res) { + if (res->status == httplib::StatusCode::OK_200) { + CLI_LOG("Successfully updated model ID '" + model_handle_ + "'!"); + return; + } else { + CTL_ERR("Model failed to update with status code: " << res->status); + return; + } } else { - CLI_LOG("Warning: Unknown configuration key '" << key << "' ignored."); + auto err = res.error(); + CTL_ERR("HTTP error: " << httplib::to_string(err)); + return; } } - -void ModelUpdCmd::UpdateVectorField(const std::string& key, - const std::string& value) { - std::vector tokens; - std::istringstream iss(value); - std::string token; - while (std::getline(iss, token, ',')) { - tokens.push_back(token); - } - model_config_.stop = tokens; -} - -void ModelUpdCmd::UpdateNumericField(const std::string& key, - const std::string& value, - std::function setter) { - try { - float numericValue = std::stof(value); - setter(numericValue); - } catch (const std::exception& e) { - CLI_LOG("Failed to parse numeric value for " << key << ": " << e.what()); - } -} - -void ModelUpdCmd::UpdateBooleanField(const std::string& key, - const std::string& value, - std::function setter) { - bool boolValue = (value == "true" || value == "1"); - setter(boolValue); -} - -void ModelUpdCmd::LogUpdate(const std::string& key, const std::string& value) { - CLI_LOG("Updated " << key << " to: " << value); -} - } // namespace commands \ No newline at end of file diff --git a/engine/commands/model_upd_cmd.h b/engine/commands/model_upd_cmd.h index 49c104157..6a5e8f42f 100644 --- a/engine/commands/model_upd_cmd.h +++ b/engine/commands/model_upd_cmd.h @@ -4,27 +4,14 @@ #include #include #include -#include "config/model_config.h" -#include "config/yaml_config.h" -#include "database/models.h" namespace commands { class ModelUpdCmd { public: ModelUpdCmd(std::string model_handle); - void Exec(const std::unordered_map& options); + void Exec(const std::string& host, int port, + const std::unordered_map& options); private: std::string model_handle_; - config::ModelConfig model_config_; - config::YamlHandler yaml_handler_; - cortex::db::Models model_list_utils_; - - void UpdateConfig(const std::string& key, const std::string& value); - void UpdateVectorField(const std::string& key, const std::string& value); - void UpdateNumericField(const std::string& key, const std::string& value, - std::function setter); - void UpdateBooleanField(const std::string& key, const std::string& value, - std::function setter); - void LogUpdate(const std::string& key, const std::string& value); }; } // 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 58ee9160f..38a7eaf66 100644 --- a/engine/controllers/command_line_parser.cc +++ b/engine/controllers/command_line_parser.cc @@ -245,7 +245,7 @@ void CommandLineParser::SetupModelCommands() { if (std::exchange(executed_, true)) return; commands::ModelListCmd().Exec(cml_data_.config.apiServerHost, - std::stoi(cml_data_.config.apiServerPort)); + std::stoi(cml_data_.config.apiServerPort)); }); auto get_models_cmd = @@ -598,6 +598,8 @@ void CommandLineParser::ModelUpdate(CLI::App* parent) { if (std::exchange(executed_, true)) return; commands::ModelUpdCmd command(cml_data_.model_id); - command.Exec(cml_data_.model_update_options); + command.Exec(cml_data_.config.apiServerHost, + std::stoi(cml_data_.config.apiServerPort), + cml_data_.model_update_options); }); } From 55b5ae2741ea53aaa94b35df097f16965ab794d6 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Tue, 15 Oct 2024 20:05:19 +0700 Subject: [PATCH 10/40] fix: engine list --- engine/commands/engine_list_cmd.cc | 50 +++++++++++++++++++---- engine/commands/engine_list_cmd.h | 10 +---- engine/controllers/command_line_parser.cc | 3 +- engine/controllers/engines.cc | 1 + 4 files changed, 46 insertions(+), 18 deletions(-) diff --git a/engine/commands/engine_list_cmd.cc b/engine/commands/engine_list_cmd.cc index 335e10439..c34bef1aa 100644 --- a/engine/commands/engine_list_cmd.cc +++ b/engine/commands/engine_list_cmd.cc @@ -1,21 +1,53 @@ #include "engine_list_cmd.h" +#include "httplib.h" +#include "json/json.h" +#include "server_start_cmd.h" +#include "utils/logging_utils.h" +// clang-format off #include +// clang-format on namespace commands { -bool EngineListCmd::Exec() { - auto status_list = engine_service_.GetEngineInfoList(); +bool EngineListCmd::Exec(const std::string& host, int port) { + // Start server if server is not started yet + if (!commands::IsServerAlive(host, port)) { + CLI_LOG("Starting server ..."); + commands::ServerStartCmd ssc; + if (!ssc.Exec(host, port)) { + return false; + } + } tabulate::Table table; table.add_row( {"#", "Name", "Supported Formats", "Version", "Variant", "Status"}); - for (int i = 0; i < status_list.size(); i++) { - auto engine_status = status_list[i]; - std::string index = std::to_string(i + 1); - auto variant = engine_status.variant.value_or(""); - auto version = engine_status.version.value_or(""); - table.add_row({index, engine_status.product_name, engine_status.format, - version, variant, engine_status.status}); + + httplib::Client cli(host + ":" + std::to_string(port)); + auto res = cli.Get("/v1/engines"); + if (res) { + if (res->status == httplib::StatusCode::OK_200) { + int count = 0; + // CLI_LOG(res->body); + Json::Value body; + Json::Reader reader; + reader.parse(res->body, body); + if (!body["data"].isNull()) { + for (auto const& v : body["data"]) { + count += 1; + table.add_row({std::to_string(count), v["name"].asString(), + v["format"].asString(), v["version"].asString(), + v["variant"].asString(), v["status"].asString()}); + } + } + } else { + CTL_ERR("Failed to get engine list with status code: " << res->status); + return false; + } + } else { + auto err = res.error(); + CTL_ERR("HTTP error: " << httplib::to_string(err)); + return false; } std::cout << table << std::endl; diff --git a/engine/commands/engine_list_cmd.h b/engine/commands/engine_list_cmd.h index be38bdd2d..96ad956b2 100644 --- a/engine/commands/engine_list_cmd.h +++ b/engine/commands/engine_list_cmd.h @@ -1,17 +1,11 @@ #pragma once -#include "services/engine_service.h" +#include namespace commands { class EngineListCmd { public: - explicit EngineListCmd() - : engine_service_{EngineService(std::make_shared())} {}; - - bool Exec(); - - private: - EngineService engine_service_; + bool Exec(const std::string& host, int port); }; } // namespace commands diff --git a/engine/controllers/command_line_parser.cc b/engine/controllers/command_line_parser.cc index 38a7eaf66..d0fc301d0 100644 --- a/engine/controllers/command_line_parser.cc +++ b/engine/controllers/command_line_parser.cc @@ -360,7 +360,8 @@ void CommandLineParser::SetupEngineCommands() { if (std::exchange(executed_, true)) return; commands::EngineListCmd command; - command.Exec(); + command.Exec(cml_data_.config.apiServerHost, + std::stoi(cml_data_.config.apiServerPort)); }); auto install_cmd = engines_cmd->add_subcommand("install", "Install engine"); diff --git a/engine/controllers/engines.cc b/engine/controllers/engines.cc index 8ce792742..cc17b1b12 100644 --- a/engine/controllers/engines.cc +++ b/engine/controllers/engines.cc @@ -53,6 +53,7 @@ void Engines::ListEngine( ret["variant"] = status.variant.value_or(""); ret["productName"] = status.product_name; ret["status"] = status.status; + ret["format"] = status.format; data.append(std::move(ret)); } From 963d83f1d2f73c66680b26aaeeb969a6d38239bf Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Tue, 15 Oct 2024 20:14:12 +0700 Subject: [PATCH 11/40] fix: engine get --- engine/commands/engine_get_cmd.cc | 51 ++++++++++++++++++----- engine/commands/engine_get_cmd.h | 11 ++--- engine/controllers/command_line_parser.cc | 4 +- engine/controllers/engines.cc | 1 + 4 files changed, 47 insertions(+), 20 deletions(-) diff --git a/engine/commands/engine_get_cmd.cc b/engine/commands/engine_get_cmd.cc index 67818a537..96180e49a 100644 --- a/engine/commands/engine_get_cmd.cc +++ b/engine/commands/engine_get_cmd.cc @@ -1,24 +1,53 @@ #include "engine_get_cmd.h" #include -#include -#include "services/engine_service.h" + +#include "httplib.h" +#include "json/json.h" +#include "server_start_cmd.h" #include "utils/logging_utils.h" +// clang-format off +#include +// clang-format on + namespace commands { -void EngineGetCmd::Exec(const std::string& engine_name) const { - auto engine = engine_service_.GetEngineInfo(engine_name); - if (engine.has_error()) { - CLI_LOG(engine.error()); - return; +void EngineGetCmd::Exec(const std::string& host, int port, + const std::string& engine_name) const { + // Start server if server is not started yet + if (!commands::IsServerAlive(host, port)) { + CLI_LOG("Starting server ..."); + commands::ServerStartCmd ssc; + if (!ssc.Exec(host, port)) { + return; + } } - auto version = engine->version.value_or(""); - auto variant = engine->variant.value_or(""); tabulate::Table table; table.add_row({"Name", "Supported Formats", "Version", "Variant", "Status"}); - table.add_row( - {engine->product_name, engine->format, version, variant, engine->status}); + httplib::Client cli(host + ":" + std::to_string(port)); + auto res = cli.Get("/v1/engines/" + engine_name); + if (res) { + if (res->status == httplib::StatusCode::OK_200) { + // CLI_LOG(res->body); + Json::Value v; + Json::Reader reader; + reader.parse(res->body, v); + + table.add_row({v["name"].asString(), v["format"].asString(), + v["version"].asString(), v["variant"].asString(), + v["status"].asString()}); + + } else { + CTL_ERR("Failed to get engine list with status code: " << res->status); + return; + } + } else { + auto err = res.error(); + CTL_ERR("HTTP error: " << httplib::to_string(err)); + return; + } + std::cout << table << std::endl; } }; // namespace commands diff --git a/engine/commands/engine_get_cmd.h b/engine/commands/engine_get_cmd.h index 0a58b7e37..c6415b2db 100644 --- a/engine/commands/engine_get_cmd.h +++ b/engine/commands/engine_get_cmd.h @@ -1,16 +1,11 @@ #pragma once - -#include "services/engine_service.h" +#include namespace commands { class EngineGetCmd { public: - explicit EngineGetCmd() - : engine_service_{EngineService(std::make_shared())} {}; - - void Exec(const std::string& engineName) const; + void Exec(const std::string& host, int port, + const std::string& engineName) const; - private: - EngineService engine_service_; }; } // namespace commands diff --git a/engine/controllers/command_line_parser.cc b/engine/controllers/command_line_parser.cc index d0fc301d0..c7cb22f82 100644 --- a/engine/controllers/command_line_parser.cc +++ b/engine/controllers/command_line_parser.cc @@ -530,7 +530,9 @@ void CommandLineParser::EngineGet(CLI::App* parent) { engine_get_cmd->callback([this, engine_name] { if (std::exchange(executed_, true)) return; - commands::EngineGetCmd().Exec(engine_name); + commands::EngineGetCmd().Exec(cml_data_.config.apiServerHost, + std::stoi(cml_data_.config.apiServerPort), + engine_name); }); } } diff --git a/engine/controllers/engines.cc b/engine/controllers/engines.cc index cc17b1b12..d9e6af3ef 100644 --- a/engine/controllers/engines.cc +++ b/engine/controllers/engines.cc @@ -77,6 +77,7 @@ void Engines::GetEngine(const HttpRequestPtr& req, ret["variant"] = status->variant.value_or(""); ret["productName"] = status->product_name; ret["status"] = status->status; + ret["format"] = status->format; auto resp = cortex_utils::CreateCortexHttpJsonResponse(ret); resp->setStatusCode(k200OK); From ca7b23551aa8dcb250747f3f68f09fc1cff065b7 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Tue, 15 Oct 2024 20:20:37 +0700 Subject: [PATCH 12/40] fix: engine uninstall --- engine/commands/engine_uninstall_cmd.cc | 29 ++++++++++++++++++----- engine/commands/engine_uninstall_cmd.h | 9 +------ engine/commands/model_del_cmd.h | 6 ----- engine/controllers/command_line_parser.cc | 4 +++- 4 files changed, 27 insertions(+), 21 deletions(-) diff --git a/engine/commands/engine_uninstall_cmd.cc b/engine/commands/engine_uninstall_cmd.cc index 1f2095edb..6953e2dea 100644 --- a/engine/commands/engine_uninstall_cmd.cc +++ b/engine/commands/engine_uninstall_cmd.cc @@ -1,16 +1,33 @@ #include "engine_uninstall_cmd.h" -#include "services/engine_service.h" +#include "httplib.h" +#include "server_start_cmd.h" #include "utils/logging_utils.h" namespace commands { -void EngineUninstallCmd::Exec(const std::string& engine) { - auto result = engine_service_.UninstallEngine(engine); +void EngineUninstallCmd::Exec(const std::string& host, int port, + const std::string& engine) { + // Start server if server is not started yet + if (!commands::IsServerAlive(host, port)) { + CLI_LOG("Starting server ..."); + commands::ServerStartCmd ssc; + if (!ssc.Exec(host, port)) { + return; + } + } - if (result.has_error()) { - CLI_LOG(result.error()); + // Call API to delete engine + httplib::Client cli(host + ":" + std::to_string(port)); + auto res = cli.Delete("/v1/engines/" + engine); + if (res) { + if (res->status == httplib::StatusCode::OK_200) { + CLI_LOG("Engine " + engine + " uninstalled successfully"); + } else { + CTL_ERR("Engine failed to uninstall with status code: " << res->status); + } } else { - CLI_LOG("Engine " + engine + " uninstalled successfully!"); + auto err = res.error(); + CTL_ERR("HTTP error: " << httplib::to_string(err)); } } }; // namespace commands diff --git a/engine/commands/engine_uninstall_cmd.h b/engine/commands/engine_uninstall_cmd.h index 46b1bd923..d2ffbf9fa 100644 --- a/engine/commands/engine_uninstall_cmd.h +++ b/engine/commands/engine_uninstall_cmd.h @@ -1,18 +1,11 @@ #pragma once -#include #include -#include "services/engine_service.h" namespace commands { class EngineUninstallCmd { public: - explicit EngineUninstallCmd() - : engine_service_{EngineService(std::make_shared())} {}; + void Exec(const std::string& host, int port, const std::string& engine); - void Exec(const std::string& engine); - - private: - EngineService engine_service_; }; } // namespace commands diff --git a/engine/commands/model_del_cmd.h b/engine/commands/model_del_cmd.h index 008f43e73..ad89b3eb4 100644 --- a/engine/commands/model_del_cmd.h +++ b/engine/commands/model_del_cmd.h @@ -1,18 +1,12 @@ #pragma once #include -#include "services/model_service.h" namespace commands { class ModelDelCmd { public: - explicit ModelDelCmd() - : model_service_{ModelService(std::make_shared())} {}; - void Exec(const std::string& host, int port, const std::string& model_handle); - private: - ModelService model_service_; }; } // namespace commands diff --git a/engine/controllers/command_line_parser.cc b/engine/controllers/command_line_parser.cc index c7cb22f82..a3a67fc84 100644 --- a/engine/controllers/command_line_parser.cc +++ b/engine/controllers/command_line_parser.cc @@ -498,7 +498,9 @@ void CommandLineParser::EngineUninstall(CLI::App* parent, if (std::exchange(executed_, true)) return; try { - commands::EngineUninstallCmd().Exec(engine_name); + commands::EngineUninstallCmd().Exec( + cml_data_.config.apiServerHost, + std::stoi(cml_data_.config.apiServerPort), engine_name); } catch (const std::exception& e) { CTL_ERR(e.what()); } From 0fa1edf26f1f32da639060af73532cdf0f785128 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Wed, 16 Oct 2024 12:37:05 +0700 Subject: [PATCH 13/40] fix: add cmake for cli --- engine/CMakeLists.txt | 2 + engine/cli/CMakeLists.txt | 127 ++++++++++++++++++++++++++++++++++++++ engine/cli/main.cc | 113 +++++++++++++++++++++++++++++++++ engine/commands/ps_cmd.cc | 1 - engine/vcpkg.json | 3 +- 5 files changed, 244 insertions(+), 2 deletions(-) create mode 100644 engine/cli/CMakeLists.txt create mode 100644 engine/cli/main.cc diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index 6076bb4ed..f23d70a07 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -67,6 +67,8 @@ if(CMAKE_BUILD_TEST) add_subdirectory(test) endif() +add_subdirectory(cli) + find_package(jsoncpp CONFIG REQUIRED) find_package(Drogon CONFIG REQUIRED) find_package(yaml-cpp CONFIG REQUIRED) diff --git a/engine/cli/CMakeLists.txt b/engine/cli/CMakeLists.txt new file mode 100644 index 000000000..47667f6c5 --- /dev/null +++ b/engine/cli/CMakeLists.txt @@ -0,0 +1,127 @@ +project(cortex-cli C CXX) + +include(CheckIncludeFileCXX) + +check_include_file_cxx(any HAS_ANY) +check_include_file_cxx(string_view HAS_STRING_VIEW) +check_include_file_cxx(coroutine HAS_COROUTINE) +if(HAS_ANY + AND HAS_STRING_VIEW + AND HAS_COROUTINE) + set(CMAKE_CXX_STANDARD 20) +elseif(HAS_ANY AND HAS_STRING_VIEW) + set(CMAKE_CXX_STANDARD 17) +else() + set(CMAKE_CXX_STANDARD 14) +endif() + +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) +set(OPENSSL_USE_STATIC_LIBS TRUE) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +if(MSVC) + add_compile_options( + $<$:/MT> #---------| + $<$:/MTd> #---|-- Statically link the runtime libraries + $<$:/MT> #--| + ) +endif() + +if(DEBUG) + message(STATUS "CORTEX-CPP DEBUG IS ON") + add_compile_definitions(ALLOW_ALL_CORS) +endif() + +if(NOT DEFINED CORTEX_VARIANT) + set(CORTEX_VARIANT "prod") +endif() + +set(TARGET_NAME ${PROJECT_NAME}) +if(RENAME_EXE) + if(CORTEX_VARIANT STREQUAL "beta") + set(TARGET_NAME "${PROJECT_NAME}-beta") + elseif(CORTEX_VARIANT STREQUAL "nightly") + set(TARGET_NAME "${PROJECT_NAME}-nightly") + else() + set(TARGET_NAME ${PROJECT_NAME}) + endif() +endif() + +if(NOT DEFINED CORTEX_CONFIG_FILE_PATH) + set(CORTEX_CONFIG_FILE_PATH "user_home") +endif() + +if(NOT DEFINED CORTEX_CPP_VERSION) + set(CORTEX_CPP_VERSION "default_version") +endif() + +add_compile_definitions(CORTEX_VARIANT="${CORTEX_VARIANT}") +add_compile_definitions(CORTEX_CPP_VERSION="${CORTEX_CPP_VERSION}") +add_compile_definitions(CORTEX_CONFIG_FILE_PATH="${CORTEX_CONFIG_FILE_PATH}") + +option(CMAKE_BUILD_TEST "Enable testing" OFF) +if(CMAKE_BUILD_TEST) + add_subdirectory(test) +endif() + +find_package(jsoncpp CONFIG REQUIRED) +find_package(yaml-cpp CONFIG REQUIRED) +find_package(httplib CONFIG REQUIRED) +find_package(nlohmann_json CONFIG REQUIRED) +find_package(CLI11 CONFIG REQUIRED) +find_package(unofficial-minizip CONFIG REQUIRED) +find_package(LibArchive REQUIRED) +find_package(tabulate CONFIG REQUIRED) +find_package(CURL REQUIRED) +find_package(SQLiteCpp REQUIRED) +find_package(eventpp CONFIG REQUIRED) +find_package(Trantor CONFIG REQUIRED) + +add_executable(${TARGET_NAME} main.cc + ${CMAKE_CURRENT_SOURCE_DIR}/../utils/cpuid/cpu_info.cc + ${CMAKE_CURRENT_SOURCE_DIR}/../utils/file_logger.cc + ${CMAKE_CURRENT_SOURCE_DIR}/../controllers/command_line_parser.cc + ${CMAKE_CURRENT_SOURCE_DIR}/../services/download_service.cc + ${CMAKE_CURRENT_SOURCE_DIR}/../services/engine_service.cc + ${CMAKE_CURRENT_SOURCE_DIR}/../services/model_service.cc + ) + +target_link_libraries(${TARGET_NAME} PRIVATE httplib::httplib) +target_link_libraries(${TARGET_NAME} PRIVATE nlohmann_json::nlohmann_json) +target_link_libraries(${TARGET_NAME} PRIVATE CLI11::CLI11) +target_link_libraries(${TARGET_NAME} PRIVATE unofficial::minizip::minizip) +target_link_libraries(${TARGET_NAME} PRIVATE LibArchive::LibArchive) +target_link_libraries(${TARGET_NAME} PRIVATE tabulate::tabulate) +target_link_libraries(${TARGET_NAME} PRIVATE CURL::libcurl) +target_link_libraries(${TARGET_NAME} PRIVATE JsonCpp::JsonCpp OpenSSL::SSL OpenSSL::Crypto yaml-cpp::yaml-cpp + ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries(${TARGET_NAME} PRIVATE SQLiteCpp) +target_link_libraries(${TARGET_NAME} PRIVATE eventpp::eventpp) +target_link_libraries(${TARGET_NAME} PRIVATE Trantor::Trantor) + +# ############################################################################## + +if(CMAKE_CXX_STANDARD LESS 17) + # With C++14, use boost to support any and std::string_view + message(STATUS "use c++14") + find_package(Boost 1.61.0 REQUIRED) + target_include_directories(${TARGET_NAME} PRIVATE ${Boost_INCLUDE_DIRS}) +elseif(CMAKE_CXX_STANDARD LESS 20) + message(STATUS "use c++17") +else() + message(STATUS "use c++20") +endif() + +# aux_source_directory(../controllers CTL_SRC) +# aux_source_directory(../services SERVICES_SRC) +aux_source_directory(../common COMMON_SRC) +aux_source_directory(../models MODEL_SRC) +aux_source_directory(../cortex-common CORTEX_COMMON) +aux_source_directory(../config CONFIG_SRC) +aux_source_directory(../commands COMMANDS_SRC) +aux_source_directory(../database DB_SRC) + +target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/.. ) + +target_sources(${TARGET_NAME} PRIVATE ${COMMANDS_SRC} ${CONFIG_SRC} ${COMMON_SRC} ${DB_SRC}) diff --git a/engine/cli/main.cc b/engine/cli/main.cc new file mode 100644 index 000000000..709205c3f --- /dev/null +++ b/engine/cli/main.cc @@ -0,0 +1,113 @@ +#include +#include "controllers/command_line_parser.h" +#include "cortex-common/cortexpythoni.h" +#include "services/model_service.h" +#include "utils/archive_utils.h" +#include "utils/cortex_utils.h" +#include "utils/dylib.h" +#include "utils/event_processor.h" +#include "utils/file_logger.h" +#include "utils/file_manager_utils.h" +#include "utils/logging_utils.h" +#include "utils/system_info_utils.h" + +#if defined(__APPLE__) && defined(__MACH__) +#include // for dirname() +#include +#include +#elif defined(__linux__) +#include // for dirname() +#include +#include +#include // for readlink() +#elif defined(_WIN32) +#include +#undef max +#else +#error "Unsupported platform!" +#endif + +int main(int argc, char* argv[]) { + // Stop the program if the system is not 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 1; + } + + for (int i = 0; i < argc; i++) { + if (strcmp(argv[i], "--config_file_path") == 0) { + file_manager_utils::cortex_config_file_path = argv[i + 1]; + + } else if(strcmp(argv[i], "--data_folder_path") == 0) { + file_manager_utils::cortex_data_folder_path = argv[i + 1]; + } + } + + { file_manager_utils::CreateConfigFileIfNotExist(); } + + // Delete temporary file if it exists + auto temp = + file_manager_utils::GetExecutableFolderContainerPath() / "cortex_temp"; + if (std::filesystem::exists(temp)) { + try { + std::filesystem::remove(temp); + } catch (const std::exception& e) { + std::cerr << e.what() << '\n'; + } + } + + // Check if this process is for python execution + if (argc > 1) { + if (strcmp(argv[1], "--run_python_file") == 0) { + std::string py_home_path = (argc > 3) ? argv[3] : ""; + std::unique_ptr dl; + try { + std::string abs_path = + cortex_utils::GetCurrentPath() + kPythonRuntimeLibPath; + dl = std::make_unique(abs_path, "engine"); + } catch (const cortex_cpp::dylib::load_error& e) { + LOG_ERROR << "Could not load engine: " << e.what(); + return 1; + } + + auto func = dl->get_function("get_engine"); + auto e = func(); + e->ExecutePythonFile(argv[0], argv[2], py_home_path); + return 0; + } + } + + if (argc > 1 && strcmp(argv[1], "--start-server") == 0) { + // RunServer(); + return 0; + } + + bool verbose = false; + for (int i = 0; i < argc; i++) { + if (strcmp(argv[i], "--verbose") == 0) { + verbose = true; + } + } + trantor::FileLogger asyncFileLogger; + if (!verbose) { + auto config = file_manager_utils::GetCortexConfig(); + std::filesystem::create_directories( + std::filesystem::path(config.logFolderPath) / + std::filesystem::path(cortex_utils::logs_folder)); + asyncFileLogger.setFileName(config.logFolderPath + "/" + + cortex_utils::logs_cli_base_name); + asyncFileLogger.setMaxLines(config.maxLogLines); // Keep last 100000 lines + asyncFileLogger.startLogging(); + trantor::Logger::setOutputFunction( + [&](const char* msg, const uint64_t len) { + asyncFileLogger.output_(msg, len); + }, + [&]() { asyncFileLogger.flush(); }); + } + CommandLineParser clp; + clp.SetupCommand(argc, argv); + return 0; +} diff --git a/engine/commands/ps_cmd.cc b/engine/commands/ps_cmd.cc index 5d5392565..970a6365d 100644 --- a/engine/commands/ps_cmd.cc +++ b/engine/commands/ps_cmd.cc @@ -1,5 +1,4 @@ #include "ps_cmd.h" -#include #include #include #include diff --git a/engine/vcpkg.json b/engine/vcpkg.json index 36693ba77..cfab8d2f5 100644 --- a/engine/vcpkg.json +++ b/engine/vcpkg.json @@ -15,6 +15,7 @@ "libarchive", "tabulate", "eventpp", - "sqlitecpp" + "sqlitecpp", + "trantor" ] } From 8eef533412282bb089e8a1bf7928d62a7a596184 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Wed, 16 Oct 2024 13:28:54 +0700 Subject: [PATCH 14/40] fix: binary name --- engine/CMakeLists.txt | 2 +- engine/cli/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index f23d70a07..2790ef771 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.5) -project(cortex C CXX) +project(cortex-server C CXX) include(CheckIncludeFileCXX) diff --git a/engine/cli/CMakeLists.txt b/engine/cli/CMakeLists.txt index 47667f6c5..72fdbba63 100644 --- a/engine/cli/CMakeLists.txt +++ b/engine/cli/CMakeLists.txt @@ -1,4 +1,4 @@ -project(cortex-cli C CXX) +project(cortex C CXX) include(CheckIncludeFileCXX) From 109bf0b736ddb9a69fd04aae8e225209590dfb7b Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Wed, 16 Oct 2024 13:41:12 +0700 Subject: [PATCH 15/40] fix: test CMakeLists --- engine/cli/CMakeLists.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/engine/cli/CMakeLists.txt b/engine/cli/CMakeLists.txt index 72fdbba63..d0b62d769 100644 --- a/engine/cli/CMakeLists.txt +++ b/engine/cli/CMakeLists.txt @@ -60,11 +60,6 @@ add_compile_definitions(CORTEX_VARIANT="${CORTEX_VARIANT}") add_compile_definitions(CORTEX_CPP_VERSION="${CORTEX_CPP_VERSION}") add_compile_definitions(CORTEX_CONFIG_FILE_PATH="${CORTEX_CONFIG_FILE_PATH}") -option(CMAKE_BUILD_TEST "Enable testing" OFF) -if(CMAKE_BUILD_TEST) - add_subdirectory(test) -endif() - find_package(jsoncpp CONFIG REQUIRED) find_package(yaml-cpp CONFIG REQUIRED) find_package(httplib CONFIG REQUIRED) From db649e57fa6d9c322dff44a5b3ee8a04c1523a6b Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Wed, 16 Oct 2024 13:52:24 +0700 Subject: [PATCH 16/40] fix: Makefile --- engine/Makefile | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/engine/Makefile b/engine/Makefile index d75df75a2..ded87aa72 100644 --- a/engine/Makefile +++ b/engine/Makefile @@ -19,6 +19,7 @@ PACKAGE_NAME ?= cortexcpp VERSION ?= 0.1.1 SOURCE_BINARY_PATH ?= ../../cortex/cortex DESTINATION_BINARY_NAME ?= cortex +DESTINATION_BINARY_SERVER_NAME ?= cortex-server DATA_FOLDER_NAME ?= .cortex CONFIGURATION_FILE_NAME ?= .cortexrc UNINSTALLER_FILE_NAME ?= cortex-uninstall.sh @@ -68,16 +69,19 @@ endif pre-package: ifeq ($(OS),Windows_NT) @powershell -Command "mkdir -p cortex;" - @powershell -Command "cp build\cortex.exe .\cortex\$(DESTINATION_BINARY_NAME).exe;" + @powershell -Command "cp build\cortex-server.exe .\cortex\$(DESTINATION_BINARY_SERVER_NAME).exe;" + @powershell -Command "cp build\cli\cortex.exe .\cortex\$(DESTINATION_BINARY_NAME).exe;" @powershell -Command "cp ..\.github\patches\windows\msvcp140.dll .\cortex\;" @powershell -Command "cp ..\.github\patches\windows\vcruntime140_1.dll .\cortex\;" @powershell -Command "cp ..\.github\patches\windows\vcruntime140.dll .\cortex\;" else ifeq ($(shell uname -s),Linux) @mkdir -p cortex; \ - cp build/cortex cortex/$(DESTINATION_BINARY_NAME); + cp build/cortex-server cortex/$(DESTINATION_BINARY_SERVER_NAME); \ + cp build/cli/cortex cortex/$(DESTINATION_BINARY_NAME); else @mkdir -p cortex; \ - cp build/cortex cortex/$(DESTINATION_BINARY_NAME); + cp build/cortex-server cortex/$(DESTINATION_BINARY_SERVER_NAME); \ + cp build/cli/cortex cortex/$(DESTINATION_BINARY_NAME); endif codesign-binary: From 8d437f8eb226bd3e5b1cd1f51f26ef0b3a5be7d0 Mon Sep 17 00:00:00 2001 From: Hien To Date: Wed, 16 Oct 2024 14:36:48 +0700 Subject: [PATCH 17/40] fix: installer for 2 binaries --- .github/workflows/template-build-linux-x64.yml | 9 ++++++--- .github/workflows/template-build-macos.yml | 18 ++++++++++++++---- .../workflows/template-build-windows-x64.yml | 9 ++++++--- engine/Makefile | 7 +++++-- engine/templates/linux/create_deb.sh | 9 ++++++--- engine/templates/linux/create_deb_local.sh | 9 ++++++--- engine/templates/macos/cortex-uninstall.sh | 2 ++ engine/templates/macos/create_pkg.sh | 12 ++++++++---- engine/templates/macos/create_pkg_local.sh | 12 ++++++++---- engine/templates/windows/installer-beta.iss | 1 + engine/templates/windows/installer-nightly.iss | 1 + engine/templates/windows/installer.iss | 1 + .../templates/windows/local-installer-beta.iss | 1 + .../windows/local-installer-nightly.iss | 1 + engine/templates/windows/local-installer.iss | 1 + 15 files changed, 67 insertions(+), 26 deletions(-) diff --git a/.github/workflows/template-build-linux-x64.yml b/.github/workflows/template-build-linux-x64.yml index 65e2e65e5..d82aa463f 100644 --- a/.github/workflows/template-build-linux-x64.yml +++ b/.github/workflows/template-build-linux-x64.yml @@ -84,6 +84,7 @@ jobs: if [ "${{ inputs.channel }}" == "stable" ]; then echo "::set-output name=package_name::cortexcpp" echo "::set-output name=destination_binary_name::cortex" + echo "::set-output name=destination_binary_server_name::cortex-server" echo "::set-output name=data_folder_name::cortexcpp" echo "::set-output name=configuration_file_name::.cortexrc" echo "::set-output name=uninstaller_file_name::cortex-uninstall.sh" @@ -94,6 +95,7 @@ jobs: if [ "${{ inputs.channel }}" == "beta" ]; then echo "::set-output name=package_name::cortexcpp-beta" echo "::set-output name=destination_binary_name::cortex-beta" + echo "::set-output name=destination_binary_server_name::cortex-server-beta" echo "::set-output name=data_folder_name::cortexcpp-beta" echo "::set-output name=configuration_file_name::.cortexrc-beta" echo "::set-output name=uninstaller_file_name::cortex-beta-uninstall.sh" @@ -104,6 +106,7 @@ jobs: if [ "${{ inputs.channel }}" == "nightly" ]; then echo "::set-output name=package_name::cortexcpp-nightly" echo "::set-output name=destination_binary_name::cortex-nightly" + echo "::set-output name=destination_binary_server_name::cortex-server-nightly" echo "::set-output name=data_folder_name::cortexcpp-nightly" echo "::set-output name=configuration_file_name::.cortexrc-nightly" echo "::set-output name=uninstaller_file_name::cortex-nightly-uninstall.sh" @@ -150,13 +153,13 @@ jobs: - name: Pre-package run: | cd engine - make pre-package DESTINATION_BINARY_NAME="${{ steps.set-output-params.outputs.destination_binary_name }}" + make pre-package DESTINATION_BINARY_NAME="${{ steps.set-output-params.outputs.destination_binary_name }}" DESTINATION_BINARY_SERVER_NAME="${{ steps.set-output-params.outputs.destination_binary_server_name }}" - name: Build network Installers shell: bash run: | cd engine - make build-installer PACKAGE_NAME="${{ steps.set-output-params.outputs.package_name }}" SOURCE_BINARY_PATH="../../cortex/${{ steps.set-output-params.outputs.destination_binary_name }}" VERSION=${{ inputs.new_version }} DESTINATION_BINARY_NAME="${{ steps.set-output-params.outputs.destination_binary_name }}" DATA_FOLDER_NAME="${{ steps.set-output-params.outputs.data_folder_name }}" CONFIGURATION_FILE_NAME="${{ steps.set-output-params.outputs.configuration_file_name }}" UNINSTALLER_FILE_NAME="${{ steps.set-output-params.outputs.uninstaller_file_name }}" + make build-installer PACKAGE_NAME="${{ steps.set-output-params.outputs.package_name }}" SOURCE_BINARY_PATH="../../cortex/${{ steps.set-output-params.outputs.destination_binary_name }}" SOURCE_BINARY_SERVER_PATH="../../cortex/${{ steps.set-output-params.outputs.destination_binary_server_name }}" VERSION=${{ inputs.new_version }} DESTINATION_BINARY_NAME="${{ steps.set-output-params.outputs.destination_binary_name }}" DESTINATION_BINARY_SERVER_NAME="${{ steps.set-output-params.outputs.destination_binary_server_name }}" DATA_FOLDER_NAME="${{ steps.set-output-params.outputs.data_folder_name }}" CONFIGURATION_FILE_NAME="${{ steps.set-output-params.outputs.configuration_file_name }}" UNINSTALLER_FILE_NAME="${{ steps.set-output-params.outputs.uninstaller_file_name }}" mv ${{ steps.set-output-params.outputs.package_name }}.deb ${{ steps.set-output-params.outputs.package_name }}-network.deb - name: Build local Installers @@ -185,7 +188,7 @@ jobs: rm -rf ${{ steps.set-output-params.outputs.package_name }} rm ${{ steps.set-output-params.outputs.package_name }}.deb chmod +x create_deb_local.sh - ./create_deb_local.sh ${{ steps.set-output-params.outputs.package_name }} ${{ inputs.new_version }} ../../cortex/${{ steps.set-output-params.outputs.destination_binary_name }} ${{ steps.set-output-params.outputs.destination_binary_name }} ${{ steps.set-output-params.outputs.data_folder_name }} ${{ steps.set-output-params.outputs.configuration_file_name }}; + ./create_deb_local.sh ${{ steps.set-output-params.outputs.package_name }} ${{ inputs.new_version }} ../../cortex/${{ steps.set-output-params.outputs.destination_binary_name }} ../../cortex/${{ steps.set-output-params.outputs.destination_binary_server_name }} ${{ steps.set-output-params.outputs.destination_binary_name }} ${{ steps.set-output-params.outputs.destination_binary_server_name }} ${{ steps.set-output-params.outputs.data_folder_name }} ${{ steps.set-output-params.outputs.configuration_file_name }}; cp ${{ steps.set-output-params.outputs.package_name }}.deb ../../${{ steps.set-output-params.outputs.package_name }}-local.deb - name: Package diff --git a/.github/workflows/template-build-macos.yml b/.github/workflows/template-build-macos.yml index cb0490a85..65ba97840 100644 --- a/.github/workflows/template-build-macos.yml +++ b/.github/workflows/template-build-macos.yml @@ -108,6 +108,7 @@ jobs: if [ "${{ inputs.channel }}" == "stable" ]; then echo "::set-output name=package_name::cortexcpp" echo "::set-output name=destination_binary_name::cortex" + echo "::set-output name=destination_binary_server_name::cortex-server" echo "::set-output name=data_folder_name::cortexcpp" echo "::set-output name=configuration_file_name::.cortexrc" echo "::set-output name=uninstaller_file_name::cortex-uninstall.sh" @@ -118,6 +119,7 @@ jobs: if [ "${{ inputs.channel }}" == "beta" ]; then echo "::set-output name=package_name::cortexcpp-beta" echo "::set-output name=destination_binary_name::cortex-beta" + echo "::set-output name=destination_binary_server_name::cortex-server-beta" echo "::set-output name=data_folder_name::cortexcpp-beta" echo "::set-output name=configuration_file_name::.cortexrc-beta" echo "::set-output name=uninstaller_file_name::cortex-beta-uninstall.sh" @@ -128,6 +130,7 @@ jobs: if [ "${{ inputs.channel }}" == "nightly" ]; then echo "::set-output name=package_name::cortexcpp-nightly" echo "::set-output name=destination_binary_name::cortex-nightly" + echo "::set-output name=destination_binary_server_name::cortex-server-nightly" echo "::set-output name=data_folder_name::cortexcpp-nightly" echo "::set-output name=configuration_file_name::.cortexrc-nightly" echo "::set-output name=uninstaller_file_name::cortex-nightly-uninstall.sh" @@ -164,7 +167,7 @@ jobs: - name: Pre-package run: | cd engine - make pre-package DESTINATION_BINARY_NAME="${{ steps.set-output-params.outputs.destination_binary_name }}" + make pre-package DESTINATION_BINARY_NAME="${{ steps.set-output-params.outputs.destination_binary_name }}" DESTINATION_BINARY_SERVER_NAME="${{ steps.set-output-params.outputs.destination_binary_server_name }}" - name: Upload Artifact uses: actions/upload-artifact@v4 @@ -192,6 +195,7 @@ jobs: if [ "${{ inputs.channel }}" == "stable" ]; then echo "::set-output name=package_name::cortexcpp" echo "::set-output name=destination_binary_name::cortex" + echo "::set-output name=destination_binary_server_name::cortex-server" echo "::set-output name=data_folder_name::cortexcpp" echo "::set-output name=configuration_file_name::.cortexrc" echo "::set-output name=uninstaller_file_name::cortex-uninstall.sh" @@ -202,6 +206,7 @@ jobs: if [ "${{ inputs.channel }}" == "beta" ]; then echo "::set-output name=package_name::cortexcpp-beta" echo "::set-output name=destination_binary_name::cortex-beta" + echo "::set-output name=destination_binary_server_name::cortex-server-beta" echo "::set-output name=data_folder_name::cortexcpp-beta" echo "::set-output name=configuration_file_name::.cortexrc-beta" echo "::set-output name=uninstaller_file_name::cortex-beta-uninstall.sh" @@ -212,6 +217,7 @@ jobs: if [ "${{ inputs.channel }}" == "nightly" ]; then echo "::set-output name=package_name::cortexcpp-nightly" echo "::set-output name=destination_binary_name::cortex-nightly" + echo "::set-output name=destination_binary_server_name::cortex-server-nightly" echo "::set-output name=data_folder_name::cortexcpp-nightly" echo "::set-output name=configuration_file_name::.cortexrc-nightly" echo "::set-output name=uninstaller_file_name::cortex-nightly-uninstall.sh" @@ -250,13 +256,16 @@ jobs: mkdir -p engine/cortex ls -al find . | grep ${{ steps.set-output-params.outputs.destination_binary_name }} + find . | grep ${{ steps.set-output-params.outputs.destination_binary_server_name }} lipo -create cortex-${{ inputs.new_version }}-mac-arm64/${{ steps.set-output-params.outputs.destination_binary_name }} cortex-${{ inputs.new_version }}-mac-amd64/${{ steps.set-output-params.outputs.destination_binary_name }} -output engine/cortex/${{ steps.set-output-params.outputs.destination_binary_name }} + lipo -create cortex-${{ inputs.new_version }}-mac-arm64/${{ steps.set-output-params.outputs.destination_binary_server_name }} cortex-${{ inputs.new_version }}-mac-amd64/${{ steps.set-output-params.outputs.destination_binary_server_name }} -output engine/cortex/${{ steps.set-output-params.outputs.destination_binary_server_name }} chmod +x engine/cortex/${{ steps.set-output-params.outputs.destination_binary_name }} + chmod +x engine/cortex/${{ steps.set-output-params.outputs.destination_binary_server_name }} - name: Code Signing binaries run: | cd engine - make codesign-binary CODE_SIGN=true DEVELOPER_ID="${{ secrets.DEVELOPER_ID }}" DESTINATION_BINARY_NAME="${{ steps.set-output-params.outputs.destination_binary_name }}" + make codesign-binary CODE_SIGN=true DEVELOPER_ID="${{ secrets.DEVELOPER_ID }}" DESTINATION_BINARY_NAME="${{ steps.set-output-params.outputs.destination_binary_name }}" DESTINATION_BINARY_SERVER_NAME="${{ steps.set-output-params.outputs.destination_binary_server_name }}" - name: Notary macOS Binary run: | @@ -264,6 +273,7 @@ jobs: cd engine/cortex # Notarize the binary quill notarize ./${{ steps.set-output-params.outputs.destination_binary_name }} + quill notarize ./${{ steps.set-output-params.outputs.destination_binary_server_name }} env: QUILL_NOTARY_KEY_ID: ${{ secrets.NOTARY_KEY_ID }} QUILL_NOTARY_ISSUER: ${{ secrets.NOTARY_ISSUER }} @@ -273,7 +283,7 @@ jobs: shell: bash run: | cd engine - make build-installer PACKAGE_NAME="${{ steps.set-output-params.outputs.package_name }}" VERSION=${{ inputs.new_version }} SOURCE_BINARY_PATH="../../cortex/${{ steps.set-output-params.outputs.destination_binary_name }}" DESTINATION_BINARY_NAME="${{ steps.set-output-params.outputs.destination_binary_name }}" DATA_FOLDER_NAME="${{ steps.set-output-params.outputs.data_folder_name }}" CONFIGURATION_FILE_NAME="${{ steps.set-output-params.outputs.configuration_file_name }}" UNINSTALLER_FILE_NAME="${{ steps.set-output-params.outputs.uninstaller_file_name }}" + make build-installer PACKAGE_NAME="${{ steps.set-output-params.outputs.package_name }}" VERSION=${{ inputs.new_version }} SOURCE_BINARY_PATH="../../cortex/${{ steps.set-output-params.outputs.destination_binary_name }}" SOURCE_BINARY_SERVER_PATH="../../cortex/${{ steps.set-output-params.outputs.destination_binary_server_name }}" DESTINATION_BINARY_NAME="${{ steps.set-output-params.outputs.destination_binary_name }}" DESTINATION_BINARY_SERVER_NAME="${{ steps.set-output-params.outputs.destination_binary_server_name }}" DATA_FOLDER_NAME="${{ steps.set-output-params.outputs.data_folder_name }}" CONFIGURATION_FILE_NAME="${{ steps.set-output-params.outputs.configuration_file_name }}" UNINSTALLER_FILE_NAME="${{ steps.set-output-params.outputs.uninstaller_file_name }}" cat templates/macos/Scripts/postinstall - name: Codesign and notary for macos installer @@ -298,7 +308,7 @@ jobs: cd ../../ chmod +x create_pkg_local.sh - ./create_pkg_local.sh ${{ steps.set-output-params.outputs.package_name }} ${{ inputs.new_version }} ../../cortex/${{ steps.set-output-params.outputs.destination_binary_name }} ${{ steps.set-output-params.outputs.destination_binary_name }} ${{ steps.set-output-params.outputs.data_folder_name }} ${{ steps.set-output-params.outputs.configuration_file_name }} ${{ steps.set-output-params.outputs.uninstaller_file_name }} + ./create_pkg_local.sh ${{ steps.set-output-params.outputs.package_name }} ${{ inputs.new_version }} ../../cortex/${{ steps.set-output-params.outputs.destination_binary_name }} ../../cortex/${{ steps.set-output-params.outputs.destination_binary_server_name }} ${{ steps.set-output-params.outputs.destination_binary_name }} ${{ steps.set-output-params.outputs.destination_binary_server_name }} ${{ steps.set-output-params.outputs.data_folder_name }} ${{ steps.set-output-params.outputs.configuration_file_name }} ${{ steps.set-output-params.outputs.uninstaller_file_name }} cp ${{ steps.set-output-params.outputs.package_name }}.pkg ../../ - name: Codesign and notary for macos installer diff --git a/.github/workflows/template-build-windows-x64.yml b/.github/workflows/template-build-windows-x64.yml index c7b0e5fed..8da0f35e3 100644 --- a/.github/workflows/template-build-windows-x64.yml +++ b/.github/workflows/template-build-windows-x64.yml @@ -105,6 +105,7 @@ jobs: if [ "${{ inputs.channel }}" == "stable" ]; then echo "::set-output name=package_name::cortexcpp" echo "::set-output name=destination_binary_name::cortex" + echo "::set-output name=destination_binary_server_name::cortex-server" echo "::set-output name=data_folder_name::cortexcpp" echo "::set-output name=configuration_file_name::.cortexrc" echo "::set-output name=uninstaller_file_name::cortex-uninstall.sh" @@ -116,6 +117,7 @@ jobs: if [ "${{ inputs.channel }}" == "beta" ]; then echo "::set-output name=package_name::cortexcpp-beta" echo "::set-output name=destination_binary_name::cortex-beta" + echo "::set-output name=destination_binary_server_name::cortex-server-beta" echo "::set-output name=data_folder_name::cortexcpp-beta" echo "::set-output name=configuration_file_name::.cortexrc-beta" echo "::set-output name=uninstaller_file_name::cortex-beta-uninstall.sh" @@ -127,6 +129,7 @@ jobs: if [ "${{ inputs.channel }}" == "nightly" ]; then echo "::set-output name=package_name::cortexcpp-nightly" echo "::set-output name=destination_binary_name::cortex-nightly" + echo "::set-output name=destination_binary_server_name::cortex-server-nightly" echo "::set-output name=data_folder_name::cortexcpp-nightly" echo "::set-output name=configuration_file_name::.cortexrc-nightly" echo "::set-output name=uninstaller_file_name::cortex-nightly-uninstall.sh" @@ -186,12 +189,12 @@ jobs: - name: Pre-package run: | cd engine - make pre-package DESTINATION_BINARY_NAME="${{ steps.set-output-params.outputs.destination_binary_name }}" + make pre-package DESTINATION_BINARY_NAME="${{ steps.set-output-params.outputs.destination_binary_name }}" DESTINATION_BINARY_SERVER_NAME="${{ steps.set-output-params.outputs.destination_binary_server_name }}" - name: Code Signing binaries run: | cd engine - make codesign-binary DESTINATION_BINARY_NAME="${{ steps.set-output-params.outputs.destination_binary_name }}" AZURE_KEY_VAULT_URI="${{ secrets.AZURE_KEY_VAULT_URI }}" AZURE_CLIENT_ID="${{ secrets.AZURE_CLIENT_ID }}" AZURE_TENANT_ID="${{ secrets.AZURE_TENANT_ID }}" AZURE_CLIENT_SECRET="${{ secrets.AZURE_CLIENT_SECRET }}" AZURE_CERT_NAME="${{ secrets.AZURE_CERT_NAME }}" + make codesign-binary DESTINATION_BINARY_NAME="${{ steps.set-output-params.outputs.destination_binary_name }}" DESTINATION_BINARY_SERVER_NAME="${{ steps.set-output-params.outputs.destination_binary_server_name }}" AZURE_KEY_VAULT_URI="${{ secrets.AZURE_KEY_VAULT_URI }}" AZURE_CLIENT_ID="${{ secrets.AZURE_CLIENT_ID }}" AZURE_TENANT_ID="${{ secrets.AZURE_TENANT_ID }}" AZURE_CLIENT_SECRET="${{ secrets.AZURE_CLIENT_SECRET }}" AZURE_CERT_NAME="${{ secrets.AZURE_CERT_NAME }}" - name: Update version in installer.iss using sed shell: bash @@ -208,7 +211,7 @@ jobs: shell: bash run: | cd engine - make build-installer PACKAGE_NAME=${{ steps.set-output-params.outputs.package_name }} VERSION=${{ inputs.new_version }} DESTINATION_BINARY_NAME="${{ steps.set-output-params.outputs.destination_binary_name }}" + make build-installer PACKAGE_NAME=${{ steps.set-output-params.outputs.package_name }} VERSION=${{ inputs.new_version }} DESTINATION_BINARY_NAME="${{ steps.set-output-params.outputs.destination_binary_name }}" DESTINATION_BINARY_SERVER_NAME="${{ steps.set-output-params.outputs.destination_binary_server_name }}" ls ../ - name: Build local Installers diff --git a/engine/Makefile b/engine/Makefile index ded87aa72..58b5fb975 100644 --- a/engine/Makefile +++ b/engine/Makefile @@ -18,6 +18,7 @@ DEVELOPER_ID ?= xxxx PACKAGE_NAME ?= cortexcpp VERSION ?= 0.1.1 SOURCE_BINARY_PATH ?= ../../cortex/cortex +SOURCE_BINARY_SERVER_PATH ?= ../../cortex/cortex-server DESTINATION_BINARY_NAME ?= cortex DESTINATION_BINARY_SERVER_NAME ?= cortex-server DATA_FOLDER_NAME ?= .cortex @@ -93,11 +94,13 @@ endif ifeq ($(OS),Windows_NT) @powershell -Command "dotnet tool install --global AzureSignTool;" @powershell -Command '~\.dotnet\tools\azuresigntool.exe sign -kvu "$(AZURE_KEY_VAULT_URI)" -kvi "$(AZURE_CLIENT_ID)" -kvt "$(AZURE_TENANT_ID)" -kvs "$(AZURE_CLIENT_SECRET)" -kvc "$(AZURE_CERT_NAME)" -tr http://timestamp.globalsign.com/tsa/r6advanced1 -v ".\cortex\$(DESTINATION_BINARY_NAME).exe";' + @powershell -Command '~\.dotnet\tools\azuresigntool.exe sign -kvu "$(AZURE_KEY_VAULT_URI)" -kvi "$(AZURE_CLIENT_ID)" -kvt "$(AZURE_TENANT_ID)" -kvs "$(AZURE_CLIENT_SECRET)" -kvc "$(AZURE_CERT_NAME)" -tr http://timestamp.globalsign.com/tsa/r6advanced1 -v ".\cortex\$(DESTINATIDESTINATION_BINARY_SERVER_NAMEON_BINARY_NAME).exe";' else ifeq ($(shell uname -s),Linux) @echo "Skipping Code Sign for linux" @exit 0 else codesign --force -s "$(DEVELOPER_ID)" --options=runtime --entitlements="./templates/macos/entitlements.plist" ./cortex/$(DESTINATION_BINARY_NAME); + codesign --force -s "$(DEVELOPER_ID)" --options=runtime --entitlements="./templates/macos/entitlements.plist" ./cortex/$(DESTINATION_BINARY_SERVER_NAME); endif package: @@ -117,13 +120,13 @@ else ifeq ($(shell uname -s),Linux) @echo "Building installer for linux"; \ cd templates/linux; \ chmod +x create_deb.sh; \ - ./create_deb.sh $(PACKAGE_NAME) $(VERSION) $(SOURCE_BINARY_PATH) $(DESTINATION_BINARY_NAME) $(DATA_FOLDER_NAME) $(CONFIGURATION_FILE_NAME); \ + ./create_deb.sh $(PACKAGE_NAME) $(VERSION) $(SOURCE_BINARY_PATH) $(SOURCE_BINARY_SERVER_PATH) $(DESTINATION_BINARY_NAME) $(DESTINATION_BINARY_SERVER_NAME) $(DATA_FOLDER_NAME) $(CONFIGURATION_FILE_NAME); \ cp $(PACKAGE_NAME).deb ../../ else @echo "Building installer for Macos"; \ cd templates/macos; \ chmod +x create_pkg.sh; \ - ./create_pkg.sh $(PACKAGE_NAME) $(VERSION) $(SOURCE_BINARY_PATH) $(DESTINATION_BINARY_NAME) $(DATA_FOLDER_NAME) $(CONFIGURATION_FILE_NAME) $(UNINSTALLER_FILE_NAME); \ + ./create_pkg.sh $(PACKAGE_NAME) $(VERSION) $(SOURCE_BINARY_PATH) $(SOURCE_BINARY_SERVER_PATH) $(DESTINATION_BINARY_NAME) $(DESTINATION_BINARY_SERVER_NAME) $(DATA_FOLDER_NAME) $(CONFIGURATION_FILE_NAME) $(UNINSTALLER_FILE_NAME); \ cp $(PACKAGE_NAME).pkg ../../ endif diff --git a/engine/templates/linux/create_deb.sh b/engine/templates/linux/create_deb.sh index 119d12421..29492bdd8 100644 --- a/engine/templates/linux/create_deb.sh +++ b/engine/templates/linux/create_deb.sh @@ -1,14 +1,17 @@ PACKAGE_NAME=$1 VERSION=$2 SOURCE_BINARY_PATH=$3 -DESTINATION_BINARY_NAME=$4 -DATA_FOLDER_NAME=$5 -CONFIGURATION_FILE_NAME=$6 +SOURCE_BINARY_SERVER_PATH=$4 +DESTINATION_BINARY_NAME=$5 +DESTINATION_BINARY_SERVER_NAME=$6 +DATA_FOLDER_NAME=$7 +CONFIGURATION_FILE_NAME=$8 mkdir -p $PACKAGE_NAME/DEBIAN mkdir -p $PACKAGE_NAME/usr/bin cp $SOURCE_BINARY_PATH $PACKAGE_NAME/usr/bin/$DESTINATION_BINARY_NAME +cp $SOURCE_BINARY_SERVER_PATH $PACKAGE_NAME/usr/bin/$DESTINATION_BINARY_SERVER_NAME export DESTINATION_BINARY_NAME diff --git a/engine/templates/linux/create_deb_local.sh b/engine/templates/linux/create_deb_local.sh index cf9c3cb07..6b54dc19d 100644 --- a/engine/templates/linux/create_deb_local.sh +++ b/engine/templates/linux/create_deb_local.sh @@ -1,14 +1,17 @@ PACKAGE_NAME=$1 VERSION=$2 SOURCE_BINARY_PATH=$3 -DESTINATION_BINARY_NAME=$4 -DATA_FOLDER_NAME=$5 -CONFIGURATION_FILE_NAME=$6 +SOURCE_BINARY_SERVER_PATH=$4 +DESTINATION_BINARY_NAME=$5 +DESTINATION_BINARY_SERVER_NAME=$6 +DATA_FOLDER_NAME=$7 +CONFIGURATION_FILE_NAME=$8 mkdir -p $PACKAGE_NAME/DEBIAN mkdir -p $PACKAGE_NAME/usr/bin cp $SOURCE_BINARY_PATH $PACKAGE_NAME/usr/bin/$DESTINATION_BINARY_NAME +cp $SOURCE_BINARY_SERVER_PATH $PACKAGE_NAME/usr/bin/$DESTINATION_BINARY_SERVER_NAME mkdir -p $PACKAGE_NAME/tmp/$DESTINATION_BINARY_NAME-dependencies cp dependencies/* $PACKAGE_NAME/tmp/$DESTINATION_BINARY_NAME-dependencies diff --git a/engine/templates/macos/cortex-uninstall.sh b/engine/templates/macos/cortex-uninstall.sh index b75167f0e..b764bb43f 100644 --- a/engine/templates/macos/cortex-uninstall.sh +++ b/engine/templates/macos/cortex-uninstall.sh @@ -3,6 +3,7 @@ DESTINATION_BINARY_NAME=cortex DATA_FOLDER_NAME=.cortex CONFIGURATION_FILE_NAME=.cortexrc UNINSTALLER_FILE_NAME=cortex-uninstall.sh +DESTINATION_BINARY_SERVER_NAME=cortex-server # required root privileges if [ "$EUID" -ne 0 ] @@ -21,6 +22,7 @@ fi sudo -u "$USER_TO_RUN_AS" /usr/local/bin/$DESTINATION_BINARY_NAME stop > /dev/null 2>&1 rm /usr/local/bin/$DESTINATION_BINARY_NAME +rm /usr/local/bin/$DESTINATION_BINARY_SERVER_NAME echo "Do you want to delete the '$USER_HOME/$DATA_FOLDER_NAME' data folder and file '$USER_HOME/$CONFIGURATION_FILE_NAME'? (y/n) [default: n]" read -r answer diff --git a/engine/templates/macos/create_pkg.sh b/engine/templates/macos/create_pkg.sh index 8be3fb362..47fa6d927 100644 --- a/engine/templates/macos/create_pkg.sh +++ b/engine/templates/macos/create_pkg.sh @@ -1,15 +1,18 @@ PACKAGE_NAME=$1 VERSION=$2 SOURCE_BINARY_PATH=$3 -DESTINATION_BINARY_NAME=$4 -DATA_FOLDER_NAME=$5 -CONFIGURATION_FILE_NAME=$6 -UNINSTALLER_FILE_NAME=$7 +SOURCE_BINARY_SERVER_PATH=$4 +DESTINATION_BINARY_NAME=$5 +DESTINATION_BINARY_SERVER_NAME=$6 +DATA_FOLDER_NAME=$7 +CONFIGURATION_FILE_NAME=$8 +UNINSTALLER_FILE_NAME=$9 mkdir installer mkdir Scripts cp $SOURCE_BINARY_PATH installer/$DESTINATION_BINARY_NAME +cp $SOURCE_BINARY_SERVER_PATH installer/$DESTINATION_BINARY_SERVER_NAME export DESTINATION_BINARY_NAME cp postinstall Scripts/postinstall @@ -24,5 +27,6 @@ sed -i '' "2s/.*/DESTINATION_BINARY_NAME=$DESTINATION_BINARY_NAME/" installer/$U sed -i '' "3s/.*/DATA_FOLDER_NAME=$DATA_FOLDER_NAME/" installer/$UNINSTALLER_FILE_NAME sed -i '' "4s/.*/CONFIGURATION_FILE_NAME=$CONFIGURATION_FILE_NAME/" installer/$UNINSTALLER_FILE_NAME sed -i '' "5s/.*/UNINSTALLER_FILE_NAME=$UNINSTALLER_FILE_NAME/" installer/$UNINSTALLER_FILE_NAME +sed -i '' "6s/.*/DESTINATION_BINARY_SERVER_NAME=$DESTINATION_BINARY_SERVER_NAME/" installer/$UNINSTALLER_FILE_NAME pkgbuild --identifier ai.${PACKAGE_NAME}.pkg --version $VERSION --scripts Scripts --install-location /usr/local/bin --root ./installer ${PACKAGE_NAME}.pkg diff --git a/engine/templates/macos/create_pkg_local.sh b/engine/templates/macos/create_pkg_local.sh index 5dce34931..de74b2bc7 100644 --- a/engine/templates/macos/create_pkg_local.sh +++ b/engine/templates/macos/create_pkg_local.sh @@ -1,15 +1,18 @@ PACKAGE_NAME=$1 VERSION=$2 SOURCE_BINARY_PATH=$3 -DESTINATION_BINARY_NAME=$4 -DATA_FOLDER_NAME=$5 -CONFIGURATION_FILE_NAME=$6 -UNINSTALLER_FILE_NAME=$7 +SOURCE_BINARY_SERVER_PATH=$4 +DESTINATION_BINARY_NAME=$5 +DESTINATION_BINARY_SERVER_NAME=$6 +DATA_FOLDER_NAME=$7 +CONFIGURATION_FILE_NAME=$8 +UNINSTALLER_FILE_NAME=$9 mkdir installer mkdir Scripts cp $SOURCE_BINARY_PATH installer/$DESTINATION_BINARY_NAME +cp $SOURCE_BINARY_SERVER_PATH installer/$DESTINATION_BINARY_SERVER_NAME export DESTINATION_BINARY_NAME cp postinstall_local Scripts/postinstall @@ -24,5 +27,6 @@ sed -i '' "2s/.*/DESTINATION_BINARY_NAME=$DESTINATION_BINARY_NAME/" installer/$U sed -i '' "3s/.*/DATA_FOLDER_NAME=$DATA_FOLDER_NAME/" installer/$UNINSTALLER_FILE_NAME sed -i '' "4s/.*/CONFIGURATION_FILE_NAME=$CONFIGURATION_FILE_NAME/" installer/$UNINSTALLER_FILE_NAME sed -i '' "5s/.*/UNINSTALLER_FILE_NAME=$UNINSTALLER_FILE_NAME/" installer/$UNINSTALLER_FILE_NAME +sed -i '' "6s/.*/DESTINATION_BINARY_SERVER_NAME=$DESTINATION_BINARY_SERVER_NAME/" installer/$UNINSTALLER_FILE_NAME pkgbuild --identifier ai.${PACKAGE_NAME}.pkg --version $VERSION --scripts Scripts --install-location /usr/local/bin --root ./installer ${PACKAGE_NAME}.pkg diff --git a/engine/templates/windows/installer-beta.iss b/engine/templates/windows/installer-beta.iss index be341c57b..07c779835 100644 --- a/engine/templates/windows/installer-beta.iss +++ b/engine/templates/windows/installer-beta.iss @@ -18,6 +18,7 @@ Name: "english"; MessagesFile: "compiler:Default.isl" ; Define the files to be installed [Files] Source: "cortex-beta.exe"; DestDir: "{app}"; Flags: ignoreversion +Source: "cortex-server-beta.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "msvcp140.dll"; DestDir: "{app}"; Flags: ignoreversion Source: "vcruntime140.dll"; DestDir: "{app}"; Flags: ignoreversion Source: "vcruntime140_1.dll"; DestDir: "{app}"; Flags: ignoreversion diff --git a/engine/templates/windows/installer-nightly.iss b/engine/templates/windows/installer-nightly.iss index 1f85e5f46..537a5899b 100644 --- a/engine/templates/windows/installer-nightly.iss +++ b/engine/templates/windows/installer-nightly.iss @@ -18,6 +18,7 @@ Name: "english"; MessagesFile: "compiler:Default.isl" ; Define the files to be installed [Files] Source: "cortex-nightly.exe"; DestDir: "{app}"; Flags: ignoreversion +Source: "cortex-server-nightly.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "msvcp140.dll"; DestDir: "{app}"; Flags: ignoreversion Source: "vcruntime140.dll"; DestDir: "{app}"; Flags: ignoreversion Source: "vcruntime140_1.dll"; DestDir: "{app}"; Flags: ignoreversion diff --git a/engine/templates/windows/installer.iss b/engine/templates/windows/installer.iss index 8b113b8f3..d3a3158c9 100644 --- a/engine/templates/windows/installer.iss +++ b/engine/templates/windows/installer.iss @@ -18,6 +18,7 @@ Name: "english"; MessagesFile: "compiler:Default.isl" ; Define the files to be installed [Files] Source: "cortex.exe"; DestDir: "{app}"; Flags: ignoreversion +Source: "cortex-server.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "msvcp140.dll"; DestDir: "{app}"; Flags: ignoreversion Source: "vcruntime140.dll"; DestDir: "{app}"; Flags: ignoreversion Source: "vcruntime140_1.dll"; DestDir: "{app}"; Flags: ignoreversion diff --git a/engine/templates/windows/local-installer-beta.iss b/engine/templates/windows/local-installer-beta.iss index ef751e047..df3041465 100644 --- a/engine/templates/windows/local-installer-beta.iss +++ b/engine/templates/windows/local-installer-beta.iss @@ -18,6 +18,7 @@ Name: "english"; MessagesFile: "compiler:Default.isl" ; Define the files to be installed [Files] Source: "cortex-beta.exe"; DestDir: "{app}"; Flags: ignoreversion +Source: "cortex-server-beta.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "msvcp140.dll"; DestDir: "{app}"; Flags: ignoreversion Source: "vcruntime140.dll"; DestDir: "{app}"; Flags: ignoreversion Source: "vcruntime140_1.dll"; DestDir: "{app}"; Flags: ignoreversion diff --git a/engine/templates/windows/local-installer-nightly.iss b/engine/templates/windows/local-installer-nightly.iss index d8255e68b..c69d54608 100644 --- a/engine/templates/windows/local-installer-nightly.iss +++ b/engine/templates/windows/local-installer-nightly.iss @@ -18,6 +18,7 @@ Name: "english"; MessagesFile: "compiler:Default.isl" ; Define the files to be installed [Files] Source: "cortex-nightly.exe"; DestDir: "{app}"; Flags: ignoreversion +Source: "cortex-server-nightly.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "msvcp140.dll"; DestDir: "{app}"; Flags: ignoreversion Source: "vcruntime140.dll"; DestDir: "{app}"; Flags: ignoreversion Source: "vcruntime140_1.dll"; DestDir: "{app}"; Flags: ignoreversion diff --git a/engine/templates/windows/local-installer.iss b/engine/templates/windows/local-installer.iss index 77fb4ae17..26c18da87 100644 --- a/engine/templates/windows/local-installer.iss +++ b/engine/templates/windows/local-installer.iss @@ -18,6 +18,7 @@ Name: "english"; MessagesFile: "compiler:Default.isl" ; Define the files to be installed [Files] Source: "cortex.exe"; DestDir: "{app}"; Flags: ignoreversion +Source: "cortex-server.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "msvcp140.dll"; DestDir: "{app}"; Flags: ignoreversion Source: "vcruntime140.dll"; DestDir: "{app}"; Flags: ignoreversion Source: "vcruntime140_1.dll"; DestDir: "{app}"; Flags: ignoreversion From 1e64d3574036c0c24935674f70ef4b822e84939a Mon Sep 17 00:00:00 2001 From: Hien To Date: Wed, 16 Oct 2024 14:43:52 +0700 Subject: [PATCH 18/40] fix: installer for 2 binaries --- engine/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/Makefile b/engine/Makefile index 58b5fb975..507c9319d 100644 --- a/engine/Makefile +++ b/engine/Makefile @@ -94,7 +94,7 @@ endif ifeq ($(OS),Windows_NT) @powershell -Command "dotnet tool install --global AzureSignTool;" @powershell -Command '~\.dotnet\tools\azuresigntool.exe sign -kvu "$(AZURE_KEY_VAULT_URI)" -kvi "$(AZURE_CLIENT_ID)" -kvt "$(AZURE_TENANT_ID)" -kvs "$(AZURE_CLIENT_SECRET)" -kvc "$(AZURE_CERT_NAME)" -tr http://timestamp.globalsign.com/tsa/r6advanced1 -v ".\cortex\$(DESTINATION_BINARY_NAME).exe";' - @powershell -Command '~\.dotnet\tools\azuresigntool.exe sign -kvu "$(AZURE_KEY_VAULT_URI)" -kvi "$(AZURE_CLIENT_ID)" -kvt "$(AZURE_TENANT_ID)" -kvs "$(AZURE_CLIENT_SECRET)" -kvc "$(AZURE_CERT_NAME)" -tr http://timestamp.globalsign.com/tsa/r6advanced1 -v ".\cortex\$(DESTINATIDESTINATION_BINARY_SERVER_NAMEON_BINARY_NAME).exe";' + @powershell -Command '~\.dotnet\tools\azuresigntool.exe sign -kvu "$(AZURE_KEY_VAULT_URI)" -kvi "$(AZURE_CLIENT_ID)" -kvt "$(AZURE_TENANT_ID)" -kvs "$(AZURE_CLIENT_SECRET)" -kvc "$(AZURE_CERT_NAME)" -tr http://timestamp.globalsign.com/tsa/r6advanced1 -v ".\cortex\$(DESTINATION_BINARY_SERVER_NAME).exe";' else ifeq ($(shell uname -s),Linux) @echo "Skipping Code Sign for linux" @exit 0 From 5a616f74c6efb07aea03768f75de0e6861639664 Mon Sep 17 00:00:00 2001 From: Hien To Date: Wed, 16 Oct 2024 14:59:37 +0700 Subject: [PATCH 19/40] fix: windows installer disable dir page --- engine/templates/windows/installer-beta.iss | 1 + engine/templates/windows/installer-nightly.iss | 1 + engine/templates/windows/installer.iss | 1 + engine/templates/windows/local-installer-beta.iss | 1 + engine/templates/windows/local-installer-nightly.iss | 1 + engine/templates/windows/local-installer.iss | 1 + 6 files changed, 6 insertions(+) diff --git a/engine/templates/windows/installer-beta.iss b/engine/templates/windows/installer-beta.iss index 07c779835..6d34a764c 100644 --- a/engine/templates/windows/installer-beta.iss +++ b/engine/templates/windows/installer-beta.iss @@ -10,6 +10,7 @@ Compression=lzma SolidCompression=yes PrivilegesRequired=lowest AllowNoIcons=yes +DisableDirPage=yes ; Define the languages section [Languages] diff --git a/engine/templates/windows/installer-nightly.iss b/engine/templates/windows/installer-nightly.iss index 537a5899b..ceba683c1 100644 --- a/engine/templates/windows/installer-nightly.iss +++ b/engine/templates/windows/installer-nightly.iss @@ -10,6 +10,7 @@ Compression=lzma SolidCompression=yes PrivilegesRequired=lowest AllowNoIcons=yes +DisableDirPage=yes ; Define the languages section [Languages] diff --git a/engine/templates/windows/installer.iss b/engine/templates/windows/installer.iss index d3a3158c9..bf6cdc146 100644 --- a/engine/templates/windows/installer.iss +++ b/engine/templates/windows/installer.iss @@ -10,6 +10,7 @@ Compression=lzma SolidCompression=yes PrivilegesRequired=lowest AllowNoIcons=yes +DisableDirPage=yes ; Define the languages section [Languages] diff --git a/engine/templates/windows/local-installer-beta.iss b/engine/templates/windows/local-installer-beta.iss index df3041465..84ad400c9 100644 --- a/engine/templates/windows/local-installer-beta.iss +++ b/engine/templates/windows/local-installer-beta.iss @@ -10,6 +10,7 @@ Compression=lzma SolidCompression=yes PrivilegesRequired=lowest AllowNoIcons=yes +DisableDirPage=yes ; Define the languages section [Languages] diff --git a/engine/templates/windows/local-installer-nightly.iss b/engine/templates/windows/local-installer-nightly.iss index c69d54608..e5155bc1a 100644 --- a/engine/templates/windows/local-installer-nightly.iss +++ b/engine/templates/windows/local-installer-nightly.iss @@ -10,6 +10,7 @@ Compression=lzma SolidCompression=yes PrivilegesRequired=lowest AllowNoIcons=yes +DisableDirPage=yes ; Define the languages section [Languages] diff --git a/engine/templates/windows/local-installer.iss b/engine/templates/windows/local-installer.iss index 26c18da87..e23e8da7a 100644 --- a/engine/templates/windows/local-installer.iss +++ b/engine/templates/windows/local-installer.iss @@ -10,6 +10,7 @@ Compression=lzma SolidCompression=yes PrivilegesRequired=lowest AllowNoIcons=yes +DisableDirPage=yes ; Define the languages section [Languages] From 3114515be9a202d2407e4caaa7e5f194110628eb Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Wed, 16 Oct 2024 16:10:10 +0700 Subject: [PATCH 20/40] fix: add upd server cmd (in-progress) --- engine/CMakeLists.txt | 5 + engine/cli/CMakeLists.txt | 5 + engine/cli/main.cc | 21 +- engine/commands/cortex_upd_cmd.h | 17 ++ engine/commands/cortex_upd_server_cmd.cc | 345 +++++++++++++++++++++++ engine/commands/cortex_upd_server_cmd.h | 33 +++ engine/commands/server_start_cmd.cc | 17 +- engine/main.cc | 29 +- 8 files changed, 430 insertions(+), 42 deletions(-) create mode 100644 engine/commands/cortex_upd_server_cmd.cc create mode 100644 engine/commands/cortex_upd_server_cmd.h diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index 2790ef771..1af0a5f6c 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -124,3 +124,8 @@ aux_source_directory(database DB_SRC) target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ) target_sources(${TARGET_NAME} PRIVATE ${COMMANDS_SRC} ${CONFIG_SRC} ${CTL_SRC} ${COMMON_SRC} ${SERVICES_SRC} ${DB_SRC}) + +set_target_properties(${TARGET_NAME} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR} + RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR} +) \ No newline at end of file diff --git a/engine/cli/CMakeLists.txt b/engine/cli/CMakeLists.txt index d0b62d769..2c1e784a8 100644 --- a/engine/cli/CMakeLists.txt +++ b/engine/cli/CMakeLists.txt @@ -120,3 +120,8 @@ aux_source_directory(../database DB_SRC) target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/.. ) target_sources(${TARGET_NAME} PRIVATE ${COMMANDS_SRC} ${CONFIG_SRC} ${COMMON_SRC} ${DB_SRC}) + +set_target_properties(${TARGET_NAME} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR} + RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR} +) \ No newline at end of file diff --git a/engine/cli/main.cc b/engine/cli/main.cc index 709205c3f..10b356fc5 100644 --- a/engine/cli/main.cc +++ b/engine/cli/main.cc @@ -1,4 +1,6 @@ #include +#include "commands/cortex_upd_cmd.h" +#include "commands/cortex_upd_server_cmd.h" #include "controllers/command_line_parser.h" #include "cortex-common/cortexpythoni.h" #include "services/model_service.h" @@ -41,7 +43,7 @@ int main(int argc, char* argv[]) { if (strcmp(argv[i], "--config_file_path") == 0) { file_manager_utils::cortex_config_file_path = argv[i + 1]; - } else if(strcmp(argv[i], "--data_folder_path") == 0) { + } else if (strcmp(argv[i], "--data_folder_path") == 0) { file_manager_utils::cortex_data_folder_path = argv[i + 1]; } } @@ -59,6 +61,18 @@ int main(int argc, char* argv[]) { } } + // Check if server exists, if not notify to user to install server + auto exe = commands::GetCortexServerBinary(); + auto server_binary_path = + std::filesystem::path(cortex_utils::GetCurrentPath()) / + std::filesystem::path(exe); + if (!std::filesystem::exists(server_binary_path)) { + std::cout << CORTEX_CPP_VERSION + << " requires server binary, run xxx to install server" + << std::endl; + return 0; + } + // Check if this process is for python execution if (argc > 1) { if (strcmp(argv[1], "--run_python_file") == 0) { @@ -80,11 +94,6 @@ int main(int argc, char* argv[]) { } } - if (argc > 1 && strcmp(argv[1], "--start-server") == 0) { - // RunServer(); - return 0; - } - bool verbose = false; for (int i = 0; i < argc; i++) { if (strcmp(argv[i], "--verbose") == 0) { diff --git a/engine/commands/cortex_upd_cmd.h b/engine/commands/cortex_upd_cmd.h index e7d5cf289..2196f7a67 100644 --- a/engine/commands/cortex_upd_cmd.h +++ b/engine/commands/cortex_upd_cmd.h @@ -14,6 +14,7 @@ namespace commands { constexpr const auto kNightlyHost = "delta.jan.ai"; constexpr const auto kNightlyFileName = "cortex-nightly.tar.gz"; const std::string kCortexBinary = "cortex"; +const std::string kCortexServerBinary = "cortex-server"; constexpr const auto kBetaComp = "-rc"; constexpr const auto kReleaseFormat = ".tar.gz"; constexpr const auto kTimeoutCheckUpdate = std::chrono::milliseconds(1000); @@ -47,6 +48,22 @@ inline std::string GetCortexBinary() { } } +inline std::string GetCortexServerBinary() { +#if defined(_WIN32) + constexpr const bool has_exe = true; +#else + constexpr const bool has_exe = false; +#endif + if (CORTEX_VARIANT == file_manager_utils::kNightlyVariant) { + return has_exe ? kCortexServerBinary + "-nightly.exe" + : kCortexServerBinary + "-nightly"; + } else if (CORTEX_VARIANT == file_manager_utils::kBetaVariant) { + return has_exe ? kCortexServerBinary + "-beta.exe" : kCortexServerBinary + "-beta"; + } else { + return has_exe ? kCortexServerBinary + ".exe" : kCortexServerBinary; + } +} + inline std::string GetHostName() { if (CORTEX_VARIANT == file_manager_utils::kNightlyVariant) { return "https://delta.jan.ai"; diff --git a/engine/commands/cortex_upd_server_cmd.cc b/engine/commands/cortex_upd_server_cmd.cc new file mode 100644 index 000000000..375e4d3bc --- /dev/null +++ b/engine/commands/cortex_upd_server_cmd.cc @@ -0,0 +1,345 @@ +#include "cortex_upd_server_cmd.h" +#include "cortex_upd_cmd.h" +#include "httplib.h" +#include "server_stop_cmd.h" +#include "utils/archive_utils.h" +#include "utils/scope_exit.h" +#include "utils/system_info_utils.h" +#include "utils/url_parser.h" + +namespace commands { + +namespace { +std::chrono::seconds GetUpdateIntervalCheck() { + if (CORTEX_VARIANT == file_manager_utils::kNightlyVariant) { + return std::chrono::seconds(10 * 60); + } else if (CORTEX_VARIANT == file_manager_utils::kBetaVariant) { + return std::chrono::seconds(60 * 60); + } else { + return std::chrono::seconds(24 * 60 * 60); + } +} + +std::chrono::seconds GetTimeSinceEpochMillisec() { + using namespace std::chrono; + return duration_cast(system_clock::now().time_since_epoch()); +} + +std::unique_ptr GetSystemInfoWithUniversal() { + auto system_info = system_info_utils::GetSystemInfo(); + if (system_info->os == "mac") { + CTL_INF("Change arch from " << system_info->arch << " to universal"); + system_info->arch = "universal"; + } + return system_info; +} + +} // namespace + +void CortexUpdServerCmd::Exec(const std::string& v) { + // Check for update, if current version is the latest, notify to user +// if (auto latest_version = commands::CheckNewUpdate(std::nullopt); +// latest_version.has_value() && *latest_version == CORTEX_CPP_VERSION) { +// CLI_LOG("cortex is up to date"); +// return; +// } + + { + auto config = file_manager_utils::GetCortexConfig(); + httplib::Client cli(config.apiServerHost + ":" + config.apiServerPort); + auto res = cli.Get("/healthz"); + if (res) { + CLI_LOG("Server is running. Stopping server before updating!"); + commands::ServerStopCmd ssc(config.apiServerHost, + std::stoi(config.apiServerPort)); + ssc.Exec(); + } + } + + // Try to remove cortex temp folder if it exists first + try { + auto n = std::filesystem::remove_all( + std::filesystem::temp_directory_path() / "cortex"); + CTL_INF("Deleted " << n << " files or directories"); + } catch (const std::exception& e) { + CTL_WRN(e.what()); + } + + if (CORTEX_VARIANT == file_manager_utils::kProdVariant) { + if (!GetStable(v)) + return; + } else if (CORTEX_VARIANT == file_manager_utils::kBetaVariant) { + if (!GetBeta(v)) + return; + } else { + if (!GetNightly(v)) + return; + } + CLI_LOG("Update cortex sucessfully"); +} + +bool CortexUpdServerCmd::GetStable(const std::string& v) { + auto system_info = GetSystemInfoWithUniversal(); + CTL_INF("OS: " << system_info->os << ", Arch: " << system_info->arch); + + // Download file + auto github_host = GetHostName(); + auto release_path = GetReleasePath(); + CTL_INF("Engine release path: " << github_host << release_path); + + httplib::Client cli(github_host); + if (auto res = cli.Get(release_path)) { + if (res->status == httplib::StatusCode::OK_200) { + try { + auto json_data = nlohmann::json::parse(res->body); + if (json_data.empty()) { + CLI_LOG("Version not found: " << v); + return false; + } + + if (!HandleGithubRelease(json_data["assets"], + {system_info->os + "-" + system_info->arch})) { + return false; + } + } catch (const nlohmann::json::parse_error& e) { + CTL_ERR("JSON parse error: " << e.what()); + return false; + } + } else { + CTL_ERR("HTTP error: " << res->status); + return false; + } + } else { + auto err = res.error(); + CTL_ERR("HTTP error: " << httplib::to_string(err)); + return false; + } + + // Replace binary file + auto executable_path = file_manager_utils::GetExecutableFolderContainerPath(); + auto src = + std::filesystem::temp_directory_path() / "cortex" / GetCortexServerBinary(); + auto dst = executable_path / GetCortexServerBinary(); + utils::ScopeExit se([]() { + auto cortex_tmp = std::filesystem::temp_directory_path() / "cortex"; + try { + auto n = std::filesystem::remove_all(cortex_tmp); + CTL_INF("Deleted " << n << " files or directories"); + } catch (const std::exception& e) { + CTL_WRN(e.what()); + } + }); + return ReplaceBinaryInflight(src, dst); +} + +bool CortexUpdServerCmd::GetBeta(const std::string& v) { + auto system_info = GetSystemInfoWithUniversal(); + CTL_INF("OS: " << system_info->os << ", Arch: " << system_info->arch); + + // Download file + auto github_host = GetHostName(); + auto release_path = GetReleasePath(); + CTL_INF("Engine release path: " << github_host << release_path); + + httplib::Client cli(github_host); + if (auto res = cli.Get(release_path)) { + if (res->status == httplib::StatusCode::OK_200) { + try { + auto json_res = nlohmann::json::parse(res->body); + + nlohmann::json json_data; + for (auto& jr : json_res) { + // Get the latest beta or match version + if (auto tag = jr["tag_name"].get(); + (v.empty() && tag.find(kBetaComp) != std::string::npos) || + (tag == v)) { + json_data = jr; + break; + } + } + + if (json_data.empty()) { + CLI_LOG("Version not found: " << v); + return false; + } + + if (!HandleGithubRelease(json_data["assets"], + {system_info->os + "-" + system_info->arch})) { + return false; + } + } catch (const nlohmann::json::parse_error& e) { + CTL_ERR("JSON parse error: " << e.what()); + return false; + } + } else { + CTL_ERR("HTTP error: " << res->status); + return false; + } + } else { + auto err = res.error(); + CTL_ERR("HTTP error: " << httplib::to_string(err)); + return false; + } + + // Replace binary file + auto executable_path = file_manager_utils::GetExecutableFolderContainerPath(); + auto src = + std::filesystem::temp_directory_path() / "cortex" / GetCortexServerBinary(); + auto dst = executable_path / GetCortexServerBinary(); + utils::ScopeExit se([]() { + auto cortex_tmp = std::filesystem::temp_directory_path() / "cortex"; + try { + auto n = std::filesystem::remove_all(cortex_tmp); + CTL_INF("Deleted " << n << " files or directories"); + } catch (const std::exception& e) { + CTL_WRN(e.what()); + } + }); + return ReplaceBinaryInflight(src, dst); +} + +bool CortexUpdServerCmd::HandleGithubRelease(const nlohmann::json& assets, + const std::string& os_arch) { + std::string matched_variant = ""; + for (auto& asset : assets) { + auto asset_name = asset["name"].get(); + if (asset_name.find(kCortexBinary) != std::string::npos && + asset_name.find(os_arch) != std::string::npos && + asset_name.find(kReleaseFormat) != 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 false; + } + CTL_INF("Matched variant: " << matched_variant); + + for (auto& asset : assets) { + auto asset_name = asset["name"].get(); + if (asset_name == matched_variant) { + auto download_url = asset["browser_download_url"].get(); + auto file_name = asset["name"].get(); + CTL_INF("Download url: " << download_url); + + auto local_path = + std::filesystem::temp_directory_path() / "cortex" / asset_name; + try { + if (!std::filesystem::exists(local_path.parent_path())) { + std::filesystem::create_directories(local_path.parent_path()); + } + } catch (const std::filesystem::filesystem_error& e) { + CTL_ERR("Failed to create directories: " << e.what()); + return false; + } + auto download_task{DownloadTask{.id = "cortex", + .type = DownloadType::Cortex, + .items = {DownloadItem{ + .id = "cortex", + .downloadUrl = download_url, + .localPath = local_path, + }}}}; + + auto result = download_service_->AddDownloadTask( + download_task, [](const DownloadTask& finishedTask) { + // try to unzip the downloaded file + CTL_INF("Downloaded engine path: " + << finishedTask.items[0].localPath.string()); + + auto extract_path = + finishedTask.items[0].localPath.parent_path().parent_path(); + + archive_utils::ExtractArchive( + finishedTask.items[0].localPath.string(), + extract_path.string()); + + CTL_INF("Finished!"); + }); + if (result.has_error()) { + CTL_ERR("Failed to download: " << result.error()); + } + break; + } + } + return true; +} + +bool CortexUpdServerCmd::GetNightly(const std::string& v) { + auto system_info = GetSystemInfoWithUniversal(); + CTL_INF("OS: " << system_info->os << ", Arch: " << system_info->arch); + + // Download file + std::string version = v.empty() ? "latest" : v; + std::string os_arch{system_info->os + "-" + system_info->arch}; + const char* paths[] = { + "cortex", + version.c_str(), + os_arch.c_str(), + kNightlyFileName, + }; + std::vector path_list(paths, std::end(paths)); + auto url_obj = url_parser::Url{ + .protocol = "https", + .host = kNightlyHost, + .pathParams = path_list, + }; + + CTL_INF("Engine release path: " << url_parser::FromUrl(url_obj)); + + std::filesystem::path localPath = + std::filesystem::temp_directory_path() / "cortex" / path_list.back(); + try { + if (!std::filesystem::exists(localPath.parent_path())) { + std::filesystem::create_directories(localPath.parent_path()); + } + } catch (const std::filesystem::filesystem_error& e) { + CTL_ERR("Failed to create directories: " << e.what()); + return false; + } + auto download_task = + DownloadTask{.id = "cortex", + .type = DownloadType::Cortex, + .items = {DownloadItem{ + .id = "cortex", + .downloadUrl = url_parser::FromUrl(url_obj), + .localPath = localPath, + }}}; + + auto result = download_service_->AddDownloadTask( + download_task, [](const DownloadTask& finishedTask) { + // try to unzip the downloaded file + CTL_INF("Downloaded engine path: " + << finishedTask.items[0].localPath.string()); + + auto extract_path = + finishedTask.items[0].localPath.parent_path().parent_path(); + + archive_utils::ExtractArchive(finishedTask.items[0].localPath.string(), + extract_path.string()); + + CTL_INF("Finished!"); + }); + if (result.has_error()) { + CTL_ERR("Failed to download: " << result.error()); + return false; + } + + // Replace binary file + auto executable_path = file_manager_utils::GetExecutableFolderContainerPath(); + auto src = + std::filesystem::temp_directory_path() / "cortex" / GetCortexServerBinary(); + auto dst = executable_path / GetCortexServerBinary(); + utils::ScopeExit se([]() { + auto cortex_tmp = std::filesystem::temp_directory_path() / "cortex"; + try { + auto n = std::filesystem::remove_all(cortex_tmp); + CTL_INF("Deleted " << n << " files or directories"); + } catch (const std::exception& e) { + CTL_WRN(e.what()); + } + }); + return ReplaceBinaryInflight(src, dst); +} +} // namespace commands diff --git a/engine/commands/cortex_upd_server_cmd.h b/engine/commands/cortex_upd_server_cmd.h new file mode 100644 index 000000000..7aefdb03e --- /dev/null +++ b/engine/commands/cortex_upd_server_cmd.h @@ -0,0 +1,33 @@ +#pragma once +#include +#if !defined(_WIN32) +#include +#include +#endif + +#include "utils/file_manager_utils.h" + +namespace commands { + +// This class manages the 'cortex update' command functionality +// There are three release types available: +// - Stable: Only retrieves the latest version +// - Beta: Allows retrieval of the latest beta version and specific versions using the -v flag +// - Nightly: Enables retrieval of the latest nightly build and specific versions using the -v flag +class CortexUpdServerCmd { + public: + explicit CortexUpdServerCmd(std::shared_ptr download_service) + : download_service_{download_service} {}; + + void Exec(const std::string& v); + + private: + std::shared_ptr download_service_; + + bool GetStable(const std::string& v); + bool GetBeta(const std::string& v); + bool HandleGithubRelease(const nlohmann::json& assets, + const std::string& os_arch); + bool GetNightly(const std::string& v); +}; +} // namespace commands diff --git a/engine/commands/server_start_cmd.cc b/engine/commands/server_start_cmd.cc index 48ff59e29..c80a5231b 100644 --- a/engine/commands/server_start_cmd.cc +++ b/engine/commands/server_start_cmd.cc @@ -30,6 +30,7 @@ bool TryConnectToServer(const std::string& host, int port) { ServerStartCmd::ServerStartCmd() {} bool ServerStartCmd::Exec(const std::string& host, int port) { + auto exe = commands::GetCortexServerBinary(); #if defined(_WIN32) || defined(_WIN64) // Windows-specific code to create a new process STARTUPINFO si; @@ -38,7 +39,6 @@ bool ServerStartCmd::Exec(const std::string& host, int port) { ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); - auto exe = commands::GetCortexBinary(); std::string cmds = cortex_utils::GetCurrentPath() + "/" + exe + " --start-server"; // Create child process @@ -58,11 +58,12 @@ bool ServerStartCmd::Exec(const std::string& host, int port) { std::cout << "Could not start server: " << GetLastError() << std::endl; return false; } else { - if(!TryConnectToServer(host, port)) { - return false; + if (!TryConnectToServer(host, port)) { + return false; } std::cout << "Server started" << std::endl; - std::cout << "API Documentation available at: http://" << host << ":" << port << std::endl; + std::cout << "API Documentation available at: http://" << host << ":" + << port << std::endl; } #else @@ -90,16 +91,16 @@ bool ServerStartCmd::Exec(const std::string& host, int port) { setenv(name, new_v.c_str(), true); CTL_INF("LD_LIBRARY_PATH: " << getenv(name)); #endif - auto exe = commands::GetCortexBinary(); std::string p = cortex_utils::GetCurrentPath() + "/" + exe; execl(p.c_str(), exe.c_str(), "--start-server", (char*)0); } else { // Parent process - if(!TryConnectToServer(host, port)) { - return false; + if (!TryConnectToServer(host, port)) { + return false; } std::cout << "Server started" << std::endl; - std::cout << "API Documentation available at: http://" << host << ":" << port << std::endl; + std::cout << "API Documentation available at: http://" << host << ":" + << port << std::endl; } #endif return true; diff --git a/engine/main.cc b/engine/main.cc index 339b7c12a..24053767b 100644 --- a/engine/main.cc +++ b/engine/main.cc @@ -165,34 +165,7 @@ int main(int argc, char* argv[]) { } } - if (argc > 1 && strcmp(argv[1], "--start-server") == 0) { - RunServer(); - return 0; - } - bool verbose = false; - for (int i = 0; i < argc; i++) { - if (strcmp(argv[i], "--verbose") == 0) { - verbose = true; - } - } - trantor::FileLogger asyncFileLogger; - if (!verbose) { - auto config = file_manager_utils::GetCortexConfig(); - std::filesystem::create_directories( - std::filesystem::path(config.logFolderPath) / - std::filesystem::path(cortex_utils::logs_folder)); - asyncFileLogger.setFileName(config.logFolderPath + "/" + - cortex_utils::logs_cli_base_name); - asyncFileLogger.setMaxLines(config.maxLogLines); // Keep last 100000 lines - asyncFileLogger.startLogging(); - trantor::Logger::setOutputFunction( - [&](const char* msg, const uint64_t len) { - asyncFileLogger.output_(msg, len); - }, - [&]() { asyncFileLogger.flush(); }); - } - CommandLineParser clp; - clp.SetupCommand(argc, argv); + RunServer(); return 0; } From 120ca7ba30339aebde2aeebd1d0070e1da816566 Mon Sep 17 00:00:00 2001 From: Hien To Date: Wed, 16 Oct 2024 16:43:51 +0700 Subject: [PATCH 21/40] fix: add installer file to latest folder s3 for nightly updater --- .github/workflows/nightly-build.yml | 4 ++++ .github/workflows/template-build-linux-x64.yml | 1 + .github/workflows/template-build-macos.yml | 1 + .github/workflows/template-build-windows-x64.yml | 1 + 4 files changed, 7 insertions(+) diff --git a/.github/workflows/nightly-build.yml b/.github/workflows/nightly-build.yml index 8816ca6a7..de4a64e51 100644 --- a/.github/workflows/nightly-build.yml +++ b/.github/workflows/nightly-build.yml @@ -101,6 +101,10 @@ jobs: aws s3 cp s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/cortex/temp-latest/mac-universal-cortex-nightly.tar.gz s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/cortex/latest/mac-universal/cortex-nightly.tar.gz aws s3 cp s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/cortex/temp-latest/linux-amd64-cortex-nightly.tar.gz s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/cortex/latest/linux-amd64/cortex-nightly.tar.gz aws s3 cp s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/cortex/temp-latest/windows-amd64-cortex-nightly.tar.gz s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/cortex/latest/windows-amd64/cortex-nightly.tar.gz + aws s3 cp s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/cortex/temp-latest/cortex-mac-universal-network-installer.pkg s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/cortex/latest/mac-universal/cortex-mac-universal-network-installer.pkg + aws s3 cp s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/cortex/temp-latest/cortex-linux-amd64-network-installer.deb s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/cortex/latest/linux-amd64/cortex-linux-amd64-network-installer.deb + aws s3 cp s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/cortex/temp-latest/cortex-windows-amd64-network-installer.exe s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/cortex/latest/windows-amd64/cortex-windows-amd64-network-installer.exe + env: AWS_ACCESS_KEY_ID: ${{ secrets.DELTA_AWS_ACCESS_KEY_ID }} diff --git a/.github/workflows/template-build-linux-x64.yml b/.github/workflows/template-build-linux-x64.yml index d82aa463f..0cbde59af 100644 --- a/.github/workflows/template-build-linux-x64.yml +++ b/.github/workflows/template-build-linux-x64.yml @@ -218,6 +218,7 @@ jobs: if: inputs.public_provider == 'aws-s3' run: | aws s3 cp ./engine/cortex.tar.gz s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/cortex/temp-latest/linux-amd64-cortex-nightly.tar.gz + aws s3 cp ./engine/${{ steps.set-output-params.outputs.package_name }}-network.deb s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/cortex/temp-latest/cortex-linux-amd64-network-installer.deb aws s3 cp ./engine/cortex.tar.gz s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/cortex/v${{ inputs.new_version }}/linux-amd64/cortex-nightly.tar.gz aws s3 cp ./engine/${{ steps.set-output-params.outputs.package_name }}-network.deb s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/cortex/v${{ inputs.new_version }}/linux-amd64/cortex-${{ inputs.new_version }}-linux-amd64-network-installer.deb diff --git a/.github/workflows/template-build-macos.yml b/.github/workflows/template-build-macos.yml index 65ba97840..b8a02aec9 100644 --- a/.github/workflows/template-build-macos.yml +++ b/.github/workflows/template-build-macos.yml @@ -350,6 +350,7 @@ jobs: if: inputs.public_provider == 'aws-s3' run: | aws s3 cp ./engine/cortex.tar.gz s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/cortex/temp-latest/mac-universal-cortex-nightly.tar.gz + aws s3 cp ./engine/${{ steps.set-output-params.outputs.package_name }}-network.pkg s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/cortex/temp-latest/cortex-mac-universal-network-installer.pkg aws s3 cp ./engine/cortex.tar.gz s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/cortex/v${{ inputs.new_version }}/mac-universal/cortex-nightly.tar.gz aws s3 cp ./engine/${{ steps.set-output-params.outputs.package_name }}-network.pkg s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/cortex/v${{ inputs.new_version }}/mac-universal/cortex-${{ inputs.new_version }}-mac-universal-network-installer.pkg diff --git a/.github/workflows/template-build-windows-x64.yml b/.github/workflows/template-build-windows-x64.yml index 8da0f35e3..98576bd0b 100644 --- a/.github/workflows/template-build-windows-x64.yml +++ b/.github/workflows/template-build-windows-x64.yml @@ -290,6 +290,7 @@ jobs: Import-Module "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1" refreshenv aws s3 cp ./engine/cortex.tar.gz s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/cortex/temp-latest/windows-amd64-cortex-nightly.tar.gz + aws s3 cp ./network-setup.exe s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/cortex/temp-latest/cortex-windows-amd64-network-installer.exe aws s3 cp ./engine/cortex.tar.gz s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/cortex/v${{ inputs.new_version }}/windows-amd64/cortex-nightly.tar.gz aws s3 cp ./network-setup.exe s3://${{ secrets.DELTA_AWS_S3_BUCKET_NAME }}/cortex/v${{ inputs.new_version }}/windows-amd64/cortex-${{ inputs.new_version }}-windows-amd64-network-installer.exe From fa5e761bd738e3c19e2fca3984e96f25ae4058d7 Mon Sep 17 00:00:00 2001 From: Hien To Date: Wed, 16 Oct 2024 16:59:26 +0700 Subject: [PATCH 22/40] fix: installer adds param skip post install --- engine/templates/linux/postinst | 6 ++++++ engine/templates/linux/postinst_local | 6 ++++++ engine/templates/macos/postinstall | 5 +++++ engine/templates/macos/postinstall_local | 5 +++++ engine/templates/windows/installer-beta.iss | 7 +++++++ engine/templates/windows/installer-nightly.iss | 7 +++++++ engine/templates/windows/installer.iss | 7 +++++++ engine/templates/windows/local-installer-beta.iss | 7 +++++++ engine/templates/windows/local-installer-nightly.iss | 7 +++++++ engine/templates/windows/local-installer.iss | 7 +++++++ 10 files changed, 64 insertions(+) diff --git a/engine/templates/linux/postinst b/engine/templates/linux/postinst index dc954487e..401b9f4b8 100644 --- a/engine/templates/linux/postinst +++ b/engine/templates/linux/postinst @@ -1,5 +1,11 @@ #!/bin/sh DESTINATION_BINARY_NAME=cortex + +if [ "$SKIP_POSTINSTALL" = "true" ]; then + echo "Skipping postinstall script." + exit 0 +fi + USER_TO_RUN_AS=${SUDO_USER:-$(whoami)} echo "Download cortex.llamacpp engines by default for user $USER_TO_RUN_AS" sudo -u $USER_TO_RUN_AS env PATH=$PATH:/usr/lib/wsl/lib /usr/bin/$DESTINATION_BINARY_NAME engines install llama-cpp diff --git a/engine/templates/linux/postinst_local b/engine/templates/linux/postinst_local index 44908a33f..04883171d 100644 --- a/engine/templates/linux/postinst_local +++ b/engine/templates/linux/postinst_local @@ -1,5 +1,11 @@ #!/bin/sh DESTINATION_BINARY_NAME=cortex + +if [ "$SKIP_POSTINSTALL" = "true" ]; then + echo "Skipping postinstall script." + exit 0 +fi + USER_TO_RUN_AS=${SUDO_USER:-$(whoami)} echo "Download cortex.llamacpp engines by default for user $USER_TO_RUN_AS" sudo -u $USER_TO_RUN_AS env PATH=$PATH:/usr/lib/wsl/lib /usr/bin/$DESTINATION_BINARY_NAME engines install llama-cpp -s /tmp/$DESTINATION_BINARY_NAME-dependencies diff --git a/engine/templates/macos/postinstall b/engine/templates/macos/postinstall index c13ed1b74..21e9e64d7 100644 --- a/engine/templates/macos/postinstall +++ b/engine/templates/macos/postinstall @@ -4,6 +4,11 @@ DESTINATION_BINARY_NAME=cortex DATA_FOLDER_NAME=.cortex CONFIGURATION_FILE_NAME=.cortexrc +if [ "$SKIP_POSTINSTALL" = "true" ]; then + echo "Skipping postinstall script." + exit 0 +fi + USER_TO_RUN_AS=$(stat -f "%Su" /dev/console) echo "Download cortex.llamacpp engines by default for user $USER_TO_RUN_AS" diff --git a/engine/templates/macos/postinstall_local b/engine/templates/macos/postinstall_local index 47d851de3..b0c95e682 100644 --- a/engine/templates/macos/postinstall_local +++ b/engine/templates/macos/postinstall_local @@ -4,6 +4,11 @@ DESTINATION_BINARY_NAME=cortex DATA_FOLDER_NAME=.cortex CONFIGURATION_FILE_NAME=.cortexrc +if [ "$SKIP_POSTINSTALL" = "true" ]; then + echo "Skipping postinstall script." + exit 0 +fi + USER_TO_RUN_AS=$(stat -f "%Su" /dev/console) echo "Download cortex.llamacpp engines by default for user $USER_TO_RUN_AS" diff --git a/engine/templates/windows/installer-beta.iss b/engine/templates/windows/installer-beta.iss index 6d34a764c..0fe40a5e3 100644 --- a/engine/templates/windows/installer-beta.iss +++ b/engine/templates/windows/installer-beta.iss @@ -53,6 +53,13 @@ begin CmdLine := Format('setx PATH "%s;%%PATH%%"', [ExpandedAppDir]); Exec('cmd.exe', '/C ' + CmdLine, '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + // Check if the parameter /SkipPostInstall is passed + if ParamStr(1) = '/SkipPostInstall' then + begin + Log('Skipping post-install actions.'); + Exit; // Exit the procedure without doing anything + end; + // Update status message for downloading llamacpp engine WizardForm.StatusLabel.Caption := 'Downloading llama.cpp engine and dependencies ...'; WizardForm.StatusLabel.Update; diff --git a/engine/templates/windows/installer-nightly.iss b/engine/templates/windows/installer-nightly.iss index ceba683c1..0a2f0a3d5 100644 --- a/engine/templates/windows/installer-nightly.iss +++ b/engine/templates/windows/installer-nightly.iss @@ -53,6 +53,13 @@ begin CmdLine := Format('setx PATH "%s;%%PATH%%"', [ExpandedAppDir]); Exec('cmd.exe', '/C ' + CmdLine, '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + // Check if the parameter /SkipPostInstall is passed + if ParamStr(1) = '/SkipPostInstall' then + begin + Log('Skipping post-install actions.'); + Exit; // Exit the procedure without doing anything + end; + // Update status message for downloading llamacpp engine WizardForm.StatusLabel.Caption := 'Downloading llama.cpp engine and dependencies ...'; WizardForm.StatusLabel.Update; diff --git a/engine/templates/windows/installer.iss b/engine/templates/windows/installer.iss index bf6cdc146..6c83db1c0 100644 --- a/engine/templates/windows/installer.iss +++ b/engine/templates/windows/installer.iss @@ -53,6 +53,13 @@ begin CmdLine := Format('setx PATH "%s;%%PATH%%"', [ExpandedAppDir]); Exec('cmd.exe', '/C ' + CmdLine, '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + // Check if the parameter /SkipPostInstall is passed + if ParamStr(1) = '/SkipPostInstall' then + begin + Log('Skipping post-install actions.'); + Exit; // Exit the procedure without doing anything + end; + // Update status message for downloading llamacpp engine WizardForm.StatusLabel.Caption := 'Downloading llama.cpp engine and dependencies ...'; WizardForm.StatusLabel.Update; diff --git a/engine/templates/windows/local-installer-beta.iss b/engine/templates/windows/local-installer-beta.iss index 84ad400c9..8df37e2d7 100644 --- a/engine/templates/windows/local-installer-beta.iss +++ b/engine/templates/windows/local-installer-beta.iss @@ -49,6 +49,13 @@ begin CmdLine := Format('setx PATH "%s;%%PATH%%"', [ExpandedAppDir]); Exec('cmd.exe', '/C ' + CmdLine, '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + // Check if the parameter /SkipPostInstall is passed + if ParamStr(1) = '/SkipPostInstall' then + begin + Log('Skipping post-install actions.'); + Exit; // Exit the procedure without doing anything + end; + // Update status message for installing engines WizardForm.StatusLabel.Caption := 'Installing engines from offline package...'; WizardForm.StatusLabel.Update; diff --git a/engine/templates/windows/local-installer-nightly.iss b/engine/templates/windows/local-installer-nightly.iss index e5155bc1a..395927e77 100644 --- a/engine/templates/windows/local-installer-nightly.iss +++ b/engine/templates/windows/local-installer-nightly.iss @@ -49,6 +49,13 @@ begin CmdLine := Format('setx PATH "%s;%%PATH%%"', [ExpandedAppDir]); Exec('cmd.exe', '/C ' + CmdLine, '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + // Check if the parameter /SkipPostInstall is passed + if ParamStr(1) = '/SkipPostInstall' then + begin + Log('Skipping post-install actions.'); + Exit; // Exit the procedure without doing anything + end; + // Update status message for installing engines WizardForm.StatusLabel.Caption := 'Installing engines from offline package...'; WizardForm.StatusLabel.Update; diff --git a/engine/templates/windows/local-installer.iss b/engine/templates/windows/local-installer.iss index e23e8da7a..60a788f6b 100644 --- a/engine/templates/windows/local-installer.iss +++ b/engine/templates/windows/local-installer.iss @@ -49,6 +49,13 @@ begin CmdLine := Format('setx PATH "%s;%%PATH%%"', [ExpandedAppDir]); Exec('cmd.exe', '/C ' + CmdLine, '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + // Check if the parameter /SkipPostInstall is passed + if ParamStr(1) = '/SkipPostInstall' then + begin + Log('Skipping post-install actions.'); + Exit; // Exit the procedure without doing anything + end; + // Update status message for installing engines WizardForm.StatusLabel.Caption := 'Installing engines from offline package...'; WizardForm.StatusLabel.Update; From be04f4bbdeb89c8ddb5edba1c48825d24fe029a4 Mon Sep 17 00:00:00 2001 From: Service Account Date: Wed, 16 Oct 2024 18:44:00 +0700 Subject: [PATCH 23/40] fix: skip postinstall macos --- engine/templates/macos/postinstall | 2 +- engine/templates/macos/postinstall_local | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/engine/templates/macos/postinstall b/engine/templates/macos/postinstall index 21e9e64d7..734dc3ea1 100644 --- a/engine/templates/macos/postinstall +++ b/engine/templates/macos/postinstall @@ -4,7 +4,7 @@ DESTINATION_BINARY_NAME=cortex DATA_FOLDER_NAME=.cortex CONFIGURATION_FILE_NAME=.cortexrc -if [ "$SKIP_POSTINSTALL" = "true" ]; then +if [ -f "/tmp/cortex_installer_skip_postinstall" ]; then echo "Skipping postinstall script." exit 0 fi diff --git a/engine/templates/macos/postinstall_local b/engine/templates/macos/postinstall_local index b0c95e682..dbd9ae23c 100644 --- a/engine/templates/macos/postinstall_local +++ b/engine/templates/macos/postinstall_local @@ -4,7 +4,7 @@ DESTINATION_BINARY_NAME=cortex DATA_FOLDER_NAME=.cortex CONFIGURATION_FILE_NAME=.cortexrc -if [ "$SKIP_POSTINSTALL" = "true" ]; then +if [ -f "/tmp/cortex_installer_skip_postinstall" ]; then echo "Skipping postinstall script." exit 0 fi From 2411315ec206018a1ee31996e6d15c46f01f0a68 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 17 Oct 2024 07:53:57 +0700 Subject: [PATCH 24/40] fix: nightly installer --- engine/commands/cortex_upd_cmd.cc | 86 ++++++++++++++++++++++++++----- engine/utils/command_executor.h | 1 + engine/utils/logging_utils.h | 13 ++--- 3 files changed, 79 insertions(+), 21 deletions(-) diff --git a/engine/commands/cortex_upd_cmd.cc b/engine/commands/cortex_upd_cmd.cc index 2d2caea8a..c148f8ee5 100644 --- a/engine/commands/cortex_upd_cmd.cc +++ b/engine/commands/cortex_upd_cmd.cc @@ -36,6 +36,75 @@ std::unique_ptr GetSystemInfoWithUniversal() { return system_info; } +// https://delta.jan.ai/cortex/v1.0.0-176/windows-amd64/cortex-1.0.0-176-windows-amd64-network-installer.exe +// https://delta.jan.ai/cortex/v1.0.0-176/mac-universal/cortex-1.0.0-176-mac-universal-network-installer.pkg +// https://delta.jan.ai/cortex/v1.0.0-176/linux-amd64/cortex-1.0.0-176-linux-amd64-network-installer.deb +std::string GetNightlyInstallerName(const std::string& v, + const std::string& os_arch) { + const std::string kCortex = "cortex"; + std::string version = v == "latest" ? "" : (v + "-"); +#if defined(__APPLE__) && defined(__MACH__) + return kCortex + "-" + version + os_arch + "-network-installer.pkg"; +#elif defined(__linux__) + return kCortex + "-" + version + os_arch + "-network-installer.deb"; +#else + return kCortex + "-" + version + os_arch + "-network-installer.exe"; +#endif +} + +// C:\Users\vansa\AppData\Local\Temp\cortex\cortex-windows-amd64-network-installer.exe +std::string GetInstallCmd(const std::string& exe_path) { +#if defined(__APPLE__) && defined(__MACH__) + return "SKIP_POSTINSTALL=true && sudo installer -pkg " + exe_path + " -target /"; +#elif defined(__linux__) + return "echo -e "n\n" | sudo SKIP_POSTINSTALL=true apt install -y --allow-downgrades " + exe_path; +#else + return "start /wait \"\" " + exe_path + + " /SkipPostInstall /VERYSILENT /SUPPRESSMSGBOXES /NORESTART"; +#endif +} + +bool InstallNewVersion(const std::filesystem::path& dst, + const std::string& exe_path) { + std::filesystem::path temp = dst.parent_path() / "cortex_temp"; + auto restore_binary = [&temp, &dst]() { + if (std::filesystem::exists(temp)) { + std::rename(temp.string().c_str(), dst.string().c_str()); + CLI_LOG("Restored binary file"); + } + }; + try { + if (std::filesystem::exists(temp)) { + std::filesystem::remove(temp); + } + // rename binary + std::rename(dst.string().c_str(), temp.string().c_str()); + // install here + CommandExecutor c(GetInstallCmd(exe_path)); + auto output = c.execute(); + if (!std::filesystem::exists(dst)) { + CTL_ERR("Something went wrong!"); + restore_binary(); + return false; + } + + // delete temp +#if !defined(_WIN32) + if (unlink(temp.string().c_str()) != 0) { + CTL_ERR("Error deleting self: " << strerror(errno)); + restore_binary(); + return false; + } +#endif + + } catch (const std::exception& e) { + CTL_ERR("Something went wrong: " << e.what()); + restore_binary(); + return false; + } + return true; +} + } // namespace std::optional CheckNewUpdate( @@ -429,7 +498,7 @@ bool CortexUpdCmd::GetNightly(const std::string& v) { "cortex", version.c_str(), os_arch.c_str(), - kNightlyFileName, + GetNightlyInstallerName(version, os_arch).c_str(), }; std::vector path_list(paths, std::end(paths)); auto url_obj = url_parser::Url{ @@ -438,7 +507,7 @@ bool CortexUpdCmd::GetNightly(const std::string& v) { .pathParams = path_list, }; - CTL_INF("Engine release path: " << url_parser::FromUrl(url_obj)); + CTL_INF("Cortex release path: " << url_parser::FromUrl(url_obj)); std::filesystem::path localPath = std::filesystem::temp_directory_path() / "cortex" / path_list.back(); @@ -462,15 +531,9 @@ bool CortexUpdCmd::GetNightly(const std::string& v) { auto result = download_service_->AddDownloadTask( download_task, [](const DownloadTask& finishedTask) { // try to unzip the downloaded file - CTL_INF("Downloaded engine path: " + CTL_INF("Downloaded cortex path: " << finishedTask.items[0].localPath.string()); - auto extract_path = - finishedTask.items[0].localPath.parent_path().parent_path(); - - archive_utils::ExtractArchive(finishedTask.items[0].localPath.string(), - extract_path.string()); - CTL_INF("Finished!"); }); if (result.has_error()) { @@ -480,8 +543,6 @@ bool CortexUpdCmd::GetNightly(const std::string& v) { // Replace binary file auto executable_path = file_manager_utils::GetExecutableFolderContainerPath(); - auto src = - std::filesystem::temp_directory_path() / "cortex" / GetCortexBinary(); auto dst = executable_path / GetCortexBinary(); utils::ScopeExit se([]() { auto cortex_tmp = std::filesystem::temp_directory_path() / "cortex"; @@ -492,6 +553,7 @@ bool CortexUpdCmd::GetNightly(const std::string& v) { CTL_WRN(e.what()); } }); - return ReplaceBinaryInflight(src, dst); + + return InstallNewVersion(dst, localPath.string()); } } // namespace commands diff --git a/engine/utils/command_executor.h b/engine/utils/command_executor.h index 86b8e6b79..87460e2c1 100644 --- a/engine/utils/command_executor.h +++ b/engine/utils/command_executor.h @@ -1,3 +1,4 @@ +#pragma once #include #include #include diff --git a/engine/utils/logging_utils.h b/engine/utils/logging_utils.h index c143c2177..035ce573e 100644 --- a/engine/utils/logging_utils.h +++ b/engine/utils/logging_utils.h @@ -7,19 +7,14 @@ inline bool log_verbose = false; // Only use trantor log #define CTL_DBG(msg) \ - if (!log_verbose) { \ - LOG_DEBUG << msg; \ - } + LOG_DEBUG << msg; + #define CTL_INF(msg) \ - if (!log_verbose) { \ - LOG_INFO << msg; \ - } + LOG_INFO << msg; #define CTL_WRN(msg) \ - if (!log_verbose) { \ - LOG_WARN << msg; \ - } + LOG_WARN << msg; // Use std::cout if not verbose, use trantor log if verbose #define CTL_ERR(msg) \ From ed1f0ab2f9fb57a75159e4ca89dd437c77409108 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 17 Oct 2024 07:58:05 +0700 Subject: [PATCH 25/40] fix: remove update server cmd --- engine/cli/main.cc | 6 +- engine/commands/cortex_upd_server_cmd.cc | 345 ----------------------- engine/commands/cortex_upd_server_cmd.h | 33 --- 3 files changed, 3 insertions(+), 381 deletions(-) delete mode 100644 engine/commands/cortex_upd_server_cmd.cc delete mode 100644 engine/commands/cortex_upd_server_cmd.h diff --git a/engine/cli/main.cc b/engine/cli/main.cc index 10b356fc5..0447a2a04 100644 --- a/engine/cli/main.cc +++ b/engine/cli/main.cc @@ -1,6 +1,5 @@ #include #include "commands/cortex_upd_cmd.h" -#include "commands/cortex_upd_server_cmd.h" #include "controllers/command_line_parser.h" #include "cortex-common/cortexpythoni.h" #include "services/model_service.h" @@ -68,8 +67,9 @@ int main(int argc, char* argv[]) { std::filesystem::path(exe); if (!std::filesystem::exists(server_binary_path)) { std::cout << CORTEX_CPP_VERSION - << " requires server binary, run xxx to install server" - << std::endl; + << " requires server binary, to install server, run: " + << commands::GetRole() << commands::GetCortexBinary() + << " update --server" << std::endl; return 0; } diff --git a/engine/commands/cortex_upd_server_cmd.cc b/engine/commands/cortex_upd_server_cmd.cc deleted file mode 100644 index 375e4d3bc..000000000 --- a/engine/commands/cortex_upd_server_cmd.cc +++ /dev/null @@ -1,345 +0,0 @@ -#include "cortex_upd_server_cmd.h" -#include "cortex_upd_cmd.h" -#include "httplib.h" -#include "server_stop_cmd.h" -#include "utils/archive_utils.h" -#include "utils/scope_exit.h" -#include "utils/system_info_utils.h" -#include "utils/url_parser.h" - -namespace commands { - -namespace { -std::chrono::seconds GetUpdateIntervalCheck() { - if (CORTEX_VARIANT == file_manager_utils::kNightlyVariant) { - return std::chrono::seconds(10 * 60); - } else if (CORTEX_VARIANT == file_manager_utils::kBetaVariant) { - return std::chrono::seconds(60 * 60); - } else { - return std::chrono::seconds(24 * 60 * 60); - } -} - -std::chrono::seconds GetTimeSinceEpochMillisec() { - using namespace std::chrono; - return duration_cast(system_clock::now().time_since_epoch()); -} - -std::unique_ptr GetSystemInfoWithUniversal() { - auto system_info = system_info_utils::GetSystemInfo(); - if (system_info->os == "mac") { - CTL_INF("Change arch from " << system_info->arch << " to universal"); - system_info->arch = "universal"; - } - return system_info; -} - -} // namespace - -void CortexUpdServerCmd::Exec(const std::string& v) { - // Check for update, if current version is the latest, notify to user -// if (auto latest_version = commands::CheckNewUpdate(std::nullopt); -// latest_version.has_value() && *latest_version == CORTEX_CPP_VERSION) { -// CLI_LOG("cortex is up to date"); -// return; -// } - - { - auto config = file_manager_utils::GetCortexConfig(); - httplib::Client cli(config.apiServerHost + ":" + config.apiServerPort); - auto res = cli.Get("/healthz"); - if (res) { - CLI_LOG("Server is running. Stopping server before updating!"); - commands::ServerStopCmd ssc(config.apiServerHost, - std::stoi(config.apiServerPort)); - ssc.Exec(); - } - } - - // Try to remove cortex temp folder if it exists first - try { - auto n = std::filesystem::remove_all( - std::filesystem::temp_directory_path() / "cortex"); - CTL_INF("Deleted " << n << " files or directories"); - } catch (const std::exception& e) { - CTL_WRN(e.what()); - } - - if (CORTEX_VARIANT == file_manager_utils::kProdVariant) { - if (!GetStable(v)) - return; - } else if (CORTEX_VARIANT == file_manager_utils::kBetaVariant) { - if (!GetBeta(v)) - return; - } else { - if (!GetNightly(v)) - return; - } - CLI_LOG("Update cortex sucessfully"); -} - -bool CortexUpdServerCmd::GetStable(const std::string& v) { - auto system_info = GetSystemInfoWithUniversal(); - CTL_INF("OS: " << system_info->os << ", Arch: " << system_info->arch); - - // Download file - auto github_host = GetHostName(); - auto release_path = GetReleasePath(); - CTL_INF("Engine release path: " << github_host << release_path); - - httplib::Client cli(github_host); - if (auto res = cli.Get(release_path)) { - if (res->status == httplib::StatusCode::OK_200) { - try { - auto json_data = nlohmann::json::parse(res->body); - if (json_data.empty()) { - CLI_LOG("Version not found: " << v); - return false; - } - - if (!HandleGithubRelease(json_data["assets"], - {system_info->os + "-" + system_info->arch})) { - return false; - } - } catch (const nlohmann::json::parse_error& e) { - CTL_ERR("JSON parse error: " << e.what()); - return false; - } - } else { - CTL_ERR("HTTP error: " << res->status); - return false; - } - } else { - auto err = res.error(); - CTL_ERR("HTTP error: " << httplib::to_string(err)); - return false; - } - - // Replace binary file - auto executable_path = file_manager_utils::GetExecutableFolderContainerPath(); - auto src = - std::filesystem::temp_directory_path() / "cortex" / GetCortexServerBinary(); - auto dst = executable_path / GetCortexServerBinary(); - utils::ScopeExit se([]() { - auto cortex_tmp = std::filesystem::temp_directory_path() / "cortex"; - try { - auto n = std::filesystem::remove_all(cortex_tmp); - CTL_INF("Deleted " << n << " files or directories"); - } catch (const std::exception& e) { - CTL_WRN(e.what()); - } - }); - return ReplaceBinaryInflight(src, dst); -} - -bool CortexUpdServerCmd::GetBeta(const std::string& v) { - auto system_info = GetSystemInfoWithUniversal(); - CTL_INF("OS: " << system_info->os << ", Arch: " << system_info->arch); - - // Download file - auto github_host = GetHostName(); - auto release_path = GetReleasePath(); - CTL_INF("Engine release path: " << github_host << release_path); - - httplib::Client cli(github_host); - if (auto res = cli.Get(release_path)) { - if (res->status == httplib::StatusCode::OK_200) { - try { - auto json_res = nlohmann::json::parse(res->body); - - nlohmann::json json_data; - for (auto& jr : json_res) { - // Get the latest beta or match version - if (auto tag = jr["tag_name"].get(); - (v.empty() && tag.find(kBetaComp) != std::string::npos) || - (tag == v)) { - json_data = jr; - break; - } - } - - if (json_data.empty()) { - CLI_LOG("Version not found: " << v); - return false; - } - - if (!HandleGithubRelease(json_data["assets"], - {system_info->os + "-" + system_info->arch})) { - return false; - } - } catch (const nlohmann::json::parse_error& e) { - CTL_ERR("JSON parse error: " << e.what()); - return false; - } - } else { - CTL_ERR("HTTP error: " << res->status); - return false; - } - } else { - auto err = res.error(); - CTL_ERR("HTTP error: " << httplib::to_string(err)); - return false; - } - - // Replace binary file - auto executable_path = file_manager_utils::GetExecutableFolderContainerPath(); - auto src = - std::filesystem::temp_directory_path() / "cortex" / GetCortexServerBinary(); - auto dst = executable_path / GetCortexServerBinary(); - utils::ScopeExit se([]() { - auto cortex_tmp = std::filesystem::temp_directory_path() / "cortex"; - try { - auto n = std::filesystem::remove_all(cortex_tmp); - CTL_INF("Deleted " << n << " files or directories"); - } catch (const std::exception& e) { - CTL_WRN(e.what()); - } - }); - return ReplaceBinaryInflight(src, dst); -} - -bool CortexUpdServerCmd::HandleGithubRelease(const nlohmann::json& assets, - const std::string& os_arch) { - std::string matched_variant = ""; - for (auto& asset : assets) { - auto asset_name = asset["name"].get(); - if (asset_name.find(kCortexBinary) != std::string::npos && - asset_name.find(os_arch) != std::string::npos && - asset_name.find(kReleaseFormat) != 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 false; - } - CTL_INF("Matched variant: " << matched_variant); - - for (auto& asset : assets) { - auto asset_name = asset["name"].get(); - if (asset_name == matched_variant) { - auto download_url = asset["browser_download_url"].get(); - auto file_name = asset["name"].get(); - CTL_INF("Download url: " << download_url); - - auto local_path = - std::filesystem::temp_directory_path() / "cortex" / asset_name; - try { - if (!std::filesystem::exists(local_path.parent_path())) { - std::filesystem::create_directories(local_path.parent_path()); - } - } catch (const std::filesystem::filesystem_error& e) { - CTL_ERR("Failed to create directories: " << e.what()); - return false; - } - auto download_task{DownloadTask{.id = "cortex", - .type = DownloadType::Cortex, - .items = {DownloadItem{ - .id = "cortex", - .downloadUrl = download_url, - .localPath = local_path, - }}}}; - - auto result = download_service_->AddDownloadTask( - download_task, [](const DownloadTask& finishedTask) { - // try to unzip the downloaded file - CTL_INF("Downloaded engine path: " - << finishedTask.items[0].localPath.string()); - - auto extract_path = - finishedTask.items[0].localPath.parent_path().parent_path(); - - archive_utils::ExtractArchive( - finishedTask.items[0].localPath.string(), - extract_path.string()); - - CTL_INF("Finished!"); - }); - if (result.has_error()) { - CTL_ERR("Failed to download: " << result.error()); - } - break; - } - } - return true; -} - -bool CortexUpdServerCmd::GetNightly(const std::string& v) { - auto system_info = GetSystemInfoWithUniversal(); - CTL_INF("OS: " << system_info->os << ", Arch: " << system_info->arch); - - // Download file - std::string version = v.empty() ? "latest" : v; - std::string os_arch{system_info->os + "-" + system_info->arch}; - const char* paths[] = { - "cortex", - version.c_str(), - os_arch.c_str(), - kNightlyFileName, - }; - std::vector path_list(paths, std::end(paths)); - auto url_obj = url_parser::Url{ - .protocol = "https", - .host = kNightlyHost, - .pathParams = path_list, - }; - - CTL_INF("Engine release path: " << url_parser::FromUrl(url_obj)); - - std::filesystem::path localPath = - std::filesystem::temp_directory_path() / "cortex" / path_list.back(); - try { - if (!std::filesystem::exists(localPath.parent_path())) { - std::filesystem::create_directories(localPath.parent_path()); - } - } catch (const std::filesystem::filesystem_error& e) { - CTL_ERR("Failed to create directories: " << e.what()); - return false; - } - auto download_task = - DownloadTask{.id = "cortex", - .type = DownloadType::Cortex, - .items = {DownloadItem{ - .id = "cortex", - .downloadUrl = url_parser::FromUrl(url_obj), - .localPath = localPath, - }}}; - - auto result = download_service_->AddDownloadTask( - download_task, [](const DownloadTask& finishedTask) { - // try to unzip the downloaded file - CTL_INF("Downloaded engine path: " - << finishedTask.items[0].localPath.string()); - - auto extract_path = - finishedTask.items[0].localPath.parent_path().parent_path(); - - archive_utils::ExtractArchive(finishedTask.items[0].localPath.string(), - extract_path.string()); - - CTL_INF("Finished!"); - }); - if (result.has_error()) { - CTL_ERR("Failed to download: " << result.error()); - return false; - } - - // Replace binary file - auto executable_path = file_manager_utils::GetExecutableFolderContainerPath(); - auto src = - std::filesystem::temp_directory_path() / "cortex" / GetCortexServerBinary(); - auto dst = executable_path / GetCortexServerBinary(); - utils::ScopeExit se([]() { - auto cortex_tmp = std::filesystem::temp_directory_path() / "cortex"; - try { - auto n = std::filesystem::remove_all(cortex_tmp); - CTL_INF("Deleted " << n << " files or directories"); - } catch (const std::exception& e) { - CTL_WRN(e.what()); - } - }); - return ReplaceBinaryInflight(src, dst); -} -} // namespace commands diff --git a/engine/commands/cortex_upd_server_cmd.h b/engine/commands/cortex_upd_server_cmd.h deleted file mode 100644 index 7aefdb03e..000000000 --- a/engine/commands/cortex_upd_server_cmd.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once -#include -#if !defined(_WIN32) -#include -#include -#endif - -#include "utils/file_manager_utils.h" - -namespace commands { - -// This class manages the 'cortex update' command functionality -// There are three release types available: -// - Stable: Only retrieves the latest version -// - Beta: Allows retrieval of the latest beta version and specific versions using the -v flag -// - Nightly: Enables retrieval of the latest nightly build and specific versions using the -v flag -class CortexUpdServerCmd { - public: - explicit CortexUpdServerCmd(std::shared_ptr download_service) - : download_service_{download_service} {}; - - void Exec(const std::string& v); - - private: - std::shared_ptr download_service_; - - bool GetStable(const std::string& v); - bool GetBeta(const std::string& v); - bool HandleGithubRelease(const nlohmann::json& assets, - const std::string& os_arch); - bool GetNightly(const std::string& v); -}; -} // namespace commands From 4853daa105f5c733546b73fcb0abc0e8c997b910 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 17 Oct 2024 08:00:57 +0700 Subject: [PATCH 26/40] fix: pre-package --- engine/CMakeLists.txt | 1 + engine/Makefile | 6 +++--- engine/cli/CMakeLists.txt | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index 1af0a5f6c..1d29319b6 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -128,4 +128,5 @@ target_sources(${TARGET_NAME} PRIVATE ${COMMANDS_SRC} ${CONFIG_SRC} ${CTL_SRC} $ set_target_properties(${TARGET_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR} RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR} + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} ) \ No newline at end of file diff --git a/engine/Makefile b/engine/Makefile index ded87aa72..c320bf463 100644 --- a/engine/Makefile +++ b/engine/Makefile @@ -70,18 +70,18 @@ pre-package: ifeq ($(OS),Windows_NT) @powershell -Command "mkdir -p cortex;" @powershell -Command "cp build\cortex-server.exe .\cortex\$(DESTINATION_BINARY_SERVER_NAME).exe;" - @powershell -Command "cp build\cli\cortex.exe .\cortex\$(DESTINATION_BINARY_NAME).exe;" + @powershell -Command "cp build\cortex.exe .\cortex\$(DESTINATION_BINARY_NAME).exe;" @powershell -Command "cp ..\.github\patches\windows\msvcp140.dll .\cortex\;" @powershell -Command "cp ..\.github\patches\windows\vcruntime140_1.dll .\cortex\;" @powershell -Command "cp ..\.github\patches\windows\vcruntime140.dll .\cortex\;" else ifeq ($(shell uname -s),Linux) @mkdir -p cortex; \ cp build/cortex-server cortex/$(DESTINATION_BINARY_SERVER_NAME); \ - cp build/cli/cortex cortex/$(DESTINATION_BINARY_NAME); + cp build/cortex cortex/$(DESTINATION_BINARY_NAME); else @mkdir -p cortex; \ cp build/cortex-server cortex/$(DESTINATION_BINARY_SERVER_NAME); \ - cp build/cli/cortex cortex/$(DESTINATION_BINARY_NAME); + cp build/cortex cortex/$(DESTINATION_BINARY_NAME); endif codesign-binary: diff --git a/engine/cli/CMakeLists.txt b/engine/cli/CMakeLists.txt index 2c1e784a8..cab65af18 100644 --- a/engine/cli/CMakeLists.txt +++ b/engine/cli/CMakeLists.txt @@ -124,4 +124,5 @@ target_sources(${TARGET_NAME} PRIVATE ${COMMANDS_SRC} ${CONFIG_SRC} ${COMMON_SRC set_target_properties(${TARGET_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR} RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR} + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} ) \ No newline at end of file From d2cf334b204df44137c2ee82021e12d188502ffe Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 17 Oct 2024 08:05:10 +0700 Subject: [PATCH 27/40] fix: build --- engine/commands/cortex_upd_cmd.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/engine/commands/cortex_upd_cmd.cc b/engine/commands/cortex_upd_cmd.cc index c148f8ee5..a00ffc1fb 100644 --- a/engine/commands/cortex_upd_cmd.cc +++ b/engine/commands/cortex_upd_cmd.cc @@ -57,7 +57,7 @@ std::string GetInstallCmd(const std::string& exe_path) { #if defined(__APPLE__) && defined(__MACH__) return "SKIP_POSTINSTALL=true && sudo installer -pkg " + exe_path + " -target /"; #elif defined(__linux__) - return "echo -e "n\n" | sudo SKIP_POSTINSTALL=true apt install -y --allow-downgrades " + exe_path; + return "echo -e \"n\\n\" | sudo SKIP_POSTINSTALL=true apt install -y --allow-downgrades " + exe_path; #else return "start /wait \"\" " + exe_path + " /SkipPostInstall /VERYSILENT /SUPPRESSMSGBOXES /NORESTART"; @@ -494,11 +494,12 @@ bool CortexUpdCmd::GetNightly(const std::string& v) { // Download file std::string version = v.empty() ? "latest" : v; std::string os_arch{system_info->os + "-" + system_info->arch}; + std::string installer_name = GetNightlyInstallerName(version, os_arch); const char* paths[] = { "cortex", version.c_str(), os_arch.c_str(), - GetNightlyInstallerName(version, os_arch).c_str(), + installer_name.c_str(), }; std::vector path_list(paths, std::end(paths)); auto url_obj = url_parser::Url{ From ab025903a93ec93cf83fbc9bab1822479c8cf4ba Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 17 Oct 2024 08:38:17 +0700 Subject: [PATCH 28/40] fix: support cortex update --server --- engine/cli/main.cc | 12 ++++++++++++ engine/commands/cortex_upd_cmd.cc | 14 +++++++++----- engine/commands/cortex_upd_cmd.h | 2 +- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/engine/cli/main.cc b/engine/cli/main.cc index 0447a2a04..7b64d251f 100644 --- a/engine/cli/main.cc +++ b/engine/cli/main.cc @@ -2,6 +2,7 @@ #include "commands/cortex_upd_cmd.h" #include "controllers/command_line_parser.h" #include "cortex-common/cortexpythoni.h" +#include "services/download_service.h" #include "services/model_service.h" #include "utils/archive_utils.h" #include "utils/cortex_utils.h" @@ -44,6 +45,17 @@ int main(int argc, char* argv[]) { } else if (strcmp(argv[i], "--data_folder_path") == 0) { file_manager_utils::cortex_data_folder_path = argv[i + 1]; + } else if ((strcmp(argv[i], "--server") == 0) && + (strcmp(argv[i - 1], "update") == 0)) { +#if !defined(_WIN32) + if (getuid()) { + CLI_LOG("Error: Not root user. Please run with sudo."); + return 0; + } +#endif + auto cuc = commands::CortexUpdCmd(std::make_shared()); + cuc.Exec({}, true /*force*/); + return 0; } } diff --git a/engine/commands/cortex_upd_cmd.cc b/engine/commands/cortex_upd_cmd.cc index a00ffc1fb..6debc91a1 100644 --- a/engine/commands/cortex_upd_cmd.cc +++ b/engine/commands/cortex_upd_cmd.cc @@ -55,9 +55,12 @@ std::string GetNightlyInstallerName(const std::string& v, // C:\Users\vansa\AppData\Local\Temp\cortex\cortex-windows-amd64-network-installer.exe std::string GetInstallCmd(const std::string& exe_path) { #if defined(__APPLE__) && defined(__MACH__) - return "SKIP_POSTINSTALL=true && sudo installer -pkg " + exe_path + " -target /"; + return "SKIP_POSTINSTALL=true && sudo installer -pkg " + exe_path + + " -target /"; #elif defined(__linux__) - return "echo -e \"n\\n\" | sudo SKIP_POSTINSTALL=true apt install -y --allow-downgrades " + exe_path; + return "echo -e \"n\\n\" | sudo SKIP_POSTINSTALL=true apt install -y " + "--allow-downgrades " + + exe_path; #else return "start /wait \"\" " + exe_path + " /SkipPostInstall /VERYSILENT /SUPPRESSMSGBOXES /NORESTART"; @@ -83,7 +86,7 @@ bool InstallNewVersion(const std::filesystem::path& dst, CommandExecutor c(GetInstallCmd(exe_path)); auto output = c.execute(); if (!std::filesystem::exists(dst)) { - CTL_ERR("Something went wrong!"); + CTL_ERR("Something went wrong!"); restore_binary(); return false; } @@ -257,10 +260,11 @@ bool ReplaceBinaryInflight(const std::filesystem::path& src, return true; } -void CortexUpdCmd::Exec(const std::string& v) { +void CortexUpdCmd::Exec(const std::string& v, bool force) { // Check for update, if current version is the latest, notify to user if (auto latest_version = commands::CheckNewUpdate(std::nullopt); - latest_version.has_value() && *latest_version == CORTEX_CPP_VERSION) { + latest_version.has_value() && *latest_version == CORTEX_CPP_VERSION && + !force) { CLI_LOG("cortex is up to date"); return; } diff --git a/engine/commands/cortex_upd_cmd.h b/engine/commands/cortex_upd_cmd.h index 2196f7a67..1d74dc4df 100644 --- a/engine/commands/cortex_upd_cmd.h +++ b/engine/commands/cortex_upd_cmd.h @@ -98,7 +98,7 @@ class CortexUpdCmd { explicit CortexUpdCmd(std::shared_ptr download_service) : download_service_{download_service} {}; - void Exec(const std::string& v); + void Exec(const std::string& v, bool force = false); private: std::shared_ptr download_service_; From f54866562277c1c07b13869c369ebe6d642a1cf9 Mon Sep 17 00:00:00 2001 From: Hien To Date: Thu, 17 Oct 2024 08:58:07 +0700 Subject: [PATCH 29/40] fix: installer adds param skip post install --- engine/templates/macos/postinstall | 2 +- engine/templates/macos/postinstall_local | 2 +- engine/templates/windows/installer-beta.iss | 1 - engine/templates/windows/installer-nightly.iss | 1 - engine/templates/windows/installer.iss | 1 - engine/templates/windows/local-installer-beta.iss | 1 - engine/templates/windows/local-installer-nightly.iss | 1 - engine/templates/windows/local-installer.iss | 1 - 8 files changed, 2 insertions(+), 8 deletions(-) diff --git a/engine/templates/macos/postinstall b/engine/templates/macos/postinstall index 734dc3ea1..6d06c673d 100644 --- a/engine/templates/macos/postinstall +++ b/engine/templates/macos/postinstall @@ -4,7 +4,7 @@ DESTINATION_BINARY_NAME=cortex DATA_FOLDER_NAME=.cortex CONFIGURATION_FILE_NAME=.cortexrc -if [ -f "/tmp/cortex_installer_skip_postinstall" ]; then +if [ -f "/var/tmp/cortex_installer_skip_postinstall" ]; then echo "Skipping postinstall script." exit 0 fi diff --git a/engine/templates/macos/postinstall_local b/engine/templates/macos/postinstall_local index dbd9ae23c..7a6af4090 100644 --- a/engine/templates/macos/postinstall_local +++ b/engine/templates/macos/postinstall_local @@ -4,7 +4,7 @@ DESTINATION_BINARY_NAME=cortex DATA_FOLDER_NAME=.cortex CONFIGURATION_FILE_NAME=.cortexrc -if [ -f "/tmp/cortex_installer_skip_postinstall" ]; then +if [ -f "/var/tmp/cortex_installer_skip_postinstall" ]; then echo "Skipping postinstall script." exit 0 fi diff --git a/engine/templates/windows/installer-beta.iss b/engine/templates/windows/installer-beta.iss index 0fe40a5e3..f91cbd0f4 100644 --- a/engine/templates/windows/installer-beta.iss +++ b/engine/templates/windows/installer-beta.iss @@ -10,7 +10,6 @@ Compression=lzma SolidCompression=yes PrivilegesRequired=lowest AllowNoIcons=yes -DisableDirPage=yes ; Define the languages section [Languages] diff --git a/engine/templates/windows/installer-nightly.iss b/engine/templates/windows/installer-nightly.iss index 0a2f0a3d5..60ad2c71d 100644 --- a/engine/templates/windows/installer-nightly.iss +++ b/engine/templates/windows/installer-nightly.iss @@ -10,7 +10,6 @@ Compression=lzma SolidCompression=yes PrivilegesRequired=lowest AllowNoIcons=yes -DisableDirPage=yes ; Define the languages section [Languages] diff --git a/engine/templates/windows/installer.iss b/engine/templates/windows/installer.iss index 6c83db1c0..65dbf1f57 100644 --- a/engine/templates/windows/installer.iss +++ b/engine/templates/windows/installer.iss @@ -10,7 +10,6 @@ Compression=lzma SolidCompression=yes PrivilegesRequired=lowest AllowNoIcons=yes -DisableDirPage=yes ; Define the languages section [Languages] diff --git a/engine/templates/windows/local-installer-beta.iss b/engine/templates/windows/local-installer-beta.iss index 8df37e2d7..81b1c277b 100644 --- a/engine/templates/windows/local-installer-beta.iss +++ b/engine/templates/windows/local-installer-beta.iss @@ -10,7 +10,6 @@ Compression=lzma SolidCompression=yes PrivilegesRequired=lowest AllowNoIcons=yes -DisableDirPage=yes ; Define the languages section [Languages] diff --git a/engine/templates/windows/local-installer-nightly.iss b/engine/templates/windows/local-installer-nightly.iss index 395927e77..04bf869b5 100644 --- a/engine/templates/windows/local-installer-nightly.iss +++ b/engine/templates/windows/local-installer-nightly.iss @@ -10,7 +10,6 @@ Compression=lzma SolidCompression=yes PrivilegesRequired=lowest AllowNoIcons=yes -DisableDirPage=yes ; Define the languages section [Languages] diff --git a/engine/templates/windows/local-installer.iss b/engine/templates/windows/local-installer.iss index 60a788f6b..b42b1f393 100644 --- a/engine/templates/windows/local-installer.iss +++ b/engine/templates/windows/local-installer.iss @@ -10,7 +10,6 @@ Compression=lzma SolidCompression=yes PrivilegesRequired=lowest AllowNoIcons=yes -DisableDirPage=yes ; Define the languages section [Languages] From 5b75268fa4b8b61dc87ce9c0201ecc35e084fbc5 Mon Sep 17 00:00:00 2001 From: Hien To Date: Thu, 17 Oct 2024 09:43:56 +0700 Subject: [PATCH 30/40] fix: installer adds param skip post install --- engine/templates/windows/installer-beta.iss | 21 +++++++++++++++---- .../templates/windows/installer-nightly.iss | 21 +++++++++++++++---- engine/templates/windows/installer.iss | 21 +++++++++++++++---- .../windows/local-installer-beta.iss | 21 +++++++++++++++---- .../windows/local-installer-nightly.iss | 21 +++++++++++++++---- engine/templates/windows/local-installer.iss | 21 +++++++++++++++---- 6 files changed, 102 insertions(+), 24 deletions(-) diff --git a/engine/templates/windows/installer-beta.iss b/engine/templates/windows/installer-beta.iss index f91cbd0f4..7bb937d11 100644 --- a/engine/templates/windows/installer-beta.iss +++ b/engine/templates/windows/installer-beta.iss @@ -38,7 +38,20 @@ var ExpandedAppDir: String; CmdLine, CortexInstallCmd: String; ResultCode: Integer; + i: Integer; + SkipPostInstall: Boolean; begin + SkipPostInstall := False; + + // Loop through all parameters to check for /SkipPostInstall + for i := 1 to ParamCount do + begin + if ParamStr(i) = '/SkipPostInstall' then + begin + SkipPostInstall := True; + end; + end; + ExpandedAppDir := ExpandConstant('{app}'); // Set the maximum value for the progress bar to 100 (representing 100%) @@ -52,11 +65,11 @@ begin CmdLine := Format('setx PATH "%s;%%PATH%%"', [ExpandedAppDir]); Exec('cmd.exe', '/C ' + CmdLine, '', SW_HIDE, ewWaitUntilTerminated, ResultCode); - // Check if the parameter /SkipPostInstall is passed - if ParamStr(1) = '/SkipPostInstall' then + // If the /SkipPostInstall flag is set, exit after setting the PATH + if SkipPostInstall then begin - Log('Skipping post-install actions.'); - Exit; // Exit the procedure without doing anything + Log('Skipping post-install actions after setting the PATH.'); + Exit; end; // Update status message for downloading llamacpp engine diff --git a/engine/templates/windows/installer-nightly.iss b/engine/templates/windows/installer-nightly.iss index 60ad2c71d..21a681234 100644 --- a/engine/templates/windows/installer-nightly.iss +++ b/engine/templates/windows/installer-nightly.iss @@ -38,7 +38,20 @@ var ExpandedAppDir: String; CmdLine, CortexInstallCmd: String; ResultCode: Integer; + i: Integer; + SkipPostInstall: Boolean; begin + SkipPostInstall := False; + + // Loop through all parameters to check for /SkipPostInstall + for i := 1 to ParamCount do + begin + if ParamStr(i) = '/SkipPostInstall' then + begin + SkipPostInstall := True; + end; + end; + ExpandedAppDir := ExpandConstant('{app}'); // Set the maximum value for the progress bar to 100 (representing 100%) @@ -52,11 +65,11 @@ begin CmdLine := Format('setx PATH "%s;%%PATH%%"', [ExpandedAppDir]); Exec('cmd.exe', '/C ' + CmdLine, '', SW_HIDE, ewWaitUntilTerminated, ResultCode); - // Check if the parameter /SkipPostInstall is passed - if ParamStr(1) = '/SkipPostInstall' then + // If the /SkipPostInstall flag is set, exit after setting the PATH + if SkipPostInstall then begin - Log('Skipping post-install actions.'); - Exit; // Exit the procedure without doing anything + Log('Skipping post-install actions after setting the PATH.'); + Exit; end; // Update status message for downloading llamacpp engine diff --git a/engine/templates/windows/installer.iss b/engine/templates/windows/installer.iss index 65dbf1f57..5bbd83ec7 100644 --- a/engine/templates/windows/installer.iss +++ b/engine/templates/windows/installer.iss @@ -38,7 +38,20 @@ var ExpandedAppDir: String; CmdLine, CortexInstallCmd: String; ResultCode: Integer; + i: Integer; + SkipPostInstall: Boolean; begin + SkipPostInstall := False; + + // Loop through all parameters to check for /SkipPostInstall + for i := 1 to ParamCount do + begin + if ParamStr(i) = '/SkipPostInstall' then + begin + SkipPostInstall := True; + end; + end; + ExpandedAppDir := ExpandConstant('{app}'); // Set the maximum value for the progress bar to 100 (representing 100%) @@ -52,11 +65,11 @@ begin CmdLine := Format('setx PATH "%s;%%PATH%%"', [ExpandedAppDir]); Exec('cmd.exe', '/C ' + CmdLine, '', SW_HIDE, ewWaitUntilTerminated, ResultCode); - // Check if the parameter /SkipPostInstall is passed - if ParamStr(1) = '/SkipPostInstall' then + // If the /SkipPostInstall flag is set, exit after setting the PATH + if SkipPostInstall then begin - Log('Skipping post-install actions.'); - Exit; // Exit the procedure without doing anything + Log('Skipping post-install actions after setting the PATH.'); + Exit; end; // Update status message for downloading llamacpp engine diff --git a/engine/templates/windows/local-installer-beta.iss b/engine/templates/windows/local-installer-beta.iss index 81b1c277b..345616588 100644 --- a/engine/templates/windows/local-installer-beta.iss +++ b/engine/templates/windows/local-installer-beta.iss @@ -40,7 +40,20 @@ var TempFolder: String; CmdLine, CortexInstallCmd: String; ResultCode: Integer; + i: Integer; + SkipPostInstall: Boolean; begin + SkipPostInstall := False; + + // Loop through all parameters to check for /SkipPostInstall + for i := 1 to ParamCount do + begin + if ParamStr(i) = '/SkipPostInstall' then + begin + SkipPostInstall := True; + end; + end; + ExpandedAppDir := ExpandConstant('{app}'); TempFolder := ExpandConstant('{tmp}\dependencies'); // Path to the extracted dependencies folder @@ -48,11 +61,11 @@ begin CmdLine := Format('setx PATH "%s;%%PATH%%"', [ExpandedAppDir]); Exec('cmd.exe', '/C ' + CmdLine, '', SW_HIDE, ewWaitUntilTerminated, ResultCode); - // Check if the parameter /SkipPostInstall is passed - if ParamStr(1) = '/SkipPostInstall' then + // If the /SkipPostInstall flag is set, exit after setting the PATH + if SkipPostInstall then begin - Log('Skipping post-install actions.'); - Exit; // Exit the procedure without doing anything + Log('Skipping post-install actions after setting the PATH.'); + Exit; end; // Update status message for installing engines diff --git a/engine/templates/windows/local-installer-nightly.iss b/engine/templates/windows/local-installer-nightly.iss index 04bf869b5..a0fc52712 100644 --- a/engine/templates/windows/local-installer-nightly.iss +++ b/engine/templates/windows/local-installer-nightly.iss @@ -40,7 +40,20 @@ var TempFolder: String; CmdLine, CortexInstallCmd: String; ResultCode: Integer; + i: Integer; + SkipPostInstall: Boolean; begin + SkipPostInstall := False; + + // Loop through all parameters to check for /SkipPostInstall + for i := 1 to ParamCount do + begin + if ParamStr(i) = '/SkipPostInstall' then + begin + SkipPostInstall := True; + end; + end; + ExpandedAppDir := ExpandConstant('{app}'); TempFolder := ExpandConstant('{tmp}\dependencies'); // Path to the extracted dependencies folder @@ -48,11 +61,11 @@ begin CmdLine := Format('setx PATH "%s;%%PATH%%"', [ExpandedAppDir]); Exec('cmd.exe', '/C ' + CmdLine, '', SW_HIDE, ewWaitUntilTerminated, ResultCode); - // Check if the parameter /SkipPostInstall is passed - if ParamStr(1) = '/SkipPostInstall' then + // If the /SkipPostInstall flag is set, exit after setting the PATH + if SkipPostInstall then begin - Log('Skipping post-install actions.'); - Exit; // Exit the procedure without doing anything + Log('Skipping post-install actions after setting the PATH.'); + Exit; end; // Update status message for installing engines diff --git a/engine/templates/windows/local-installer.iss b/engine/templates/windows/local-installer.iss index b42b1f393..2dd7626f7 100644 --- a/engine/templates/windows/local-installer.iss +++ b/engine/templates/windows/local-installer.iss @@ -40,7 +40,20 @@ var TempFolder: String; CmdLine, CortexInstallCmd: String; ResultCode: Integer; + i: Integer; + SkipPostInstall: Boolean; begin + SkipPostInstall := False; + + // Loop through all parameters to check for /SkipPostInstall + for i := 1 to ParamCount do + begin + if ParamStr(i) = '/SkipPostInstall' then + begin + SkipPostInstall := True; + end; + end; + ExpandedAppDir := ExpandConstant('{app}'); TempFolder := ExpandConstant('{tmp}\dependencies'); // Path to the extracted dependencies folder @@ -48,11 +61,11 @@ begin CmdLine := Format('setx PATH "%s;%%PATH%%"', [ExpandedAppDir]); Exec('cmd.exe', '/C ' + CmdLine, '', SW_HIDE, ewWaitUntilTerminated, ResultCode); - // Check if the parameter /SkipPostInstall is passed - if ParamStr(1) = '/SkipPostInstall' then + // If the /SkipPostInstall flag is set, exit after setting the PATH + if SkipPostInstall then begin - Log('Skipping post-install actions.'); - Exit; // Exit the procedure without doing anything + Log('Skipping post-install actions after setting the PATH.'); + Exit; end; // Update status message for installing engines From 00cb1090214215e7c33fcc71bea738ad1a0dc8a7 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 17 Oct 2024 11:02:35 +0700 Subject: [PATCH 31/40] fix: correct command --- engine/commands/cortex_upd_cmd.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/engine/commands/cortex_upd_cmd.cc b/engine/commands/cortex_upd_cmd.cc index 6debc91a1..c049e732b 100644 --- a/engine/commands/cortex_upd_cmd.cc +++ b/engine/commands/cortex_upd_cmd.cc @@ -55,15 +55,15 @@ std::string GetNightlyInstallerName(const std::string& v, // C:\Users\vansa\AppData\Local\Temp\cortex\cortex-windows-amd64-network-installer.exe std::string GetInstallCmd(const std::string& exe_path) { #if defined(__APPLE__) && defined(__MACH__) - return "SKIP_POSTINSTALL=true && sudo installer -pkg " + exe_path + - " -target /"; + return "touch /var/tmp/cortex_installer_skip_postinstall && sudo installer -pkg " + exe_path + + " -target / && rm /var/tmp/cortex_installer_skip_postinstall"; #elif defined(__linux__) return "echo -e \"n\\n\" | sudo SKIP_POSTINSTALL=true apt install -y " "--allow-downgrades " + exe_path; #else return "start /wait \"\" " + exe_path + - " /SkipPostInstall /VERYSILENT /SUPPRESSMSGBOXES /NORESTART"; + " /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SkipPostInstall"; #endif } From 5b79baa139101982d96ec2246f41208a7f16d9d3 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 17 Oct 2024 12:12:18 +0700 Subject: [PATCH 32/40] fix: update beta and stable --- engine/commands/cortex_upd_cmd.cc | 54 +++++++++++++++---------------- engine/commands/cortex_upd_cmd.h | 5 ++- 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/engine/commands/cortex_upd_cmd.cc b/engine/commands/cortex_upd_cmd.cc index c049e732b..a6447ac30 100644 --- a/engine/commands/cortex_upd_cmd.cc +++ b/engine/commands/cortex_upd_cmd.cc @@ -55,7 +55,9 @@ std::string GetNightlyInstallerName(const std::string& v, // C:\Users\vansa\AppData\Local\Temp\cortex\cortex-windows-amd64-network-installer.exe std::string GetInstallCmd(const std::string& exe_path) { #if defined(__APPLE__) && defined(__MACH__) - return "touch /var/tmp/cortex_installer_skip_postinstall && sudo installer -pkg " + exe_path + + return "touch /var/tmp/cortex_installer_skip_postinstall && sudo installer " + "-pkg " + + exe_path + " -target / && rm /var/tmp/cortex_installer_skip_postinstall"; #elif defined(__linux__) return "echo -e \"n\\n\" | sudo SKIP_POSTINSTALL=true apt install -y " @@ -304,6 +306,7 @@ void CortexUpdCmd::Exec(const std::string& v, bool force) { } bool CortexUpdCmd::GetStable(const std::string& v) { + std::optional downloaded_exe_path; auto system_info = GetSystemInfoWithUniversal(); CTL_INF("OS: " << system_info->os << ", Arch: " << system_info->arch); @@ -322,8 +325,10 @@ bool CortexUpdCmd::GetStable(const std::string& v) { return false; } - if (!HandleGithubRelease(json_data["assets"], - {system_info->os + "-" + system_info->arch})) { + if (downloaded_exe_path = HandleGithubRelease( + json_data["assets"], + {system_info->os + "-" + system_info->arch}); + !downloaded_exe_path) { return false; } } catch (const nlohmann::json::parse_error& e) { @@ -340,10 +345,7 @@ bool CortexUpdCmd::GetStable(const std::string& v) { return false; } - // Replace binary file auto executable_path = file_manager_utils::GetExecutableFolderContainerPath(); - auto src = - std::filesystem::temp_directory_path() / "cortex" / GetCortexBinary(); auto dst = executable_path / GetCortexBinary(); utils::ScopeExit se([]() { auto cortex_tmp = std::filesystem::temp_directory_path() / "cortex"; @@ -354,10 +356,13 @@ bool CortexUpdCmd::GetStable(const std::string& v) { CTL_WRN(e.what()); } }); - return ReplaceBinaryInflight(src, dst); + + assert(!!downloaded_exe_path); + return InstallNewVersion(dst, downloaded_exe_path.value()); } bool CortexUpdCmd::GetBeta(const std::string& v) { + std::optional downloaded_exe_path; auto system_info = GetSystemInfoWithUniversal(); CTL_INF("OS: " << system_info->os << ", Arch: " << system_info->arch); @@ -388,8 +393,10 @@ bool CortexUpdCmd::GetBeta(const std::string& v) { return false; } - if (!HandleGithubRelease(json_data["assets"], - {system_info->os + "-" + system_info->arch})) { + if (downloaded_exe_path = HandleGithubRelease( + json_data["assets"], + {system_info->os + "-" + system_info->arch}); + !downloaded_exe_path) { return false; } } catch (const nlohmann::json::parse_error& e) { @@ -406,10 +413,7 @@ bool CortexUpdCmd::GetBeta(const std::string& v) { return false; } - // Replace binary file auto executable_path = file_manager_utils::GetExecutableFolderContainerPath(); - auto src = - std::filesystem::temp_directory_path() / "cortex" / GetCortexBinary(); auto dst = executable_path / GetCortexBinary(); utils::ScopeExit se([]() { auto cortex_tmp = std::filesystem::temp_directory_path() / "cortex"; @@ -420,11 +424,14 @@ bool CortexUpdCmd::GetBeta(const std::string& v) { CTL_WRN(e.what()); } }); - return ReplaceBinaryInflight(src, dst); + + assert(!!downloaded_exe_path); + return InstallNewVersion(dst, downloaded_exe_path.value()); + ; } -bool CortexUpdCmd::HandleGithubRelease(const nlohmann::json& assets, - const std::string& os_arch) { +std::optional CortexUpdCmd::HandleGithubRelease( + const nlohmann::json& assets, const std::string& os_arch) { std::string matched_variant = ""; for (auto& asset : assets) { auto asset_name = asset["name"].get(); @@ -438,7 +445,7 @@ bool CortexUpdCmd::HandleGithubRelease(const nlohmann::json& assets, } if (matched_variant.empty()) { CTL_ERR("No variant found for " << os_arch); - return false; + return std::nullopt; } CTL_INF("Matched variant: " << matched_variant); @@ -457,7 +464,7 @@ bool CortexUpdCmd::HandleGithubRelease(const nlohmann::json& assets, } } catch (const std::filesystem::filesystem_error& e) { CTL_ERR("Failed to create directories: " << e.what()); - return false; + return std::nullopt; } auto download_task{DownloadTask{.id = "cortex", .type = DownloadType::Cortex, @@ -473,22 +480,16 @@ bool CortexUpdCmd::HandleGithubRelease(const nlohmann::json& assets, CTL_INF("Downloaded engine path: " << finishedTask.items[0].localPath.string()); - auto extract_path = - finishedTask.items[0].localPath.parent_path().parent_path(); - - archive_utils::ExtractArchive( - finishedTask.items[0].localPath.string(), - extract_path.string()); - CTL_INF("Finished!"); }); if (result.has_error()) { CTL_ERR("Failed to download: " << result.error()); + return std::nullopt; } - break; + return local_path; } } - return true; + return std::nullopt; } bool CortexUpdCmd::GetNightly(const std::string& v) { @@ -546,7 +547,6 @@ bool CortexUpdCmd::GetNightly(const std::string& v) { return false; } - // Replace binary file auto executable_path = file_manager_utils::GetExecutableFolderContainerPath(); auto dst = executable_path / GetCortexBinary(); utils::ScopeExit se([]() { diff --git a/engine/commands/cortex_upd_cmd.h b/engine/commands/cortex_upd_cmd.h index 1d74dc4df..938e598ad 100644 --- a/engine/commands/cortex_upd_cmd.h +++ b/engine/commands/cortex_upd_cmd.h @@ -12,11 +12,10 @@ namespace commands { #define CORTEX_VARIANT file_manager_utils::kProdVariant #endif constexpr const auto kNightlyHost = "delta.jan.ai"; -constexpr const auto kNightlyFileName = "cortex-nightly.tar.gz"; const std::string kCortexBinary = "cortex"; const std::string kCortexServerBinary = "cortex-server"; constexpr const auto kBetaComp = "-rc"; -constexpr const auto kReleaseFormat = ".tar.gz"; +constexpr const auto kReleaseFormat = "network-installer"; constexpr const auto kTimeoutCheckUpdate = std::chrono::milliseconds(1000); inline std::string GetRole() { @@ -105,7 +104,7 @@ class CortexUpdCmd { bool GetStable(const std::string& v); bool GetBeta(const std::string& v); - bool HandleGithubRelease(const nlohmann::json& assets, + std::optional HandleGithubRelease(const nlohmann::json& assets, const std::string& os_arch); bool GetNightly(const std::string& v); }; From 9704f651b42dd43c8659753df6d7cd4a3df79827 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 17 Oct 2024 12:58:38 +0700 Subject: [PATCH 33/40] fix: build --- engine/commands/cortex_upd_cmd.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/commands/cortex_upd_cmd.cc b/engine/commands/cortex_upd_cmd.cc index a6447ac30..1c8bc26b1 100644 --- a/engine/commands/cortex_upd_cmd.cc +++ b/engine/commands/cortex_upd_cmd.cc @@ -486,7 +486,7 @@ std::optional CortexUpdCmd::HandleGithubRelease( CTL_ERR("Failed to download: " << result.error()); return std::nullopt; } - return local_path; + return local_path.string(); } } return std::nullopt; From b2e6d848ff7f7a1a256001bcf9ceddf88e457bc4 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 17 Oct 2024 14:51:58 +0700 Subject: [PATCH 34/40] chore: move commands to cli --- engine/CMakeLists.txt | 7 +------ engine/cli/CMakeLists.txt | 9 +++------ engine/{controllers => cli}/command_line_parser.cc | 0 engine/{controllers => cli}/command_line_parser.h | 0 engine/{ => cli}/commands/chat_cmd.cc | 0 engine/{ => cli}/commands/chat_cmd.h | 0 engine/{ => cli}/commands/chat_completion_cmd.cc | 0 engine/{ => cli}/commands/chat_completion_cmd.h | 0 engine/{ => cli}/commands/cortex_upd_cmd.cc | 0 engine/{ => cli}/commands/cortex_upd_cmd.h | 0 engine/{ => cli}/commands/engine_get_cmd.cc | 0 engine/{ => cli}/commands/engine_get_cmd.h | 0 engine/{ => cli}/commands/engine_install_cmd.cc | 0 engine/{ => cli}/commands/engine_install_cmd.h | 0 engine/{ => cli}/commands/engine_list_cmd.cc | 0 engine/{ => cli}/commands/engine_list_cmd.h | 0 engine/{ => cli}/commands/engine_uninstall_cmd.cc | 0 engine/{ => cli}/commands/engine_uninstall_cmd.h | 0 engine/{ => cli}/commands/model_alias_cmd.cc | 0 engine/{ => cli}/commands/model_alias_cmd.h | 0 engine/{ => cli}/commands/model_del_cmd.cc | 0 engine/{ => cli}/commands/model_del_cmd.h | 0 engine/{ => cli}/commands/model_get_cmd.cc | 0 engine/{ => cli}/commands/model_get_cmd.h | 0 engine/{ => cli}/commands/model_import_cmd.cc | 0 engine/{ => cli}/commands/model_import_cmd.h | 0 engine/{ => cli}/commands/model_list_cmd.cc | 0 engine/{ => cli}/commands/model_list_cmd.h | 0 engine/{ => cli}/commands/model_pull_cmd.cc | 0 engine/{ => cli}/commands/model_pull_cmd.h | 0 engine/{ => cli}/commands/model_start_cmd.cc | 0 engine/{ => cli}/commands/model_start_cmd.h | 0 engine/{ => cli}/commands/model_status_cmd.cc | 0 engine/{ => cli}/commands/model_status_cmd.h | 0 engine/{ => cli}/commands/model_stop_cmd.cc | 0 engine/{ => cli}/commands/model_stop_cmd.h | 0 engine/{ => cli}/commands/model_upd_cmd.cc | 0 engine/{ => cli}/commands/model_upd_cmd.h | 0 engine/{ => cli}/commands/ps_cmd.cc | 0 engine/{ => cli}/commands/ps_cmd.h | 0 engine/{ => cli}/commands/run_cmd.cc | 0 engine/{ => cli}/commands/run_cmd.h | 0 engine/{ => cli}/commands/server_start_cmd.cc | 0 engine/{ => cli}/commands/server_start_cmd.h | 0 engine/{ => cli}/commands/server_stop_cmd.cc | 0 engine/{ => cli}/commands/server_stop_cmd.h | 0 engine/cli/main.cc | 2 +- engine/main.cc | 1 - engine/test/components/CMakeLists.txt | 4 ++-- engine/test/components/test_cortex_upd_cmd.cc | 2 +- 50 files changed, 8 insertions(+), 17 deletions(-) rename engine/{controllers => cli}/command_line_parser.cc (100%) rename engine/{controllers => cli}/command_line_parser.h (100%) rename engine/{ => cli}/commands/chat_cmd.cc (100%) rename engine/{ => cli}/commands/chat_cmd.h (100%) rename engine/{ => cli}/commands/chat_completion_cmd.cc (100%) rename engine/{ => cli}/commands/chat_completion_cmd.h (100%) rename engine/{ => cli}/commands/cortex_upd_cmd.cc (100%) rename engine/{ => cli}/commands/cortex_upd_cmd.h (100%) rename engine/{ => cli}/commands/engine_get_cmd.cc (100%) rename engine/{ => cli}/commands/engine_get_cmd.h (100%) rename engine/{ => cli}/commands/engine_install_cmd.cc (100%) rename engine/{ => cli}/commands/engine_install_cmd.h (100%) rename engine/{ => cli}/commands/engine_list_cmd.cc (100%) rename engine/{ => cli}/commands/engine_list_cmd.h (100%) rename engine/{ => cli}/commands/engine_uninstall_cmd.cc (100%) rename engine/{ => cli}/commands/engine_uninstall_cmd.h (100%) rename engine/{ => cli}/commands/model_alias_cmd.cc (100%) rename engine/{ => cli}/commands/model_alias_cmd.h (100%) rename engine/{ => cli}/commands/model_del_cmd.cc (100%) rename engine/{ => cli}/commands/model_del_cmd.h (100%) rename engine/{ => cli}/commands/model_get_cmd.cc (100%) rename engine/{ => cli}/commands/model_get_cmd.h (100%) rename engine/{ => cli}/commands/model_import_cmd.cc (100%) rename engine/{ => cli}/commands/model_import_cmd.h (100%) rename engine/{ => cli}/commands/model_list_cmd.cc (100%) rename engine/{ => cli}/commands/model_list_cmd.h (100%) rename engine/{ => cli}/commands/model_pull_cmd.cc (100%) rename engine/{ => cli}/commands/model_pull_cmd.h (100%) rename engine/{ => cli}/commands/model_start_cmd.cc (100%) rename engine/{ => cli}/commands/model_start_cmd.h (100%) rename engine/{ => cli}/commands/model_status_cmd.cc (100%) rename engine/{ => cli}/commands/model_status_cmd.h (100%) rename engine/{ => cli}/commands/model_stop_cmd.cc (100%) rename engine/{ => cli}/commands/model_stop_cmd.h (100%) rename engine/{ => cli}/commands/model_upd_cmd.cc (100%) rename engine/{ => cli}/commands/model_upd_cmd.h (100%) rename engine/{ => cli}/commands/ps_cmd.cc (100%) rename engine/{ => cli}/commands/ps_cmd.h (100%) rename engine/{ => cli}/commands/run_cmd.cc (100%) rename engine/{ => cli}/commands/run_cmd.h (100%) rename engine/{ => cli}/commands/server_start_cmd.cc (100%) rename engine/{ => cli}/commands/server_start_cmd.h (100%) rename engine/{ => cli}/commands/server_stop_cmd.cc (100%) rename engine/{ => cli}/commands/server_stop_cmd.h (100%) diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index 1d29319b6..12adf08b1 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -74,10 +74,8 @@ find_package(Drogon CONFIG REQUIRED) find_package(yaml-cpp CONFIG REQUIRED) find_package(httplib CONFIG REQUIRED) find_package(nlohmann_json CONFIG REQUIRED) -find_package(CLI11 CONFIG REQUIRED) find_package(unofficial-minizip CONFIG REQUIRED) find_package(LibArchive REQUIRED) -find_package(tabulate CONFIG REQUIRED) find_package(CURL REQUIRED) find_package(SQLiteCpp REQUIRED) find_package(eventpp CONFIG REQUIRED) @@ -89,10 +87,8 @@ add_executable(${TARGET_NAME} main.cc target_link_libraries(${TARGET_NAME} PRIVATE httplib::httplib) target_link_libraries(${TARGET_NAME} PRIVATE nlohmann_json::nlohmann_json) -target_link_libraries(${TARGET_NAME} PRIVATE CLI11::CLI11) target_link_libraries(${TARGET_NAME} PRIVATE unofficial::minizip::minizip) target_link_libraries(${TARGET_NAME} PRIVATE LibArchive::LibArchive) -target_link_libraries(${TARGET_NAME} PRIVATE tabulate::tabulate) target_link_libraries(${TARGET_NAME} PRIVATE CURL::libcurl) target_link_libraries(${TARGET_NAME} PRIVATE JsonCpp::JsonCpp Drogon::Drogon OpenSSL::SSL OpenSSL::Crypto yaml-cpp::yaml-cpp ${CMAKE_THREAD_LIBS_INIT}) @@ -118,12 +114,11 @@ aux_source_directory(common COMMON_SRC) aux_source_directory(models MODEL_SRC) aux_source_directory(cortex-common CORTEX_COMMON) aux_source_directory(config CONFIG_SRC) -aux_source_directory(commands COMMANDS_SRC) aux_source_directory(database DB_SRC) target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ) -target_sources(${TARGET_NAME} PRIVATE ${COMMANDS_SRC} ${CONFIG_SRC} ${CTL_SRC} ${COMMON_SRC} ${SERVICES_SRC} ${DB_SRC}) +target_sources(${TARGET_NAME} PRIVATE ${CONFIG_SRC} ${CTL_SRC} ${COMMON_SRC} ${SERVICES_SRC} ${DB_SRC}) set_target_properties(${TARGET_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR} diff --git a/engine/cli/CMakeLists.txt b/engine/cli/CMakeLists.txt index cab65af18..f13bb51bc 100644 --- a/engine/cli/CMakeLists.txt +++ b/engine/cli/CMakeLists.txt @@ -70,13 +70,12 @@ find_package(LibArchive REQUIRED) find_package(tabulate CONFIG REQUIRED) find_package(CURL REQUIRED) find_package(SQLiteCpp REQUIRED) -find_package(eventpp CONFIG REQUIRED) find_package(Trantor CONFIG REQUIRED) add_executable(${TARGET_NAME} main.cc ${CMAKE_CURRENT_SOURCE_DIR}/../utils/cpuid/cpu_info.cc ${CMAKE_CURRENT_SOURCE_DIR}/../utils/file_logger.cc - ${CMAKE_CURRENT_SOURCE_DIR}/../controllers/command_line_parser.cc + ${CMAKE_CURRENT_SOURCE_DIR}/command_line_parser.cc ${CMAKE_CURRENT_SOURCE_DIR}/../services/download_service.cc ${CMAKE_CURRENT_SOURCE_DIR}/../services/engine_service.cc ${CMAKE_CURRENT_SOURCE_DIR}/../services/model_service.cc @@ -92,7 +91,6 @@ target_link_libraries(${TARGET_NAME} PRIVATE CURL::libcurl) target_link_libraries(${TARGET_NAME} PRIVATE JsonCpp::JsonCpp OpenSSL::SSL OpenSSL::Crypto yaml-cpp::yaml-cpp ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries(${TARGET_NAME} PRIVATE SQLiteCpp) -target_link_libraries(${TARGET_NAME} PRIVATE eventpp::eventpp) target_link_libraries(${TARGET_NAME} PRIVATE Trantor::Trantor) # ############################################################################## @@ -108,16 +106,15 @@ else() message(STATUS "use c++20") endif() -# aux_source_directory(../controllers CTL_SRC) -# aux_source_directory(../services SERVICES_SRC) aux_source_directory(../common COMMON_SRC) aux_source_directory(../models MODEL_SRC) aux_source_directory(../cortex-common CORTEX_COMMON) aux_source_directory(../config CONFIG_SRC) -aux_source_directory(../commands COMMANDS_SRC) +aux_source_directory(commands COMMANDS_SRC) aux_source_directory(../database DB_SRC) target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/.. ) +target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_sources(${TARGET_NAME} PRIVATE ${COMMANDS_SRC} ${CONFIG_SRC} ${COMMON_SRC} ${DB_SRC}) diff --git a/engine/controllers/command_line_parser.cc b/engine/cli/command_line_parser.cc similarity index 100% rename from engine/controllers/command_line_parser.cc rename to engine/cli/command_line_parser.cc diff --git a/engine/controllers/command_line_parser.h b/engine/cli/command_line_parser.h similarity index 100% rename from engine/controllers/command_line_parser.h rename to engine/cli/command_line_parser.h diff --git a/engine/commands/chat_cmd.cc b/engine/cli/commands/chat_cmd.cc similarity index 100% rename from engine/commands/chat_cmd.cc rename to engine/cli/commands/chat_cmd.cc diff --git a/engine/commands/chat_cmd.h b/engine/cli/commands/chat_cmd.h similarity index 100% rename from engine/commands/chat_cmd.h rename to engine/cli/commands/chat_cmd.h diff --git a/engine/commands/chat_completion_cmd.cc b/engine/cli/commands/chat_completion_cmd.cc similarity index 100% rename from engine/commands/chat_completion_cmd.cc rename to engine/cli/commands/chat_completion_cmd.cc diff --git a/engine/commands/chat_completion_cmd.h b/engine/cli/commands/chat_completion_cmd.h similarity index 100% rename from engine/commands/chat_completion_cmd.h rename to engine/cli/commands/chat_completion_cmd.h diff --git a/engine/commands/cortex_upd_cmd.cc b/engine/cli/commands/cortex_upd_cmd.cc similarity index 100% rename from engine/commands/cortex_upd_cmd.cc rename to engine/cli/commands/cortex_upd_cmd.cc diff --git a/engine/commands/cortex_upd_cmd.h b/engine/cli/commands/cortex_upd_cmd.h similarity index 100% rename from engine/commands/cortex_upd_cmd.h rename to engine/cli/commands/cortex_upd_cmd.h diff --git a/engine/commands/engine_get_cmd.cc b/engine/cli/commands/engine_get_cmd.cc similarity index 100% rename from engine/commands/engine_get_cmd.cc rename to engine/cli/commands/engine_get_cmd.cc diff --git a/engine/commands/engine_get_cmd.h b/engine/cli/commands/engine_get_cmd.h similarity index 100% rename from engine/commands/engine_get_cmd.h rename to engine/cli/commands/engine_get_cmd.h diff --git a/engine/commands/engine_install_cmd.cc b/engine/cli/commands/engine_install_cmd.cc similarity index 100% rename from engine/commands/engine_install_cmd.cc rename to engine/cli/commands/engine_install_cmd.cc diff --git a/engine/commands/engine_install_cmd.h b/engine/cli/commands/engine_install_cmd.h similarity index 100% rename from engine/commands/engine_install_cmd.h rename to engine/cli/commands/engine_install_cmd.h diff --git a/engine/commands/engine_list_cmd.cc b/engine/cli/commands/engine_list_cmd.cc similarity index 100% rename from engine/commands/engine_list_cmd.cc rename to engine/cli/commands/engine_list_cmd.cc diff --git a/engine/commands/engine_list_cmd.h b/engine/cli/commands/engine_list_cmd.h similarity index 100% rename from engine/commands/engine_list_cmd.h rename to engine/cli/commands/engine_list_cmd.h diff --git a/engine/commands/engine_uninstall_cmd.cc b/engine/cli/commands/engine_uninstall_cmd.cc similarity index 100% rename from engine/commands/engine_uninstall_cmd.cc rename to engine/cli/commands/engine_uninstall_cmd.cc diff --git a/engine/commands/engine_uninstall_cmd.h b/engine/cli/commands/engine_uninstall_cmd.h similarity index 100% rename from engine/commands/engine_uninstall_cmd.h rename to engine/cli/commands/engine_uninstall_cmd.h diff --git a/engine/commands/model_alias_cmd.cc b/engine/cli/commands/model_alias_cmd.cc similarity index 100% rename from engine/commands/model_alias_cmd.cc rename to engine/cli/commands/model_alias_cmd.cc diff --git a/engine/commands/model_alias_cmd.h b/engine/cli/commands/model_alias_cmd.h similarity index 100% rename from engine/commands/model_alias_cmd.h rename to engine/cli/commands/model_alias_cmd.h diff --git a/engine/commands/model_del_cmd.cc b/engine/cli/commands/model_del_cmd.cc similarity index 100% rename from engine/commands/model_del_cmd.cc rename to engine/cli/commands/model_del_cmd.cc diff --git a/engine/commands/model_del_cmd.h b/engine/cli/commands/model_del_cmd.h similarity index 100% rename from engine/commands/model_del_cmd.h rename to engine/cli/commands/model_del_cmd.h diff --git a/engine/commands/model_get_cmd.cc b/engine/cli/commands/model_get_cmd.cc similarity index 100% rename from engine/commands/model_get_cmd.cc rename to engine/cli/commands/model_get_cmd.cc diff --git a/engine/commands/model_get_cmd.h b/engine/cli/commands/model_get_cmd.h similarity index 100% rename from engine/commands/model_get_cmd.h rename to engine/cli/commands/model_get_cmd.h diff --git a/engine/commands/model_import_cmd.cc b/engine/cli/commands/model_import_cmd.cc similarity index 100% rename from engine/commands/model_import_cmd.cc rename to engine/cli/commands/model_import_cmd.cc diff --git a/engine/commands/model_import_cmd.h b/engine/cli/commands/model_import_cmd.h similarity index 100% rename from engine/commands/model_import_cmd.h rename to engine/cli/commands/model_import_cmd.h diff --git a/engine/commands/model_list_cmd.cc b/engine/cli/commands/model_list_cmd.cc similarity index 100% rename from engine/commands/model_list_cmd.cc rename to engine/cli/commands/model_list_cmd.cc diff --git a/engine/commands/model_list_cmd.h b/engine/cli/commands/model_list_cmd.h similarity index 100% rename from engine/commands/model_list_cmd.h rename to engine/cli/commands/model_list_cmd.h diff --git a/engine/commands/model_pull_cmd.cc b/engine/cli/commands/model_pull_cmd.cc similarity index 100% rename from engine/commands/model_pull_cmd.cc rename to engine/cli/commands/model_pull_cmd.cc diff --git a/engine/commands/model_pull_cmd.h b/engine/cli/commands/model_pull_cmd.h similarity index 100% rename from engine/commands/model_pull_cmd.h rename to engine/cli/commands/model_pull_cmd.h diff --git a/engine/commands/model_start_cmd.cc b/engine/cli/commands/model_start_cmd.cc similarity index 100% rename from engine/commands/model_start_cmd.cc rename to engine/cli/commands/model_start_cmd.cc diff --git a/engine/commands/model_start_cmd.h b/engine/cli/commands/model_start_cmd.h similarity index 100% rename from engine/commands/model_start_cmd.h rename to engine/cli/commands/model_start_cmd.h diff --git a/engine/commands/model_status_cmd.cc b/engine/cli/commands/model_status_cmd.cc similarity index 100% rename from engine/commands/model_status_cmd.cc rename to engine/cli/commands/model_status_cmd.cc diff --git a/engine/commands/model_status_cmd.h b/engine/cli/commands/model_status_cmd.h similarity index 100% rename from engine/commands/model_status_cmd.h rename to engine/cli/commands/model_status_cmd.h diff --git a/engine/commands/model_stop_cmd.cc b/engine/cli/commands/model_stop_cmd.cc similarity index 100% rename from engine/commands/model_stop_cmd.cc rename to engine/cli/commands/model_stop_cmd.cc diff --git a/engine/commands/model_stop_cmd.h b/engine/cli/commands/model_stop_cmd.h similarity index 100% rename from engine/commands/model_stop_cmd.h rename to engine/cli/commands/model_stop_cmd.h diff --git a/engine/commands/model_upd_cmd.cc b/engine/cli/commands/model_upd_cmd.cc similarity index 100% rename from engine/commands/model_upd_cmd.cc rename to engine/cli/commands/model_upd_cmd.cc diff --git a/engine/commands/model_upd_cmd.h b/engine/cli/commands/model_upd_cmd.h similarity index 100% rename from engine/commands/model_upd_cmd.h rename to engine/cli/commands/model_upd_cmd.h diff --git a/engine/commands/ps_cmd.cc b/engine/cli/commands/ps_cmd.cc similarity index 100% rename from engine/commands/ps_cmd.cc rename to engine/cli/commands/ps_cmd.cc diff --git a/engine/commands/ps_cmd.h b/engine/cli/commands/ps_cmd.h similarity index 100% rename from engine/commands/ps_cmd.h rename to engine/cli/commands/ps_cmd.h diff --git a/engine/commands/run_cmd.cc b/engine/cli/commands/run_cmd.cc similarity index 100% rename from engine/commands/run_cmd.cc rename to engine/cli/commands/run_cmd.cc diff --git a/engine/commands/run_cmd.h b/engine/cli/commands/run_cmd.h similarity index 100% rename from engine/commands/run_cmd.h rename to engine/cli/commands/run_cmd.h diff --git a/engine/commands/server_start_cmd.cc b/engine/cli/commands/server_start_cmd.cc similarity index 100% rename from engine/commands/server_start_cmd.cc rename to engine/cli/commands/server_start_cmd.cc diff --git a/engine/commands/server_start_cmd.h b/engine/cli/commands/server_start_cmd.h similarity index 100% rename from engine/commands/server_start_cmd.h rename to engine/cli/commands/server_start_cmd.h diff --git a/engine/commands/server_stop_cmd.cc b/engine/cli/commands/server_stop_cmd.cc similarity index 100% rename from engine/commands/server_stop_cmd.cc rename to engine/cli/commands/server_stop_cmd.cc diff --git a/engine/commands/server_stop_cmd.h b/engine/cli/commands/server_stop_cmd.h similarity index 100% rename from engine/commands/server_stop_cmd.h rename to engine/cli/commands/server_stop_cmd.h diff --git a/engine/cli/main.cc b/engine/cli/main.cc index 7b64d251f..35aa3ba49 100644 --- a/engine/cli/main.cc +++ b/engine/cli/main.cc @@ -1,6 +1,6 @@ #include #include "commands/cortex_upd_cmd.h" -#include "controllers/command_line_parser.h" +#include "command_line_parser.h" #include "cortex-common/cortexpythoni.h" #include "services/download_service.h" #include "services/model_service.h" diff --git a/engine/main.cc b/engine/main.cc index 24053767b..f75de968b 100644 --- a/engine/main.cc +++ b/engine/main.cc @@ -1,7 +1,6 @@ #include #include #include -#include "controllers/command_line_parser.h" #include "controllers/engines.h" #include "controllers/events.h" #include "controllers/models.h" diff --git a/engine/test/components/CMakeLists.txt b/engine/test/components/CMakeLists.txt index d8865aeb0..1c1e84de7 100644 --- a/engine/test/components/CMakeLists.txt +++ b/engine/test/components/CMakeLists.txt @@ -7,8 +7,8 @@ add_executable(${PROJECT_NAME} ${SRCS} ${CMAKE_CURRENT_SOURCE_DIR}/../../config/yaml_config.cc ${CMAKE_CURRENT_SOURCE_DIR}/../../config/gguf_parser.cc - ${CMAKE_CURRENT_SOURCE_DIR}/../../commands/cortex_upd_cmd.cc - ${CMAKE_CURRENT_SOURCE_DIR}/../../commands/server_stop_cmd.cc + ${CMAKE_CURRENT_SOURCE_DIR}/../../cli/commands/cortex_upd_cmd.cc + ${CMAKE_CURRENT_SOURCE_DIR}/../../cli/commands/server_stop_cmd.cc ${CMAKE_CURRENT_SOURCE_DIR}/../../services/download_service.cc ${CMAKE_CURRENT_SOURCE_DIR}/../../database/models.cc ) diff --git a/engine/test/components/test_cortex_upd_cmd.cc b/engine/test/components/test_cortex_upd_cmd.cc index ff70c814d..a8815f4f4 100644 --- a/engine/test/components/test_cortex_upd_cmd.cc +++ b/engine/test/components/test_cortex_upd_cmd.cc @@ -1,4 +1,4 @@ -#include "commands/cortex_upd_cmd.h" +#include "cli/commands/cortex_upd_cmd.h" #include "gtest/gtest.h" namespace { From 6645e610f4eb290e05980d9a0d9c1f01b45ee576 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 17 Oct 2024 15:03:44 +0700 Subject: [PATCH 35/40] fix: models start timeout --- engine/cli/commands/model_start_cmd.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/engine/cli/commands/model_start_cmd.cc b/engine/cli/commands/model_start_cmd.cc index 5756a012d..5daf02f2a 100644 --- a/engine/cli/commands/model_start_cmd.cc +++ b/engine/cli/commands/model_start_cmd.cc @@ -19,6 +19,7 @@ bool ModelStartCmd::Exec(const std::string& host, int port, Json::Value json_data; json_data["model"] = model_handle; auto data_str = json_data.toStyledString(); + cli.set_read_timeout(std::chrono::seconds(60)); auto res = cli.Post("/v1/models/start", httplib::Headers(), data_str.data(), data_str.size(), "application/json"); if (res) { From 1e8a9ee881fd11f5cbd62897b9bc7b6c2dd606e3 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 17 Oct 2024 15:56:53 +0700 Subject: [PATCH 36/40] chore: refactor main cli --- engine/cli/main.cc | 117 +++++++++++++++++++++------------------------ 1 file changed, 55 insertions(+), 62 deletions(-) diff --git a/engine/cli/main.cc b/engine/cli/main.cc index 35aa3ba49..c9d906a28 100644 --- a/engine/cli/main.cc +++ b/engine/cli/main.cc @@ -1,6 +1,6 @@ #include -#include "commands/cortex_upd_cmd.h" #include "command_line_parser.h" +#include "commands/cortex_upd_cmd.h" #include "cortex-common/cortexpythoni.h" #include "services/download_service.h" #include "services/model_service.h" @@ -29,6 +29,47 @@ #error "Unsupported platform!" #endif +void RemoveBinaryTempFileIfExists() { + auto temp = + file_manager_utils::GetExecutableFolderContainerPath() / "cortex_temp"; + if (std::filesystem::exists(temp)) { + try { + std::filesystem::remove(temp); + } catch (const std::exception& e) { + std::cerr << e.what() << '\n'; + } + } +} + +void SetupLogger(trantor::FileLogger& async_logger, bool verbose) { + if (!verbose) { + auto config = file_manager_utils::GetCortexConfig(); + std::filesystem::create_directories( + std::filesystem::path(config.logFolderPath) / + std::filesystem::path(cortex_utils::logs_folder)); + async_logger.setFileName(config.logFolderPath + "/" + + cortex_utils::logs_cli_base_name); + async_logger.setMaxLines(config.maxLogLines); // Keep last 100000 lines + async_logger.startLogging(); + trantor::Logger::setOutputFunction( + [&](const char* msg, const uint64_t len) { + async_logger.output_(msg, len); + }, + [&]() { async_logger.flush(); }); + } +} + +void InstallServer() { +#if !defined(_WIN32) + if (getuid()) { + CLI_LOG("Error: Not root user. Please run with sudo."); + return 0; + } +#endif + auto cuc = commands::CortexUpdCmd(std::make_shared()); + cuc.Exec({}, true /*force*/); +} + int main(int argc, char* argv[]) { // Stop the program if the system is not supported auto system_info = system_info_utils::GetSystemInfo(); @@ -39,6 +80,8 @@ int main(int argc, char* argv[]) { return 1; } + bool should_install_server = false; + bool verbose = false; for (int i = 0; i < argc; i++) { if (strcmp(argv[i], "--config_file_path") == 0) { file_manager_utils::cortex_config_file_path = argv[i + 1]; @@ -47,29 +90,22 @@ int main(int argc, char* argv[]) { file_manager_utils::cortex_data_folder_path = argv[i + 1]; } else if ((strcmp(argv[i], "--server") == 0) && (strcmp(argv[i - 1], "update") == 0)) { -#if !defined(_WIN32) - if (getuid()) { - CLI_LOG("Error: Not root user. Please run with sudo."); - return 0; - } -#endif - auto cuc = commands::CortexUpdCmd(std::make_shared()); - cuc.Exec({}, true /*force*/); - return 0; + should_install_server = true; + } else if (strcmp(argv[i], "--verbose") == 0) { + verbose = true; } } { file_manager_utils::CreateConfigFileIfNotExist(); } - // Delete temporary file if it exists - auto temp = - file_manager_utils::GetExecutableFolderContainerPath() / "cortex_temp"; - if (std::filesystem::exists(temp)) { - try { - std::filesystem::remove(temp); - } catch (const std::exception& e) { - std::cerr << e.what() << '\n'; - } + RemoveBinaryTempFileIfExists(); + + trantor::FileLogger async_file_logger; + SetupLogger(async_file_logger, verbose); + + if (should_install_server) { + InstallServer(); + return 0; } // Check if server exists, if not notify to user to install server @@ -85,49 +121,6 @@ int main(int argc, char* argv[]) { return 0; } - // Check if this process is for python execution - if (argc > 1) { - if (strcmp(argv[1], "--run_python_file") == 0) { - std::string py_home_path = (argc > 3) ? argv[3] : ""; - std::unique_ptr dl; - try { - std::string abs_path = - cortex_utils::GetCurrentPath() + kPythonRuntimeLibPath; - dl = std::make_unique(abs_path, "engine"); - } catch (const cortex_cpp::dylib::load_error& e) { - LOG_ERROR << "Could not load engine: " << e.what(); - return 1; - } - - auto func = dl->get_function("get_engine"); - auto e = func(); - e->ExecutePythonFile(argv[0], argv[2], py_home_path); - return 0; - } - } - - bool verbose = false; - for (int i = 0; i < argc; i++) { - if (strcmp(argv[i], "--verbose") == 0) { - verbose = true; - } - } - trantor::FileLogger asyncFileLogger; - if (!verbose) { - auto config = file_manager_utils::GetCortexConfig(); - std::filesystem::create_directories( - std::filesystem::path(config.logFolderPath) / - std::filesystem::path(cortex_utils::logs_folder)); - asyncFileLogger.setFileName(config.logFolderPath + "/" + - cortex_utils::logs_cli_base_name); - asyncFileLogger.setMaxLines(config.maxLogLines); // Keep last 100000 lines - asyncFileLogger.startLogging(); - trantor::Logger::setOutputFunction( - [&](const char* msg, const uint64_t len) { - asyncFileLogger.output_(msg, len); - }, - [&]() { asyncFileLogger.flush(); }); - } CommandLineParser clp; clp.SetupCommand(argc, argv); return 0; From 8885ceca4d49e0012a197c273c4f00b640e307de Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 17 Oct 2024 16:02:24 +0700 Subject: [PATCH 37/40] fix: log --- engine/cli/commands/cortex_upd_cmd.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/engine/cli/commands/cortex_upd_cmd.cc b/engine/cli/commands/cortex_upd_cmd.cc index d935a1683..b926148f3 100644 --- a/engine/cli/commands/cortex_upd_cmd.cc +++ b/engine/cli/commands/cortex_upd_cmd.cc @@ -88,7 +88,7 @@ bool InstallNewVersion(const std::filesystem::path& dst, CommandExecutor c(GetInstallCmd(exe_path)); auto output = c.execute(); if (!std::filesystem::exists(dst)) { - CTL_ERR("Something went wrong!"); + CLI_LOG_ERROR("Something went wrong: could not execute command"); restore_binary(); return false; } @@ -96,14 +96,14 @@ bool InstallNewVersion(const std::filesystem::path& dst, // delete temp #if !defined(_WIN32) if (unlink(temp.string().c_str()) != 0) { - CTL_ERR("Error deleting self: " << strerror(errno)); + CLI_LOG_ERROR("Error deleting self: " << strerror(errno)); restore_binary(); return false; } #endif } catch (const std::exception& e) { - CTL_ERR("Something went wrong: " << e.what()); + CLI_LOG_ERROR("Something went wrong: " << e.what()); restore_binary(); return false; } @@ -446,7 +446,7 @@ std::optional CortexUpdCmd::HandleGithubRelease( CTL_INF(asset_name); } if (matched_variant.empty()) { - CTL_ERR("No variant found for " << os_arch); + CLI_LOG_ERROR("No variant found for " << os_arch); return std::nullopt; } CTL_INF("Matched variant: " << matched_variant); @@ -465,7 +465,7 @@ std::optional CortexUpdCmd::HandleGithubRelease( std::filesystem::create_directories(local_path.parent_path()); } } catch (const std::filesystem::filesystem_error& e) { - CTL_ERR("Failed to create directories: " << e.what()); + CLI_LOG_ERROR("Failed to create directories: " << e.what()); return std::nullopt; } auto download_task{DownloadTask{.id = "cortex", @@ -485,7 +485,7 @@ std::optional CortexUpdCmd::HandleGithubRelease( CTL_INF("Finished!"); }); if (result.has_error()) { - CTL_ERR("Failed to download: " << result.error()); + CLI_LOG_ERROR("Failed to download: " << result.error()); return std::nullopt; } return local_path.string(); From 78d7627d57bfdcadc1cc8c75c8a43cfbaa36f1d2 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 17 Oct 2024 16:10:28 +0700 Subject: [PATCH 38/40] fix: log --- engine/cli/main.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/cli/main.cc b/engine/cli/main.cc index c9d906a28..52c1ce457 100644 --- a/engine/cli/main.cc +++ b/engine/cli/main.cc @@ -63,7 +63,7 @@ void InstallServer() { #if !defined(_WIN32) if (getuid()) { CLI_LOG("Error: Not root user. Please run with sudo."); - return 0; + return; } #endif auto cuc = commands::CortexUpdCmd(std::make_shared()); From d18926c091f65e01409d66df0de2fcff8becc8d8 Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 17 Oct 2024 20:48:16 +0700 Subject: [PATCH 39/40] fix: support --port for server --- engine/main.cc | 13 +++++++++---- engine/utils/file_manager_utils.h | 3 +-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/engine/main.cc b/engine/main.cc index a66803a0c..7b36ea5d4 100644 --- a/engine/main.cc +++ b/engine/main.cc @@ -32,7 +32,7 @@ #error "Unsupported platform!" #endif -void RunServer() { +void RunServer(std::optional port) { #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) signal(SIGINT, SIG_IGN); #elif defined(_WIN32) @@ -43,6 +43,11 @@ void RunServer() { reinterpret_cast(console_ctrl_handler), true); #endif auto config = file_manager_utils::GetCortexConfig(); + if (port.has_value() && *port != std::stoi(config.apiServerPort)) { + auto config_path = file_manager_utils::GetConfigurationPath(); + config.apiServerPort = std::to_string(*port); + config_yaml_utils::DumpYamlConfig(config, config_path.string()); + } std::cout << "Host: " << config.apiServerHost << " Port: " << config.apiServerPort << "\n"; @@ -117,16 +122,17 @@ int main(int argc, char* argv[]) { if (system_info->arch == system_info_utils::kUnsupported || system_info->os == system_info_utils::kUnsupported) { CLI_LOG_ERROR("Unsupported OS or architecture: " << system_info->os << ", " - << system_info->arch); + << system_info->arch); return 1; } for (int i = 0; i < argc; i++) { if (strcmp(argv[i], "--config_file_path") == 0) { file_manager_utils::cortex_config_file_path = argv[i + 1]; - } else if (strcmp(argv[i], "--data_folder_path") == 0) { file_manager_utils::cortex_data_folder_path = argv[i + 1]; + } else if (strcmp(argv[i], "--port") == 0) { + server_port = std::stoi(argv[i + 1]); } } @@ -164,7 +170,6 @@ int main(int argc, char* argv[]) { } } - RunServer(); return 0; } diff --git a/engine/utils/file_manager_utils.h b/engine/utils/file_manager_utils.h index 47aca20b1..04cb2e8f9 100644 --- a/engine/utils/file_manager_utils.h +++ b/engine/utils/file_manager_utils.h @@ -151,8 +151,7 @@ inline void CreateConfigFileIfNotExist() { cortex_data_folder_path.empty() ? file_manager_utils::GetHomeDirectoryPath() / default_data_folder_name - : std::filesystem::path(cortex_data_folder_path) / - default_data_folder_name; + : std::filesystem::path(cortex_data_folder_path); CLI_LOG("Default data folder path: " + defaultDataFolderPath.string()); auto config = config_yaml_utils::CortexConfig{ From 523bd4b96418dd42a17054d3f492ca994f319d8b Mon Sep 17 00:00:00 2001 From: vansangpfiev Date: Thu, 17 Oct 2024 20:57:18 +0700 Subject: [PATCH 40/40] fix: build --- engine/main.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/engine/main.cc b/engine/main.cc index 7b36ea5d4..f66deee0c 100644 --- a/engine/main.cc +++ b/engine/main.cc @@ -126,6 +126,7 @@ int main(int argc, char* argv[]) { return 1; } + std::optional server_port; for (int i = 0; i < argc; i++) { if (strcmp(argv[i], "--config_file_path") == 0) { file_manager_utils::cortex_config_file_path = argv[i + 1]; @@ -170,6 +171,6 @@ int main(int argc, char* argv[]) { } } - RunServer(); + RunServer(server_port); return 0; }