macos fixes
Some checks failed
BlockStorage/repertory_mac/pipeline/head There was a failure building this commit
BlockStorage/repertory/pipeline/head There was a failure building this commit

This commit is contained in:
2025-08-05 14:28:39 -05:00
parent f674017610
commit f73cd9b6cf
7 changed files with 115 additions and 9 deletions

View File

@@ -177,6 +177,7 @@ nuspell_version
oleaut32 oleaut32
openal_version openal_version
openssldir openssldir
osascript
osxfuse osxfuse
pistream pistream
pkgconfig pkgconfig

View File

@@ -614,7 +614,9 @@ public:
return mount_location_; return mount_location_;
} }
[[nodiscard]] auto mount(std::vector<std::string> args) -> int; [[nodiscard]] auto mount(std::vector<std::string> orig_args,
std::vector<std::string> args, provider_type prov,
std::string_view unique_id) -> int;
}; };
} // namespace repertory } // namespace repertory

View File

@@ -48,6 +48,15 @@ inline const std::array<std::string, 4U> attribute_namespaces = {
void windows_create_to_unix(const UINT32 &create_options, void windows_create_to_unix(const UINT32 &create_options,
const UINT32 &granted_access, std::uint32_t &flags, const UINT32 &granted_access, std::uint32_t &flags,
remote::file_mode &mode); remote::file_mode &mode);
#if defined(__APPLE__)
[[nodiscard]] auto
generate_launchd_plist(const std::string &label, std::string plist_path,
const std::vector<std::string> &args,
const std::string &working_dir = "/tmp",
const std::string &stdout_log = "/tmp/stdout.log",
const std::string &stderr_log = "/tmp/stderr.log")
-> bool;
#endif // defined(__APPLE__)
} // namespace repertory::utils } // namespace repertory::utils
#endif // !_WIN32 #endif // !_WIN32

View File

@@ -19,6 +19,7 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
*/ */
#include <unistd.h>
#if !defined(_WIN32) #if !defined(_WIN32)
#include "drives/fuse/fuse_base.hpp" #include "drives/fuse/fuse_base.hpp"
@@ -396,14 +397,16 @@ auto fuse_base::mkdir_(const char *path, mode_t mode) -> int {
}); });
} }
auto fuse_base::mount(std::vector<std::string> args) -> int { auto fuse_base::mount(std::vector<std::string> orig_args,
std::vector<std::string> args, provider_type prov,
std::string_view unique_id) -> int {
auto res = parse_args(args); auto res = parse_args(args);
if (res != 0) { if (res != 0) {
return res; return res;
} }
if (not foreground_ && not utils::collection::includes(args, "-f")) { if (not foreground_ && not utils::collection::includes(args, "-f")) {
args.emplace_back("-f"); args.insert(std::next(args.begin()), "-f");
} }
std::vector<const char *> fuse_argv(args.size()); std::vector<const char *> fuse_argv(args.size());
@@ -422,7 +425,7 @@ auto fuse_base::mount(std::vector<std::string> args) -> int {
fuse_parse_cmdline(&f_args, &opts); fuse_parse_cmdline(&f_args, &opts);
mount_location = opts.mountpoint; mount_location = opts.mountpoint;
#else // FUSE_USE_VERSION < 30 #else // FUSE_USE_VERSION < 30
fuse_parse_cmdline(&f_args, &mount_location, nullptr, nullptr); auto res = fuse_parse_cmdline(&f_args, &mount_location, nullptr, nullptr);
#endif // FUSE_USE_VERSION >= 30 #endif // FUSE_USE_VERSION >= 30
if (mount_location != nullptr) { if (mount_location != nullptr) {
@@ -432,6 +435,49 @@ auto fuse_base::mount(std::vector<std::string> args) -> int {
} }
} }
#if defined(__APPLE__)
if (not foreground_) {
if (not utils::file::change_to_process_directory()) {
std::cerr << "Failed to change to process directory" << std::endl;
return -1;
}
orig_args[0U] = utils::path::combine(".", {"repertory"});
orig_args.insert(std::next(orig_args.begin()), "-f");
auto label = std::format("com.fifthgrid.blockstorage.repertory.{}.{}",
provider_type_to_string(prov), unique_id);
if (not utils::generate_launchd_plist(
label, utils::path::combine("~", {"/Library/LaunchAgents"}),
orig_args, utils::path::absolute("."),
fmt::format("/tmp/repertory_{}_{}.out",
provider_type_to_string(prov), unique_id),
fmt::format("/tmp/repertory_{}_{}.err",
provider_type_to_string(prov), unique_id))) {
std::cerr << fmt::format("Failed to generate plist|{}", label)
<< std::endl;
return -1;
}
system(fmt::format("launchctl bootstrap gui/{} '{}' 1>/dev/null 2>&1",
getuid(),
utils::path::combine("~",
{
"/Library/LaunchAgents",
fmt::format("{}.plist", label),
}))
.c_str());
res = system(
fmt::format("launchctl kickstart gui/{}/{}", getuid(), label).c_str());
if (res != 0) {
std::cerr << fmt::format("Failed to kickstart {}/{}", getuid(), label)
<< std::endl;
}
return res;
}
#endif // defined(__APPLE__)
notify_fuse_args_parsed(args); notify_fuse_args_parsed(args);
const auto main_func = [&]() -> int { const auto main_func = [&]() -> int {
@@ -447,7 +493,6 @@ auto fuse_base::mount(std::vector<std::string> args) -> int {
return main_func(); return main_func();
} }
repertory::project_cleanup();
return utils::create_daemon(main_func); return utils::create_daemon(main_func);
} }

View File

@@ -273,6 +273,49 @@ auto create_daemon(std::function<int()> main_func) -> int {
return main_func(); return main_func();
} }
#if defined(__APPLE__)
auto generate_launchd_plist(const std::string &label, std::string plist_path,
const std::vector<std::string> &args,
const std::string &working_dir,
const std::string &stdout_log,
const std::string &stderr_log) -> bool {
pugi::xml_document doc;
auto decl = doc.append_child(pugi::node_declaration);
decl.append_attribute("version") = "1.0";
decl.append_attribute("encoding") = "UTF-8";
auto plist = doc.append_child("plist");
plist.append_attribute("version") = "1.0";
auto dict = plist.append_child("dict");
dict.append_child("key").text().set("Label");
dict.append_child("string").text().set(label.c_str());
dict.append_child("key").text().set("ProgramArguments");
auto array = dict.append_child("array");
for (const auto &arg : args) {
array.append_child("string").text().set(arg.c_str());
}
dict.append_child("key").text().set("WorkingDirectory");
dict.append_child("string").text().set(working_dir.c_str());
dict.append_child("key").text().set("KeepAlive");
dict.append_child("false");
dict.append_child("key").text().set("StandardOutPath");
dict.append_child("string").text().set(stdout_log.c_str());
dict.append_child("key").text().set("StandardErrorPath");
dict.append_child("string").text().set(stderr_log.c_str());
return doc.save_file(
utils::path::combine(plist_path, {label + ".plist"}).c_str(), " ",
pugi::format_indent | pugi::format_write_bom);
}
#endif // defined(__APPLE__)
} // namespace repertory::utils } // namespace repertory::utils
#endif // !defined(_WIN32) #endif // !defined(_WIN32)

View File

@@ -30,6 +30,12 @@ namespace repertory::cli::actions {
mount(std::vector<const char *> args, std::string data_directory, mount(std::vector<const char *> args, std::string data_directory,
int &mount_result, provider_type prov, const std::string &remote_host, int &mount_result, provider_type prov, const std::string &remote_host,
std::uint16_t remote_port, const std::string &unique_id) -> exit_code { std::uint16_t remote_port, const std::string &unique_id) -> exit_code {
std::vector<std::string> orig_args;
args.reserve(args.size());
for (const auto *arg : args) {
orig_args.emplace_back(arg);
}
lock_data global_lock(provider_type::unknown, "global"); lock_data global_lock(provider_type::unknown, "global");
{ {
auto lock_result = global_lock.grab_lock(100U); auto lock_result = global_lock.grab_lock(100U);
@@ -158,7 +164,7 @@ mount(std::vector<const char *> args, std::string data_directory,
} }
global_lock.release(); global_lock.release();
mount_result = drive.mount(drive_args); mount_result = drive.mount(orig_args, drive_args, prov, unique_id);
return exit_code::mount_result; return exit_code::mount_result;
} catch (const std::exception &e) { } catch (const std::exception &e) {
std::cerr << "FATAL: " << e.what() << std::endl; std::cerr << "FATAL: " << e.what() << std::endl;
@@ -180,7 +186,7 @@ mount(std::vector<const char *> args, std::string data_directory,
} }
global_lock.release(); global_lock.release();
mount_result = drive.mount(drive_args); mount_result = drive.mount(orig_args, drive_args, prov, unique_id);
return exit_code::mount_result; return exit_code::mount_result;
} catch (const std::exception &e) { } catch (const std::exception &e) {
std::cerr << "FATAL: " << e.what() << std::endl; std::cerr << "FATAL: " << e.what() << std::endl;

View File

@@ -42,7 +42,7 @@ unmount(std::vector<const char *> /* args */, const std::string &data_directory,
.unmount(); .unmount();
if (response.response_type == rpc_response_type::success) { if (response.response_type == rpc_response_type::success) {
auto orig_response{response}; auto orig_response{response};
std::cout << "waiting for unmount ..." << std::flush; std::cout << "Waiting for unmount..." << std::flush;
for (std::uint8_t retry{0U}; for (std::uint8_t retry{0U};
retry < retry_count && retry < retry_count &&
response.response_type == rpc_response_type::success; response.response_type == rpc_response_type::success;