Custom Commands: Typen (Hintergrund/Vordergrund/Nachricht) mit Output-Modal
This commit is contained in:
1 parent
d83a6f60ef
commit
ab234fde69
8 files changed
+241
-36
No files matched your search
@@ -159,6 +159,7 @@ public static class SessionEndpoint
|
||||
|
||||
var body = await JsonSerializer.DeserializeAsync<JsonElement>(ctx.Request.Body);
|
||||
var command = body.TryGetProperty("command", out var c) ? c.GetString() : null;
|
||||
var mode = body.TryGetProperty("mode", out var m) ? m.GetString() ?? "background" : "background";
|
||||
|
||||
if (string.IsNullOrWhiteSpace(command))
|
||||
{
|
||||
@@ -169,35 +170,97 @@ public static class SessionEndpoint
|
||||
|
||||
var workingDir = !string.IsNullOrWhiteSpace(session.Workspace) ? session.Workspace : "/tmp";
|
||||
|
||||
try
|
||||
if (mode == "foreground")
|
||||
{
|
||||
var scriptPath = $"/tmp/gott-exec-{Guid.NewGuid():N}.sh";
|
||||
await System.IO.File.WriteAllTextAsync(scriptPath, $"#!/bin/bash\ncd {workingDir}\n{command}\nrm -f {scriptPath}\n");
|
||||
|
||||
var psi = new ProcessStartInfo
|
||||
// Synchron ausführen, auf Ergebnis warten
|
||||
try
|
||||
{
|
||||
FileName = "systemd-run",
|
||||
Arguments = $"--scope --quiet bash {scriptPath}",
|
||||
WorkingDirectory = workingDir,
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
CreateNoWindow = true
|
||||
};
|
||||
var psi = new ProcessStartInfo
|
||||
{
|
||||
FileName = "/bin/bash",
|
||||
WorkingDirectory = workingDir,
|
||||
RedirectStandardInput = true,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true
|
||||
};
|
||||
|
||||
var process = Process.Start(psi);
|
||||
if (process != null)
|
||||
using var proc = System.Diagnostics.Process.Start(psi);
|
||||
if (proc == null)
|
||||
{
|
||||
ctx.Response.StatusCode = 500;
|
||||
await ctx.Response.WriteAsJsonAsync(new { error = "Prozess konnte nicht gestartet werden" });
|
||||
return;
|
||||
}
|
||||
|
||||
await proc.StandardInput.WriteAsync(command);
|
||||
proc.StandardInput.Close();
|
||||
|
||||
using var cts = new System.Threading.CancellationTokenSource(TimeSpan.FromSeconds(30));
|
||||
try
|
||||
{
|
||||
await proc.WaitForExitAsync(cts.Token);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
proc.Kill(entireProcessTree: true);
|
||||
await ctx.Response.WriteAsJsonAsync(new { status = "timeout", output = "Timeout nach 30 Sekunden", exitCode = -1 });
|
||||
return;
|
||||
}
|
||||
|
||||
var stdout = await proc.StandardOutput.ReadToEndAsync();
|
||||
var stderr = await proc.StandardError.ReadToEndAsync();
|
||||
|
||||
var output = new System.Text.StringBuilder();
|
||||
if (!string.IsNullOrEmpty(stdout)) output.Append(stdout);
|
||||
if (!string.IsNullOrEmpty(stderr))
|
||||
{
|
||||
if (output.Length > 0) output.Append("\n--- stderr ---\n");
|
||||
output.Append(stderr);
|
||||
}
|
||||
|
||||
await ctx.Response.WriteAsJsonAsync(new { status = "completed", output = output.ToString(), exitCode = proc.ExitCode });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
process.WaitForExit(500);
|
||||
ctx.Response.StatusCode = 500;
|
||||
await ctx.Response.WriteAsJsonAsync(new { error = ex.Message });
|
||||
}
|
||||
|
||||
ctx.Response.StatusCode = 202;
|
||||
await ctx.Response.WriteAsJsonAsync(new { status = "started", command = command });
|
||||
}
|
||||
catch (Exception ex)
|
||||
else
|
||||
{
|
||||
ctx.Response.StatusCode = 500;
|
||||
await ctx.Response.WriteAsJsonAsync(new { error = ex.Message });
|
||||
// Fire-and-forget via systemd-run
|
||||
try
|
||||
{
|
||||
var scriptPath = $"/tmp/gott-exec-{Guid.NewGuid():N}.sh";
|
||||
await System.IO.File.WriteAllTextAsync(scriptPath, $"#!/bin/bash\ncd {workingDir}\n{command}\nrm -f {scriptPath}\n");
|
||||
|
||||
var psi = new ProcessStartInfo
|
||||
{
|
||||
FileName = "systemd-run",
|
||||
Arguments = $"--scope --quiet bash {scriptPath}",
|
||||
WorkingDirectory = workingDir,
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
CreateNoWindow = true
|
||||
};
|
||||
|
||||
var process = Process.Start(psi);
|
||||
if (process != null)
|
||||
{
|
||||
process.WaitForExit(500);
|
||||
}
|
||||
|
||||
ctx.Response.StatusCode = 202;
|
||||
await ctx.Response.WriteAsJsonAsync(new { status = "started", command = command });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ctx.Response.StatusCode = 500;
|
||||
await ctx.Response.WriteAsJsonAsync(new { error = ex.Message });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user