44#include " cortex_upd_cmd.h"
55#include " httplib.h"
66#include " nlohmann/json.hpp"
7+ #include " server_stop_cmd.h"
78#include " services/download_service.h"
89#include " utils/archive_utils.h"
910#include " utils/file_manager_utils.h"
1213
1314namespace commands {
1415
15- namespace {
16- const std::string kCortexBinary = " cortex-cpp" ;
17- }
18-
1916CortexUpdCmd::CortexUpdCmd () {}
2017
2118void CortexUpdCmd::Exec (std::string v) {
22- // TODO(sang) stop server if it is running
19+ {
20+ auto config = file_manager_utils::GetCortexConfig ();
21+ httplib::Client cli (config.apiServerHost + " :" + config.apiServerPort );
22+ auto res = cli.Get (" /health/healthz" );
23+ if (res) {
24+ CLI_LOG (" Server is running. Stopping server before updating!" );
25+ commands::ServerStopCmd ssc (config.apiServerHost ,
26+ std::stoi (config.apiServerPort ));
27+ ssc.Exec ();
28+ }
29+ }
30+ if (CORTEX_VARIANT == file_manager_utils::kNightlyVariant ) {
31+ if (!GetNightly (v))
32+ return ;
33+ } else {
34+ if (!GetStableAndBeta (v))
35+ return ;
36+ }
37+ CLI_LOG (" Update cortex sucessfully" );
38+ }
39+
40+ bool CortexUpdCmd::GetStableAndBeta (const std::string& v) {
2341 // Check if the architecture and OS are supported
2442 auto system_info = system_info_utils::GetSystemInfo ();
2543 if (system_info.arch == system_info_utils::kUnsupported ||
2644 system_info.os == system_info_utils::kUnsupported ) {
2745 CTL_ERR (" Unsupported OS or architecture: " << system_info.os << " , "
2846 << system_info.arch );
29- return ;
47+ return false ;
3048 }
3149 CTL_INF (" OS: " << system_info.os << " , Arch: " << system_info.arch );
3250
@@ -50,7 +68,7 @@ void CortexUpdCmd::Exec(std::string v) {
5068 std::string matched_variant = " " ;
5169 for (auto & asset : assets) {
5270 auto asset_name = asset[" name" ].get <std::string>();
53- if (asset_name.find (" cortex-cpp " ) != std::string::npos &&
71+ if (asset_name.find (kCortexBinary ) != std::string::npos &&
5472 asset_name.find (os_arch) != std::string::npos) {
5573 matched_variant = asset_name;
5674 break ;
@@ -59,7 +77,7 @@ void CortexUpdCmd::Exec(std::string v) {
5977 }
6078 if (matched_variant.empty ()) {
6179 CTL_ERR (" No variant found for " << os_arch);
62- return ;
80+ return false ;
6381 }
6482 CTL_INF (" Matched variant: " << matched_variant);
6583
@@ -99,73 +117,82 @@ void CortexUpdCmd::Exec(std::string v) {
99117 archive_utils::ExtractArchive (download_path.string (),
100118 extract_path.string ());
101119
102- // remove the downloaded file
103- // TODO(any) Could not delete file on Windows because it is currently hold by httplib(?)
104- // Not sure about other platforms
105- try {
106- std::filesystem::remove (absolute_path);
107- } catch (const std::exception& e) {
108- CTL_WRN (" Could not delete file: " << e.what ());
109- }
110120 CTL_INF (" Finished!" );
111121 });
112122 break ;
113123 }
114124 }
115125 } catch (const nlohmann::json::parse_error& e) {
116126 std::cerr << " JSON parse error: " << e.what () << std::endl;
117- return ;
127+ return false ;
118128 }
119129 } else {
120130 CTL_ERR (" HTTP error: " << res->status );
121- return ;
131+ return false ;
122132 }
123133 } else {
124134 auto err = res.error ();
125135 CTL_ERR (" HTTP error: " << httplib::to_string (err));
126- return ;
136+ return false ;
127137 }
128- #if defined(_WIN32)
129- auto executable_path = file_manager_utils::GetExecutableFolderContainerPath ();
130- auto temp = executable_path / " cortex_tmp.exe" ;
131- remove (temp.string ().c_str ()); // ignore return code
132-
133- auto src =
134- executable_path / " cortex" / kCortexBinary / (kCortexBinary + " .exe" );
135- auto dst = executable_path / (kCortexBinary + " .exe" );
136- // Rename
137- rename (dst.string ().c_str (), temp.string ().c_str ());
138- // Update
139- CopyFile (const_cast <char *>(src.string ().c_str ()),
140- const_cast <char *>(dst.string ().c_str ()), false );
141- auto download_folder = executable_path / " cortex" ;
142- remove (download_folder);
143- remove (temp.string ().c_str ());
144- #else
138+
139+ // Replace binary file
145140 auto executable_path = file_manager_utils::GetExecutableFolderContainerPath ();
146- auto temp = executable_path / " cortex_tmp" ;
147- auto src = executable_path / " cortex" / kCortexBinary / kCortexBinary ;
148- auto dst = executable_path / kCortexBinary ;
149- if (std::rename (dst.string ().c_str (), temp.string ().c_str ())) {
150- CTL_ERR (" Failed to rename from " << dst.string () << " to "
151- << temp.string ());
152- return ;
153- }
154- try {
155- std::filesystem::copy_file (
156- src, dst, std::filesystem::copy_options::overwrite_existing);
157- std::filesystem::permissions (dst, std::filesystem::perms::owner_all |
158- std::filesystem::perms::group_all |
159- std::filesystem::perms::others_read |
160- std::filesystem::perms::others_exec);
161- std::filesystem::remove (temp);
162- auto download_folder = executable_path / " cortex/" ;
163- std::filesystem::remove_all (download_folder);
164- } catch (const std::exception& e) {
165- CTL_WRN (" Something wrong happened: " << e.what ());
166- return ;
141+ auto src = executable_path / " cortex" / kCortexBinary / GetCortexBinary ();
142+ auto dst = executable_path / GetCortexBinary ();
143+ return ReplaceBinaryInflight (src, dst);
144+ }
145+
146+ bool CortexUpdCmd::GetNightly (const std::string& v) {
147+ // Check if the architecture and OS are supported
148+ auto system_info = system_info_utils::GetSystemInfo ();
149+ if (system_info.arch == system_info_utils::kUnsupported ||
150+ system_info.os == system_info_utils::kUnsupported ) {
151+ CTL_ERR (" Unsupported OS or architecture: " << system_info.os << " , "
152+ << system_info.arch );
153+ return false ;
167154 }
168- #endif
169- CLI_LOG (" Update cortex sucessfully" );
155+ CTL_INF (" OS: " << system_info.os << " , Arch: " << system_info.arch );
156+
157+ // Download file
158+ std::string version = v.empty () ? " latest" : std::move (v);
159+ std::ostringstream release_path;
160+ release_path << " cortex/" << version << " /" << system_info.os << " -"
161+ << system_info.arch << " /" << kNightlyFileName ;
162+ CTL_INF (" Engine release path: " << kNightlyHost << release_path.str ());
163+
164+ auto download_task = DownloadTask{.id = " cortex" ,
165+ .type = DownloadType::Cortex,
166+ .error = std::nullopt ,
167+ .items = {DownloadItem{
168+ .id = " cortex" ,
169+ .host = kNightlyHost ,
170+ .fileName = kNightlyFileName ,
171+ .type = DownloadType::Cortex,
172+ .path = release_path.str (),
173+ }}};
174+
175+ DownloadService download_service;
176+ download_service.AddDownloadTask (
177+ download_task, [this ](const std::string& absolute_path, bool unused) {
178+ // try to unzip the downloaded file
179+ std::filesystem::path download_path{absolute_path};
180+ CTL_INF (" Downloaded engine path: " << download_path.string ());
181+
182+ std::filesystem::path extract_path =
183+ download_path.parent_path ().parent_path ();
184+
185+ archive_utils::ExtractArchive (download_path.string (),
186+ extract_path.string ());
187+
188+ CTL_INF (" Finished!" );
189+ });
190+
191+ // Replace binay file
192+ auto executable_path = file_manager_utils::GetExecutableFolderContainerPath ();
193+ auto src = executable_path / " cortex" / GetCortexBinary ();
194+ auto dst = executable_path / GetCortexBinary ();
195+ return ReplaceBinaryInflight (src, dst);
170196}
197+
171198} // namespace commands
0 commit comments