diff options
| author | Dan Engelbrecht <[email protected]> | 2025-01-13 11:40:23 +0100 |
|---|---|---|
| committer | Dan Engelbrecht <[email protected]> | 2025-01-13 11:40:23 +0100 |
| commit | dda538aa2b24a4e99d719e96e5a82f21889612ab (patch) | |
| tree | 5c2f30abd66080870d8a6b7ce7b7d46a2e5c91d8 /src/zenutil/service.cpp | |
| parent | linux service stop (diff) | |
| download | zen-dda538aa2b24a4e99d719e96e5a82f21889612ab.tar.xz zen-dda538aa2b24a4e99d719e96e5a82f21889612ab.zip | |
generate unit file
Diffstat (limited to 'src/zenutil/service.cpp')
| -rw-r--r-- | src/zenutil/service.cpp | 74 |
1 files changed, 71 insertions, 3 deletions
diff --git a/src/zenutil/service.cpp b/src/zenutil/service.cpp index 01ef66431..d31786835 100644 --- a/src/zenutil/service.cpp +++ b/src/zenutil/service.cpp @@ -12,11 +12,17 @@ #endif #if ZEN_PLATFORM_MAC # include <zencore/filesystem.h> +# include <zencore/fmtutils.h> # include <unistd.h> # include <sys/stat.h> +#endif +#if ZEN_PLATFORM_LINUX +# include <zencore/filesystem.h> +# include <zencore/fmtutils.h> -# include <xpc/xpc.h> +# include <unistd.h> +# include <sys/stat.h> #endif namespace zen { @@ -228,7 +234,7 @@ namespace { "</dict>\n" "</plist>\n", DaemonName, - ExecutablePath.string(), + ExecutablePath, ProgramArguments.ToView(), ServiceName, ServiceName, @@ -354,6 +360,49 @@ namespace { #if ZEN_PLATFORM_LINUX // const char* SystemInstallFolder = "/etc/systemd/system/"; + +std::string GetUnitName(std::string_view ServiceName) { return fmt::format("com.epicgames.unreal.{}", ServiceName); } + +std::filesystem::path GetServiceUnitPath(const std::string& UnitName) +{ + const std::filesystem::path SystemUnitFolder = "/etc/systemd/system/"; + return SystemUnitFolder / (UnitName + ".service"); +} + +std::string BuildUnitFile(std::string_view ServiceName, + const std::filesystem::path& ExecutablePath, + std::string_view CommandLineOptions, + std::string_view AliasName) +{ + #if 0 + ZEN_UNUSED(ServiceName, ExecutablePath, CommandLineOptions, AliasName); + return ""; + #else + return fmt::format("[Unit]\n" + "Description={}\n" + "Documentation=https://github.com/epicgames/zen\n" + "\n" + "DefaultDependencies=no\n" + "After=network.target\n" + "StartLimitIntervalSec=0\n" + "\n" + "[Service]\n" + "Type=simple\n" + "Restart=always\n" + "RestartSec=1\n" + "User=serviceuser\n" + "ExecStart={} {}\n" + "Restart=always\n" + "RuntimeDirectory={}\n" + "[Install]\n" + "Alias={}", + ServiceName, + ExecutablePath, CommandLineOptions, + ExecutablePath.parent_path(), + AliasName); + #endif +} + #endif // ZEN_PLATFORM_LINUX } // namespace @@ -889,7 +938,26 @@ std::error_code InstallService(std::string_view ServiceName, const ServiceSpec& Spec) { ZEN_UNUSED(ServiceName, Spec); - ZEN_NOT_IMPLEMENTED("linux service implementation incomplete"); + + const std::string UnitName = GetUnitName(ServiceName); + std::string UnitFile = BuildUnitFile(ServiceName, Spec.ExecutablePath, Spec.CommandLineOptions, UnitName); + + const std::filesystem::path ServiceUnitPath = GetServiceUnitPath(UnitName); + ZEN_INFO("Writing systemd unit file to {}", ServiceUnitPath.string()); + try + { + zen::WriteFile(ServiceUnitPath, IoBuffer(IoBuffer::Wrap, UnitFile.data(), UnitFile.size())); + } + catch (const std::system_error& Ex) + { + return MakeErrorCode(Ex.code().value()); + } + + ZEN_INFO("Changing permissions to 644 for {}", ServiceUnitPath.string()); + if (chmod(ServiceUnitPath.string().c_str(), 0644) == -1) + { + return MakeErrorCodeFromLastError(); + } return {}; } |