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
openal_version
openssldir
osascript
osxfuse
pistream
pkgconfig

View File

@@ -614,7 +614,9 @@ public:
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

View File

@@ -48,6 +48,15 @@ inline const std::array<std::string, 4U> attribute_namespaces = {
void windows_create_to_unix(const UINT32 &create_options,
const UINT32 &granted_access, std::uint32_t &flags,
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
#endif // !_WIN32

View File

@@ -19,6 +19,7 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include <unistd.h>
#if !defined(_WIN32)
#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);
if (res != 0) {
return res;
}
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());
@@ -422,7 +425,7 @@ auto fuse_base::mount(std::vector<std::string> args) -> int {
fuse_parse_cmdline(&f_args, &opts);
mount_location = opts.mountpoint;
#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
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);
const auto main_func = [&]() -> int {
@@ -447,7 +493,6 @@ auto fuse_base::mount(std::vector<std::string> args) -> int {
return main_func();
}
repertory::project_cleanup();
return utils::create_daemon(main_func);
}

View File

@@ -273,6 +273,49 @@ auto create_daemon(std::function<int()> main_func) -> int {
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
#endif // !defined(_WIN32)

View File

@@ -30,6 +30,12 @@ namespace repertory::cli::actions {
mount(std::vector<const char *> args, std::string data_directory,
int &mount_result, provider_type prov, const std::string &remote_host,
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");
{
auto lock_result = global_lock.grab_lock(100U);
@@ -129,7 +135,7 @@ mount(std::vector<const char *> args, std::string data_directory,
constexpr const std::uint8_t retry_count{30U};
std::cout << "Connecting to remote [" << remote_host << ':' << remote_port
<< "] ..." << std::flush;
<< "]..." << std::flush;
auto online{false};
for (std::uint8_t retry{0U}; not online && retry < retry_count; ++retry) {
online = remote_client(config).check() == 0;
@@ -158,7 +164,7 @@ mount(std::vector<const char *> args, std::string data_directory,
}
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;
} catch (const std::exception &e) {
std::cerr << "FATAL: " << e.what() << std::endl;
@@ -180,7 +186,7 @@ mount(std::vector<const char *> args, std::string data_directory,
}
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;
} catch (const std::exception &e) {
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();
if (response.response_type == rpc_response_type::success) {
auto orig_response{response};
std::cout << "waiting for unmount ..." << std::flush;
std::cout << "Waiting for unmount..." << std::flush;
for (std::uint8_t retry{0U};
retry < retry_count &&
response.response_type == rpc_response_type::success;