aboutsummaryrefslogtreecommitdiff
path: root/src/zenutil/service.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2025-01-13 11:40:23 +0100
committerDan Engelbrecht <[email protected]>2025-01-13 11:40:23 +0100
commitdda538aa2b24a4e99d719e96e5a82f21889612ab (patch)
tree5c2f30abd66080870d8a6b7ce7b7d46a2e5c91d8 /src/zenutil/service.cpp
parentlinux service stop (diff)
downloadzen-dda538aa2b24a4e99d719e96e5a82f21889612ab.tar.xz
zen-dda538aa2b24a4e99d719e96e5a82f21889612ab.zip
generate unit file
Diffstat (limited to 'src/zenutil/service.cpp')
-rw-r--r--src/zenutil/service.cpp74
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 {};
}