fix(launcher): require executable Linux hosts
This commit is contained in:
parent
10a712d66b
commit
ae2cbbee8c
5 changed files with 134 additions and 10 deletions
|
|
@ -12,12 +12,14 @@ namespace AcDream.Launcher.Core.Orchestration;
|
|||
public sealed class LauncherExecutableSet
|
||||
{
|
||||
private readonly Func<string, bool> _fileExists;
|
||||
private readonly Func<string, bool> _hasUnixExecutePermission;
|
||||
|
||||
public LauncherExecutableSet(
|
||||
string graphicalHostPath,
|
||||
string headlessHostPath,
|
||||
string? workingDirectory = null,
|
||||
Func<string, bool>? fileExists = null)
|
||||
Func<string, bool>? fileExists = null,
|
||||
Func<string, bool>? hasUnixExecutePermission = null)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(graphicalHostPath);
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(headlessHostPath);
|
||||
|
|
@ -25,6 +27,8 @@ public sealed class LauncherExecutableSet
|
|||
HeadlessHostPath = headlessHostPath;
|
||||
WorkingDirectory = workingDirectory;
|
||||
_fileExists = fileExists ?? File.Exists;
|
||||
_hasUnixExecutePermission =
|
||||
hasUnixExecutePermission ?? HasUnixExecutePermission;
|
||||
}
|
||||
|
||||
public string GraphicalHostPath { get; }
|
||||
|
|
@ -38,17 +42,25 @@ public sealed class LauncherExecutableSet
|
|||
string path = mode == LaunchMode.Headless
|
||||
? HeadlessHostPath
|
||||
: GraphicalHostPath;
|
||||
if (_fileExists(path))
|
||||
{
|
||||
return LauncherCapability.Available;
|
||||
}
|
||||
|
||||
string host = mode == LaunchMode.Headless
|
||||
? "headless host"
|
||||
: "graphical client";
|
||||
return LauncherCapability.Unavailable(
|
||||
$"The co-deployed {host} is missing at '{path}'. Reinstall or update "
|
||||
+ "the client before launching.");
|
||||
if (!_fileExists(path))
|
||||
{
|
||||
return LauncherCapability.Unavailable(
|
||||
$"The co-deployed {host} is missing at '{path}'. Reinstall or update "
|
||||
+ "the client before launching.");
|
||||
}
|
||||
|
||||
if (OperatingSystem.IsLinux() && !_hasUnixExecutePermission(path))
|
||||
{
|
||||
return LauncherCapability.Unavailable(
|
||||
$"The co-deployed {host} at '{path}' exists but is not executable. "
|
||||
+ "Restore its executable permission (for example, chmod +x) or "
|
||||
+ "reinstall/update the client before launching.");
|
||||
}
|
||||
|
||||
return LauncherCapability.Available;
|
||||
}
|
||||
|
||||
public LauncherProcessSpec CreatePlaySpec(
|
||||
|
|
@ -99,4 +111,27 @@ public sealed class LauncherExecutableSet
|
|||
capability.Reason ?? "The selected launcher host is unavailable.");
|
||||
}
|
||||
}
|
||||
|
||||
private static bool HasUnixExecutePermission(string path)
|
||||
{
|
||||
if (!OperatingSystem.IsLinux())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
const UnixFileMode executeBits =
|
||||
UnixFileMode.UserExecute
|
||||
| UnixFileMode.GroupExecute
|
||||
| UnixFileMode.OtherExecute;
|
||||
return (File.GetUnixFileMode(path) & executeBits) != 0;
|
||||
}
|
||||
catch (Exception ex) when (ex is IOException or UnauthorizedAccessException)
|
||||
{
|
||||
// Fail closed if the file vanished or its metadata cannot be read
|
||||
// after the existence check. The next capability refresh retries.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue