diff --git a/app/Console/Commands/NetgesconNodeRefreshCommand.php b/app/Console/Commands/NetgesconNodeRefreshCommand.php
index 0acc5b1..e0827d5 100644
--- a/app/Console/Commands/NetgesconNodeRefreshCommand.php
+++ b/app/Console/Commands/NetgesconNodeRefreshCommand.php
@@ -15,6 +15,7 @@ class NetgesconNodeRefreshCommand extends Command
{--force : Continua anche con working tree sporco lato sync}
{--require-drive : Fallisce se il backup Drive non viene completato}
{--skip-backup : Salta backup pre-update (solo test/debug)}
+ {--skip-composer : Salta composer install/autoload (solo recovery su nodi con vendor non scrivibile)}
{--skip-migrate : Salta php artisan migrate --force}
{--skip-maintenance : Salta php artisan down/up (solo test/debug)}
{--skip-view-cache : Salta rebuild view cache}
@@ -31,6 +32,7 @@ public function handle(): int
$driveBackup = (bool) $this->option('drive');
$requireDrive = (bool) $this->option('require-drive');
$skipBackup = (bool) $this->option('skip-backup');
+ $skipComposer = (bool) $this->option('skip-composer');
$skipMigrate = (bool) $this->option('skip-migrate');
$skipMaintenance = (bool) $this->option('skip-maintenance');
$skipViewCache = (bool) $this->option('skip-view-cache');
@@ -118,24 +120,29 @@ public function handle(): int
$fullOutput[] = 'NODE REFRESH: netgescon:git-sync';
$fullOutput[] = $gitOutput;
- $this->writeProgress(46, 'Composer install e autoload', 'running');
- $composerResult = $this->runShellStep([
- 'composer',
- 'install',
- '--no-interaction',
- '--prefer-dist',
- '--optimize-autoloader',
- '--no-progress',
- ]);
- $fullOutput[] = 'NODE REFRESH: composer install --no-interaction --prefer-dist --optimize-autoloader --no-progress';
- $fullOutput[] = $composerResult['output'];
+ if (! $skipComposer) {
+ $this->writeProgress(46, 'Composer install e autoload', 'running');
+ $composerResult = $this->runShellStep([
+ 'composer',
+ 'install',
+ '--no-interaction',
+ '--prefer-dist',
+ '--optimize-autoloader',
+ '--no-progress',
+ ]);
+ $fullOutput[] = 'NODE REFRESH: composer install --no-interaction --prefer-dist --optimize-autoloader --no-progress';
+ $fullOutput[] = $composerResult['output'];
- if (! $composerResult['success']) {
- $this->error('Composer install fallito.');
- $this->line($composerResult['output']);
- $this->writeProgress(100, 'Composer install fallito', 'failed', $composerResult['exit_code']);
+ if (! $composerResult['success']) {
+ $this->error('Composer install fallito.');
+ $this->line($composerResult['output']);
+ $this->writeProgress(100, 'Composer install fallito', 'failed', $composerResult['exit_code']);
- return self::FAILURE;
+ return self::FAILURE;
+ }
+ } else {
+ $this->writeProgress(46, 'Composer install saltato (recovery)', 'running');
+ $fullOutput[] = 'NODE REFRESH: composer install saltato via --skip-composer';
}
$this->writeProgress(58, 'Build frontend se disponibile', 'running');
diff --git a/app/Filament/Pages/Supporto/Modifiche.php b/app/Filament/Pages/Supporto/Modifiche.php
index e3895cd..bbceec9 100644
--- a/app/Filament/Pages/Supporto/Modifiche.php
+++ b/app/Filament/Pages/Supporto/Modifiche.php
@@ -358,6 +358,21 @@ public function runNodeRefreshFallback(): void
$this->startNodeRefreshJob(true);
}
+ public function runNodeRefreshSkipComposer(): void
+ {
+ if (! $this->canRunUpdate()) {
+ Notification::make()
+ ->title('Permessi insufficienti')
+ ->body('Solo super-admin/admin/amministratore possono lanciare il refresh completo del nodo.')
+ ->danger()
+ ->send();
+
+ return;
+ }
+
+ $this->startNodeRefreshJob(true, true);
+ }
+
public function generateDevelopmentSnapshot(): void
{
if (! $this->canRunUpdate()) {
@@ -1764,7 +1779,7 @@ private function startGitSyncJob(): void
->send();
}
- private function startNodeRefreshJob(bool $skipMaintenance = false): void
+ private function startNodeRefreshJob(bool $skipMaintenance = false, bool $skipComposer = false): void
{
$jobId = now()->format('YmdHis') . '-' . Str::lower(Str::random(6));
$jobsDir = storage_path('app/support/update-jobs');
@@ -1778,17 +1793,21 @@ private function startNodeRefreshJob(bool $skipMaintenance = false): void
$this->updateJobId = $jobId;
$this->updateInProgress = true;
$this->updateProgressPercent = 1;
- $this->updateProgressMessage = $skipMaintenance
- ? 'Preparazione refresh nodo da Gitea senza maintenance mode...'
- : 'Preparazione refresh nodo da Gitea...';
+ $this->updateProgressMessage = $skipComposer
+ ? 'Preparazione refresh nodo da Gitea senza maintenance e senza composer...'
+ : ($skipMaintenance
+ ? 'Preparazione refresh nodo da Gitea senza maintenance mode...'
+ : 'Preparazione refresh nodo da Gitea...');
$this->updateProgressStatus = 'running';
@file_put_contents($progressPath, json_encode([
'timestamp' => now()->toIso8601String(),
'percent' => 1,
- 'message' => $skipMaintenance
- ? 'Preparazione refresh nodo da Gitea senza maintenance mode...'
- : 'Preparazione refresh nodo da Gitea...',
+ 'message' => $skipComposer
+ ? 'Preparazione refresh nodo da Gitea senza maintenance e senza composer...'
+ : ($skipMaintenance
+ ? 'Preparazione refresh nodo da Gitea senza maintenance mode...'
+ : 'Preparazione refresh nodo da Gitea...'),
'status' => 'running',
'exit_code' => null,
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
@@ -1818,6 +1837,10 @@ private function startNodeRefreshJob(bool $skipMaintenance = false): void
$args[] = '--skip-maintenance';
}
+ if ($skipComposer) {
+ $args[] = '--skip-composer';
+ }
+
if ($driveEnabled && $adminId > 0) {
$args[] = '--drive';
$args[] = '--admin-id=' . $adminId;
@@ -1849,9 +1872,11 @@ private function startNodeRefreshJob(bool $skipMaintenance = false): void
Notification::make()
->title('Refresh nodo avviato')
- ->body($skipMaintenance
- ? 'Refresh nodo avviato senza maintenance mode. Usalo solo come percorso di riserva su macchine dove il blocco accessi non si attiva.'
- : 'Sync da Gitea, migrate e rebuild cache verranno eseguiti direttamente sul nodo da browser.')
+ ->body($skipComposer
+ ? 'Refresh nodo avviato senza maintenance e senza composer. Usalo solo come recovery su macchine dove vendor non e scrivibile dal processo web.'
+ : ($skipMaintenance
+ ? 'Refresh nodo avviato senza maintenance mode. Usalo solo come percorso di riserva su macchine dove il blocco accessi non si attiva.'
+ : 'Sync da Gitea, migrate e rebuild cache verranno eseguiti direttamente sul nodo da browser.'))
->success()
->send();
}
diff --git a/resources/views/filament/pages/supporto/aggiornamento-launcher.blade.php b/resources/views/filament/pages/supporto/aggiornamento-launcher.blade.php
index bd344fa..7831d66 100644
--- a/resources/views/filament/pages/supporto/aggiornamento-launcher.blade.php
+++ b/resources/views/filament/pages/supporto/aggiornamento-launcher.blade.php
@@ -65,6 +65,9 @@