backups: default is_successful to false

This commit is contained in:
Matthew Penner 2021-08-03 15:46:08 -06:00
parent b19a1640f0
commit c46131e7ad
8 changed files with 49 additions and 10 deletions

View file

@ -225,7 +225,7 @@ class BackupController extends ClientApiController
throw new BadRequestHttpException('This server is not currently in a state that allows for a backup to be restored.'); throw new BadRequestHttpException('This server is not currently in a state that allows for a backup to be restored.');
} }
if (!$backup->is_successful && !$backup->completed_at) { if (!$backup->is_successful && is_null($backup->completed_at)) {
throw new BadRequestHttpException('This backup cannot be restored at this time: not completed or failed.'); throw new BadRequestHttpException('This backup cannot be restored at this time: not completed or failed.');
} }

View file

@ -12,7 +12,7 @@ class ReportBackupCompleteRequest extends FormRequest
public function rules() public function rules()
{ {
return [ return [
'successful' => 'present|boolean', 'successful' => 'required|boolean',
'checksum' => 'nullable|string|required_if:successful,true', 'checksum' => 'nullable|string|required_if:successful,true',
'checksum_type' => 'nullable|string|required_if:successful,true', 'checksum_type' => 'nullable|string|required_if:successful,true',
'size' => 'nullable|numeric|required_if:successful,true', 'size' => 'nullable|numeric|required_if:successful,true',

View file

@ -64,7 +64,7 @@ class Backup extends Model
* @var array * @var array
*/ */
protected $attributes = [ protected $attributes = [
'is_successful' => true, 'is_successful' => false,
'is_locked' => false, 'is_locked' => false,
'checksum' => null, 'checksum' => null,
'bytes' => 0, 'bytes' => 0,

View file

@ -25,7 +25,8 @@ class BackupRepository extends EloquentRepository
return $this->getBuilder() return $this->getBuilder()
->withTrashed() ->withTrashed()
->where('server_id', $server) ->where('server_id', $server)
->where('is_successful', true) ->whereNull('completed_at')
->orWhere('is_successful', '=', true)
->where('created_at', '>=', Carbon::now()->subSeconds($seconds)->toDateTimeString()) ->where('created_at', '>=', Carbon::now()->subSeconds($seconds)->toDateTimeString())
->get() ->get()
->toBase(); ->toBase();

View file

@ -63,7 +63,7 @@ class DeleteBackupService
// I also don't really see any reason you'd have a locked, failed backup to keep // I also don't really see any reason you'd have a locked, failed backup to keep
// around. The logic that updates the backup to the failed state will also remove // around. The logic that updates the backup to the failed state will also remove
// the lock, so this condition should really never happen. // the lock, so this condition should really never happen.
if ($backup->is_locked && ($backup->completed_at && $backup->is_successful)) { if ($backup->is_locked && ($backup->is_successful && !is_null($backup->completed_at))) {
throw new BackupLockedException(); throw new BackupLockedException();
} }

View file

@ -132,8 +132,9 @@ class InitiateBackupService
} }
} }
// Check if the server has reached or exceeded it's backup limit. // Check if the server has reached or exceeded its backup limit.
$successful = $server->backups()->where('is_successful', true); // completed_at == null will cover any ongoing backups, while is_successful == true will cover any completed backups.
$successful = $server->backups()->whereNull('completed_at')->orWhere('is_successful', true);
if (!$server->backup_limit || $successful->count() >= $server->backup_limit) { if (!$server->backup_limit || $successful->count() >= $server->backup_limit) {
// Do not allow the user to continue if this server is already at its limit and can't override. // Do not allow the user to continue if this server is already at its limit and can't override.
if (!$override || $server->backup_limit <= 0) { if (!$override || $server->backup_limit <= 0) {

View file

@ -0,0 +1,37 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class ChangeSuccessfulFieldToDefaultToFalseOnBackupsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('backups', function (Blueprint $table) {
$table->boolean('is_successful')->after('uuid')->default(false)->change();
});
// Convert currently processing backups to the new format so things don't break.
DB::table('backups')->select('id')->where('is_successful', 1)->whereNull('completed_at')->update([
'is_successful' => 0,
]);
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('backups', function (Blueprint $table) {
$table->boolean('is_successful')->after('uuid')->default(true)->change();
});
}
}

View file

@ -44,7 +44,7 @@ export default ({ backup, className }: Props) => {
<GreyRowBox css={tw`flex-wrap md:flex-nowrap items-center`} className={className}> <GreyRowBox css={tw`flex-wrap md:flex-nowrap items-center`} className={className}>
<div css={tw`flex items-center truncate w-full md:flex-1`}> <div css={tw`flex items-center truncate w-full md:flex-1`}>
<div css={tw`mr-4`}> <div css={tw`mr-4`}>
{backup.completedAt ? {backup.completedAt !== null ?
backup.isLocked ? backup.isLocked ?
<FontAwesomeIcon icon={faLock} css={tw`text-yellow-500`}/> <FontAwesomeIcon icon={faLock} css={tw`text-yellow-500`}/>
: :
@ -55,7 +55,7 @@ export default ({ backup, className }: Props) => {
</div> </div>
<div css={tw`flex flex-col truncate`}> <div css={tw`flex flex-col truncate`}>
<div css={tw`flex items-center text-sm mb-1`}> <div css={tw`flex items-center text-sm mb-1`}>
{!backup.isSuccessful && {backup.completedAt !== null && !backup.isSuccessful &&
<span css={tw`bg-red-500 py-px px-2 rounded-full text-white text-xs uppercase border border-red-600 mr-2`}> <span css={tw`bg-red-500 py-px px-2 rounded-full text-white text-xs uppercase border border-red-600 mr-2`}>
Failed Failed
</span> </span>
@ -63,7 +63,7 @@ export default ({ backup, className }: Props) => {
<p css={tw`break-words truncate`}> <p css={tw`break-words truncate`}>
{backup.name} {backup.name}
</p> </p>
{(backup.completedAt && backup.isSuccessful) && {(backup.completedAt !== null && backup.isSuccessful) &&
<span css={tw`ml-3 text-neutral-300 text-xs font-extralight hidden sm:inline`}>{bytesToHuman(backup.bytes)}</span> <span css={tw`ml-3 text-neutral-300 text-xs font-extralight hidden sm:inline`}>{bytesToHuman(backup.bytes)}</span>
} }
</div> </div>