Address review: add startStreamingResponse helper, stream prune output, restore button location

Co-authored-by: szaimen <42591237+szaimen@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-03-20 15:24:24 +00:00
parent 95f23defeb
commit 8b63032955
3 changed files with 26 additions and 26 deletions

View File

@@ -202,16 +202,7 @@ readonly class DockerController {
error_log('WARNING: Not pulling container images. Instead, using local ones.');
}
$nonbufResp = $response
->withBody(new NonBufferedBody())
->withHeader('Content-Type', 'text/html; charset=utf-8')
->withHeader('X-Accel-Buffering', 'no')
->withHeader('Cache-Control', 'no-cache');
// Text written into this body is immediately sent to the client, without waiting for later content.
$streamingResponseBody = $nonbufResp->getBody();
$streamingResponseBody->write($this->getStreamingResponseHtmlStart());
[$nonbufResp, $streamingResponseBody] = $this->startStreamingResponse($response);
// Create a closure to pass around to the code, which should to the logging (because it e.g. decides
// if it'll actually pull an image), but which should not need to know anything about the
@@ -286,14 +277,7 @@ readonly class DockerController {
}
public function SystemPrune(Request $request, Response $response, array $args) : Response {
$nonbufResp = $response
->withBody(new NonBufferedBody())
->withHeader('Content-Type', 'text/html; charset=utf-8')
->withHeader('X-Accel-Buffering', 'no')
->withHeader('Cache-Control', 'no-cache');
$streamingResponseBody = $nonbufResp->getBody();
$streamingResponseBody->write($this->getStreamingResponseHtmlStart());
[$nonbufResp, $streamingResponseBody] = $this->startStreamingResponse($response);
$addToStreamingResponseBody = function (string $message) use ($streamingResponseBody) : void {
$streamingResponseBody->write("<div>{$message}</div>");
@@ -352,6 +336,20 @@ readonly class DockerController {
$this->PerformRecursiveContainerStop($id);
}
private function startStreamingResponse(Response $response) : array {
$nonbufResp = $response
->withBody(new NonBufferedBody())
->withHeader('Content-Type', 'text/html; charset=utf-8')
->withHeader('X-Accel-Buffering', 'no')
->withHeader('Cache-Control', 'no-cache');
// Text written into this body is immediately sent to the client, without waiting for later content.
$streamingResponseBody = $nonbufResp->getBody();
$streamingResponseBody->write($this->getStreamingResponseHtmlStart());
return [$nonbufResp, $streamingResponseBody];
}
private function getStreamingResponseHtmlStart() : string {
return <<<END
<!DOCTYPE html>

View File

@@ -1007,7 +1007,11 @@ readonly class DockerActionManager {
}
try {
$this->guzzleClient->post($url);
$resp = $this->guzzleClient->post($url);
$body = (string) $resp->getBody();
if ($addToStreamingResponseBody !== null && $body !== '') {
$addToStreamingResponseBody($body);
}
} catch (RequestException $e) {
error_log(sprintf('Docker prune (%s) failed: %s', $endpoint, $e->getMessage()));
if ($addToStreamingResponseBody !== null) {

View File

@@ -322,6 +322,11 @@
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
<input type="submit" value="Stop containers" />
</form>
<form method="POST" action="api/docker/prune" target="overlay-log">
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
<input type="submit" value="Run docker system prune" onclick="return confirm('Run docker system prune? This will remove unused images, containers and volumes. Continue?')" />
</form>
{% endif %}
{% else %}
{% if isBackupOrRestoreRunning == true %}
@@ -367,13 +372,6 @@
</form>
{% endif %}
{% endif %}
{% if was_start_button_clicked == true %}
<form method="POST" action="api/docker/prune" target="overlay-log">
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
<input type="submit" value="Run docker system prune" onclick="return confirm('Run docker system prune? This will remove unused images, containers and volumes. Continue?')" />
</form>
{% endif %}
{% endif %}
{% endif %}