fix(storage): persist S3 settings for new volume backups (#11635)

This commit is contained in:
Andras Bacsai 2026-09-05 15:18:26 +02:00 committed by GitHub
parent 47c61feb84
commit 2a25e0490e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 119 additions and 9 deletions

View file

@ -147,7 +147,11 @@ public function updatedS3StorageId(): void
} }
$this->resetErrorBag('s3StorageId'); $this->resetErrorBag('s3StorageId');
$this->backup?->update(['s3_storage_id' => $this->s3StorageId]); if (! $this->validateSettings()) {
return;
}
$this->backup = $this->persistBackup($this->enabled);
$this->dispatch('success', 'S3 storage updated.'); $this->dispatch('success', 'S3 storage updated.');
} }
@ -163,11 +167,11 @@ public function toggleS3(): void
$this->saveToS3 = ! $this->saveToS3; $this->saveToS3 = ! $this->saveToS3;
$this->disableLocalBackup = $this->saveToS3 && $this->disableLocalBackup; $this->disableLocalBackup = $this->saveToS3 && $this->disableLocalBackup;
$this->backup?->update([ if (! $this->validateSettings()) {
'save_s3' => $this->saveToS3, return;
'disable_local_backup' => $this->disableLocalBackup, }
's3_storage_id' => $this->s3StorageId,
]); $this->backup = $this->persistBackup($this->enabled);
$this->dispatch('success', $this->saveToS3 ? 'S3 backups enabled.' : 'S3 backups disabled.'); $this->dispatch('success', $this->saveToS3 ? 'S3 backups enabled.' : 'S3 backups disabled.');
} }

View file

@ -960,6 +960,67 @@
expect($backup->refresh()->save_s3)->toBeFalse(); expect($backup->refresh()->save_s3)->toBeFalse();
}); });
it('persists S3 settings the first time when a volume backup schedule does not exist yet', function () {
$team = Team::factory()->create();
signInForVolumeBackups($this, $team);
[$application, $volume] = createVolumeBackupApplication($team);
$s3Storage = S3Storage::create([
'name' => 'Volume backups',
'region' => 'us-east-1',
'key' => 'key',
'secret' => 'secret',
'bucket' => 'bucket',
'endpoint' => 'https://s3.example.com',
'team_id' => $team->id,
'is_usable' => true,
]);
Livewire::test(VolumeBackups::class, [
'storage' => $volume,
'resource' => $application,
'section' => 's3',
])
->assertSet('s3StorageId', $s3Storage->id)
->call('toggleS3')
->assertSet('saveToS3', true)
->assertDispatched('success');
$backup = ScheduledVolumeBackup::query()->sole();
expect($backup->enabled)->toBeFalse()
->and($backup->save_s3)->toBeTrue()
->and($backup->s3_storage_id)->toBe($s3Storage->id);
});
it('persists the selected S3 storage when a volume backup schedule does not exist yet', function () {
$team = Team::factory()->create();
signInForVolumeBackups($this, $team);
[$application, $volume] = createVolumeBackupApplication($team);
$s3Storage = S3Storage::create([
'name' => 'Volume backups',
'region' => 'us-east-1',
'key' => 'key',
'secret' => 'secret',
'bucket' => 'bucket',
'endpoint' => 'https://s3.example.com',
'team_id' => $team->id,
'is_usable' => true,
]);
Livewire::test(VolumeBackups::class, [
'storage' => $volume,
'resource' => $application,
'section' => 's3',
])
->set('s3StorageId', $s3Storage->id)
->assertDispatched('success');
$backup = ScheduledVolumeBackup::query()->sole();
expect($backup->enabled)->toBeFalse()
->and($backup->s3_storage_id)->toBe($s3Storage->id);
});
it('shows and saves volume S3 retention while S3 backups are disabled', function () { it('shows and saves volume S3 retention while S3 backups are disabled', function () {
$team = Team::factory()->create(); $team = Team::factory()->create();
signInForVolumeBackups($this, $team); signInForVolumeBackups($this, $team);
@ -1004,7 +1065,7 @@
])->assertDontSee('You do not have permission to perform this action.'); ])->assertDontSee('You do not have permission to perform this action.');
}); });
it('only updates S3 fields when toggling volume S3 backups', function () { it('does not enable S3 backups when another volume backup setting is invalid', function () {
$team = Team::factory()->create(); $team = Team::factory()->create();
signInForVolumeBackups($this, $team); signInForVolumeBackups($this, $team);
[$application, $volume] = createVolumeBackupApplication($team); [$application, $volume] = createVolumeBackupApplication($team);
@ -1031,9 +1092,54 @@
]) ])
->set('frequency', 'not a valid schedule') ->set('frequency', 'not a valid schedule')
->call('toggleS3') ->call('toggleS3')
->assertDispatched('success'); ->assertHasErrors('frequency')
->assertNotDispatched('success');
expect($backup->refresh()->save_s3)->toBeTrue() expect($backup->refresh()->save_s3)->toBeFalse()
->and($backup->frequency)->toBe('daily');
});
it('does not change S3 storage when another volume backup setting is invalid', function () {
$team = Team::factory()->create();
signInForVolumeBackups($this, $team);
[$application, $volume] = createVolumeBackupApplication($team);
$firstS3Storage = S3Storage::create([
'name' => 'First storage',
'region' => 'us-east-1',
'key' => 'first-key',
'secret' => 'secret',
'bucket' => 'first-bucket',
'endpoint' => 'https://s3.example.com',
'team_id' => $team->id,
'is_usable' => true,
]);
$secondS3Storage = S3Storage::create([
'name' => 'Second storage',
'region' => 'us-east-1',
'key' => 'second-key',
'secret' => 'secret',
'bucket' => 'second-bucket',
'endpoint' => 'https://s3.example.com',
'team_id' => $team->id,
'is_usable' => true,
]);
$backup = $volume->scheduledBackups()->create([
'team_id' => $team->id,
'frequency' => 'daily',
's3_storage_id' => $firstS3Storage->id,
]);
Livewire::test(VolumeBackups::class, [
'storage' => $volume,
'resource' => $application,
'section' => 's3',
])
->set('frequency', 'not a valid schedule')
->set('s3StorageId', $secondS3Storage->id)
->assertHasErrors('frequency')
->assertNotDispatched('success');
expect($backup->refresh()->s3_storage_id)->toBe($firstS3Storage->id)
->and($backup->frequency)->toBe('daily'); ->and($backup->frequency)->toBe('daily');
}); });