Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(cli): occ error handling #595

Merged
merged 1 commit into from
Feb 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 54 additions & 20 deletions lib/UpdateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class UpdateCommand extends Command {
protected function configure(): void {
$this
->setName('update')
->setDescription('Updates the code of an Nextcloud instance')
->setDescription('Updates the code of a Nextcloud instance')
->setHelp('This command fetches the latest code that is announced via the updater server and safely replaces the existing code with the new one.')
->addOption('no-backup', null, InputOption::VALUE_NONE, 'Skip backup of current Nextcloud version')
->addOption('no-upgrade', null, InputOption::VALUE_NONE, "Don't automatically run occ upgrade");
Expand Down Expand Up @@ -266,9 +266,14 @@ protected function execute(InputInterface $input, OutputInterface $output) {
$this->updater->log('[info] update of code successful.');
$output->writeln('Update of code successful.');

//
// Handle `occ upgrade` run
//

if ($this->skipUpgrade) {
$output->writeln('Please now execute "./occ upgrade" to finish the upgrade.');
$this->updater->log('[info] "occ upgrade" was skipped');
$this->updater->log('[info] updater finished');
$output->writeln('Please execute "./occ upgrade" manually to finish the upgrade.');
return 0;
}

Expand All @@ -280,49 +285,78 @@ protected function execute(InputInterface $input, OutputInterface $output) {
$question = new ConfirmationQuestion('Should the "occ upgrade" command be executed? [Y/n] ', true);

if (!$helper->ask($input, $output, $question)) {
$output->writeln('Please now execute "./occ upgrade" to finish the upgrade.');
$this->updater->log('[info] "occ upgrade" was skipped');
$this->updater->log('[info] updater finished');
$output->writeln('Please execute "./occ upgrade" manually to finish the upgrade.');
return 0;
}
} else {
$this->updater->log('[info] updater run in non-interactive mode - occ upgrade is started');
$this->updater->log('[info] updater run in non-interactive mode - will start "occ upgrade" now');
$output->writeln('Updater run in non-interactive mode - will start "occ upgrade" now.');
$output->writeln('');
}

chdir($path . '/..');
chmod('occ', 0755); # TODO do this in the updater
system(PHP_BINARY . ' ./occ upgrade -v', $returnValue);
$occPath = $path . '/../occ';
if (!file_exists($occPath)) {
$this->updater->log('[error] FATAL: "occ" is missing from: ' . $occPath);
$output->writeln('');
throw new \Exception('FATAL: "occ" is missing from: ' . $occPath);
}
if (chmod($occPath, 0755) === false) { # TODO do this in the updater
throw new \Exception('FATAL: Unable to make "occ" executable: ' . $occPath);
}
$occRunCommand = PHP_BINARY . ' ' . $occPath;

$this->updater->log('[info] Starting "occ upgrade"');
system($occRunCommand . ' upgrade -v', $returnValue);
if ($returnValue === 0) {
$this->updater->log('[info] "occ upgrade" finished');
$output->writeln('');
$output->writeln('"occ upgrade" finished');
} else { // something went wrong
$this->updater->log('[info] "occ upgrade" failed - return code: ' . $returnValue);
$output->writeln('');
$output->writeln('"occ upgrade" failed - return code: ' . $returnValue);
$this->updater->log('[info] updater finished - with errors');
return $returnValue;
}

//
// Handle maintenance mode toggle
//

$output->writeln('');
if ($input->isInteractive()) {
/** @var QuestionHelper */
$helper = $this->getHelper('question');
$question = new ConfirmationQuestion($this->checkTexts[11] . ' [y/N] ', false);

if ($helper->ask($input, $output, $question)) {
$output->writeln('Maintenance mode kept active');
$this->updater->log('[info] updater finished - maintenance mode kept active');
return $returnValue;
$this->updater->log('[info] maintenance mode kept active');
$output->writeln('Please execute "./occ maintenance:mode --off" manually to finish the upgrade.');
$this->updater->log('[info] updater finished');
return 0;
}
} else {
$this->updater->log('[info] updater run in non-interactive mode - disabling maintenance mode');
$this->updater->log('[info] updater run in non-interactive mode - will disable maintenance mode now');
$output->writeln('Updater run in non-interactive mode - will disable maintenance mode now.');
$output->writeln('');
}

try {
system(PHP_BINARY . ' ./occ maintenance:mode --off', $returnValueMaintenanceMode);
$this->updater->log('[info] maintenance mode is disabled - return code: ' . $returnValueMaintenanceMode);
$this->updater->log('[info] Disabling maintenance mode');
system($occRunCommand . ' maintenance:mode --off', $returnValueMaintenanceMode);
if ($returnValueMaintenanceMode === 0) {
$this->updater->log('[info] maintenance mode disabled');
$output->writeln('');
$output->writeln('Maintenance mode is disabled');
} catch (\Exception $e) {
$this->updater->log('[info] maintenance mode can not be disabled');
$this->updater->logException($e);
return 0;
} else { // something went wrong
$this->updater->log('[info] Disabling maintenance mode failed - return code: ' . $returnValueMaintenanceMode);
$output->writeln('');
$output->writeln('Maintenance mode can not be disabled');
$output->writeln('Disabling Maintenance mode failed - return code:' . $returnValueMaintenanceMode);
$this->updater->log('[info] updater finished - with errors');
return $returnValueMaintenanceMode;
}

return $returnValue;
} else {
if ($this->shouldStop) {
$output->writeln('<error>Update stopped. To resume or retry just execute the updater again.</error>');
Expand Down
Binary file modified updater.phar
Binary file not shown.