Rename sendNotification to execCommandInContainer and reuse for upgrade method

Agent-Logs-Url: https://github.com/nextcloud/all-in-one/sessions/88744552-9d64-4de2-9f64-5a98a5e3b200

Co-authored-by: szaimen <42591237+szaimen@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-04-23 19:31:01 +00:00
committed by Simon L.
parent cc8f1e4f57
commit cfdf5bdd1f
5 changed files with 59 additions and 96 deletions

View File

@@ -24,10 +24,10 @@ if ($backupExitCode === 0) {
if (getenv('SEND_SUCCESS_NOTIFICATIONS') === "0") {
error_log("Daily backup successful! Only logging successful backup and not sending backup notification since that has been disabled! You can get further info by looking at the backup logs in the AIO interface.");
} else {
$dockerActionManager->sendNotification($nextcloudContainer, 'Daily backup successful!', 'You can get further info by looking at the backup logs in the AIO interface.');
$dockerActionManager->execCommandInContainer($nextcloudContainer, ['bash', '/notify.sh', 'Daily backup successful!', 'You can get further info by looking at the backup logs in the AIO interface.']);
}
}
if ($backupExitCode > 0) {
$dockerActionManager->sendNotification($nextcloudContainer, 'Daily backup failed!', 'You can get further info by looking at the backup logs in the AIO interface.');
$dockerActionManager->execCommandInContainer($nextcloudContainer, ['bash', '/notify.sh', 'Daily backup failed!', 'You can get further info by looking at the backup logs in the AIO interface.']);
}

View File

@@ -22,5 +22,5 @@ $nextcloudContainer = $containerDefinitionFetcher->GetContainerById($id);
$df = disk_free_space(DataConst::GetDataDirectory());
if ($df !== false && (int)$df < 1024 * 1024 * 1024 * 5) {
error_log("The drive that hosts the mastercontainer volume has less than 5 GB free space. Container updates and backups might not succeed due to that!");
$dockerActionManager->sendNotification($nextcloudContainer, 'Low on space!', 'The drive that hosts the mastercontainer volume has less than 5 GB free space. Container updates and backups might not succeed due to that!');
$dockerActionManager->execCommandInContainer($nextcloudContainer, ['bash', '/notify.sh', 'Low on space!', 'The drive that hosts the mastercontainer volume has less than 5 GB free space. Container updates and backups might not succeed due to that!']);
}

View File

@@ -21,6 +21,6 @@ $nextcloudContainer = $containerDefinitionFetcher->GetContainerById($id);
$isNextcloudImageOutdated = $dockerActionManager->isNextcloudImageOutdated();
if ($isNextcloudImageOutdated === true) {
$dockerActionManager->sendNotification($nextcloudContainer, 'AIO is outdated!', 'Please open the AIO interface or ask an administrator to update it. If you do not want to do it manually each time, you can enable the daily backup feature from the AIO interface which automatically updates all containers.', '/notify-all.sh');
$dockerActionManager->execCommandInContainer($nextcloudContainer, ['bash', '/notify-all.sh', 'AIO is outdated!', 'Please open the AIO interface or ask an administrator to update it. If you do not want to do it manually each time, you can enable the daily backup feature from the AIO interface which automatically updates all containers.']);
}

View File

@@ -22,9 +22,9 @@ $isMastercontainerUpdateAvailable = $dockerActionManager->IsMastercontainerUpdat
$isAnyUpdateAvailable = $dockerActionManager->isAnyUpdateAvailable();
if ($isMastercontainerUpdateAvailable === true) {
$dockerActionManager->sendNotification($nextcloudContainer, 'Mastercontainer update available!', 'Please open your AIO interface to update it. If you do not want to do it manually each time, you can enable the daily backup feature from the AIO interface which also automatically updates the mastercontainer.');
$dockerActionManager->execCommandInContainer($nextcloudContainer, ['bash', '/notify.sh', 'Mastercontainer update available!', 'Please open your AIO interface to update it. If you do not want to do it manually each time, you can enable the daily backup feature from the AIO interface which also automatically updates the mastercontainer.']);
}
if ($isAnyUpdateAvailable === true) {
$dockerActionManager->sendNotification($nextcloudContainer, 'Container updates available!', 'Please open your AIO interface to update them. If you do not want to do it manually each time, you can enable the daily backup feature from the AIO interface which also automatically updates your containers and your Nextcloud apps.');
$dockerActionManager->execCommandInContainer($nextcloudContainer, ['bash', '/notify.sh', 'Container updates available!', 'Please open your AIO interface to update them. If you do not want to do it manually each time, you can enable the daily backup feature from the AIO interface which also automatically updates your containers and your Nextcloud apps.']);
}

View File

@@ -760,49 +760,67 @@ readonly class DockerActionManager {
return true;
}
public function sendNotification(Container $container, string $subject, string $message, string $file = '/notify.sh'): void {
if ($this->GetContainerStartingState($container) === ContainerState::Running) {
public function execCommandInContainer(Container $container, array $cmd, ?\Closure $outputCallback = null): void {
if ($this->GetContainerStartingState($container) !== ContainerState::Running) {
return;
}
$containerName = $container->identifier;
$containerName = $container->identifier;
// schedule the exec
$url = $this->BuildApiUrl(sprintf('containers/%s/exec', urlencode($containerName)));
$response = json_decode(
$this->guzzleClient->request(
'POST',
$url,
[
'json' => [
'AttachStdout' => true,
'Tty' => true,
'Cmd' => [
'bash',
$file,
$subject,
$message
],
],
]
)->getBody()->getContents(),
true,
512,
JSON_THROW_ON_ERROR,
);
$id = $response['Id'];
// start the exec
$url = $this->BuildApiUrl(sprintf('exec/%s/start', $id));
// Create exec instance
$url = $this->BuildApiUrl(sprintf('containers/%s/exec', urlencode($containerName)));
$response = json_decode(
$this->guzzleClient->request(
'POST',
$url,
[
'json' => [
'Detach' => false,
'AttachStdout' => true,
'AttachStderr' => true,
'Tty' => true,
'Cmd' => $cmd,
],
]
);
)->getBody()->getContents(),
true,
512,
JSON_THROW_ON_ERROR,
);
$execId = $response['Id'];
// Start exec
$url = $this->BuildApiUrl(sprintf('exec/%s/start', $execId));
$requestOptions = [
'json' => [
'Detach' => false,
'Tty' => true,
],
];
if ($outputCallback !== null) {
$requestOptions['stream'] = true;
}
$startResponse = $this->guzzleClient->request('POST', $url, $requestOptions);
if ($outputCallback !== null) {
$body = $startResponse->getBody();
$buffer = '';
while (!$body->eof()) {
$chunk = $body->read(1024);
$buffer .= $chunk;
while (($pos = strpos($buffer, "\n")) !== false) {
$line = substr($buffer, 0, $pos);
$buffer = substr($buffer, $pos + 1);
$line = rtrim($line, "\r");
if ($line !== '') {
$outputCallback($line);
}
}
}
if (trim($buffer) !== '') {
$outputCallback(trim($buffer));
}
}
}
@@ -1028,63 +1046,8 @@ readonly class DockerActionManager {
}
public function RunNextcloudUpgradeToLatestMajor(\Closure $addToStreamingResponseBody): void {
$containerName = 'nextcloud-aio-nextcloud';
// Create exec instance
$url = $this->BuildApiUrl(sprintf('containers/%s/exec', urlencode($containerName)));
$response = json_decode(
$this->guzzleClient->request(
'POST',
$url,
[
'json' => [
'AttachStdout' => true,
'AttachStderr' => true,
'Tty' => true,
'Cmd' => ['bash', '/upgrade-latest-major.sh'],
],
]
)->getBody()->getContents(),
true,
512,
JSON_THROW_ON_ERROR,
);
$execId = $response['Id'];
// Start exec and stream output
$url = $this->BuildApiUrl(sprintf('exec/%s/start', $execId));
$streamResponse = $this->guzzleClient->request(
'POST',
$url,
[
'stream' => true,
'json' => [
'Detach' => false,
'Tty' => true,
],
]
);
$body = $streamResponse->getBody();
$buffer = '';
while (!$body->eof()) {
$chunk = $body->read(1024);
$buffer .= $chunk;
// Flush complete lines
while (($pos = strpos($buffer, "\n")) !== false) {
$line = substr($buffer, 0, $pos);
$buffer = substr($buffer, $pos + 1);
$line = rtrim($line, "\r");
if ($line !== '') {
$addToStreamingResponseBody($line);
}
}
}
// Flush any remaining output
if (trim($buffer) !== '') {
$addToStreamingResponseBody(trim($buffer));
}
$container = $this->containerDefinitionFetcher->GetContainerById('nextcloud-aio-nextcloud');
$this->execCommandInContainer($container, ['bash', '/upgrade-latest-major.sh'], $addToStreamingResponseBody);
}
public function SystemPrune(?\Closure $addToStreamingResponseBody = null): void {